diff --git a/lua/r/doc.lua b/lua/r/doc.lua index 0be131bc..2c82b2f6 100644 --- a/lua/r/doc.lua +++ b/lua/r/doc.lua @@ -5,6 +5,7 @@ local utils = require("r.utils") local cursor = require("r.cursor") local job = require("r.job") local doc_buf_id = nil +local doc_win_id = -1 -- for `nvimpager = "float"` local M = {} @@ -90,16 +91,52 @@ M.show = function(rkeyword, txt) vim.cmd("set switchbuf=" .. savesb) end + txt = txt:gsub("\019", "'") + local lines + local is_help = false + if txt:find("\008") then + lines = require("r.rdoc").fix_rdoc(txt) + is_help = true + else + lines = vim.split(txt, "\020") + end + if doc_buf_id and vim.api.nvim_buf_is_loaded(doc_buf_id) then local savesb = vim.o.switchbuf vim.o.switchbuf = "useopen,usetab" vim.cmd.sb(doc_buf_id) vim.cmd("set switchbuf=" .. savesb) else - if vpager == "tab" or vpager == "float" then + if vpager == "tab" then vim.cmd("tabnew R_doc") elseif vpager == "split_v" then vim.cmd("vsplit R_doc") + elseif vpager == "float" then + if not doc_buf_id or not vim.api.nvim_buf_is_valid(doc_buf_id) then + doc_buf_id = vim.api.nvim_create_buf(true, false) + end + if not vim.api.nvim_win_is_valid(doc_win_id) then + local ncolumns = vim.api.nvim_win_get_width(0) + local nlines = vim.api.nvim_win_get_height(0) + local width = 80 + if ncolumns >= 60 and ncolumns <= 120 then + for _, v in pairs(lines) do + local linelen = #v + if linelen + 1 > width then width = linelen + 1 end + end + width = math.min(width, 120) + end + local height = math.ceil(nlines * 0.6) + local col = math.floor((ncolumns - width) / 2) + local row = math.floor((nlines - height) / 2) + doc_win_id = utils.open_float_win(doc_buf_id, { + title = " R Help ", + width = width, + height = height, + col = col, + row = row, + }) + end else if vim.fn.winwidth(0) < 80 then vim.cmd("topleft split R_doc") @@ -119,15 +156,6 @@ M.show = function(rkeyword, txt) vim.api.nvim_set_option_value("modifiable", true, { scope = "local" }) vim.api.nvim_buf_set_lines(0, 0, -1, true, {}) - txt = txt:gsub("\019", "'") - local lines - local is_help = false - if txt:find("\008") then - lines = require("r.rdoc").fix_rdoc(txt) - is_help = true - else - lines = vim.split(txt, "\020") - end vim.api.nvim_buf_set_lines(0, 0, -1, true, lines) if rkeyword:find("R History", 1, true) then vim.api.nvim_set_option_value("filetype", "r", { scope = "local" }) diff --git a/lua/r/edit.lua b/lua/r/edit.lua index 2f8149ae..5a9f074d 100644 --- a/lua/r/edit.lua +++ b/lua/r/edit.lua @@ -6,6 +6,7 @@ local rscript_buf = 0 local debug_info = { Time = {} } local assign_key = nil local pipe_key = nil +local edit_win_id = -1 -- for `nvimpager = "float"` local M = {} @@ -489,19 +490,42 @@ M.open_example = function() end end + local example_path = vim.fs.joinpath(config.tmpdir, "example.R"):gsub(" ", "\\ ") + if config.nvimpager == "tabnew" or config.nvimpager == "tab" then - vim.cmd("tabnew " .. vim.fs.joinpath(config.tmpdir, "example.R"):gsub(" ", "\\ ")) + vim.cmd("tabnew " .. example_path) else if config.nvimpager == "split_v" then - vim.cmd( - "belowright vsplit " - .. vim.fs.joinpath(config.tmpdir, "example.R"):gsub(" ", "\\ ") - ) + vim.cmd("belowright vsplit " .. example_path) + elseif config.nvimpager == "float" then + local buf = vim.api.nvim_create_buf(true, false) + if not vim.api.nvim_win_is_valid(edit_win_id) then + local ncolumns = vim.api.nvim_win_get_width(0) + local nlines = vim.api.nvim_win_get_height(0) + local width = 80 + if ncolumns >= 60 and ncolumns <= 120 then + -- set width to longest line length + 1 + local lines = vim.fn.readfile(example_path) + for _, v in pairs(lines) do + local linelen = #v + if linelen + 1 > width then width = linelen + 1 end + end + width = math.min(width, 120) + end + local height = math.ceil(nlines * 0.6) + local col = math.floor((ncolumns - width) / 2) + local row = math.floor((nlines - height) / 2) + edit_win_id = require("r.utils").open_float_win(buf, { + title = " R Example ", + width = width, + height = height, + col = col, + row = row, + }) + end + vim.cmd("edit " .. example_path) else - vim.cmd( - "belowright split " - .. vim.fs.joinpath(config.tmpdir, "example.R"):gsub(" ", "\\ ") - ) + vim.cmd("belowright split " .. example_path) end end vim.api.nvim_buf_set_keymap(0, "n", "q", ":q", { noremap = true, silent = true }) diff --git a/lua/r/utils.lua b/lua/r/utils.lua index 097b5429..500651e3 100644 --- a/lua/r/utils.lua +++ b/lua/r/utils.lua @@ -448,4 +448,33 @@ M.dedent = function(text) return table.concat(lines, "\n") end +---@param buf integer +---@param win_opts vim.api.keyset.win_config +---@return integer +M.open_float_win = function(buf, win_opts) + win_opts = win_opts or {} + -- centered relative to the whole editor by default + local width = 80 + local height = math.ceil(vim.o.lines * 0.6) + local col = math.floor((vim.o.columns - width) / 2) + local row = math.floor((vim.o.lines - height) / 2) + local default_win_opts = { + relative = "editor", + width = width, + height = height, + col = col, + row = row, + style = "minimal", + border = "single", + title_pos = "center", + } + + local win_id = vim.api.nvim_open_win( + buf, + true, + vim.tbl_extend("force", default_win_opts, win_opts) + ) + return win_id +end + return M