diff --git a/lua/kulala/augroups/init.lua b/lua/kulala/augroups/init.lua new file mode 100644 index 0000000..210da68 --- /dev/null +++ b/lua/kulala/augroups/init.lua @@ -0,0 +1,67 @@ +local Config = require("kulala.config") +local Parser = require("kulala.parser") +local Float = require("kulala.ui.float") +local Db = require("kulala.db") + +local M = {} + +local show_variable_info_text = function() + local line = vim.api.nvim_get_current_line() + local db_env = Db.find_unique("env") + if db_env == nil then + return nil + end + local variables = Parser.get_document() + if variables == nil then + return nil + end + variables = vim.tbl_extend("force", variables, db_env) + -- get variable under cursor + -- a variable is a string that starts with two {{ and ends with two }} + local cursor = vim.api.nvim_win_get_cursor(0) + local start_col = cursor[2] + local end_col = cursor[2] + while start_col > 0 and line:sub(start_col, start_col) ~= "{" do + start_col = start_col - 1 + end + while end_col < #line and line:sub(end_col, end_col) ~= "}" do + end_col = end_col + 1 + end + if start_col == 0 or end_col == #line then + return nil + end + local variable = line:sub(start_col + 1, end_col - 1) + local variable_value = variables[variable] or "{{" .. variable .. "}}" + return Float.create({ + contents = { variable_value }, + position = "cursor", + }) +end + +M.setup = function() + if Config.get().show_variable_info_text == "float" then + local augroup = vim.api.nvim_create_augroup("kulala_show_float_variable_info_text", { clear = true }) + local float_win_id = nil + local timer = nil + vim.api.nvim_create_autocmd("CursorMoved", { + group = augroup, + callback = function() + if float_win_id then + vim.api.nvim_win_close(float_win_id, true) + float_win_id = nil + end + if timer then + vim.fn.timer_stop(timer) + timer = nil + end + vim.schedule(function() + timer = vim.fn.timer_start(1000, function() + float_win_id = show_variable_info_text() + end) + end) + end, + }) + end +end + +return M diff --git a/lua/kulala/config/init.lua b/lua/kulala/config/init.lua index 79590b9..9c41061 100644 --- a/lua/kulala/config/init.lua +++ b/lua/kulala/config/init.lua @@ -71,6 +71,10 @@ M.defaults = { -- set scope for environment and request variables -- possible values: b = buffer, g = global environment_scope = "b", + -- enable/disable variable info text + -- this will show the variable name and value either as virtual text or float + -- possible values: false, "virtual", "float" + show_variable_info_text = false, } M.default_contenttype = { diff --git a/lua/kulala/init.lua b/lua/kulala/init.lua index 6593235..c091761 100644 --- a/lua/kulala/init.lua +++ b/lua/kulala/init.lua @@ -7,10 +7,12 @@ local JUMPS = require("kulala.jumps") local Graphql = require("kulala.graphql") local Logger = require("kulala.logger") local ScriptsUtils = require("kulala.scripts.utils") +local Augroups = require("kulala.augroups") local M = {} M.setup = function(config) CONFIG.setup(config) + Augroups.setup() end M.run = function() diff --git a/lua/kulala/ui/float.lua b/lua/kulala/ui/float.lua new file mode 100644 index 0000000..ffe41b2 --- /dev/null +++ b/lua/kulala/ui/float.lua @@ -0,0 +1,81 @@ +local M = {} + +---@enum FloatPosition +local FLOAT_POSITION = { + Center = "center", + Cursor = "cursor", +} + +---@class FloatOpts +---@field contents string[] @Contents of the buffer +---@field ft string? @Filetype of the buffer +---@field focusable boolean? @Whether the window is focusable +---@field position FloatPosition @Position of the floating window + +---Creates a floating window with the contents passed via opts +---@param opts FloatOpts +---@return integer, integer @Window and buffer IDs +M.create = function(opts) + -- Create a new buffer + local buf = vim.api.nvim_create_buf(false, true) + + -- Set the content of the buffer + vim.api.nvim_buf_set_lines(buf, 0, -1, false, opts.contents) + + if opts.ft then + vim.bo[buf].filetype = opts.ft + end + + -- Get the total dimensions of the editor + local total_width = vim.o.columns + local total_height = vim.o.lines + + -- Calculate the content dimensions + local content_width = 0 + for _, line in ipairs(opts.contents) do + if #line > content_width then + content_width = #line + end + end + local content_height = #opts.contents + + -- Ensure the window doesn't exceed the total size + local win_width = math.min(content_width, math.floor(total_width)) + local win_height = math.min(content_height, math.floor(total_height)) + + local row = 0 + local col = 0 + + if opts.position == FLOAT_POSITION.Center then + -- Ensure the window doesn't exceed 80% of the total size + win_width = math.min(content_width, math.floor(total_width * 0.8)) + win_height = math.min(content_height, math.floor(total_height * 0.8)) + -- Calculate the window position to center it + row = math.floor((total_height - win_height) / 2) + col = math.floor((total_width - win_width) / 2) + elseif opts.position == FLOAT_POSITION.Cursor then + -- Calculate the window position to center it around the cursor + row = vim.fn.line(".") - math.floor(win_height / 2) + col = vim.fn.col(".") - math.floor(win_width / 2) + end + + -- Define the floating window configuration + local win_config = { + relative = "editor", + width = win_width, + height = win_height, + row = row, + col = col, + style = "minimal", + border = "rounded", + focusable = opts.focusable or false, + } + + -- Create the floating window with the buffer + local win = vim.api.nvim_open_win(buf, opts.focusable or false, win_config) + + -- Return the window and buffer IDs + return win, buf +end + +return M