From 82dd670c0e4867419969cb55bd9c3a5e7ea73ddc Mon Sep 17 00:00:00 2001 From: kjuulh Date: Fri, 14 Oct 2022 17:26:26 +0200 Subject: [PATCH] Add base plugin --- .stylua.toml | 7 ++++ lua/ranger/actions.lua | 43 ++++++++++++++++++++ lua/ranger/commands.lua | 7 ++++ lua/ranger/floating.lua | 89 +++++++++++++++++++++++++++++++++++++++++ lua/ranger/init.lua | 11 +++++ 5 files changed, 157 insertions(+) create mode 100644 .stylua.toml create mode 100644 lua/ranger/actions.lua create mode 100644 lua/ranger/commands.lua create mode 100644 lua/ranger/floating.lua create mode 100644 lua/ranger/init.lua diff --git a/.stylua.toml b/.stylua.toml new file mode 100644 index 0000000..2bbca2c --- /dev/null +++ b/.stylua.toml @@ -0,0 +1,7 @@ +column_width = 100 +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 2 +quote_style = "AutoPreferDouble" +call_parentheses = "None" +collapse_simple_statement = "Always" diff --git a/lua/ranger/actions.lua b/lua/ranger/actions.lua new file mode 100644 index 0000000..c181cc6 --- /dev/null +++ b/lua/ranger/actions.lua @@ -0,0 +1,43 @@ +local prev_win = -1 + +local function on_exit(job_id, code, event) + if code ~= 0 then return end + + vim.cmd "silent! :q" + RANGER_BUFFER = nil + RANGER_LOADED = false + vim.g.ranger_opened = 0 + vim.cmd "silent! :checktime" + + if vim.fn.filereadable "/tmp/ranger-choose" then + for _, f in pairs(vim.fn.readfile "/tmp/ranger-choose") do + vim.cmd(string.format("silent! :edit %s", f)) + return + end + vim.cmd [[call delete("/tmp/ranger-choose")]] + end +end + +local function exec_ranger_command(cmd) + if RANGER_LOADED == false then + vim.g.ranger_opened = 1 + vim.fn.termopen(cmd, { on_exit = on_exit }) + end + vim.cmd "silent! :startinsert" +end + +local M = {} + +function M.ranger() + prev_win = vim.api.nvim_get_current_win + + require("ranger.floating").open_floating_window() + + local cmd = "ranger" + + cmd = string.format("%s --choosefiles=%s %s", cmd, "/tmp/ranger-choose", vim.fn.expand "%") + + exec_ranger_command(cmd) +end + +return M diff --git a/lua/ranger/commands.lua b/lua/ranger/commands.lua new file mode 100644 index 0000000..13d0e82 --- /dev/null +++ b/lua/ranger/commands.lua @@ -0,0 +1,7 @@ +local M = {} + +function M.setup() + vim.api.nvim_create_user_command("Ranger", function() require("ranger.actions").ranger() end, {}) +end + +return M diff --git a/lua/ranger/floating.lua b/lua/ranger/floating.lua new file mode 100644 index 0000000..d787d84 --- /dev/null +++ b/lua/ranger/floating.lua @@ -0,0 +1,89 @@ +local api = vim.api + +--- open floating window with nice borders +local function open_floating_window() + local floating_window_scaling_factor = vim.g.ranger_floating_window_scaling_factor + + -- Why is this required? + -- vim.g.ranger_floating_window_scaling_factor returns different types if the value is an integer or float + if type(floating_window_scaling_factor) == "table" then + floating_window_scaling_factor = floating_window_scaling_factor[false] + end + + local status, plenary = pcall(require, "plenary.window.float") + if + status + and vim.g.ranger_floating_window_use_plenary + and vim.g.ranger_floating_window_use_plenary ~= 0 + then + plenary.percentage_range_window(floating_window_scaling_factor, floating_window_scaling_factor) + return + end + + local height = math.ceil(vim.o.lines * floating_window_scaling_factor) - 1 + local width = math.ceil(vim.o.columns * floating_window_scaling_factor) + + local row = math.ceil(vim.o.lines - height) / 2 + local col = math.ceil(vim.o.columns - width) / 2 + + local border_opts = { + style = "minimal", + relative = "editor", + row = row - 1, + col = col - 1, + width = width + 2, + height = height + 2, + } + + local opts = + { style = "minimal", relative = "editor", row = row, col = col, width = width, height = height } + + local topleft, topright, botleft, botright + local corner_chars = vim.g.ranger_floating_window_corner_chars + if type(corner_chars) == "table" and #corner_chars == 4 then + topleft, topright, botleft, botright = unpack(corner_chars) + else + topleft, topright, botleft, botright = "╭", "╮", "╰", "╯" + end + + local border_lines = { topleft .. string.rep("─", width) .. topright } + local middle_line = "│" .. string.rep(" ", width) .. "│" + for i = 1, height do + table.insert(border_lines, middle_line) + end + table.insert(border_lines, botleft .. string.rep("─", width) .. botright) + + -- create a unlisted scratch buffer for the border + local border_buffer = api.nvim_create_buf(false, true) + + -- set border_lines in the border buffer from start 0 to end -1 and strict_indexing false + api.nvim_buf_set_lines(border_buffer, 0, -1, true, border_lines) + -- create border window + local border_window = api.nvim_open_win(border_buffer, true, border_opts) + vim.cmd "set winhl=Normal:Floating" + + -- create a unlisted scratch buffer + if RANGER_BUFFER == nil or vim.fn.bufwinnr(RANGER_BUFFER) == -1 then + RANGER_BUFFER = api.nvim_create_buf(false, true) + else + RANGER_LOADED = true + end + -- create file window, enter the window, and use the options defined in opts + local _ = api.nvim_open_win(RANGER_BUFFER, true, opts) + + vim.bo[RANGER_BUFFER].filetype = "ranger" + + vim.cmd "setlocal bufhidden=hide" + vim.cmd "setlocal nocursorcolumn" + vim.cmd("set winblend=" .. vim.g.ranger_floating_window_winblend) + + -- use autocommand to ensure that the border_buffer closes at the same time as the main buffer + local cmd = [[autocmd WinLeave silent! execute 'hide']] + vim.cmd(cmd) + cmd = [[autocmd WinLeave silent! execute 'silent bdelete! %s']] + vim.cmd(cmd:format(border_buffer)) +end + +return { + open_floating_window = open_floating_window, +} diff --git a/lua/ranger/init.lua b/lua/ranger/init.lua new file mode 100644 index 0000000..405aa4d --- /dev/null +++ b/lua/ranger/init.lua @@ -0,0 +1,11 @@ +RANGER_BUFFER = nil +RANGER_LOADED = false +vim.g.ranger_opened = 0 +vim.g.ranger_floating_window_winblend = 0 +vim.g.ranger_floating_window_scaling_factor = 0.9 + +local M = {} + +function M.setup(options) require("ranger.commands").setup() end + +return M