diff options
Diffstat (limited to 'lua/mo')
| -rw-r--r-- | lua/mo/org-agenda.lua | 134 | ||||
| -rw-r--r-- | lua/mo/org.lua | 21 |
2 files changed, 155 insertions, 0 deletions
diff --git a/lua/mo/org-agenda.lua b/lua/mo/org-agenda.lua new file mode 100644 index 0000000..fd7ed63 --- /dev/null +++ b/lua/mo/org-agenda.lua @@ -0,0 +1,134 @@ +local Menu = {} + +local default_config = { + window = { + margin = { 1, 0, 1, 0 }, + padding = { 1, 1, 1, 1 }, + title_pos = "center", + border = { "", "-", "", "", "", "", "", "" }, + zindex = 1000, + }, + icons = { + separator = "➜", + }, +} + +function Menu:new(config) + config = vim.tbl_deep_extend("force", default_config, config or {}) + + local opts = {} + opts.window = config.window + opts.icons = config.icons + + setmetatable(opts, self) + self.__index = self + return opts +end + +function Menu:_get_window_margins() + local margins = {} + + for i, m in ipairs(self.window.margin) do + local _m = m + if m > 0 and m < 1 then + if i % 2 == 0 then + _m = math.floor(vim.o.columns * m) + else + _m = math.floor(vim.o.lines * m) + end + end + margins[i] = _m + end + + return margins +end + +local function add_vertical_padding(content, size) + for _ = 1, size do + table.insert(content, "") + end +end + +function Menu:_process_items(items) + local pad_top, pad_right, pad_bot, pad_left = unpack(self.window.padding) + + local content = {} + local keys = {} + + add_vertical_padding(content, pad_top) + + for _, item in ipairs(items) do + if item.key then + keys[item.key] = item + + table.insert(content, string.rep(" ", pad_left) .. vim.fn.join({ + item.key, + self.icons.separator, + item.label, + }) .. string.rep(" ", pad_right)) + end + end + + add_vertical_padding(content, pad_bot) + + return keys, content +end + +function Menu:_open_window(title, content) + local margins = self:_get_window_margins() + local wins = vim.tbl_filter( + function(w) + return vim.api.nvim_win_is_valid(w) + and vim.api.nvim_win_get_config(w).relative == "" + end, + vim.api.nvim_list_wins() + ) + + local line_lengths = vim.tbl_map(function(s) return #s end, content) + line_lengths[#line_lengths + 1] = #title + local pref_width = vim.fn.max(line_lengths) + + self.buffer = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_lines(self.buffer, 0, -1, true, content) + + local window = vim.api.nvim_open_win(self.buffer, false, { + title = title, + title_pos = self.window.title_pos, + relative = "editor", + width = vim.fn.min({ vim.o.columns, pref_width }) + - margins[2] + - margins[4], + height = #content, + focusable = false, + anchor = "SW", + border = self.window.border, + row = vim.o.lines + - margins[3] + + ((vim.o.laststatus == 0 or vim.o.laststatus == 1 and #wins == 1) and 1 or 0) + - vim.o.cmdheight, + col = margins[4], + style = "minimal", + noautocmd = true, + } --[[@as vim.api.keyset.win_config]]) + vim.api.nvim__redraw({ win = window, valid = true }) + return window +end + +function Menu:_close() + vim.api.nvim_win_close(self.window, true) + vim.api.nvim_buf_delete(self.buffer, { force = true }) + vim.cmd.redraw() +end + +function Menu:open(data) + local keys, content = self:_process_items(data.items) + self.window = self:_open_window(data.title, content) + + local char = vim.fn.nr2char(vim.fn.getchar()) + self:_close() + + local entry = keys[char] + if entry and entry.action then return entry.action() end +end + +return Menu diff --git a/lua/mo/org.lua b/lua/mo/org.lua new file mode 100644 index 0000000..2218112 --- /dev/null +++ b/lua/mo/org.lua @@ -0,0 +1,21 @@ +--- @diagnostic disable: missing-fields + +if not package.loaded["fzf-lua"] then + vim.cmd([[packadd fzf-lua]]) +end + +require("orgmode").setup({ + org_agenda_files = "~/org/**/*", + org_default_notes_file = "~/org/refile.org", + + ui = { + input = { use_vim_ui = true }, + menu = { + handler = function(data) + require("mo.org-agenda"):new():open(data) + end + } + }, +} --[[@as OrgConfigOpts]]) + +vim.lsp.enable({ "org" }) |
