feat: add templating for laptop dotfiles

This commit is contained in:
Robert Perce 2026-03-20 00:07:21 -05:00
parent caf6e25e43
commit bdf7e407cb
21 changed files with 437 additions and 52 deletions

4
.chezmoiignore Normal file
View file

@ -0,0 +1,4 @@
README.md
{{- if has "termux" .class | not }}
.termux
{{- end }}

View file

@ -1,14 +0,0 @@
#!/usr/bin/env bash
blue="\[\e[38;5;50m\]"
rst="\[\e[0m\]"
PS1="╭╢$blue\w$rst\n╰╼ "
PATH=$PATH:"$HOME/bin"
function conf() {
fname="${XDG_CONFIG_HOME:-.config}/$1"
test -f "$fname" && source "$fname"
}
conf bash/cmds.bash

34
private_dot_bashrc.tmpl Executable file
View file

@ -0,0 +1,34 @@
#!/usr/bin/env bash
# don't put duplicate lines or those starting with spacein history
export HISTCONTROL=ignorespace:ignoredups
export HISTIGNORE='ls:cd:q'
shopt -s histappend
# prompt
blue="\[\e[38;5;50m\]"
reset="\[\e[00m\]"
cwd=$blue'\w'$reset
{{- if has "desktop" .class }}
user_host=$blue'\u@\h'$reset
history='\!'
export PS1="╭─($user_host)───[$history]───($cwd)\n╰╼ "
{{- else }}
export PS1="╭╢$cwd\n╰╼ "
{{- end }}
export PS2="╰┤ "
if [[ "$PATH" != *"$HOME/bin"* ]]; then
PATH=$PATH:"$HOME/bin"
fi
bind 'set mark-symlinked-directories on'
export EDITOR='/usr/bin/env nvim'
export VISUAL='/usr/bin/env nvim'
function conf() {
fname="${XDG_CONFIG_HOME:-$HOME/.config}/$1"
test -f "$fname" && source "$fname"
}
conf bash/cmds.bash

View file

@ -1,3 +1,9 @@
[user]
email = contact@rperce.net
name = Robert Perce
[pull]
rebase = true
[init]
defaultBranch = main
[push]
autoSetupRemote = true

View file

@ -8,15 +8,21 @@ _os() {
missing=()
check_apply() {
local os=$(_os)
while IFS= read -r package; do
cmd=$(echo "$package" | cut -d\; -f1)
pkg=$(echo "$package" | grep -Eo "$(_os):[^ ]*" || echo ":$cmd")
pkg=$(echo "$package" | grep -Eo "$os:[^ ]*" || echo ":$cmd")
pkg=$(echo "$pkg" | cut -d: -f2)
[ -n "$pkg" ] || continue
command -v "$cmd" >/dev/null || missing+=( "$pkg" )
done < ~/.config/mgmt/packages
if [ ${#missing} -eq 0 ]; then
diag "All packages installed"
else
diag "Missing ${missing[*]}"
fi
[ ${#missing} -eq 0 ]
}

View file

@ -16,31 +16,54 @@ end
vim.opt.rtp:prepend(lazypath)
-- Make sure to setup `mapleader` and `maplocalleader` before
-- loading lazy.nvim so that mappings are correct.
-- loading setting manual mappings or loading lazy.nvim
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
-- no highlights after search
vim.opt.hlsearch = false
vim.opt.ignorecase = true -- ignore casing in searches...
vim.opt.smartcase = true -- ...unless I provide both caps and lowercase
-- allow arrow keys and h/l to move to the next/prev line when at the edge
vim.opt.whichwrap:append("<,>,h,l")
-- display non-printing character
vim.opt.listchars = 'tab:┆-,trail:~,extends:>,precedes:<,nbsp:•'
vim.opt.list = true
-- highlight line with cursor
vim.opt.cursorline = true
-- spaces, not tab
vim.opt.expandtab = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.softtabstop = 2
-- all my code is in git anyways, and these files are cluttery
vim.opt.backup = false
vim.opt.writebackup = false
vim.opt.swapfile = false
-- new splits open to the right or below the current window
vim.opt.splitbelow = true
vim.opt.splitright = true
function tblmerge(x, y) for k,v in pairs(y) do x[k] = v end return x end
function tblmerge(x, y)
for k, v in pairs(y) do x[k] = v end
return x
end
local function map(mode, lhs, rhs, opts) vim.api.nvim_set_keymap(mode, lhs, rhs, tblmerge({ noremap = true, silent = true}, opts or {})) end
local function map(mode, lhs, rhs, opts)
vim.api.nvim_set_keymap(mode, lhs, rhs,
tblmerge({ noremap = true, silent = true }, opts or {}))
end
function nmap(l, r, opt) map('n', l, r, opt) end
function imap(l, r, opt) map('i', l, r, opt) end
function vmap(l, r, opt) map('v', l, r, opt) end
function imap(l, r, opt) map('i', l, r, opt) end
function vmap(l, r, opt) map('v', l, r, opt) end
-- Treat long lines as broken lines so you can move in them
nmap('j', 'gj')
@ -50,11 +73,43 @@ nmap('k', 'gk')
vmap('<', '<gv')
vmap('>', '>gv')
-- handy save
nmap("<Leader>w", ":w<CR>")
-- handy escape
imap('jk', '<Esc>')
-- tab handling
nmap("<Leader>tn", ":tabnew<CR>")
nmap('<Tab>', '<C-W>w')
nmap('<S-Tab>', '<C-W>W')
nmap('<Leader>te', ':tabedit <c-r>=expand("%:p:h")<cr>/<cr>')
-- Kill trailing whitespace
function Whitespace()
local save = vim.fn.winsaveview()
vim.cmd [[keeppatterns %s/\s\+$//e]]
vim.cmd [[keeppatterns %s/\r$//e]]
vim.fn.winrestview(save)
end
nmap('<leader>kw', ':lua Whitespace()<cr>')
-- C-; inserts current date in ISO8601 format, à la Excel
-- Requires configuring the terminal to send the correct sequence; ref
-- http://www.leonerd.org.uk/hacks/fixterms/. The correct sequence, in general, is `CSI
-- codepoint;modifier u`, where CSI is 'Esc-[', _codepoint_ is the decimal unicode
-- value (here, 59), and _modifier_ is chosen from
-- None Shift Alt A+S Ctrl C+S C+A C+A+
-- 1 2 3 4 5 6 7 8
-- For alacritty, e.g., the keybinding to configure i
-- - { key: Semicolon, mods: Control, chars: "\x1b[59;5u" }
imap('<C-;>', '<C-R>=strftime("%F")<CR>')
-- this fnamemodify invocations turns the absolute path from expand('%') into a path
-- relative to nvim's launch directory
nmap('<leader>l', ':let @+=fnamemodify(expand("%"), ":~:.") . ":" . line(".")<CR>')
-- Setup lazy.nvim
require("lazy").setup({
spec = {
@ -63,3 +118,7 @@ require("lazy").setup({
install = { colorscheme = { "habamax" } },
checker = { enabled = false },
})
-- set cursorline highlight to an underline. Has to happen after lazy setup, since
-- loading the colorscheme will overwrite any custom highlights.
vim.api.nvim_set_hl(0, 'CursorLine', { underline = true })

View file

@ -0,0 +1,9 @@
{{- if has "desktop" .class | not }}
hydras.lua
plugins/aesthetics.lua
plugins/lion.lua
plugins/markdown-preview.lua
plugins/split-focus.lua
plugins/treesitter.lua
plugins/zen-mode.lua
{{- end }}

View file

@ -0,0 +1,88 @@
local Hydra = require('hydra')
local cmd = require('hydra.keymap-util').cmd
local telescope_hint = [[
_f_: files _g_: live grep
🭇🬭🬭🬭🬭🬭🬭🬭🬭🬼 _o_: old files _/_: search in file
🭉🭁🭠🭘 🭣🭕🭌🬾
🭅 > 🭐 _r_: resume _T_: TODO comments
🬿 🭊 _h_: vim help _c_: execute command
🭋🬝🮄🮄🮄🮄🮄🮄🮄🮄🬆🭀 _k_: keymaps _;_: commands history
🭤🭒🬺🬹🬱🬭🬭🬭🬭🬵🬹🬹🭝🭙 _O_: options _?_: search history
^
_<Enter>_: Telescope _<Esc>_
]]
Hydra({
name = 'Telescope',
hint = telescope_hint,
config = {
color = 'teal',
invoke_on_body = true,
hint = {
position = 'middle',
border = 'rounded',
},
},
mode = 'n',
body = '<leader>F',
heads = {
{ 'f', cmd 'Telescope find_files' },
{ 'g', cmd 'Telescope live_grep' },
{ 'o', cmd 'Telescope oldfiles', { desc = 'recently opened files' } },
{ 'h', cmd 'Telescope help_tags', { desc = 'vim help' } },
{ 'k', cmd 'Telescope keymaps' },
{ 'O', cmd 'Telescope vim_options' },
{ 'r', cmd 'Telescope resume' },
{ '/', cmd 'Telescope current_buffer_fuzzy_find', { desc = 'search in file' } },
{ '?', cmd 'Telescope search_history', { desc = 'search history' } },
{ ';', cmd 'Telescope command_history', { desc = 'command-line history' } },
{ 'c', cmd 'Telescope commands', { desc = 'execute command' } },
{ 'T', cmd 'TodoTelescope', { desc = 'todo comments' } },
{ '<Enter>', cmd 'Telescope', { exit = true, desc = 'list all pickers' } },
{ '<Esc>', nil, { exit = true, nowait = true } },
}
})
local lsp_hint = [[
_K_: hover
🭇🬭🬭🬭🬭🬭🬭🬭🬭🬼
🭉🭁🭠🭘 🭣🭕🭌🬾 _gd_: definition _gD_: declaration
🭅 > 🭐 _gi_: implementation _go_: typedef
🬿 🭊 _gr_: references _gs_: signature
🭋🬝🮄🮄🮄🮄🮄🮄🮄🮄🬆🭀
🭤🭒🬺🬹🬱🬭🬭🬭🬭🬵🬹🬹🭝🭙 _<F2>_: rename _<F4>_: code actions
^
_gl_: diagnostic float
_[d_: prev _]d_: next
]]
Hydra({
name = 'LSP Actions',
hint = lsp_hint,
config = {
color = 'teal',
invoke_on_body = true,
hint = {
position = 'middle',
border = 'rounded',
}
},
mode = 'n',
body = '<leader>L',
heads = {
{ 'K', cmd 'lua vim.lsp.buf.hover()' },
{ 'gd', cmd 'lua vim.lsp.buf.definition()' },
{ 'gD', cmd 'lua vim.lsp.buf.declaration()' },
{ 'gi', cmd 'lua vim.lsp.buf.implementation()' },
{ 'go', cmd 'lua vim.lsp.buf.type_definition()' },
{ 'gr', cmd 'lua vim.lsp.buf.references()' },
{ 'gs', cmd 'lua vim.lsp.buf.signature_help()' },
{ '<F2>', cmd 'lua vim.lsp.buf.rename()' },
{ '<F4>', cmd 'lua vim.lsp.buf.code_action()' },
{ 'gl', cmd 'lua vim.diagnostic.open_float()' },
{ '[d', cmd 'lua vim.diagnostic.goto_prev()' },
{ ']d', cmd 'lua vim.diagnostic.goto_next()' },
{ '<Esc>', nil, { exit = true, nowait = true } },
}
})

View file

@ -0,0 +1,70 @@
return {
-- pretty statusline
{
'nvim-lualine/lualine.nvim',
config = function()
vim.o.showmode = false
require 'lualine'.setup {
options = {
icons_enabled = false,
component_separators = { left = '⡇⡷', right = '⢾⢸' },
section_separators = { left = '▓▓▒', right = '▒▓▓' },
globalstatus = true,
theme = 'catppuccin',
},
sections = {
lualine_a = { 'mode' },
lualine_b = { 'filename' },
lualine_c = { 'branch', 'diff' },
lualine_x = { 'encoding', 'filetype' },
lualine_y = { 'progress' },
lualine_z = { 'location' },
},
inactive_sections = {},
}
end
},
-- cutesy indent lines
{
'lukas-reineke/indent-blankline.nvim',
dependencies = { 'catppuccin' },
config = function()
local highlight = {
"RainbowRed",
"RainbowYellow",
"RainbowBlue",
"RainbowOrange",
"RainbowGreen",
"RainbowViolet",
"RainbowCyan",
}
local hooks = require "ibl.hooks"
-- create the highlight groups in the highlight setup hook, so they are reset
-- every time the colorscheme changes
hooks.register(hooks.type.HIGHLIGHT_SETUP, function()
vim.api.nvim_set_hl(0, "RainbowRed", { fg = "#E06C75" })
vim.api.nvim_set_hl(0, "RainbowYellow", { fg = "#E5C07B" })
vim.api.nvim_set_hl(0, "RainbowBlue", { fg = "#61AFEF" })
vim.api.nvim_set_hl(0, "RainbowOrange", { fg = "#D19A66" })
vim.api.nvim_set_hl(0, "RainbowGreen", { fg = "#98C379" })
vim.api.nvim_set_hl(0, "RainbowViolet", { fg = "#C678DD" })
vim.api.nvim_set_hl(0, "RainbowCyan", { fg = "#56B6C2" })
end)
require("ibl").setup { indent = { highlight = highlight } }
end
},
-- highlighted TODO comments
{
"folke/todo-comments.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
opts = {
highlight = {
pattern = [[.*<(KEYWORDS)\s*:?]]
}
}
}
}

View file

@ -1,3 +1,4 @@
return {
{ 'tpope/vim-vinegar' }
'tpope/vim-eunuch', --Delete/Rename/Move/&c commands that sync with the buffer
'tpope/vim-vinegar', --netrw upgrades
}

View file

@ -0,0 +1,11 @@
return {
-- cool command-nesting
{
'anuvyklack/hydra.nvim',
dependencies = { 'catppuccin' },
config = function()
package.loaded['hydras'] = nil
require 'hydras'
end
},
}

View file

@ -1,14 +0,0 @@
return {
{
'nvim-lualine/lualine.nvim',
init = function() vim.o.showmode = false end,
opts = {
options = {
icons_enabled = false,
component_separators = { left = '', right = ''},
section_separators = { left = '', right = ''},
}
}
}
}

View file

@ -0,0 +1,27 @@
return {
{
'nvim-lualine/lualine.nvim',
init = function() vim.o.showmode = false end,
opts = {
options = {
icons_enabled = false,
component_separators = { left = '⧽', right = '⧼'},
section_separators = { left = '', right = ''},
globalstatus = true,
{{- if has "desktop" .class }}
theme = 'catppuccin-nvim',
{{- end }}
},
sections = {
lualine_a = { 'mode' },
lualine_b = { 'filename' },
lualine_c = { 'branch', 'diff' },
lualine_x = { 'encoding', 'filetype' },
lualine_y = { 'progress' },
lualine_z = { 'location' },
},
inactive_sections = {},
}
}
}

View file

@ -0,0 +1,7 @@
return {
{
'tommcdo/vim-lion', --gl/gL to align block on character
lazy = false,
config = function() end
},
}

View file

@ -0,0 +1,11 @@
return {
{
'iamcco/markdown-preview.nvim',
cmd = { 'MarkdownPreviewToggle', 'MarkdownPreview', 'MarkdownPreviewStop' },
ft = { 'markdown' },
build = function() vim.fn['mkdp#util#install']() end,
keys = {
{ '<C-p>', ':MarkdownPreviewToggle<CR>' }
},
},
}

View file

@ -1,10 +1,11 @@
return {
{ "tpope/vim-repeat" },
{ "tpope/vim-surround" },
{ url = "https://codeberg.org/andyg/leap.nvim",
config = function()
vim.keymap.set({'n', 'x', 'o'}, 's', '<Plug>(leap)')
vim.keymap.set('n', 'S', '<Plug>(leap-from-window)')
end
}
{ "tpope/vim-repeat" }, --make . behave more predictably
{ "tpope/vim-surround" }, --change and set (){}[]<>''
{ "wellle/targets.vim" }, --provides text objs for brackets, quotes, tags, etc
{ url = "https://codeberg.org/andyg/leap.nvim",
config = function()
vim.keymap.set({'n', 'x', 'o'}, 's', '<Plug>(leap)')
vim.keymap.set('n', 'S', '<Plug>(leap-from-window)')
end
}
}

View file

@ -0,0 +1,8 @@
return {
{
'beauwilliams/focus.nvim', --dynamically sized splits
config = function()
require 'focus'.setup()
end
},
}

View file

@ -1,9 +1,9 @@
return {
{ "catppuccin/nvim",
name = "catppuccin",
priority = 1000,
opts = {
flavor ="frappe"
}
{ "catppuccin/nvim",
name = "catppuccin",
priority = 1000,
opts = {
flavor = "frappe"
}
}
}

View file

@ -0,0 +1,22 @@
return {
{
'nvim-treesitter/nvim-treesitter',
lazy = false,
build = ':TSUpdate',
config = function()
require('nvim-treesitter').install({
"astro", "bash", "c", "cmake", "css", "dockerfile", "fish", "go", "html", "java",
"javascript", "json", "json5", "latex", "lua", "make", "perl", "python", "regex",
"ruby", "rust", "typescript", "vim", "yaml"
}):wait(300000)
end
},
-- show block headers at top of scrollzone
{
'romgrk/nvim-treesitter-context',
config = function()
require 'treesitter-context'.setup()
end,
},
}

View file

@ -0,0 +1,35 @@
return {
{
'folke/zen-mode.nvim',
dependencies = {
'junegunn/limelight.vim',
},
opts = {
window = {
width = 60,
height = 20,
options = {
winbar = '',
signcolumn = "no", -- disable signcolumn
number = false, -- disable number column
relativenumber = false, -- disable relative numbers
cursorline = false, -- disable cursorline
cursorcolumn = false, -- disable cursor column
foldcolumn = "0", -- disable fold column
textwidth = 55,
linebreak = true,
},
},
on_open = function(_win)
vim.o.cmdheight = 2
vim.o.textwidth = 55
vim.cmd('Limelight')
end,
on_close = function(_win)
vim.o.cmdheight = 1
vim.o.textwidth = 88
vim.cmd('Limelight!')
end
},
},
}

View file

@ -1,9 +1,17 @@
bind | split-window -h
bind - split-window -v
set -g status on
bind b last-window
bind C-b last-window
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %
bind b last-window
bind c new-window
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
set -g base-index 1
setw -g pane-base-index 1
@ -21,7 +29,13 @@ set -g status-right-length 50
set -g status-justify left
set -g status-left "#[fg=blue,bold]#S#[fg=brightblack] ⧽ "
{{- if has "phone" .class }}
set -g status-right "#[fg=brightblack]⧼ %Y-%m-%d"
{{- else }}
set -g status-interval 1
set -g status-right "#[fg=brightblack] ⧼ %H:%M:%S ⧼ %Y-%m-%d"
{{- end }}
set -g window-status-format "#[fg=cyan]#I:#W#F"
set -g window-status-current-format "#[fg=black,bg=cyan]#I#[fg=black,bg=cyan,nobold,noitalics,nounderscore]:#[fg=black,bg=cyan]#W#F"