Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Clean code for popfix from scratch #4

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
todo
neovim
neovim/*
.fdignore
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
PJ_ROOT=$(PWD)

BUSTED_ARGS = \
--lpath=$(PJ_ROOT)/lua/?.lua \
--lpath=$(PJ_ROOT)/tests/?.lua \

TEST_FILE = $(PJ_ROOT)/tests/pop_test_spec.lua

neovim:
git clone --depth 1 https://github.com/neovim/neovim
make -C $@

.PHONY: test
test: neovim
make -C neovim functionaltest \
BUSTED_ARGS="$(BUSTED_ARGS)" \
TEST_FILE="$(TEST_FILE)"

1 change: 0 additions & 1 deletion lua/popfix/.gitignore

This file was deleted.

64 changes: 0 additions & 64 deletions lua/popfix/action.lua

This file was deleted.

213 changes: 110 additions & 103 deletions lua/popfix/floating_win.lua
Original file line number Diff line number Diff line change
@@ -1,123 +1,130 @@
local M = {}
local api = vim.api
local autocmd = require'popfix.autocmd'

local M = {}

local default_opts = {
relative = "editor",
width = 80,
height = 40,
row = 0,
col = 0,
title = "",
options = {},
border = false,
}

local default_border_chars = {
TOP_LEFT = '┌',
TOP_RIGHT = '┐',
MID_HORIZONTAL = '─',
MID_VERTICAL = '│',
BOTTOM_LEFT = '└',
BOTTOM_RIGHT = '┘',
TOP_LEFT = '┌',
TOP_RIGHT = '┐',
MID_HORIZONTAL = '─',
MID_VERTICAL = '│',
BOTTOM_LEFT = '└',
BOTTOM_RIGHT = '┘',
}

local function create_win(row, col, width, height, relative, focusable)
local buf = api.nvim_create_buf(false, true)
local options = {
style = "minimal",
relative = relative,
width = width,
height = height,
row = row,
col = col,
focusable = focusable
}
local win = api.nvim_open_win(buf, false, options)
return {
buf = buf,
win = win
}
local function addDefaultWindowOpts(opts, focusable)
opts.style = "minimal"
focusable = focusable
end

local function createTopLine(char, str, width)
local len
if str == nil then
len = 2
else
len = #str + 2
end
local returnString = ''
if len ~= 2 then
returnString = returnString .. string.rep(char, math.floor(width/2 - len/2))
.. ' ' .. str .. ' '
local remaining = width - (len + math.floor(width / 2 - len / 2))
returnString = returnString .. string.rep(char, remaining)
return returnString
else
returnString = returnString .. string.rep(char, width)
return returnString
end
local function createFloatingWindow(opts, focusable)
local buffer = api.nvim_create_buf(false, true)
addDefaultWindowOpts(opts, focusable)
local window = api.nvim_open_win(buffer, false, opts)
return window, buffer
end

local function fill_border_data(buf, width, height, title, border_chars)
border_chars = border_chars or default_border_chars
border_chars.TOP_LEFT = border_chars.TOP_LEFT or ' '
border_chars.TOP_RIGHT = border_chars.TOP_RIGHT or ' '
border_chars.MID_HORIZONTAL = border_chars.MID_HORIZONTAL or ' '
border_chars.MID_VERTICAL = border_chars.MID_VERTICAL or ' '
border_chars.BOTTOM_LEFT = border_chars.BOTTOM_LEFT or ' '
border_chars.BOTTOM_RIGHT = border_chars.BOTTOM_RIGHT or ' '
local topLine = createTopLine(border_chars.MID_HORIZONTAL, title, width)
local border_lines = { border_chars.TOP_LEFT.. topLine ..
border_chars.TOP_RIGHT}
local middle_line = border_chars.MID_VERTICAL.. string.rep(' ', width)
..border_chars.MID_VERTICAL
for _=1, height do
table.insert(border_lines, middle_line)
end
table.insert(border_lines, border_chars.BOTTOM_LEFT..
string.rep(border_chars.MID_HORIZONTAL, width) ..border_chars.BOTTOM_RIGHT)
local function createWindowOpts(opts)
return {
row = opts.row,
column = opts.column,
height = opts.height,
width = opts.width,
relative = opts.relative
}
end

api.nvim_buf_set_lines(buf, 0, -1, false, border_lines)
local function createBorderOpts(opts)
return {
row = opts.row - 1,
col = opts.col - 1,
width = opts.width + 2,
height = opts.height + 2,
relative = opts.relative
}
end

function M.create_win(opts)
opts.width = opts.width or default_opts.width
opts.height = opts.height or default_opts.height
opts.title = opts.title or default_opts.title
opts.row = opts.row or default_opts.row
opts.col = opts.col or default_opts.col
opts.relative = opts.relative or "editor"
if opts.border == nil then
opts.border = default_opts.border
end
local function setBorderHighlight(borderWindow)
api.nvim_win_set_option(borderWindow, 'winhl', 'Normal:Normal')
end

local border_buf = nil
local function redrawUI()
vim.cmd('redraw')
end

local function createBorderTopLine(char, str, width)
local len
if str == nil then
len = 2
else
len = #str + 2
end
local returnString = ''
if len ~= 2 then
returnString = returnString .. string.rep(char, math.floor(width/2 - len/2))
.. ' ' .. str .. ' '
local remaining = width - (len + math.floor(width / 2 - len / 2))
returnString = returnString .. string.rep(char, remaining)
return returnString
else
returnString = returnString .. string.rep(char, width)
return returnString
end
end

local win_buf_pair = create_win(opts.row, opts.col, opts.width, opts.height, opts.relative, true)
if opts.border then
local border_win_buf_pair = create_win(opts.row - 1, opts.col - 1,
opts.width + 2, opts.height + 2, opts.relative, false)
api.nvim_win_set_option(border_win_buf_pair.win, 'winhl', 'Normal:Normal'
)
vim.cmd('redraw')
api.nvim_buf_set_option(border_win_buf_pair.buf, 'bufhidden', 'hide')
border_buf = border_win_buf_pair.buf
fill_border_data(border_buf, opts.width , opts.height, opts.title , opts.border_chars)
end
local function fillBorderData(borderBuffer, width, height, title, chars)
local topLine = createBorderTopLine(chars.MID_HORIZONTAL, title, width)
local border_lines = { chars.TOP_LEFT.. topLine ..
chars.TOP_RIGHT}
local middle_line = chars.MID_VERTICAL.. string.rep(' ', width)
..chars.MID_VERTICAL
for _=1, height do
table.insert(border_lines, middle_line)
end
table.insert(border_lines, chars.BOTTOM_LEFT..
string.rep(chars.MID_HORIZONTAL, width) ..chars.BOTTOM_RIGHT)

if opts.border then
local autocmds = {
['BufDelete,BufWipeout'] = string.format('bwipeout! %s', border_buf),
['nested'] = true,
['once'] = true
}
autocmd.addCommand(win_buf_pair.buf, autocmds)
end
return win_buf_pair
api.nvim_buf_set_lines(borderBuffer, 0, -1, false, border_lines)
end

local function getBorderCharacters(border_chars)
border_chars = border_chars or default_border_chars
border_chars.TOP_LEFT = border_chars.TOP_LEFT or ' '
border_chars.TOP_RIGHT = border_chars.TOP_RIGHT or ' '
border_chars.MID_HORIZONTAL = border_chars.MID_HORIZONTAL or ' '
border_chars.MID_VERTICAL = border_chars.MID_VERTICAL or ' '
border_chars.BOTTOM_LEFT = border_chars.BOTTOM_LEFT or ' '
border_chars.BOTTOM_RIGHT = border_chars.BOTTOM_RIGHT or ' '
return border_chars
end

local function drawBorders(opts)
local borderOpts = createBorderOpts(opts)
local window, buffer = createFloatingWindow(borderOpts, false)
setBorderHighlight(window)
redrawUI()
local borderCharacters = getBorderCharacters(opts.border_chars)
fillBorderData(buffer, borderOpts.width, borderOpts.height,
borderOpts.title, borderCharacters)
return window, buffer
end

local function addAutocmdBorderCloseOnMainBufferClose(buffer, borderBuffer)
local autocmds = {
['BufDelete,BufWipeout'] = string.format('bwipeout! %s', borderBuffer),
['nested'] = true,
['once'] = true
}
autocmd.addCommand(buffer, autocmds)
end

function M.create_win(opts)
local windowOpts = createWindowOpts(opts)
local window, buffer = createFloatingWindow(windowOpts, true)
if opts.border then
local _, borderBuffer = drawBorders(opts)
addAutocmdBorderCloseOnMainBufferClose(buffer, borderBuffer)
end
return window, buffer
end

return M
Loading