add stuff

This commit is contained in:
2026-04-30 10:27:39 -04:00
parent 646a6dca78
commit 409c5ee384
6 changed files with 295 additions and 9 deletions
+7 -1
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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"}))}}]
+5
View File
@@ -0,0 +1,5 @@
vim.filetype.add({
extension = {
clje = "clojure",
},
})
+8 -6
View File
@@ -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" },
+218
View File
@@ -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