feat: improve portability and add Grug-far QoL improvements
- Refactor terminal title logic in lua/options.lua with Kitty detection and OSC 2 fallback. - Set mapleader and maplocalleader explicitly at the top of lua/options.lua. - Add <leader>sr mapping for Grug-far search and replace in lua/keymaps.lua. - Add autocommand to close Grug-far window with 'q'. - Update README.md with system dependencies (Debian/Arch) and new keymaps. - Highlight portability features (terminal titles, root detection) in README.md.
This commit is contained in:
+108
@@ -4,6 +4,10 @@
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
--]]
|
||||
|
||||
-- Set leader keys before any other configuration
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = "\\"
|
||||
|
||||
-- Copyright (C) 2026 rootiest
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
@@ -66,3 +70,107 @@ vim.api.nvim_create_user_command("Format", function(args)
|
||||
end
|
||||
require("conform").format({ async = true, lsp_format = "fallback", range = range })
|
||||
end, { range = true })
|
||||
|
||||
--[[
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ Root Management │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
--]]
|
||||
|
||||
-- Automatically change the working directory to the project root.
|
||||
-- This ensures that plugins like Snacks.picker and GrugFar work
|
||||
-- relative to the file or project you are currently editing.
|
||||
vim.api.nvim_create_autocmd("BufEnter", {
|
||||
group = vim.api.nvim_create_augroup("rootiest_auto_cd", { clear = true }),
|
||||
callback = function()
|
||||
local path = vim.api.nvim_buf_get_name(0)
|
||||
if path == "" then
|
||||
return
|
||||
end
|
||||
|
||||
-- Skip special buffers, but allow directory buffers (for explorer support)
|
||||
if vim.bo.buftype ~= "" and vim.bo.filetype ~= "snacks_explorer_tree" then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get the directory (handle both files and directory paths)
|
||||
local dir = vim.fn.isdirectory(path) == 1 and path or vim.fn.fnamemodify(path, ":p:h")
|
||||
|
||||
-- Find the project root using common markers, fallback to the directory itself
|
||||
local root = vim.fs.root(dir, { ".git", "lua", "package.json", "go.mod", "Cargo.toml", "Makefile" }) or dir
|
||||
|
||||
-- Change directory if it's different and valid
|
||||
if root and vim.fn.isdirectory(root) == 1 and root ~= vim.fn.getcwd() then
|
||||
vim.fn.chdir(root)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Grug-far QoL: Close with 'q'
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
group = vim.api.nvim_create_augroup("grug_far_q_to_close", { clear = true }),
|
||||
pattern = "grug-far",
|
||||
callback = function(args)
|
||||
vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = args.buf, silent = true, desc = "Close Grug-far" })
|
||||
end,
|
||||
})
|
||||
|
||||
--[[
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ Shell Interaction │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
--]]
|
||||
|
||||
-- Detect terminal environment
|
||||
local is_kitty = os.getenv("KITTY_PID") ~= nil
|
||||
local current_shell = os.getenv("SHELL") or "/bin/sh"
|
||||
local shell_name = current_shell:match("([^/]+)$") or "sh"
|
||||
|
||||
-- Helper function to update the terminal title
|
||||
local function set_terminal_title(title)
|
||||
-- If in Kitty, we use the direct escape sequence as it's reliable
|
||||
if is_kitty then
|
||||
io.stdout:write("\27]2;" .. title .. "\7")
|
||||
-- Fallback: Use Neovim's built-in title management for other terminals
|
||||
-- (Standard OSC 2 sequences are supported by most, but opt.title is safer)
|
||||
elseif os.getenv("TERM") ~= "linux" then
|
||||
vim.opt.title = true
|
||||
vim.opt.titlestring = title
|
||||
end
|
||||
end
|
||||
|
||||
-- Create the Autocommand Group
|
||||
local title_group = vim.api.nvim_create_augroup("TerminalTitle", { clear = true })
|
||||
|
||||
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
|
||||
group = title_group,
|
||||
callback = function()
|
||||
local buftype = vim.bo.buftype
|
||||
local filetype = vim.bo.filetype
|
||||
local filename = vim.fn.expand("%:t")
|
||||
|
||||
-- 1. Specifically catch Snacks Terminal or standard Terminals
|
||||
if filetype == "snacks_terminal" or buftype == "terminal" then
|
||||
set_terminal_title("NVIM: Terminal")
|
||||
|
||||
-- 2. Handle normal files (buftype is empty)
|
||||
elseif buftype == "" and filename ~= "" then
|
||||
set_terminal_title("NVIM: " .. filename)
|
||||
|
||||
-- 3. Handle the empty start screen
|
||||
elseif filename == "" and buftype == "" then
|
||||
set_terminal_title("Neovim")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Reset the title back to the shell name when you quit Neovim
|
||||
vim.api.nvim_create_autocmd("VimLeave", {
|
||||
group = title_group,
|
||||
callback = function()
|
||||
-- On leave, direct stdout is more reliable than setting an option
|
||||
if is_kitty or os.getenv("TERM") ~= "linux" then
|
||||
io.stdout:write("\27]2;" .. shell_name .. "\7")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user