add stuff
This commit is contained in:
+7
-1
@@ -98,7 +98,13 @@
|
||||
(keymap :n "gD" vim.lsp.buf.declaration opts)
|
||||
(keymap :n "gr" vim.lsp.buf.references opts)
|
||||
(keymap :n "gi" vim.lsp.buf.implementation opts)
|
||||
(keymap :n "K" vim.lsp.buf.hover opts)
|
||||
(keymap :n "K"
|
||||
(fn []
|
||||
(if (= vim.bo.filetype "clojure")
|
||||
(let [clje-hover (require :clje.hover)]
|
||||
(clje-hover.hover))
|
||||
(vim.lsp.buf.hover)))
|
||||
opts)
|
||||
(keymap :n "<leader>rn" vim.lsp.buf.rename opts)
|
||||
(keymap :n "<leader>ca" vim.lsp.buf.code_action opts)
|
||||
(keymap :n "[d" (fn [] (vim.diagnostic.jump {:count -1})) opts)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
;; ── Configuration ────────────────────────────────────────────────
|
||||
;; Change this single flag to flip the default for all sexp filetypes.
|
||||
|
||||
(local default-enabled true)
|
||||
(local default-enabled false)
|
||||
|
||||
;; ── Implementation ───────────────────────────────────────────────
|
||||
|
||||
|
||||
+56
-1
@@ -149,5 +149,60 @@
|
||||
{lhs "<leader>b" :group "buffer"}
|
||||
{lhs "<leader>r" :group "refactor"}
|
||||
{lhs "<leader>c" :group "code"}
|
||||
{lhs "<leader>h" :group "hunk"}
|
||||
{lhs "<leader>t" :group "toggle"}
|
||||
{lhs "<leader>l" :group "log"}]))}]
|
||||
{lhs "<leader>l" :group "log"}]))}
|
||||
|
||||
;; blink.cmp - Fast completion engine with LSP support
|
||||
{repo "saghen/blink.cmp"
|
||||
:version "*"
|
||||
:event ["InsertEnter" "CmdlineEnter"]
|
||||
:opts {:keymap {:preset "super-tab"}
|
||||
:completion {:documentation {:auto_show true}}
|
||||
:sources {:default ["lsp" "path" "buffer"]}}}
|
||||
|
||||
;; gitsigns.nvim - Git diff signs in the sign column
|
||||
{repo "lewis6991/gitsigns.nvim"
|
||||
:event ["BufReadPre" "BufNewFile"]
|
||||
:opts {:signs {:add {:text "│"}
|
||||
:change {:text "│"}
|
||||
:delete {:text "_"}
|
||||
:topdelete {:text "‾"}
|
||||
:changedelete {:text "~"}
|
||||
:untracked {:text "┆"}}
|
||||
:sign_priority 6
|
||||
:update_debounce 100
|
||||
:max_file_length 40000
|
||||
:preview_config {:border "single"
|
||||
:style "minimal"
|
||||
:relative "cursor"
|
||||
:row 0
|
||||
:col 1}
|
||||
:on_attach (fn [bufnr]
|
||||
(local gs (require :gitsigns))
|
||||
(fn map [mode l r opts]
|
||||
(let [o (or opts {})]
|
||||
(set o.buffer bufnr)
|
||||
(vim.keymap.set mode l r o)))
|
||||
(map :n "]c"
|
||||
(fn []
|
||||
(if vim.wo.diff "]c"
|
||||
(do (vim.schedule #(gs.next_hunk)) "<Ignore>")))
|
||||
{:expr true :desc "Next hunk"})
|
||||
(map :n "[c"
|
||||
(fn []
|
||||
(if vim.wo.diff "[c"
|
||||
(do (vim.schedule #(gs.prev_hunk)) "<Ignore>")))
|
||||
{:expr true :desc "Prev hunk"})
|
||||
(map [:n :v] "<leader>hs" ":Gitsigns stage_hunk<CR>" {:desc "Stage hunk"})
|
||||
(map [:n :v] "<leader>hr" ":Gitsigns reset_hunk<CR>" {:desc "Reset hunk"})
|
||||
(map :n "<leader>hS" gs.stage_buffer {:desc "Stage buffer"})
|
||||
(map :n "<leader>hu" gs.undo_stage_hunk {:desc "Undo stage"})
|
||||
(map :n "<leader>hR" gs.reset_buffer {:desc "Reset buffer"})
|
||||
(map :n "<leader>hp" gs.preview_hunk {:desc "Preview hunk"})
|
||||
(map :n "<leader>hb" #(gs.blame_line {:full true}) {:desc "Blame line"})
|
||||
(map :n "<leader>tb" gs.toggle_current_line_blame {:desc "Toggle blame"})
|
||||
(map :n "<leader>hd" gs.diffthis {:desc "Diff this"})
|
||||
(map :n "<leader>hD" #(gs.diffthis "~") {:desc "Diff this ~"})
|
||||
(map :n "<leader>td" gs.toggle_deleted {:desc "Toggle deleted"})
|
||||
(map [:o :x] "ih" ":<C-U>Gitsigns select_hunk<CR>" {:desc "Select hunk"}))}}]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
vim.filetype.add({
|
||||
extension = {
|
||||
clje = "clojure",
|
||||
},
|
||||
})
|
||||
+8
-6
@@ -1,15 +1,17 @@
|
||||
{
|
||||
"conjure": { "branch": "main", "commit": "f66b3e7f45d325bd556cd785502761e583971920" },
|
||||
"blink.cmp": { "branch": "main", "commit": "4b18c32adef2898f95cdef6192cbd5796c1a332d" },
|
||||
"conjure": { "branch": "main", "commit": "403639610bcb9b6a5dfc494dc3179cc19773a471" },
|
||||
"gitsigns.nvim": { "branch": "main", "commit": "7c4faa3540d0781a28588cafbd4dd187a28ac6e3" },
|
||||
"hop.nvim": { "branch": "master", "commit": "08ddca799089ab96a6d1763db0b8adc5320bf050" },
|
||||
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
||||
"mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" },
|
||||
"mason.nvim": { "branch": "main", "commit": "12ddd182d9efbdc848b540f16484a583d52da0fb" },
|
||||
"nfnl": { "branch": "main", "commit": "ac0177c5549df7abba7a19554c18a7765386c894" },
|
||||
"mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" },
|
||||
"nfnl": { "branch": "main", "commit": "fecf731e02bc51d88372c4f992fe1ef0c19c02ae" },
|
||||
"nvim-parinfer": { "branch": "master", "commit": "3968e669d9f02589aa311d33cb475b16b27c5fbb" },
|
||||
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
|
||||
"nvim-treesitter": { "branch": "main", "commit": "f8bbc3177d929dc86e272c41cc15219f0a7aa1ac" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
||||
"telescope.nvim": { "branch": "master", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
|
||||
"tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" },
|
||||
"tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" },
|
||||
"vim-repeat": { "branch": "master", "commit": "65846025c15494983dafe5e3b46c8f88ab2e9635" },
|
||||
"vim-sexp": { "branch": "master", "commit": "2fc0a7c7e44fe94e48156d6a5b5fea28538430eb" },
|
||||
"vim-sexp-mappings-for-regular-people": { "branch": "master", "commit": "4debb74b0a3e530f1b18e5b7dff98a40b2ad26f1" },
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
-- Custom hover for CljElixir .clje files
|
||||
-- Resolves Module/function patterns against stub files in the project's stubs/ directory
|
||||
local M = {}
|
||||
|
||||
--- Walk up from the current buffer's directory to find the stubs/ directory
|
||||
local function find_stubs_dir()
|
||||
local bufpath = vim.api.nvim_buf_get_name(0)
|
||||
if bufpath == "" then return nil end
|
||||
local dir = vim.fn.fnamemodify(bufpath, ":p:h")
|
||||
for _ = 1, 20 do
|
||||
if dir == "/" or dir == "" then break end
|
||||
if vim.fn.isdirectory(dir .. "/stubs") == 1 then
|
||||
return dir .. "/stubs"
|
||||
end
|
||||
dir = vim.fn.fnamemodify(dir, ":h")
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Extract the symbol under cursor, handling namespace/function patterns.
|
||||
--- Returns (namespace, function_name) or nil.
|
||||
local function symbol_under_cursor()
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
local col = vim.api.nvim_win_get_cursor(0)[2] -- 0-indexed byte col
|
||||
|
||||
-- Expand outward from cursor to find the full symbol (letters, digits, -, ?, !, ., /, _)
|
||||
local s, e = col + 1, col + 1
|
||||
local sym_chars = "[%w%-%?%!%.%/_><=*+]"
|
||||
while s > 1 and line:sub(s - 1, s - 1):match(sym_chars) do
|
||||
s = s - 1
|
||||
end
|
||||
while e < #line and line:sub(e + 1, e + 1):match(sym_chars) do
|
||||
e = e + 1
|
||||
end
|
||||
local word = line:sub(s, e)
|
||||
if not word or word == "" then return nil, nil end
|
||||
|
||||
-- Must contain a / to be a qualified call
|
||||
local slash = word:find("/")
|
||||
if not slash then return nil, nil end
|
||||
|
||||
local ns = word:sub(1, slash - 1)
|
||||
local fn_name = word:sub(slash + 1)
|
||||
if ns == "" or fn_name == "" then return nil, nil end
|
||||
|
||||
return ns, fn_name
|
||||
end
|
||||
|
||||
--- Resolve a namespace name to a stub file path
|
||||
local function resolve_stub_file(stubs_dir, ns)
|
||||
-- Direct match (e.g., Process.clj, erlang.clj)
|
||||
local path = stubs_dir .. "/" .. ns .. ".clj"
|
||||
if vim.fn.filereadable(path) == 1 then return path end
|
||||
|
||||
-- erl_ prefix for case-insensitive collisions (e.g., erl_io.clj for :io)
|
||||
path = stubs_dir .. "/erl_" .. ns .. ".clj"
|
||||
if vim.fn.filereadable(path) == 1 then return path end
|
||||
|
||||
-- Subdirectory (e.g., clje/core.clj)
|
||||
path = stubs_dir .. "/clje/" .. ns .. ".clj"
|
||||
if vim.fn.filereadable(path) == 1 then return path end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Find a (defn ...) or (defmacro ...) form in the file lines and return its text
|
||||
local function find_defn(lines, fn_name)
|
||||
-- Escape special pattern chars in the function name
|
||||
local pat = fn_name:gsub("([%-%.%?%!%*%+%[%]%(%)%^%$%%])", "%%%1")
|
||||
|
||||
local start_idx = nil
|
||||
for i, line in ipairs(lines) do
|
||||
-- Match (defn name or (defmacro name at the start of a line
|
||||
if line:match("^%(defn%s+" .. pat .. "$")
|
||||
or line:match("^%(defn%s+" .. pat .. "%s")
|
||||
or line:match("^%(defmacro%s+" .. pat .. "$")
|
||||
or line:match("^%(defmacro%s+" .. pat .. "%s") then
|
||||
start_idx = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not start_idx then return nil end
|
||||
|
||||
-- Collect lines for this form by tracking paren depth
|
||||
local form_lines = {}
|
||||
local depth = 0
|
||||
for i = start_idx, #lines do
|
||||
local line = lines[i]
|
||||
table.insert(form_lines, line)
|
||||
for ch in line:gmatch(".") do
|
||||
if ch == "(" then depth = depth + 1
|
||||
elseif ch == ")" then depth = depth - 1 end
|
||||
end
|
||||
if depth <= 0 and i > start_idx then break end
|
||||
end
|
||||
|
||||
return form_lines
|
||||
end
|
||||
|
||||
--- Extract a vector [args] from a signature line, stripping outer parens and trailing junk
|
||||
local function extract_sig(s)
|
||||
-- Match the innermost [args] vector
|
||||
local vec = s:match("%[(.-)%]")
|
||||
if vec then
|
||||
return "[" .. vec .. "]"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Extract docstring and signatures from defn form lines for a cleaner display
|
||||
local function parse_defn(form_lines, ns, fn_name)
|
||||
local md = {}
|
||||
local docstring_parts = {}
|
||||
local signatures = {}
|
||||
local in_docstring = false
|
||||
|
||||
for i, line in ipairs(form_lines) do
|
||||
if i == 1 then goto continue end -- skip (defn name line
|
||||
|
||||
local trimmed = line:match("^%s*(.-)%s*$")
|
||||
|
||||
-- Detect docstring (starts and/or ends with ")
|
||||
if not in_docstring and trimmed:match('^"') then
|
||||
in_docstring = true
|
||||
-- Single-line docstring
|
||||
if trimmed:match('^"(.*)"$') then
|
||||
table.insert(docstring_parts, trimmed:match('^"(.*)"$'))
|
||||
in_docstring = false
|
||||
else
|
||||
table.insert(docstring_parts, trimmed:match('^"(.*)$'))
|
||||
end
|
||||
elseif in_docstring then
|
||||
if trimmed:match('"[%)]*$') then
|
||||
table.insert(docstring_parts, trimmed:match('^(.-)"'))
|
||||
in_docstring = false
|
||||
else
|
||||
table.insert(docstring_parts, trimmed)
|
||||
end
|
||||
elseif trimmed:match("%[") then
|
||||
-- Signature line containing [args]
|
||||
local sig = extract_sig(trimmed)
|
||||
if sig then
|
||||
table.insert(signatures, sig)
|
||||
end
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
|
||||
-- Build markdown
|
||||
table.insert(md, "### `" .. ns .. "/" .. fn_name .. "`")
|
||||
table.insert(md, "")
|
||||
|
||||
if #signatures > 0 then
|
||||
table.insert(md, "```clojure")
|
||||
for _, sig in ipairs(signatures) do
|
||||
if sig == "[]" then
|
||||
table.insert(md, "(" .. ns .. "/" .. fn_name .. ")")
|
||||
else
|
||||
table.insert(md, "(" .. ns .. "/" .. fn_name .. " " .. sig .. ")")
|
||||
end
|
||||
end
|
||||
table.insert(md, "```")
|
||||
table.insert(md, "")
|
||||
end
|
||||
|
||||
if #docstring_parts > 0 then
|
||||
for _, part in ipairs(docstring_parts) do
|
||||
table.insert(md, part)
|
||||
end
|
||||
end
|
||||
|
||||
return md
|
||||
end
|
||||
|
||||
--- Main hover function — looks up Module/function in stubs
|
||||
function M.hover()
|
||||
local ns, fn_name = symbol_under_cursor()
|
||||
if not ns or not fn_name then
|
||||
vim.lsp.buf.hover()
|
||||
return
|
||||
end
|
||||
|
||||
local stubs_dir = find_stubs_dir()
|
||||
if not stubs_dir then
|
||||
vim.lsp.buf.hover()
|
||||
return
|
||||
end
|
||||
|
||||
local stub_file = resolve_stub_file(stubs_dir, ns)
|
||||
if not stub_file then
|
||||
vim.lsp.buf.hover()
|
||||
return
|
||||
end
|
||||
|
||||
local lines = vim.fn.readfile(stub_file)
|
||||
if not lines or #lines == 0 then
|
||||
vim.lsp.buf.hover()
|
||||
return
|
||||
end
|
||||
|
||||
local form_lines = find_defn(lines, fn_name)
|
||||
if not form_lines then
|
||||
-- Function not found in stub, fall back to LSP
|
||||
vim.lsp.buf.hover()
|
||||
return
|
||||
end
|
||||
|
||||
local md = parse_defn(form_lines, ns, fn_name)
|
||||
|
||||
vim.lsp.util.open_floating_preview(md, "markdown", {
|
||||
border = "rounded",
|
||||
focus_id = "clje-hover",
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user