Compare commits

...
3 Commits
Author SHA1 Message Date
gitadmin 00c8a641a6 feat(nvim): add copy_ref plugin for AI chat references
Adds a scratch buffer-based utility to copy file paths and line
ranges for pasting into AI chat conversations. Supports normal mode
(copy path), visual mode (copy path:start:end), and a scratch buffer
for collecting multiple references.
2026-07-21 10:51:57 -04:00
gitadmin 0a729ea821 refactor(env): template environment.d config and update fish aliases
Replace hardcoded config/environment.d/generic.conf with a Tera
template (environments.tmpl) rendered via mise, pulling DOTFILES_DIR,
THEME_DIR, SECOND_BRAIN, and user info from mise.toml vars.

- Add SECOND_BRAIN variable in mise.toml for the vault path
- Update fish aliases to use $SECOND_BRAIN instead of a hardcoded path
- Fix Obsidian nvim aliases with proper quoting
- Remove stale dotfiles.conf template reference
2026-07-21 10:51:20 -04:00
gitadmin c4147c6aaf feat(nvim): add zdiff.nvim plugin with keymaps 2026-07-21 10:51:20 -04:00
8 changed files with 279 additions and 8 deletions
-2
View File
@@ -1,2 +0,0 @@
TERM=xterm-256color
npm_config_prefix=$HOME/.local
+3 -3
View File
@@ -51,9 +51,9 @@ if status is-interactive
if command -q nvim
set -gx EDITOR nvim
alias oo="cd ~/Documents/nca-notes/"
alias on="nvim +Obsidian new"
alias os="nvim +Obsidian search"
alias oo="cd $SECOND_BRAIN"
alias on="nvim '+Obsidian new'"
alias os="nvim '+Obsidian search'"
alias mini="NVIM_APPNAME=mini.nvim nvim"
end
+131
View File
@@ -0,0 +1,131 @@
-- from smnatale's github.com/smnatale/nvim-config
--
-- Copy file path / selection reference for pasting into AI chats
local scratch_buf = nil
local scratch_buf_name = "copy-refs"
local function get_or_create_scratch()
-- if we already created a buffer and it's still valid, reuse it
if scratch_buf and vim.api.nvim_buf_is_valid(scratch_buf) then
return scratch_buf
end
-- look for an existing buffer by name
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_valid(buf) then
local name = vim.api.nvim_buf_get_name(buf)
if name:match("/" .. scratch_buf_name .. "$") or name == scratch_buf_name then
scratch_buf = buf
return scratch_buf
end
end
end
-- create a new unlisted scratch buffer
scratch_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(scratch_buf, scratch_buf_name)
vim.bo[scratch_buf].buftype = "nofile"
vim.bo[scratch_buf].bufhidden = "hide"
vim.bo[scratch_buf].swapfile = false
return scratch_buf
end
local function open_scratch()
local buf = get_or_create_scratch()
local width = math.floor(vim.o.columns * 0.8)
local height = math.floor(vim.o.lines * 0.8)
local row = math.floor((vim.o.lines - height) / 2)
local col = math.floor((vim.o.columns - width) / 2)
local _ = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = "rounded",
})
vim.api.nvim_buf_set_keymap(buf, "n", "q", ":close<CR>", { noremap = true, silent = true })
end
local function copy_ref(opts)
-- "%" is the current buffer's file name; ":." makes it relative to the cwd
local path = vim.fn.expand("%:.")
-- ref is what ends up in the clipboard; start with just the path
local ref = path
if opts.visual then
-- '< and '> are only set after leaving visual mode, so read the live selection:
-- "v" is the line where visual mode was started (the anchor)
local start_line = vim.fn.line("v")
-- "." is the line the cursor is on now (the moving end of the selection)
local end_line = vim.fn.line(".")
-- if the selection was made upward, swap so start is always the smaller line
if start_line > end_line then
start_line, end_line = end_line, start_line
end
-- append the range, e.g. "lua/config/keymaps.lua:1:23"
ref = path .. ":" .. start_line .. ":" .. end_line
end
-- ask for an optional free-text note on the command line (Enter to skip)
local note = vim.fn.input("Prompt (optional): ")
if note ~= "" then
-- append the note after the ref, separated by a space
ref = ref .. " " .. note
end
-- write ref into the "+" register, which is the system clipboard
vim.fn.setreg("+", ref)
-- append to scratch buffer
local buf = get_or_create_scratch()
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local insert_pos = #lines
if insert_pos > 0 and lines[insert_pos] ~= "" then
vim.api.nvim_buf_set_lines(buf, insert_pos, insert_pos, false, { "", ref })
else
vim.api.nvim_buf_set_lines(buf, insert_pos, insert_pos, false, { ref })
end
-- clear visual selection if we were in visual mode
if opts.visual then
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>", true, false, true), "n", false)
end
-- show a confirmation message with what was copied
vim.notify("Copied: " .. ref)
end
-- normal mode: copy just the file path
vim.keymap.set("n", "<leader>bc", function()
copy_ref({})
end, { desc = "Copy file path" })
-- visual mode: copy the file path plus the selected line range
vim.keymap.set("v", "<leader>bc", function()
copy_ref({ visual = true })
end, { desc = "Copy file path with line range" })
-- open the copy-ref scratch buffer
vim.keymap.set("n", "<leader>b.", function()
open_scratch()
end, { desc = "Open copy-ref scratch buffer" })
-- clear the copy-ref scratch buffer
vim.keymap.set("n", "<leader>bx", function()
local buf = get_or_create_scratch()
vim.api.nvim_buf_set_lines(buf, 0, -1, false, {})
vim.notify("Cleared copy-refs buffer")
end, { desc = "Clear copy-ref scratch buffer" })
-- yank the entire copy-ref scratch buffer into the + register
vim.keymap.set("n", "<leader>by", function()
local buf = get_or_create_scratch()
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local content = table.concat(lines, "\n")
vim.fn.setreg("+", content)
vim.notify("Yanked copy-refs buffer (" .. #lines .. " lines)")
end, { desc = "Yank copy-ref scratch buffer" })
-1
View File
@@ -42,7 +42,6 @@ vim.keymap.set("n", "<leader>bn", "<cmd>enew<cr>", { desc = "New File" })
-- vim.keymap.set("n", "<leader>bd", "<cmd>bdelete<cr>", { desc = "Unload Buffer" })
vim.keymap.set("n", "<leader>`", "<cmd>e #<cr>", { desc = "Switch to Other Buffer" })
vim.keymap.set("n", "<leader>bc", "<cmd>tabclose<cr>", { desc = "Close Tab" })
-- Clear search with <esc>
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<cr>', { desc = "clear hlsearch" })
+131
View File
@@ -0,0 +1,131 @@
-- from smnatale's github.com/smnatale/nvim-config
--
-- Copy file path / selection reference for pasting into AI chats
local scratch_buf = nil
local scratch_buf_name = "copy-refs"
local function get_or_create_scratch()
-- if we already created a buffer and it's still valid, reuse it
if scratch_buf and vim.api.nvim_buf_is_valid(scratch_buf) then
return scratch_buf
end
-- look for an existing buffer by name
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_is_valid(buf) then
local name = vim.api.nvim_buf_get_name(buf)
if name:match("/" .. scratch_buf_name .. "$") or name == scratch_buf_name then
scratch_buf = buf
return scratch_buf
end
end
end
-- create a new unlisted scratch buffer
scratch_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(scratch_buf, scratch_buf_name)
vim.bo[scratch_buf].buftype = "nofile"
vim.bo[scratch_buf].bufhidden = "hide"
vim.bo[scratch_buf].swapfile = false
return scratch_buf
end
local function open_scratch()
local buf = get_or_create_scratch()
local width = math.floor(vim.o.columns * 0.8)
local height = math.floor(vim.o.lines * 0.8)
local row = math.floor((vim.o.lines - height) / 2)
local col = math.floor((vim.o.columns - width) / 2)
local _ = vim.api.nvim_open_win(buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = "rounded",
})
vim.api.nvim_buf_set_keymap(buf, "n", "q", ":close<CR>", { noremap = true, silent = true })
end
local function copy_ref(opts)
-- "%" is the current buffer's file name; ":." makes it relative to the cwd
local path = vim.fn.expand("%:.")
-- ref is what ends up in the clipboard; start with just the path
local ref = path
if opts.visual then
-- '< and '> are only set after leaving visual mode, so read the live selection:
-- "v" is the line where visual mode was started (the anchor)
local start_line = vim.fn.line("v")
-- "." is the line the cursor is on now (the moving end of the selection)
local end_line = vim.fn.line(".")
-- if the selection was made upward, swap so start is always the smaller line
if start_line > end_line then
start_line, end_line = end_line, start_line
end
-- append the range, e.g. "lua/config/keymaps.lua:1:23"
ref = path .. ":" .. start_line .. ":" .. end_line
end
-- ask for an optional free-text note on the command line (Enter to skip)
local note = vim.fn.input("Prompt (optional): ")
if note ~= "" then
-- append the note after the ref, separated by a space
ref = ref .. " " .. note
end
-- write ref into the "+" register, which is the system clipboard
vim.fn.setreg("+", ref)
-- append to scratch buffer
local buf = get_or_create_scratch()
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local insert_pos = #lines
if insert_pos > 0 and lines[insert_pos] ~= "" then
vim.api.nvim_buf_set_lines(buf, insert_pos, insert_pos, false, { "", ref })
else
vim.api.nvim_buf_set_lines(buf, insert_pos, insert_pos, false, { ref })
end
-- clear visual selection if we were in visual mode
if opts.visual then
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>", true, false, true), "n", false)
end
-- show a confirmation message with what was copied
vim.notify("Copied: " .. ref)
end
-- normal mode: copy just the file path
vim.keymap.set("n", "<leader>bc", function()
copy_ref({})
end, { desc = "Copy file path" })
-- visual mode: copy the file path plus the selected line range
vim.keymap.set("v", "<leader>bc", function()
copy_ref({ visual = true })
end, { desc = "Copy file path with line range" })
-- open the copy-ref scratch buffer
vim.keymap.set("n", "<leader>b.", function()
open_scratch()
end, { desc = "Open copy-ref scratch buffer" })
-- clear the copy-ref scratch buffer
vim.keymap.set("n", "<leader>bx", function()
local buf = get_or_create_scratch()
vim.api.nvim_buf_set_lines(buf, 0, -1, false, {})
vim.notify("Cleared copy-refs buffer")
end, { desc = "Clear copy-ref scratch buffer" })
-- yank the entire copy-ref scratch buffer into the + register
vim.keymap.set("n", "<leader>by", function()
local buf = get_or_create_scratch()
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
local content = table.concat(lines, "\n")
vim.fn.setreg("+", content)
vim.notify("Yanked copy-refs buffer (" .. #lines .. " lines)")
end, { desc = "Yank copy-ref scratch buffer" })
+4
View File
@@ -0,0 +1,4 @@
vim.pack.add({{ src = "https://github.com/martindur/zdiff.nvim" }})
vim.keymap.set('n', "<leader>gz", "<cmd>Zdiff<cr>", { desc = "Zdiff (uncommitted)" })
vim.keymap.set('n', "<leader>gZ", "<cmd>Zdiff main<cr>", { desc = "Zdiff (vs main)" })
+2 -2
View File
@@ -3,6 +3,7 @@ USER_FULLNAME = "Steve Beaulac"
USER_EMAIL = "steve@beaulac.me"
DOTFILES_DIR = "{{config_root}}"
THEME_DIR = "~/.config/omarchy/current/theme"
SECOND_BRAIN = "~/Documents/sjv-brain"
[env]
DOTFILES_DIR = "{{config_root}}"
@@ -15,9 +16,8 @@ dotfiles.default_mode = "symlink-each"
"~/.config/btop" = "config/btop"
"~/.config/btop/themes/current.theme" = { source = "~/.config/omarchy/current/theme/btop.theme", mode = "symlink" }
"~/.config/emacs" = "config/emacs"
"~/.config/environment.d" = "config/environment.d"
"~/.config/environment.d/generic.conf" = { source = "templates/environments.tmpl", mode = "template", template = "tera" }
"~/.gnupg" = "config/gnupg"
"~/.config/environment.d/dotfiles.conf" = { source = "templates/dofiles.conf.tmpl", template = "tera", mode = "template" }
"~/.config/fish" = "config/fish" # check if we really need the fisher plugins
"~/.config/gdb" = "config/gdb"
"~/.config/ghostty" = "config/ghostty"
+8
View File
@@ -0,0 +1,8 @@
TERM=xterm-256color
npm_config_prefix=$HOME/.local
DOTFILES_DIR = "{{ vars.DOTFILES_DIR }}"
USER_FULLNAME = "{{ vars.USER_FULLNAME }}"
USER_EMAIL = "{{ vars.USER_FULLNAME }}"
THEME_DIR = "{{ vars.THEME_DIR }}"
SECOND_BRAIN = "{{ vars.SECOND_BRAIN }}"