Compare commits

...

9 Commits

Author SHA1 Message Date
jasonhilder 8e63ee325b fish config cleanup. 2026-05-26 08:07:51 +02:00
jasonhilder 20bcf236ca Nvim cleanup. 2026-05-26 08:07:43 +02:00
jasonhilder 6256b9da66 Added new system dependancies. 2026-05-26 08:07:24 +02:00
jasonhilder 1eed4b819a What am I doing with my life... 2026-05-22 08:02:56 +02:00
jasonhilder 456c2593a4 added php installs. 2026-05-21 11:35:44 +02:00
jasonhilder 17144b3a74 Cleanup. 2026-05-21 11:35:39 +02:00
jasonhilder 7568ee801b Quick theme kintsugi. 2026-05-21 10:04:38 +02:00
jasonhilder 0149b1a64f Small theme changes and updates. 2026-05-20 13:03:53 +02:00
jasonhilder e0fae18689 Major change to use mini suit of plugins. 2026-05-20 13:03:35 +02:00
8 changed files with 310 additions and 372 deletions
+28 -30
View File
@@ -1,5 +1,5 @@
[general]
import = [ "~/.config/alacritty/dank-theme.toml" ]
# import = [ "~/.config/alacritty/dank-theme.toml" ]
[font]
size = 13.5
@@ -7,7 +7,6 @@ offset = { x = 0, y = 3 }
normal = { family = "JetBrainsMono Nerd Font", style = "Regular" }
[window]
# opacity = 0.99
padding.x = 10
padding.y = 10
decorations = "None"
@@ -16,36 +15,35 @@ decorations = "None"
style.shape = "Beam"
style.blinking = "Always"
# Kanagawa Wave Alacritty Colors
# THEME
[colors.primary]
background = "#181818"
foreground = "#E4E4E4"
[colors.normal]
black = '#090618'
red = '#c34043'
green = '#76946a'
yellow = '#c0a36e'
blue = '#7e9cd8'
magenta = '#957fb8'
cyan = '#6a9589'
white = '#c8c093'
[colors.bright]
black = '#727169'
red = '#e82424'
green = '#98bb6c'
yellow = '#e6c384'
blue = '#7fb4ca'
magenta = '#938aa9'
cyan = '#7aa89f'
white = '#dcd7ba'
[colors.cursor]
text = "#141415"
cursor = "#cdcdcd"
[colors.selection]
background = '#2d4f67'
foreground = '#c8c093'
text = "#cdcdcd"
background = "#333738"
[[colors.indexed_colors]]
index = 16
color = '#ffa066'
[colors.normal]
black = "#333333" # punctuation / muted bg tone
red = "#b38f8f" # invalid
green = "#98c379" # string
yellow = "#DBAD49" # keyword / storage / self
blue = "#819aff" # number
magenta = "#939799" # type / constant
cyan = "#678E87" # annotation
white = "#dddddd" # default / operator / func
[[colors.indexed_colors]]
index = 17
color = '#ff5d62'
[colors.bright]
black = "#af9661" # comment
red = "#b38f8f" # invalid (same, no bright variant)
green = "#98c379" # string (same)
yellow = "#DBAD49" # keyword bright
blue = "#8fa3b3" # link
magenta = "#868165" # punctuation
cyan = "#678E87" # annotation (same)
white = "#dddddd" # default bright
+32 -59
View File
@@ -9,7 +9,7 @@ set -gx EDITOR "/usr/local/nvim_012/bin/nvim"
set -gx VISUAL "/usr/local/nvim_012/bin/nvim"
set -gx MANPAGER "nvim +Man!"
set -gx BROWSER firefox
set -gx TERM xterm-256color
# set -gx TERM xterm-256color
set -gx COLORTERM truecolor
set -gx LANG "en_US.UTF-8"
set -gx LC_ALL "en_US.UTF-8"
@@ -87,8 +87,10 @@ alias ldk='lazydocker'
# Custom shortcuts
alias reload='source ~/.config/fish/config.fish'
alias prj='cd ~/Projects/ && ll'
alias dots='cd ~/.dotfiles'
alias dotman='bash ~/.dotfiles/install.sh'
alias wiki='cd ~/Wiki/ && nvim index.md'
alias todo='cd ~/Todo/ && nvim index.md'
alias myip='curl ipinfo.io/ip; echo ""'
alias lspmake='bear -- make -B'
alias tc='tmux attach'
@@ -99,38 +101,9 @@ alias db='lazysql'
alias services-up='docker compose -f /home/jason/Documents/Compose/local-services/docker-compose.yaml up -d'
alias services-down='docker compose -f /home/jason/Documents/Compose/local-services/docker-compose.yaml down'
# ==============================================================================
# FUNCTIONS
# ==============================================================================
# Project Manager
## Basic project picker using mini sessions and neovim
function pp
set -l project_file "$HOME/.projects"
# Create the file if it doesn't exist
if not test -f "$project_file"
touch "$project_file"
end
if count $argv >/dev/null
# Case 1: Path provided - Add to list
set -l absolute_path (realpath $argv[1])
if grep -Fxq "$absolute_path" "$project_file"
echo "Project already exists in list."
else
echo "$absolute_path" >>"$project_file"
echo "Added: $absolute_path"
end
else
# Case 2: No arguments - Select and Open
set -l selection (cat "$project_file" | awk -F'/' '{print $NF "\t" $0}' | fzf --height 40% --reverse --header="Select Project" --with-nth=1 --delimiter=(printf '\t') | cut -f2)
if test -n "$selection"
clear
cd "$selection"
commandline -f repaint # Ensures the prompt updates after cd
end
end
nvim -c "lua MiniSessions.select()"
end
# ==============================================================================
@@ -153,29 +126,29 @@ set -g __fish_git_prompt_char_stagedstate '●'
set -g __fish_git_prompt_char_untrackedfiles ''
# Auto-attach to tmux on interactive shell start
if status is-interactive && not set -q TMUX
# Get all session names matching shell, shell-2, shell-3 etc
set sessions (tmux list-sessions -F '#S' 2>/dev/null)
if test (count $sessions) -eq 0
tmux new-session -s shell
else
# Check if any shell session is unattached and attach it
set target (tmux list-sessions -F '#{session_name} #{session_attached}' 2>/dev/null \
| grep '^shell' | grep ' 0$' | head -1 | awk '{print $1}')
if test -n "$target"
tmux attach -t $target
else
# All shell sessions attached — find next number
set nums 1
for s in $sessions
if string match -rq '^shell-(\d+)$' $s
set nums $nums (string replace 'shell-' '' $s)
end
end
set next (math (string join \n $nums | sort -n | tail -1) + 1)
tmux new-session -s shell-$next
end
end
end
# if status is-interactive && not set -q TMUX
# # Get all session names matching shell, shell-2, shell-3 etc
# set sessions (tmux list-sessions -F '#S' 2>/dev/null)
#
# if test (count $sessions) -eq 0
# tmux new-session -s shell
# else
# # Check if any shell session is unattached and attach it
# set target (tmux list-sessions -F '#{session_name} #{session_attached}' 2>/dev/null \
# | grep '^shell' | grep ' 0$' | head -1 | awk '{print $1}')
#
# if test -n "$target"
# tmux attach -t $target
# else
# # All shell sessions attached — find next number
# set nums 1
# for s in $sessions
# if string match -rq '^shell-(\d+)$' $s
# set nums $nums (string replace 'shell-' '' $s)
# end
# end
# set next (math (string join \n $nums | sort -n | tail -1) + 1)
# tmux new-session -s shell-$next
# end
# end
# end
+19 -30
View File
@@ -1,36 +1,24 @@
require("vim._core.ui2").enable({})
map = vim.keymap.set
vim.g.mapleader = " "
vim.g.termguicolors = true -- Enable 24-bit RGB colors
vim.o.nu = true -- Show line numbers
vim.o.relativenumber = true -- Show relative line numbers
vim.o.cursorline = true -- Highlight the line where the cursor is
vim.o.wrap = false -- Don't wrap long lines to the next line
vim.o.list = true -- Show invisible characters (tabs, trailing spaces)
vim.o.scrolloff = 15 -- Keep 15 lines above/below cursor when scrolling
vim.o.winborder = 'rounded' -- Use rounded borders for floating windows
vim.o.ignorecase = true -- Ignore case in search patterns
vim.o.smartcase = true -- ...unless search contains an uppercase letter
vim.o.hlsearch = true -- Keep search results highlighted
vim.o.incsearch = true -- Show search results as you type
vim.o.path = "**" -- Search down into subdirectories (classic Vim)
vim.o.expandtab = true -- Use spaces instead of tabs
vim.o.shiftwidth = 4 -- 4 spaces per indent
vim.o.tabstop = 4 -- 4 spaces for a tab
vim.o.softtabstop = 4 -- Tab key inserts 4 spaces
vim.o.swapfile = false -- Disable creation of .swp files
vim.o.backup = false -- Disable backup files
vim.o.undofile = true -- Save undo history to a file
vim.o.splitright = true -- Open vertical splits to the right
vim.o.splitbelow = true -- Open horizontal splits below
vim.o.timeoutlen = 300 -- Time (ms) to wait for a mapped sequence to complete
vim.o.autocomplete = true
vim.o.showmode = false
vim.opt.clipboard = "unnamedplus"
vim.o.completeopt = 'menuone,noselect'
vim.o.undodir = os.getenv("HOME") .. "/.cache/nvim/undodir"
vim.g.termguicolors = true
-- mini.basics sets defaults see plugin folder for more
vim.o.swapfile = false
vim.o.winborder = "single"
vim.o.winblend = 0
vim.o.pumblend = 0
vim.o.scrolloff = 20
vim.o.shiftwidth = 4
vim.o.tabstop = 4
vim.o.softtabstop = 4
vim.o.path = "**"
vim.o.clipboard = "unnamedplus"
vim.o.foldmethod = "expr"
vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()"
vim.o.foldlevel = 99
vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()"
vim.o.completeopt = "menuone,noselect,fuzzy,nosort"
vim.opt.shortmess:append("c")
vim.o.undodir = os.getenv("HOME") .. "/.cache/nvim/undodir"
map("t", "<ESC><ESC>", "<C-\\><C-n>")
map({"t", "n"}, "<C-h>", "<C-\\><C-n><C-w><C-h>")
@@ -43,9 +31,10 @@ map("v", "J", ":m '>+1<CR>gv=gv")
map("v", "K", ":m '<-2<CR>gv=gv")
map("v", "<S-Tab>", "<gv")
map("v", "<Tab>" , ">gv")
map("n", "<leader>p", ":b#<CR>")
map("n", "<leader>l", ":b#<CR>")
map("n", "<leader>e", ":Ex<CR>")
map("n", "<leader>x", ":bd<CR>")
require("autocmds")
require("terminal")
require("plugins")
+27 -109
View File
@@ -1,122 +1,40 @@
-- Terminals should open with insert mode
vim.api.nvim_create_autocmd("BufEnter", { pattern = "term://*", callback = function() vim.cmd("startinsert") end })
vim.api.nvim_create_autocmd({ "BufEnter", "TermEnter", "WinEnter" }, {
pattern = "term://*",
callback = function()
if vim.bo.buftype == "terminal" then
vim.schedule(function()
vim.cmd("startinsert")
end)
end
end
})
-- Start treesitter
vim.api.nvim_create_autocmd('FileType', {
pattern = '*',
callback = function()
pcall(vim.treesitter.start)
end,
pattern = '*',
callback = function(ev)
if ev.match ~= "odin" then
pcall(vim.treesitter.start)
end
end,
})
-- highlights yanked text
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
vim.highlight.on_yank({
higroup = "IncSearch",
timeout = 200,
})
end,
})
-- Set absolute numbers when in insert mode otherwise relativenumbers
local nums = vim.api.nvim_create_augroup('smart_numbers', {})
vim.api.nvim_create_autocmd('InsertEnter', {
group = nums,
callback = function()
vim.opt.relativenumber = false
end,
})
vim.api.nvim_create_autocmd('InsertLeave', {
group = nums,
callback = function()
vim.opt.relativenumber = true
end,
callback = function()
vim.highlight.on_yank({
higroup = "IncSearch",
timeout = 200,
})
end,
})
-- removes trailing whitespace on save
vim.api.nvim_create_autocmd("BufWritePre", {
callback = function()
local save_cursor = vim.fn.getpos(".")
vim.cmd([[%s/\s\+$//e]])
vim.fn.setpos(".", save_cursor)
end,
callback = function()
local save_cursor = vim.fn.getpos(".")
vim.cmd([[%s/\s\+$//e]])
vim.fn.setpos(".", save_cursor)
end,
})
-- Lsp autocomplete
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('my.lsp', {}),
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if not client then return end
-- Set completeopt for a better experience
vim.opt.completeopt = { 'menu', 'menuone', 'noinsert', 'noselect' }
-- Enable completion if the server supports it
if client:supports_method('textDocument/completion') then
vim.lsp.completion.enable(true, client.id, ev.buf, {
autotrigger = true, -- false = manual trigger only
})
end
end,
})
-- Define highlight groups
vim.api.nvim_set_hl(0, "TodoFix", { fg = "#FF5555", bold = true })
vim.api.nvim_set_hl(0, "TodoTodo", { fg = "#FFB86C", bold = true })
vim.api.nvim_set_hl(0, "TodoNote", { fg = "#A8D8FF", bold = true })
vim.api.nvim_set_hl(0, "TodoInfo", { fg = "#98DB6F", bold = true })
-- Match and highlight keywords in comments
local keywords = {
{ pattern = "FIX:.*", group = "TodoFix" },
{ pattern = "TODO:.*", group = "TodoTodo" },
{ pattern = "NOTE:.*", group = "TodoNote" },
{ pattern = "INFO:.*", group = "TodoInfo" },
}
vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost" }, {
callback = function()
for _, kw in ipairs(keywords) do
vim.fn.matchadd(kw.group, kw.pattern)
end
end,
})
-- Format: whole file or visual selection via :Fc
local function smart_format()
local mode = vim.fn.mode()
local in_visual = mode == "v" or mode == "V" or mode == "\22"
local clients = vim.lsp.get_clients({ bufnr = 0 })
local has_formatter = false
for _, client in ipairs(clients) do
if client.supports_method("textDocument/formatting") then
has_formatter = true
break
end
end
if in_visual then
if has_formatter then
vim.lsp.buf.format({
range = {
start = vim.api.nvim_buf_get_mark(0, "<"),
["end"] = vim.api.nvim_buf_get_mark(0, ">"),
},
})
else
vim.cmd("normal! gv=")
end
else
if has_formatter then
vim.lsp.buf.format({ async = false })
else
local view = vim.fn.winsaveview()
vim.cmd("normal! gg=G")
vim.fn.winrestview(view)
end
end
end
vim.api.nvim_create_user_command("FF", smart_format, { range = true })
+41 -42
View File
@@ -1,53 +1,52 @@
vim.pack.add({
{ src = "https://github.com/ibhagwan/fzf-lua" },
{ src = "https://github.com/neovim/nvim-lspconfig" },
{ src = "https://github.com/romus204/tree-sitter-manager.nvim" },
{ src = "https://github.com/rebelot/kanagawa.nvim" },
{ src = "https://github.com/tribela/transparent.nvim" },
{ src = "https://github.com/nvim-lualine/lualine.nvim" }
{ src = 'https://github.com/nvim-mini/mini.nvim' },
{ src = 'https://github.com/neovim/nvim-lspconfig' },
{ src = 'https://github.com/romus204/tree-sitter-manager.nvim' },
{ src = 'https://github.com/metalelf0/kintsugi-nvim' },
{ src = 'https://github.com/xiyaowong/transparent.nvim' },
{ src = 'https://github.com/brenoprata10/nvim-highlight-colors' }
})
vim.cmd(":colorscheme kanagawa")
require("tree-sitter-manager").setup({})
local theme = require('lualine.themes.kanagawa')
for _, mode in pairs(theme) do
if mode.b then mode.b.bg = '#16161D' end
if mode.c then mode.c.bg = '#16161D' end
if mode.x then mode.x.bg = '#16161D' end
if mode.y then mode.y.bg = '#16161D' end
if mode.z then mode.z.bg = '#16161D' end
end
require('lualine').setup({
options = {
theme = theme,
component_separators = '',
section_separators = '',
},
sections = {
lualine_a = {'mode'},
lualine_b = {},
lualine_c = {'filename'},
lualine_x = {'diagnostics'},
lualine_y = {},
lualine_z = {'lsp_status', 'location'},
},
require('tree-sitter-manager').setup()
require('nvim-highlight-colors').setup()
-- Mini setups
require('mini.extra').setup()
require('mini.pairs').setup()
require('mini.files').setup()
require('mini.surround').setup()
require('mini.sessions').setup()
require('mini.statusline').setup()
require('mini.basics').setup({options = { extra_ui = true }})
require('mini.completion').setup({lsp_completion = { auto_setup = true }})
require('mini.pick').setup({
window = {
config = function()
local height = math.floor(0.50 * vim.o.lines)
local width = math.floor(0.50 * vim.o.columns)
return {
anchor = 'NW', height = height, width = width,
row = math.floor(0.5 * (vim.o.lines - height)),
col = math.floor(0.5 * (vim.o.columns - width)),
}
end
}
})
require("fzf-lua").setup()
map("n", "<leader>f", ":lua FzfLua.files()<CR>")
map("n", "<leader>o", ":lua FzfLua.buffers()<CR>")
map("n", "<leader>h", ":lua FzfLua.help_tags()<CR>")
map("n", "<leader>d", ":lua FzfLua.diagnostics_document()<CR>")
map("n", "<leader>a", ":lua FzfLua.lsp_code_actions()<CR>")
map("n", "<leader>ss", ":lua FzfLua.grep_project()<CR>")
map("n", "<leader>sf", ":lua FzfLua.grep_curbuf()<CR>")
map("n", "<leader>sw", ":lua FzfLua.grep_cword()<CR>")
vim.cmd(":HighlightColors Off")
vim.cmd(":colorscheme kintsugi-dark")
-- Lsp specific, uses nvim-lspconfigs with the below
vim.lsp.enable({ "gopls", "ols" })
map("n", "L", ":lua vim.diagnostic.open_float()<CR>")
map("n", "gd", ":lua vim.lsp.buf.definition()<CR>")
map("n", "<leader>r", ":lua vim.lsp.buf.rename()<CR>")
map("n", "<leader>a", ":lua vim.lsp.buf.code_action()<CR>")
-- Mini Keybinds
map("n", "<leader>e", function() MiniFiles.open(vim.fn.getcwd()) end)
map("n", "<leader>f", function() MiniPick.builtin.files(nil, { source = { cwd = vim.fn.getcwd() } }) end)
map("n", "<leader>o", ":lua MiniPick.builtin.buffers()<CR>")
map("n", "<leader>h", ":lua MiniPick.builtin.help()<CR>")
map("n", "<leader>d", ":lua MiniExtra.pickers.diagnostic()<CR>")
map("n", "<leader>ss", function() MiniPick.builtin.grep_live(nil, { source = { cwd = vim.fn.getcwd() } }) end)
map("n", "<leader>pp", ":lua MiniSessions.select()<CR>")
map("n", "<leader>tc", ":HighlightColors Toggle<CR>")
+58
View File
@@ -0,0 +1,58 @@
local term_buf = nil
local function open_term_split()
vim.cmd('botright vsplit')
local win = vim.api.nvim_get_current_win()
if term_buf and vim.api.nvim_buf_is_valid(term_buf) then
vim.api.nvim_win_set_buf(win, term_buf)
else
vim.cmd('terminal')
term_buf = vim.api.nvim_get_current_buf()
end
vim.api.nvim_win_set_width(win, math.floor(vim.o.columns * 0.37))
vim.cmd('startinsert')
end
local function toggle_term()
-- Check if terminal is already visible in a window
for _, win in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_get_buf(win) == term_buf then
vim.api.nvim_win_close(win, false)
return
end
end
open_term_split()
end
local function open_term_fullscreen()
if term_buf and vim.api.nvim_buf_is_valid(term_buf) then
vim.api.nvim_set_current_buf(term_buf)
else
vim.cmd('terminal')
term_buf = vim.api.nvim_get_current_buf()
end
vim.cmd('startinsert')
end
local function prev_non_term_buf()
local cur = vim.api.nvim_get_current_buf()
local bufs = vim.fn.getbufinfo({ buflisted = 1 })
local candidates = {}
for _, info in ipairs(bufs) do
if info.bufnr ~= cur and vim.bo[info.bufnr].buftype ~= 'terminal' then
table.insert(candidates, info)
end
end
if #candidates == 0 then
print('No previous non-terminal buffer')
return
end
table.sort(candidates, function(a, b) return a.lastused > b.lastused end)
vim.api.nvim_set_current_buf(candidates[1].bufnr)
end
map('n', '<leader>l', prev_non_term_buf, { desc = 'Go to previous non-terminal buffer' })
map('n', '<C-j>', toggle_term, { desc = 'Toggle terminal split' })
map('n', '<C-o>', open_term_fullscreen, { desc = 'Open terminal fullscreen' })
map('t', '<C-j>', toggle_term, { desc = 'Toggle terminal split' })
map('t', '<C-o>', prev_non_term_buf, { desc = 'Exit terminal mode' })
+2 -1
View File
@@ -5,6 +5,7 @@ set -g mouse on
set -g base-index 1
set -g pane-base-index 1
set -s escape-time 10
set-option -g focus-events on
# remap prefix from 'C-b' to 'C-f'
unbind l
@@ -44,7 +45,7 @@ bind e run-shell 'tmux popup -d "#{pane_current_path}" -xC -yC -w90% -h90% -E "~
## Status bar design
set -g status-justify left
set -g status-position top
set -g status-bg '#16161D'
set -g status-bg '#121212'
set -g status-fg '#DCD7BA'
set -g status-left-length 20
set -g status-right ' #[fg=colour232,bg="#af875f",bold]#{?client_prefix, [PFX] ,} #[fg="#1c1c1c",bg="#767676",bold][#S] '
+103 -101
View File
@@ -13,143 +13,145 @@ DO_INSTALL=false
CONFIRM_MODE=true # only true when no args are passed
usage() {
echo "Usage: $0 [-l] [-i]"
echo " -l Only create symlinks (no confirmation)"
echo " -i Only install system packages (no confirmation)"
echo " (no args = do both, with confirmation)"
exit 1
echo "Usage: $0 [-l] [-i]"
echo " -l Only create symlinks (no confirmation)"
echo " -i Only install system packages (no confirmation)"
echo " (no args = do both, with confirmation)"
exit 1
}
if [ $# -eq 0 ]; then
DO_LINKS=true
DO_INSTALL=true
CONFIRM_MODE=true
DO_LINKS=true
DO_INSTALL=true
CONFIRM_MODE=true
else
CONFIRM_MODE=false
while getopts ":lih" opt; do
case $opt in
l) DO_LINKS=true ;;
i) DO_INSTALL=true ;;
h) usage ;;
*) usage ;;
esac
done
CONFIRM_MODE=false
while getopts ":lih" opt; do
case $opt in
l) DO_LINKS=true ;;
i) DO_INSTALL=true ;;
h) usage ;;
*) usage ;;
esac
done
fi
# ---------------------------------------------------------------------------------
## Helper function for linking
# ---------------------------------------------------------------------------------
link_file() {
local src="$1"
local dest="$2"
local src="$1"
local dest="$2"
if [ -L "$dest" ]; then
if [ "$(readlink "$dest")" == "$src" ]; then
echo "✅ Symlink already correct: $dest$src"
((SKIPPED++))
else
echo "⚠️ $dest is a symlink but points to the wrong target."
echo " Replacing with correct symlink..."
rm "$dest"
ln -s "$src" "$dest"
echo "🔁 Fixed: $dest$src"
((CREATED++))
fi
elif [ -e "$dest" ]; then
echo "⚠️ $dest exists but is not a symlink. Skipping."
((SKIPPED++))
else
mkdir -p "$(dirname "$dest")"
ln -s "$src" "$dest"
echo "✅ Linked: $dest$src"
((CREATED++))
fi
if [ -L "$dest" ]; then
if [ "$(readlink "$dest")" == "$src" ]; then
echo "✅ Symlink already correct: $dest$src"
((SKIPPED++))
else
echo "⚠️ $dest is a symlink but points to the wrong target."
echo " Replacing with correct symlink..."
rm "$dest"
ln -s "$src" "$dest"
echo "🔁 Fixed: $dest$src"
((CREATED++))
fi
elif [ -e "$dest" ]; then
echo "⚠️ $dest exists but is not a symlink. Skipping."
((SKIPPED++))
else
mkdir -p "$(dirname "$dest")"
ln -s "$src" "$dest"
echo "✅ Linked: $dest$src"
((CREATED++))
fi
}
# ---------------------------------------------------------------------------------
## LINK SYMLINKS
# ---------------------------------------------------------------------------------
if [ "$DO_LINKS" = true ]; then
if [ "$CONFIRM_MODE" = true ]; then
read -p "❓ Do you want to create symlinks for your dotfiles? [y/N] " confirm
case "$confirm" in
[Yy]*) ;; # continue below
*) DO_LINKS=false ;;
esac
fi
if [ "$CONFIRM_MODE" = true ]; then
read -p "❓ Do you want to create symlinks for your dotfiles? [y/N] " confirm
case "$confirm" in
[Yy]*) ;; # continue below
*) DO_LINKS=false ;;
esac
fi
fi
if [ "$DO_LINKS" = true ]; then
echo "🔗 Checking and creating symlinks..."
CREATED=0
SKIPPED=0
echo "🔗 Checking and creating symlinks..."
CREATED=0
SKIPPED=0
link_file "$DOTFILES_DIR/config/tmux" "$HOME/.config/tmux"
link_file "$DOTFILES_DIR/config/kanata" "$HOME/.config/kanata"
link_file "$DOTFILES_DIR/config/fish" "$HOME/.config/fish"
link_file "$DOTFILES_DIR/config/alacritty" "$HOME/.config/alacritty"
link_file "$DOTFILES_DIR/config/nvim" "$HOME/.config/nvim"
link_file "$DOTFILES_DIR/config/gitu" "$HOME/.config/gitu"
link_file "$DOTFILES_DIR/config/lf" "$HOME/.config/lf"
link_file "$DOTFILES_DIR/config/tmux" "$HOME/.config/tmux"
link_file "$DOTFILES_DIR/config/kanata" "$HOME/.config/kanata"
link_file "$DOTFILES_DIR/config/fish" "$HOME/.config/fish"
link_file "$DOTFILES_DIR/config/alacritty" "$HOME/.config/alacritty"
link_file "$DOTFILES_DIR/config/nvim" "$HOME/.config/nvim"
link_file "$DOTFILES_DIR/config/gitu" "$HOME/.config/gitu"
link_file "$DOTFILES_DIR/config/lf" "$HOME/.config/lf"
echo ""
echo "🧾 Summary: $CREATED symlink(s) created or fixed, $SKIPPED skipped."
echo ""
echo ""
echo "🧾 Summary: $CREATED symlink(s) created or fixed, $SKIPPED skipped."
echo ""
echo "✅ Symlink setup complete."
echo ""
echo "✅ Symlink setup complete."
echo ""
fi
# ---------------------------------------------------------------------------------
## INSTALL SYSTEM PACKAGES
# ---------------------------------------------------------------------------------
if [ "$DO_INSTALL" = true ]; then
if [ "$CONFIRM_MODE" = true ]; then
read -p "❓ Do you want to install system packages? [y/N] " confirm
case "$confirm" in
[Yy]*) ;; # continue below
*) DO_INSTALL=false ;;
esac
fi
if [ "$CONFIRM_MODE" = true ]; then
read -p "❓ Do you want to install system packages? [y/N] " confirm
case "$confirm" in
[Yy]*) ;; # continue below
*) DO_INSTALL=false ;;
esac
fi
fi
if [ "$DO_INSTALL" = true ]; then
REQUIRED_PACKAGES=(
# system essentials
wget curl git unzip lf jq alacritty fzf
fd-find direnv ripgrep tree bat syncthing
build-essential make bear valgrind fish
tmux ca-certificates gnupg libfuse2
fonts-symbola fonts-noto fonts-noto-color-emoji
)
REQUIRED_PACKAGES=(
# system essentials
wget curl git unzip lf jq alacritty fzf
fd-find direnv ripgrep tree bat syncthing
build-essential make bear valgrind fish
tmux ca-certificates gnupg libfuse2 rsync
fonts-symbola fonts-noto fonts-noto-color-emoji
# php
php-cli php-mysql php-curl php-mbstring php-zip
)
MISSING_PACKAGES=()
MISSING_PACKAGES=()
echo "🔍 Checking for missing packages..."
echo ""
echo "🔍 Checking for missing packages..."
echo ""
# Check which packages are missing using dpkg
for pkg in "${REQUIRED_PACKAGES[@]}"; do
# dpkg-query checks for the installed status.
# We check for a non-zero exit status which indicates the package is NOT installed.
if ! dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed"; then
MISSING_PACKAGES+=("$pkg")
fi
done
# Check which packages are missing using dpkg
for pkg in "${REQUIRED_PACKAGES[@]}"; do
# dpkg-query checks for the installed status.
# We check for a non-zero exit status which indicates the package is NOT installed.
if ! dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed"; then
MISSING_PACKAGES+=("$pkg")
fi
done
if [ ${#MISSING_PACKAGES[@]} -eq 0 ]; then
echo "✅ All required packages are already installed."
else
echo "📦 Updating package lists..."
# Update package lists before installing
sudo apt update
if [ ${#MISSING_PACKAGES[@]} -eq 0 ]; then
echo "✅ All required packages are already installed."
else
echo "📦 Updating package lists..."
# Update package lists before installing
sudo apt update
echo "📦 Installing missing packages: ${MISSING_PACKAGES[*]}"
# Use sudo apt install for installing on Debian
sudo apt install "${MISSING_PACKAGES[@]}"
fi
echo "📦 Installing missing packages: ${MISSING_PACKAGES[*]}"
# Use sudo apt install for installing on Debian
sudo apt install "${MISSING_PACKAGES[@]}"
fi
echo ""
echo "✅ Package setup complete."
echo ""
echo ""
echo "✅ Package setup complete."
echo ""
fi