Compare commits
42 Commits
e5c749bd25
...
garage
| Author | SHA1 | Date | |
|---|---|---|---|
| ec4785be12 | |||
| 5972c3c5df | |||
| 2fdf72d746 | |||
| f8390f006d | |||
| 0c2b2875ed | |||
| 0ab2aa869c | |||
| 42b634c19b | |||
| ad2e33db35 | |||
| 35a9e08a7e | |||
| 4d895b2c52 | |||
| 9db467735f | |||
| 7b72fa6796 | |||
| 13ddf830c9 | |||
| f4ce2ef3c3 | |||
| 27ec787416 | |||
| f1b0fd94fb | |||
| 866a25a66d | |||
| 34b6439521 | |||
| 60834ccae1 | |||
| 78ea031fd6 | |||
| ed51e48bb4 | |||
| 799b186e9f | |||
| 3b4e2621da | |||
| c8a4741d94 | |||
| 0d394dd577 | |||
| 13530beaaf | |||
| 458847c4af | |||
| 7aaf25ce85 | |||
| fe553b1c3f | |||
| aa8ce447c1 | |||
| 14585bca9e | |||
| 05bdb4abdc | |||
| ec50d3f12f | |||
| c958a0ab9d | |||
| d08998a0ca | |||
| f1b3dbb9c3 | |||
| 9418d8ccc7 | |||
| d7311cca46 | |||
| eeafb5195c | |||
| 2762a4ff65 | |||
| e48a477c02 | |||
| d45a3971fd |
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "config/shared/nvim"]
|
||||
path = config/shared/nvim
|
||||
url = git@gitea.tomastm.com:tomas.mirchev/nvim-config.git
|
||||
[submodule "config/shared/barg-parser"]
|
||||
path = config/shared/barg-parser
|
||||
url = git@gitea.tomastm.com:tomas.mirchev/barg-parser.git
|
||||
162
config.json
162
config.json
@@ -1,162 +0,0 @@
|
||||
{
|
||||
"template": {
|
||||
"htop": {
|
||||
"link": {
|
||||
"from": "shared/htop",
|
||||
"to": "~/.config/htop"
|
||||
}
|
||||
},
|
||||
"bin": {
|
||||
"link": {
|
||||
"from": "shared/bin",
|
||||
"to": "~/bin"
|
||||
}
|
||||
},
|
||||
"vim": {
|
||||
"link": {
|
||||
"from": "shared/vim",
|
||||
"to": "~/.vimrc"
|
||||
},
|
||||
"-post-link": "curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim && vim -es -u ~/.vimrc -i NONE -c 'PlugInstall' -c 'qa'"
|
||||
},
|
||||
"nvim": {
|
||||
"link": {
|
||||
"from": "shared/nvim",
|
||||
"to": "~/.config/nvim/init.lua"
|
||||
},
|
||||
"post-link": "(grep -q 'alias vim=nvim' ~/.zshrc || echo 'alias vim=nvim' >> ~/.zshrc) || true"
|
||||
},
|
||||
"zsh": {
|
||||
"link": {
|
||||
"from": "shared/zsh_root",
|
||||
"to": "~/.zshrc"
|
||||
}
|
||||
},
|
||||
"zsh_config": {
|
||||
"link": {
|
||||
"from": "shared/zsh_config",
|
||||
"to": "~/.config/zsh"
|
||||
}
|
||||
},
|
||||
"tmux": {
|
||||
"link": {
|
||||
"from": "shared/tmux",
|
||||
"to": "~/.tmux.conf"
|
||||
}
|
||||
},
|
||||
"git": {
|
||||
"link": {
|
||||
"from": "shared/git",
|
||||
"to": "~/.gitconfig"
|
||||
}
|
||||
},
|
||||
"wezterm": {
|
||||
"link": {
|
||||
"from": "shared/wezterm",
|
||||
"to": "~/.wezterm.lua"
|
||||
}
|
||||
},
|
||||
"alacritty": {
|
||||
"link": {
|
||||
"from": "shared/alacritty",
|
||||
"to": "~/.alacritty.toml"
|
||||
}
|
||||
},
|
||||
"ghostty": {
|
||||
"link": {
|
||||
"from": "shared/ghostty",
|
||||
"to": "~/.config/ghostty"
|
||||
}
|
||||
}
|
||||
},
|
||||
"environments": {
|
||||
"macos": [
|
||||
"zsh",
|
||||
"zsh_config",
|
||||
{
|
||||
"package": "bin",
|
||||
"link": {
|
||||
"from": "macos/bin",
|
||||
"to": "~/bin"
|
||||
}
|
||||
},
|
||||
"tmux",
|
||||
"nvim",
|
||||
"git",
|
||||
"ghostty",
|
||||
"alacritty",
|
||||
{
|
||||
"package": "karabiner",
|
||||
"link": {
|
||||
"from": "macos/karabiner",
|
||||
"to": "~/.config/karabiner"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "linearmouse",
|
||||
"link": {
|
||||
"from": "macos/linearmouse",
|
||||
"to": "~/.config/linearmouse"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "rectangle",
|
||||
"link-comment": "Needs manual import from config/macos/linearmouse"
|
||||
}
|
||||
],
|
||||
"linux-vm": [
|
||||
"zsh_config",
|
||||
{
|
||||
"package": "zsh",
|
||||
"install": "sudo apt install -y zsh",
|
||||
"post-link": "./scripts/linux-setup_zsh.sh"
|
||||
},
|
||||
{
|
||||
"package": "tmux",
|
||||
"link": {
|
||||
"from": "linux-vm/tmux",
|
||||
"to": "~/.tmux.conf"
|
||||
},
|
||||
"install": "sudo apt install -y tmux"
|
||||
},
|
||||
{
|
||||
"package": "nvim",
|
||||
"install": "bash -c 'wget -O nvim.deb https://gitea.tomastm.com/tomas.mirchev/neovim/releases/download/v0.10.0/nvim-linux-$(dpkg --print-architecture).deb && sudo dpkg -i nvim.deb && rm nvim.deb'"
|
||||
},
|
||||
{
|
||||
"package": "git",
|
||||
"install": "sudo apt install -y git"
|
||||
},
|
||||
{
|
||||
"package": "htop",
|
||||
"install": "sudo apt install -y htop"
|
||||
},
|
||||
"bin"
|
||||
],
|
||||
"linux-dev": [
|
||||
"zsh_config",
|
||||
{
|
||||
"package": "zsh",
|
||||
"install": "sudo apt install -y zsh",
|
||||
"post-link": "./scripts/linux-setup_zsh.sh"
|
||||
},
|
||||
{
|
||||
"package": "nvim",
|
||||
"ignore-template": true,
|
||||
"link": {
|
||||
"from": "linux-dev/nvim",
|
||||
"to": "~/.config/nvim"
|
||||
},
|
||||
"post-link": "nvim --headless '+Lazy! restore' +qa"
|
||||
},
|
||||
{
|
||||
"package": "git",
|
||||
"install": "sudo apt install -y git"
|
||||
},
|
||||
{
|
||||
"package": "htop",
|
||||
"install": "sudo apt install -y htop"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
require("themes.invero").load()
|
||||
@@ -1,22 +0,0 @@
|
||||
--[[
|
||||
Neovim Lua config: ways to set things
|
||||
|
||||
- vim.opt : preferred modern API for options (handles lists, cleaner syntax)
|
||||
- vim.g : global variables (leader key, plugin settings, disable builtins, etc.)
|
||||
- vim.o : global-only option (rarely needed directly)
|
||||
- vim.wo : window-local option (applies to current window only, use in autocmds)
|
||||
- vim.bo : buffer-local option (applies to current buffer only, use in autocmds)
|
||||
- vim.env : set environment variables (like PATH, LANG)
|
||||
- vim.fn : call Vimscript functions (e.g. vim.fn.getcwd())
|
||||
- vim.cmd : run raw Vimscript/Ex commands (e.g. vim.cmd("colorscheme desert"))
|
||||
- vim.api : low-level Neovim API (create autocmds, keymaps, buffer/window ops, etc.)
|
||||
|
||||
TL;DR -> use vim.opt + vim.g in options.lua for defaults.
|
||||
Use vim.wo/vim.bo only in context-specific tweaks (autocmds).
|
||||
Use vim.env, vim.fn, vim.cmd, vim.api as needed for scripting.
|
||||
]]
|
||||
|
||||
require("config.options")
|
||||
require("config.keymaps")
|
||||
require("config.lazy")
|
||||
require("config.autocmds")
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"cmp-nvim-lsp": { "branch": "main", "commit": "bd5a7d6db125d4654b50eeae9f5217f24bb22fd3" },
|
||||
"cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" },
|
||||
"conform.nvim": { "branch": "master", "commit": "b4aab989db276993ea5dcb78872be494ce546521" },
|
||||
"fidget.nvim": { "branch": "main", "commit": "4d5858bd4c471c895060e1b9f3575f1551184dc5" },
|
||||
"harpoon": { "branch": "harpoon2", "commit": "ed1f853847ffd04b2b61c314865665e1dadf22c7" },
|
||||
"lazy.nvim": { "branch": "main", "commit": "6c3bda4aca61a13a9c63f1c1d1b16b9d3be90d7a" },
|
||||
"mason-lspconfig.nvim": { "branch": "main", "commit": "25c11854aa25558ee6c03432edfa0df0217324be" },
|
||||
"mason.nvim": { "branch": "main", "commit": "d66c60e17dd6fd8165194b1d14d21f7eb2c1697a" },
|
||||
"nvim-autopairs": { "branch": "master", "commit": "23320e75953ac82e559c610bec5a90d9c6dfa743" },
|
||||
"nvim-cmp": { "branch": "main", "commit": "b5311ab3ed9c846b585c0c15b7559be131ec4be9" },
|
||||
"nvim-lspconfig": { "branch": "master", "commit": "d9879110d0422a566fa01d732556f4d5515e1738" },
|
||||
"nvim-tree.lua": { "branch": "master", "commit": "321bc61580fd066b76861c32de3319c3a6d089e7" },
|
||||
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
|
||||
"nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" },
|
||||
"nvim-web-devicons": { "branch": "master", "commit": "6e51ca170563330e063720449c21f43e27ca0bc1" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
||||
"schemastore.nvim": { "branch": "main", "commit": "0fccf9234acfd981867cbd42c4101829e6808790" },
|
||||
"telescope-fzf-native.nvim": { "branch": "main", "commit": "1f08ed60cafc8f6168b72b80be2b2ea149813e55" },
|
||||
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
|
||||
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" }
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
-- Highlight when yanking (copying) text
|
||||
vim.api.nvim_create_autocmd("TextYankPost", {
|
||||
callback = function()
|
||||
vim.highlight.on_yank()
|
||||
end,
|
||||
})
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
-- Reload ColorScheme by clearing cached modules
|
||||
vim.api.nvim_create_user_command("ReloadColorscheme", function()
|
||||
local current = vim.g.colors_name
|
||||
if not current then
|
||||
vim.notify("No colorscheme is currently set", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
-- clear only the cached modules for this theme
|
||||
for k in pairs(package.loaded) do
|
||||
if k:match("^themes%." .. current) then
|
||||
package.loaded[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- reload it
|
||||
vim.cmd("colorscheme " .. current)
|
||||
vim.notify("Reloaded " .. current .. " colorscheme", vim.log.levels.INFO)
|
||||
end, { desc = "Reload the current colorscheme" })
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
--[[
|
||||
Command :TSHighlightRoots (works but uncomment only when used)
|
||||
|
||||
Description:
|
||||
Collects all Tree-sitter highlight groups, resolves their links,
|
||||
and outputs the unique root groups actually used (for theming/debugging).
|
||||
|
||||
Usage:
|
||||
:TSHighlightRoots -> prints roots in the command line
|
||||
:TSHighlightRoots <filename> -> writes roots into <filename> (overwrites)
|
||||
(filename supports ~ and tab-completion)
|
||||
]]
|
||||
-- local function resolve_link(name)
|
||||
-- local seen = {}
|
||||
-- while name and not seen[name] do
|
||||
-- seen[name] = true
|
||||
-- local hl = vim.api.nvim_get_hl(0, { name = name })
|
||||
-- if hl.link then
|
||||
-- name = hl.link
|
||||
-- else
|
||||
-- return name
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- vim.api.nvim_create_autocmd("VimEnter", {
|
||||
-- callback = function()
|
||||
-- vim.api.nvim_create_user_command("TSHighlightRoots", function(opts)
|
||||
-- local roots = {}
|
||||
-- for _, group in ipairs(vim.fn.getcompletion("@", "highlight")) do
|
||||
-- local root = resolve_link(group)
|
||||
-- if root then
|
||||
-- roots[root] = true
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- local output = { "Unique root highlight groups used by Tree-sitter:" }
|
||||
-- for root in pairs(roots) do
|
||||
-- table.insert(output, " " .. root)
|
||||
-- end
|
||||
--
|
||||
-- if opts.args ~= "" then
|
||||
-- -- write to file
|
||||
-- local filename = vim.fn.expand(opts.args)
|
||||
-- local fd = assert(io.open(filename, "w"))
|
||||
-- fd:write(table.concat(output, "\n"))
|
||||
-- fd:close()
|
||||
-- print("Wrote roots to " .. filename)
|
||||
-- else
|
||||
-- -- default: print to command line
|
||||
-- for _, line in ipairs(output) do
|
||||
-- print(line)
|
||||
-- end
|
||||
-- end
|
||||
-- end, {
|
||||
-- nargs = "?", -- allow 0 or 1 argument
|
||||
-- complete = "file", -- tab-complete filenames
|
||||
-- })
|
||||
-- end,
|
||||
-- })
|
||||
|
||||
----------------------------------------------
|
||||
-- Useful tricks that do not fully work
|
||||
----------------------------------------------
|
||||
|
||||
-- -- Show cursorline only in the active window
|
||||
--
|
||||
-- vim.api.nvim_create_autocmd({ "WinEnter", "BufEnter" }, {
|
||||
-- callback = function()
|
||||
-- local ft = vim.bo.filetype
|
||||
-- vim.notify("enter: " .. ft .. " - " .. vim.bo.buftype)
|
||||
-- -- if not ft:match("^Telescope") and ft ~= "NvimTree" then
|
||||
-- -- vim.wo.cursorline = true
|
||||
-- -- end
|
||||
-- end,
|
||||
-- })
|
||||
|
||||
-- vim.api.nvim_create_autocmd({ "WinLeave", "BufLeave" }, {
|
||||
-- callback = function()
|
||||
-- local ft = vim.bo.filetype
|
||||
-- vim.notify("exit: " .. ft .. " - " .. vim.bo.buftype)
|
||||
-- -- if not ft:match("^Telescope") and ft ~= "NvimTree" then
|
||||
-- -- vim.wo.cursorline = false
|
||||
-- -- end
|
||||
-- end,
|
||||
-- })
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
-- -- Associate filetype
|
||||
--
|
||||
-- vim.api.nvim_create_autocmd("FileType", {
|
||||
-- pattern = "text",
|
||||
-- callback = function()
|
||||
-- vim.bo.filetype = "markdown"
|
||||
-- end,
|
||||
-- })
|
||||
@@ -1,50 +0,0 @@
|
||||
local remap = require("utils.remap")
|
||||
|
||||
remap.nmap("<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
|
||||
|
||||
remap.imap("jk", "<Esc>", { desc = "Exit insert mode with jk" })
|
||||
remap.cmap("jk", "<C-c>", { desc = "Exit command/search mode with jk" })
|
||||
remap.nmap("<Esc>", "<cmd>nohlsearch<CR>", { desc = "Clear highlights" })
|
||||
|
||||
-- Prevent "x" from overriding the register
|
||||
remap.nmap("x", '"_x')
|
||||
|
||||
-- Window Navigation
|
||||
remap.nmap("<C-h>", "<C-w>h", { desc = "Move focus to the left window" })
|
||||
remap.nmap("<C-l>", "<C-w>l", { desc = "Move focus to the right window" })
|
||||
remap.nmap("<C-j>", "<C-w>j", { desc = "Move focus to the lower window" })
|
||||
remap.nmap("<C-k>", "<C-w>k", { desc = "Move focus to the upper window" })
|
||||
|
||||
-- Tab management
|
||||
remap.nmap("<Leader>tn", ":tabnew<CR>", { desc = "[T]ab [N]ew" })
|
||||
remap.nmap("<Leader>tc", ":tabclose<CR>", { desc = "[T]ab [C]lose" })
|
||||
remap.nmap("<Leader>to", ":tabonly<CR>", { desc = "[T]ab [O]nly" })
|
||||
remap.nmap("<Leader>tl", ":tabnext<CR>", { desc = "[T]ab Next" })
|
||||
remap.nmap("<Leader>th", ":tabprevious<CR>", { desc = "[T]ab Previous" })
|
||||
remap.nmap("<Leader>tm.", ":tabmove +1<CR>", { desc = "[T]ab [M]ove Right" })
|
||||
remap.nmap("<Leader>tm,", ":tabmove -1<CR>", { desc = "[T]ab [M]ove Left" })
|
||||
for i = 1, 9 do
|
||||
remap.nmap(string.format("<Leader>%d", i), string.format("%dgt", i), { desc = string.format("[T]ab %d", i) })
|
||||
end
|
||||
|
||||
-- Buffer Management
|
||||
remap.nmap("<Leader>bl", ":ls<CR>", { desc = "[B]uffer [L]ist" })
|
||||
remap.nmap("<Leader>bd", ":bdelete<CR>", { desc = "[B]uffer [D]elete" })
|
||||
remap.nmap("]b", ":bnext<CR>", { desc = "[B]uffer [N]ext" })
|
||||
remap.nmap("[b", ":bprevious<CR>", { desc = "[B]uffer [P]revious" })
|
||||
remap.nmap("<Leader>bb", ":b<Space>", { desc = "[B]uffer Select" })
|
||||
remap.nmap("<Leader>bo", ":bufdo bd|1bd<CR>", { desc = "[B]uffer Delete Others" })
|
||||
|
||||
-- Terminal
|
||||
remap.nmap("<Leader>tet", function()
|
||||
vim.cmd("terminal")
|
||||
vim.cmd("startinsert")
|
||||
end, { desc = "[T]erminal" })
|
||||
remap.nmap("<leader>ter", function()
|
||||
local buf_dir = vim.fn.expand("%:p:h")
|
||||
vim.cmd("edit term://" .. buf_dir .. "//zsh")
|
||||
vim.cmd("startinsert")
|
||||
end, { desc = "[T]erminal [R]elative" })
|
||||
remap.tmap("<Esc>", "<C-\\><C-n>", { desc = "Terminal Normal Mode" })
|
||||
remap.tmap("jk", "<C-\\><C-n>", { desc = "Terminal Normal Mode" })
|
||||
remap.tmap("<C-w>", "<C-\\><C-n><C-w>", { desc = "Terminal Window Command" })
|
||||
@@ -1,18 +0,0 @@
|
||||
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
|
||||
if not (vim.uv or vim.loop).fs_stat(lazypath) then
|
||||
local lazyrepo = 'https://github.com/folke/lazy.nvim.git'
|
||||
local out = vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }
|
||||
if vim.v.shell_error ~= 0 then
|
||||
error('Error cloning lazy.nvim:\n' .. out)
|
||||
end
|
||||
end ---@diagnostic disable-next-line: undefined-field
|
||||
vim.opt.rtp:prepend(lazypath)
|
||||
|
||||
require("lazy").setup({
|
||||
spec = { { import = "plugins" } },
|
||||
ui = {
|
||||
backdrop = 100,
|
||||
border = "rounded"
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
-- Map Leader
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = " "
|
||||
|
||||
-- Use Nerd Font
|
||||
vim.g.have_nerd_font = false
|
||||
|
||||
if vim.env.CONTAINER == "true" then
|
||||
vim.g.clipboard = {
|
||||
name = "osc52",
|
||||
copy = {
|
||||
["+"] = require("vim.ui.clipboard.osc52").copy("+"),
|
||||
["*"] = require("vim.ui.clipboard.osc52").copy("*"),
|
||||
},
|
||||
paste = {
|
||||
["+"] = require("vim.ui.clipboard.osc52").paste("+"),
|
||||
["*"] = require("vim.ui.clipboard.osc52").paste("*"),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
-- Sync clipboard between OS and Neovim
|
||||
vim.schedule(function()
|
||||
vim.opt.clipboard = "unnamedplus"
|
||||
end)
|
||||
|
||||
-- Add vertical line
|
||||
vim.opt.colorcolumn = "100"
|
||||
|
||||
-- vim.opt.laststatus = 3
|
||||
vim.opt.signcolumn = "no"
|
||||
|
||||
-- Enable TrueColor
|
||||
vim.opt.termguicolors = false
|
||||
|
||||
-- Scroll lines/columns
|
||||
vim.opt.mousescroll = "hor:1,ver:1"
|
||||
|
||||
-- Set indentation preferences
|
||||
vim.opt.expandtab = true -- Convert tabs to spaces
|
||||
vim.opt.shiftwidth = 4 -- Number of spaces for auto-indent
|
||||
vim.opt.tabstop = 4 -- Number of spaces a tab counts for
|
||||
vim.opt.softtabstop = 4 -- Number of spaces a tab counts for when editing
|
||||
vim.opt.autoindent = true -- Copy indent from current line when starting new line
|
||||
vim.opt.smartindent = true -- Do smart autoindenting when starting a new line
|
||||
|
||||
-- Disable line wrapping
|
||||
vim.opt.wrap = false
|
||||
|
||||
-- Enable break indent
|
||||
vim.opt.breakindent = true
|
||||
|
||||
-- Make line numbers default
|
||||
vim.opt.number = true
|
||||
vim.opt.relativenumber = true
|
||||
|
||||
-- Enable mouse mode, can be useful for resizing splits for example
|
||||
vim.opt.mouse = "a"
|
||||
|
||||
-- Full path on status line
|
||||
vim.opt.statusline = "%F%m%r%h%w%=%l,%c %P "
|
||||
-- vim.opt.statusline = "%= %F%m%r%h%w ─ (%l,%c %P) %="
|
||||
-- vim.opt.fillchars:append({ stl = "─", stlnc = "─" })
|
||||
|
||||
-- Save undo history
|
||||
vim.opt.undofile = true
|
||||
|
||||
-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
|
||||
vim.opt.ignorecase = true
|
||||
vim.opt.smartcase = true
|
||||
|
||||
-- Decrease update time
|
||||
vim.opt.updatetime = 250
|
||||
|
||||
-- Decrease mapped sequence wait time
|
||||
-- Displays which-key popup sooner
|
||||
vim.opt.timeoutlen = 300
|
||||
|
||||
-- Configure how new splits should be opened
|
||||
vim.opt.splitright = true
|
||||
vim.opt.splitbelow = true
|
||||
|
||||
-- Preview substitutions live, as you type
|
||||
vim.opt.inccommand = "split"
|
||||
|
||||
-- Show which line your cursor is on
|
||||
vim.opt.cursorline = true
|
||||
|
||||
vim.opt.guicursor = "n-v-i-c:block"
|
||||
|
||||
-- Minimal number of screen lines to keep above and below the cursor
|
||||
vim.opt.scrolloff = 10
|
||||
|
||||
-- Load the colorscheme
|
||||
vim.cmd.colorscheme("invero")
|
||||
@@ -1,46 +0,0 @@
|
||||
return { -- Autoformat
|
||||
"stevearc/conform.nvim",
|
||||
event = { "BufWritePre" },
|
||||
cmd = { "ConformInfo" },
|
||||
keys = {
|
||||
{
|
||||
"<leader>f",
|
||||
function()
|
||||
require("conform").format({ async = true, lsp_format = "fallback" })
|
||||
end,
|
||||
mode = "",
|
||||
desc = "[F]ormat buffer",
|
||||
},
|
||||
},
|
||||
opts = {
|
||||
notify_on_error = false,
|
||||
format_on_save = function(bufnr)
|
||||
local disable_filetypes = { c = true, cpp = true }
|
||||
local lsp_format_opt
|
||||
if disable_filetypes[vim.bo[bufnr].filetype] then
|
||||
lsp_format_opt = "never"
|
||||
else
|
||||
lsp_format_opt = "fallback"
|
||||
end
|
||||
return {
|
||||
timeout_ms = 500,
|
||||
lsp_format = lsp_format_opt,
|
||||
}
|
||||
end,
|
||||
formatters_by_ft = {
|
||||
lua = { "stylua" },
|
||||
sh = { "shfmt" },
|
||||
swift = { "swift_format" },
|
||||
python = { "isort", "black", stop_after_first = true },
|
||||
javascript = { "prettierd", "prettier", stop_after_first = true },
|
||||
javascriptreact = { "prettierd", "prettier", stop_after_first = true },
|
||||
typescript = { "prettierd", "prettier", stop_after_first = true },
|
||||
typescriptreact = { "prettierd", "prettier", stop_after_first = true },
|
||||
},
|
||||
formatters = {
|
||||
shfmt = {
|
||||
prepend_args = { "-i", "4", "-ci" }, -- 4 spaces, indent cases
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
return {
|
||||
'windwp/nvim-autopairs',
|
||||
event = 'InsertEnter',
|
||||
-- Optional dependency
|
||||
dependencies = { 'hrsh7th/nvim-cmp' },
|
||||
config = function()
|
||||
require('nvim-autopairs').setup {}
|
||||
-- If you want to automatically add `(` after selecting a function or method
|
||||
local cmp_autopairs = require 'nvim-autopairs.completion.cmp'
|
||||
local cmp = require 'cmp'
|
||||
cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done())
|
||||
end,
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
return {
|
||||
"windwp/nvim-ts-autotag",
|
||||
opts = {
|
||||
autotag = {
|
||||
enable = true,
|
||||
enable_close = true,
|
||||
enable_rename = true,
|
||||
enable_close_on_slash = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
return {
|
||||
"hrsh7th/nvim-cmp",
|
||||
event = "InsertEnter",
|
||||
dependencies = {
|
||||
"hrsh7th/cmp-nvim-lsp",
|
||||
"hrsh7th/cmp-path",
|
||||
},
|
||||
config = function()
|
||||
local cmp = require("cmp")
|
||||
cmp.setup({
|
||||
window = {
|
||||
completion = {
|
||||
border = "single",
|
||||
-- or border = true for default border
|
||||
},
|
||||
documentation = {
|
||||
border = "single",
|
||||
},
|
||||
},
|
||||
completion = { completeopt = "menu,menuone,noselect" }, -- This ensures nothing is auto-selected
|
||||
sources = cmp.config.sources({
|
||||
{ name = "nvim_lsp" }, -- from language server
|
||||
{ name = "buffer" }, -- from current buffer
|
||||
{ name = "path" }, -- for file paths
|
||||
}),
|
||||
mapping = cmp.mapping.preset.insert({
|
||||
["<Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item({ behavior = cmp.SelectBehavior.Insert })
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
["<S-Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item({ behavior = cmp.SelectBehavior.Insert })
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
["<C-e>"] = cmp.mapping.abort(), -- This closes the completion menu
|
||||
|
||||
["<C-u>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() and cmp.get_selected_entry() then
|
||||
cmp.scroll_docs(-4)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
["<C-d>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() and cmp.get_selected_entry() then
|
||||
cmp.scroll_docs(4)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
}),
|
||||
})
|
||||
end,
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
return {
|
||||
"ThePrimeagen/harpoon",
|
||||
branch = "harpoon2",
|
||||
opts = {
|
||||
menu = {
|
||||
width = vim.api.nvim_win_get_width(0) - 4,
|
||||
},
|
||||
settings = {
|
||||
save_on_toggle = true,
|
||||
},
|
||||
},
|
||||
keys = function()
|
||||
local keys = {
|
||||
{
|
||||
"<leader>H",
|
||||
function()
|
||||
require("harpoon"):list():add()
|
||||
end,
|
||||
desc = "Harpoon File",
|
||||
},
|
||||
{
|
||||
"<leader>h",
|
||||
function()
|
||||
local harpoon = require("harpoon")
|
||||
harpoon.ui:toggle_quick_menu(harpoon:list())
|
||||
end,
|
||||
desc = "Harpoon Quick Menu",
|
||||
},
|
||||
}
|
||||
|
||||
for i = 1, 5 do
|
||||
table.insert(keys, {
|
||||
"<C-" .. i .. ">",
|
||||
function()
|
||||
require("harpoon"):list():select(i)
|
||||
end,
|
||||
desc = "Harpoon to File " .. i,
|
||||
})
|
||||
end
|
||||
return keys
|
||||
end,
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
local remap = require("utils.remap")
|
||||
|
||||
vim.diagnostic.config({
|
||||
update_in_insert = false,
|
||||
virtual_text = {
|
||||
source = true,
|
||||
},
|
||||
float = {
|
||||
border = "rounded",
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, {
|
||||
border = "rounded",
|
||||
})
|
||||
vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, {
|
||||
border = "rounded",
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
"neovim/nvim-lspconfig",
|
||||
dependencies = {
|
||||
{ "williamboman/mason.nvim", version = "1.8.0", config = true },
|
||||
{ "williamboman/mason-lspconfig.nvim", version = "1.31.0"},
|
||||
{ "j-hui/fidget.nvim", opts = {} }, -- side fidget showing status
|
||||
"hrsh7th/cmp-nvim-lsp", -- completion
|
||||
"b0o/schemastore.nvim",
|
||||
},
|
||||
config = function()
|
||||
require("mason").setup({
|
||||
ui = {
|
||||
border = "rounded",
|
||||
backdrop = 0
|
||||
},
|
||||
})
|
||||
|
||||
require("mason-lspconfig").setup()
|
||||
|
||||
local lspconfig = require("lspconfig")
|
||||
local capabilities = require("cmp_nvim_lsp").default_capabilities()
|
||||
|
||||
require("lspconfig.ui.windows").default_options = {
|
||||
border = "rounded",
|
||||
}
|
||||
|
||||
lspconfig.ts_ls.setup({
|
||||
capabilities = capabilities,
|
||||
init_options = {
|
||||
preferences = {
|
||||
includeCompletionsWithSnippetText = true,
|
||||
jsxAttributeCompletionStyle = "auto",
|
||||
},
|
||||
},
|
||||
on_attach = function(client, bufnr)
|
||||
-- Mappings
|
||||
local opts = { buffer = bufnr }
|
||||
remap.nmap("gd", vim.lsp.buf.definition, opts)
|
||||
remap.nmap("gr", vim.lsp.buf.references, opts)
|
||||
|
||||
remap.nmap("K", vim.lsp.buf.hover, opts)
|
||||
|
||||
remap.nmap("<leader>rn", vim.lsp.buf.rename, opts)
|
||||
remap.nmap("<leader>ca", vim.lsp.buf.code_action, opts)
|
||||
remap.nmap("<leader>ri", function()
|
||||
local diagnostics = vim.diagnostic.get(0)
|
||||
|
||||
-- Filter for TypeScript's unused import diagnostics (code 6133)
|
||||
local unused_imports_diagnostics = {}
|
||||
for _, diagnostic in ipairs(diagnostics) do
|
||||
if diagnostic.code == 6133 and diagnostic.source == "typescript" then
|
||||
table.insert(unused_imports_diagnostics, diagnostic)
|
||||
end
|
||||
end
|
||||
|
||||
vim.lsp.buf.code_action({
|
||||
context = {
|
||||
diagnostics = unused_imports_diagnostics,
|
||||
only = { "source.removeUnusedImports" },
|
||||
},
|
||||
})
|
||||
end, { desc = "Remove unused imports" })
|
||||
|
||||
remap.nmap("[d", vim.diagnostic.goto_prev, opts)
|
||||
remap.nmap("]d", vim.diagnostic.goto_next, opts)
|
||||
remap.nmap("<leader>d", vim.diagnostic.open_float, opts)
|
||||
end,
|
||||
})
|
||||
|
||||
lspconfig.eslint.setup({})
|
||||
lspconfig.html.setup({})
|
||||
lspconfig.cssls.setup({})
|
||||
lspconfig.jsonls.setup({
|
||||
capabilities = capabilities,
|
||||
settings = {
|
||||
json = {
|
||||
schemas = require("schemastore").json.schemas(),
|
||||
validate = { enable = true },
|
||||
allowComments = true,
|
||||
},
|
||||
},
|
||||
})
|
||||
end,
|
||||
}
|
||||
@@ -1,212 +0,0 @@
|
||||
return {
|
||||
"nvim-tree/nvim-tree.lua",
|
||||
version = "*",
|
||||
lazy = false,
|
||||
keys = {
|
||||
{ "<Leader>et", ":NvimTreeToggle<CR>", desc = "Explorer Toggle", silent = true },
|
||||
{
|
||||
"<Leader>ei",
|
||||
function()
|
||||
require("nvim-tree.api").node.show_info_popup()
|
||||
end,
|
||||
desc = "NvimTree: Info",
|
||||
mode = "n",
|
||||
},
|
||||
},
|
||||
config = function()
|
||||
local function my_on_attach(bufnr)
|
||||
local api = require("nvim-tree.api")
|
||||
|
||||
local function opts(desc)
|
||||
return { desc = "nvim-tree: " .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true }
|
||||
end
|
||||
|
||||
api.config.mappings.default_on_attach(bufnr)
|
||||
vim.keymap.set("n", "<Leader>et", api.tree.toggle, opts("Open or close the tree"))
|
||||
vim.keymap.set("n", "<Leader>ei", api.node.show_info_popup, opts("Show info popup"))
|
||||
vim.keymap.set("n", "?", api.tree.toggle_help, opts("Help"))
|
||||
|
||||
vim.keymap.del("n", "<C-k>", { buffer = bufnr })
|
||||
end
|
||||
|
||||
require("nvim-tree").setup({
|
||||
on_attach = my_on_attach,
|
||||
hijack_cursor = true,
|
||||
disable_netrw = true,
|
||||
hijack_netrw = true,
|
||||
hijack_unnamed_buffer_when_opening = true,
|
||||
root_dirs = { ".git", "package.json" },
|
||||
prefer_startup_root = true,
|
||||
sync_root_with_cwd = true,
|
||||
reload_on_bufenter = true,
|
||||
respect_buf_cwd = true,
|
||||
view = {
|
||||
centralize_selection = false,
|
||||
cursorline = true,
|
||||
cursorlineopt = "both",
|
||||
debounce_delay = 15,
|
||||
side = "left",
|
||||
preserve_window_proportions = false,
|
||||
number = false,
|
||||
relativenumber = false,
|
||||
signcolumn = "no",
|
||||
width = 30,
|
||||
},
|
||||
renderer = {
|
||||
add_trailing = false,
|
||||
group_empty = false,
|
||||
full_name = false,
|
||||
root_folder_label = false,
|
||||
-- special_files = { "Cargo.toml", "Makefile", "README.md", "readme.md" },
|
||||
special_files = {}, -- keep to overwrite defaults
|
||||
symlink_destination = true,
|
||||
icons = {
|
||||
padding = "",
|
||||
glyphs = {
|
||||
folder = {
|
||||
arrow_closed = "+",
|
||||
arrow_open = "-",
|
||||
},
|
||||
},
|
||||
show = {
|
||||
file = false,
|
||||
folder = false,
|
||||
folder_arrow = true,
|
||||
git = false,
|
||||
modified = false,
|
||||
hidden = false,
|
||||
diagnostics = false,
|
||||
bookmarks = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
hijack_directories = {
|
||||
enable = true,
|
||||
auto_open = true,
|
||||
},
|
||||
update_focused_file = {
|
||||
enable = true,
|
||||
update_root = {
|
||||
enable = true,
|
||||
ignore_list = {},
|
||||
},
|
||||
exclude = false,
|
||||
},
|
||||
filters = {
|
||||
enable = true,
|
||||
git_ignored = true,
|
||||
dotfiles = false,
|
||||
git_clean = false,
|
||||
no_buffer = false,
|
||||
no_bookmark = false,
|
||||
custom = {},
|
||||
exclude = {},
|
||||
},
|
||||
live_filter = {
|
||||
prefix = "[FILTER]: ",
|
||||
always_show_folders = true,
|
||||
},
|
||||
filesystem_watchers = {
|
||||
enable = true,
|
||||
debounce_delay = 50,
|
||||
ignore_dirs = {
|
||||
-- C / C++
|
||||
"/.ccls-cache",
|
||||
"/build",
|
||||
"/out",
|
||||
"/cmake-build-*",
|
||||
|
||||
-- Node.js / Web
|
||||
"/node_modules",
|
||||
"/dist",
|
||||
"/.next",
|
||||
"/.nuxt",
|
||||
"/coverage",
|
||||
"/storybook-static",
|
||||
|
||||
-- Rust
|
||||
"/target",
|
||||
|
||||
-- Java / JVM
|
||||
"/target", -- (Maven)
|
||||
"/build", -- (Gradle)
|
||||
"/out", -- (IDEA / javac)
|
||||
|
||||
-- Python
|
||||
"/.venv",
|
||||
"/venv",
|
||||
"/__pycache__",
|
||||
"/.mypy_cache",
|
||||
"/.pytest_cache",
|
||||
|
||||
-- Go
|
||||
"/bin",
|
||||
"/pkg",
|
||||
|
||||
-- General
|
||||
"/tmp",
|
||||
"/.cache",
|
||||
"/.idea",
|
||||
"/.vscode",
|
||||
"/logs",
|
||||
},
|
||||
},
|
||||
trash = {
|
||||
cmd = "gio trash",
|
||||
},
|
||||
})
|
||||
end,
|
||||
}
|
||||
|
||||
-- return {
|
||||
-- "nvim-neo-tree/neo-tree.nvim",
|
||||
-- version = "*",
|
||||
-- dependencies = {
|
||||
-- "nvim-lua/plenary.nvim",
|
||||
-- "nvim-tree/nvim-web-devicons",
|
||||
-- "MunifTanjim/nui.nvim",
|
||||
-- },
|
||||
-- cmd = "Neotree",
|
||||
-- keys = {
|
||||
-- { "<Leader>et", ":Neotree position=left toggle<CR>", desc = "Explorer Toggle", silent = true },
|
||||
-- { "<Leader>E", ":Neotree focus<CR>", desc = "Explorer Focus", silent = true },
|
||||
-- { "<Leader>ef", ":Neotree float<CR>", desc = "Explorer Float", silent = true },
|
||||
-- { "<Leader>eb", ":Neotree buffers<CR>", desc = "Explorer Buffers", silent = true },
|
||||
-- { "<Leader>eg", ":Neotree git_status<CR>", desc = "Explorer Git", silent = true },
|
||||
-- },
|
||||
-- opts = {
|
||||
-- event_handlers = {
|
||||
-- {
|
||||
-- event = require("neo-tree.ui.events").NEO_TREE_WINDOW_AFTER_OPEN,
|
||||
-- handler = function(args)
|
||||
-- if args and args.winid and vim.api.nvim_win_is_valid(args.winid) then
|
||||
-- vim.api.nvim_win_set_option(args.winid, "colorcolumn", "")
|
||||
-- vim.api.nvim_win_set_option(args.winid, "signcolumn", "no")
|
||||
-- end
|
||||
-- end,
|
||||
-- },
|
||||
-- },
|
||||
-- popup_border_style = "single",
|
||||
-- window = {
|
||||
-- mappings = {
|
||||
-- ["<Leader>e"] = "close_window",
|
||||
-- },
|
||||
-- },
|
||||
-- default_component_configs = {
|
||||
-- icon = { enabled = false },
|
||||
-- git_status = { symbols = {}, align = "none" },
|
||||
-- name = { trailing_slash = true }
|
||||
-- },
|
||||
-- enable_git_status = false,
|
||||
-- enable_diagnostics = false,
|
||||
-- filesystem = {
|
||||
-- follow_current_file = {
|
||||
-- enabled = true, -- Enable this feature
|
||||
-- leave_dirs_open = true, -- Leave directories open when following
|
||||
-- },
|
||||
-- filtered_items = {
|
||||
-- visible = true,
|
||||
-- }
|
||||
-- },
|
||||
-- },
|
||||
-- }
|
||||
@@ -1,52 +0,0 @@
|
||||
local remap = require("utils.remap")
|
||||
|
||||
return {
|
||||
"nvim-telescope/telescope.nvim",
|
||||
event = "VimEnter",
|
||||
branch = "0.1.x",
|
||||
dependencies = {
|
||||
"nvim-lua/plenary.nvim",
|
||||
{
|
||||
"nvim-telescope/telescope-fzf-native.nvim",
|
||||
build = "make",
|
||||
cond = function()
|
||||
return vim.fn.executable("make") == 1
|
||||
end,
|
||||
},
|
||||
{ "nvim-telescope/telescope-ui-select.nvim" },
|
||||
-- { "nvim-tree/nvim-web-devicons", enabled = vim.g.have_nerd_font },
|
||||
},
|
||||
config = function()
|
||||
require("telescope").setup({
|
||||
defaults = {
|
||||
layout_strategy = "vertical",
|
||||
layout_config = {
|
||||
width = { 0.95, max = 100 },
|
||||
height = 0.95,
|
||||
preview_cutoff = 1,
|
||||
preview_height = 0.7,
|
||||
},
|
||||
mappings = {
|
||||
n = {
|
||||
["d"] = "delete_buffer",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
pcall(require("telescope").load_extension, "fzf")
|
||||
pcall(require("telescope").load_extension, "ui-select")
|
||||
|
||||
local builtin = require("telescope.builtin")
|
||||
remap.nmap("<leader>sk", builtin.keymaps, { desc = "[S]earch [K]eymaps" })
|
||||
remap.nmap("<leader>sf", builtin.find_files, { desc = "[S]earch [F]iles" })
|
||||
remap.nmap("<leader>sw", builtin.grep_string, { desc = "[S]earch current [W]ord" })
|
||||
remap.nmap("<leader>ss", builtin.current_buffer_fuzzy_find, { desc = "[S]earch [C]urrent file" })
|
||||
remap.nmap("<leader>sg", builtin.live_grep, { desc = "[S]earch by [G]rep" })
|
||||
remap.nmap("<leader>sd", builtin.diagnostics, { desc = "[S]earch [D]iagnostics" })
|
||||
remap.nmap("<leader>sr", builtin.lsp_references, { desc = "[S]earch [R]references" })
|
||||
remap.nmap("<leader>s.", builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' })
|
||||
-- remap.nmap("<leader>ss", builtin.git_status, { desc = "[S]earch Git [S]tatus" })
|
||||
remap.nmap("<leader><leader>", builtin.buffers, { desc = "Find existing [B]uffers" })
|
||||
end,
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
return {
|
||||
"nvim-treesitter/nvim-treesitter",
|
||||
build = "TSUpdate",
|
||||
main = "nvim-treesitter.configs",
|
||||
opts = {
|
||||
ensure_installed = {
|
||||
"diff",
|
||||
"lua",
|
||||
"html",
|
||||
"css",
|
||||
"javascript",
|
||||
"typescript",
|
||||
"tsx",
|
||||
"markdown",
|
||||
"markdown_inline",
|
||||
},
|
||||
auto_install = true,
|
||||
highlight = {
|
||||
enable = true,
|
||||
},
|
||||
indent = { enable = true },
|
||||
},
|
||||
config = function(_, opts)
|
||||
require("nvim-treesitter.configs").setup(opts)
|
||||
-- Add MDX filetype detection
|
||||
vim.filetype.add({
|
||||
extension = {
|
||||
mdx = "markdown.mdx",
|
||||
},
|
||||
})
|
||||
end,
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.get(P)
|
||||
local colors = {
|
||||
base = P.white,
|
||||
surface = P.gray_light,
|
||||
outline = P.gray_dark,
|
||||
text = P.black,
|
||||
muted = P.gray,
|
||||
accent = P.blue,
|
||||
accent_light = P.blue_light,
|
||||
syntax = P.slate_indigo,
|
||||
none = "NONE",
|
||||
}
|
||||
|
||||
return vim.tbl_extend("force", P, colors)
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,35 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.get(C)
|
||||
return {
|
||||
Normal = { fg = C.text, bg = C.none },
|
||||
Directory = { fg = C.accent },
|
||||
Question = { fg = C.text },
|
||||
LineNr = { fg = C.muted },
|
||||
CursorLineNr = { fg = C.accent, bold = true },
|
||||
CursorLine = { bg = C.surface },
|
||||
Visual = { bg = C.accent_light },
|
||||
ColorColumn = { bg = C.surface },
|
||||
|
||||
Search = { fg = C.yellow },
|
||||
CurSearch = { fg = C.yellow, bg = C.none, bold = true },
|
||||
IncSearch = { fg = C.yellow, bg = C.none, bold = true },
|
||||
|
||||
MatchParen = { fg = C.accent, bg = C.accent_light, bold = true },
|
||||
EndOfBuffer = { fg = C.base }, -- End-of-buffer marker (~ lines)
|
||||
|
||||
WinSeparator = { fg = C.outline },
|
||||
-- StatusLine = { fg = C.outline, bg = C.none }, -- Active statusline (where filename)
|
||||
StatusLine = { fg = C.base, bg = C.outline, bold = false }, -- Active statusline (where filename)
|
||||
StatusLineNC = { fg = C.base, bg = C.outline, bold = false }, -- Active statusline (where filename)
|
||||
MsgArea = { fg = C.text, bg = C.none }, -- Command-line / message area
|
||||
MsgSeparator = { fg = C.text, bg = C.surface }, -- Separator for messages
|
||||
ModeMsg = { fg = C.text },
|
||||
|
||||
TabLine = { fg = C.muted }, -- Unselected tab
|
||||
TabLineSel = { fg = C.text, bold = true }, -- Selected tab
|
||||
TabLineFill = { bg = C.none }, -- Empty space in the tabline
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,7 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.get(C)
|
||||
return {}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,9 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.get(C)
|
||||
return {
|
||||
TelescopeMatching = { fg = C.yellow, bg = C.none, bold = true },
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,21 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.get(C)
|
||||
return {
|
||||
["@constant.macro"] = { fg = C.syntax },
|
||||
["@function.method"] = { fg = C.syntax },
|
||||
["@type.qualifier"] = { fg = C.syntax },
|
||||
["@variable.parameter"] = { fg = C.syntax },
|
||||
["@variable"] = { fg = C.syntax },
|
||||
["@type.definition"] = { fg = C.syntax },
|
||||
["@markup.italic"] = { fg = C.syntax },
|
||||
["@markup.strong"] = { fg = C.syntax },
|
||||
["@markup.underline"] = { fg = C.syntax },
|
||||
["@markup.strikethrough"] = { fg = C.syntax },
|
||||
|
||||
["@_jsx_attribute"] = { link = "Constant" },
|
||||
["@string.documentation.python"] = { link = "Comment" },
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,38 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.get(C)
|
||||
return {
|
||||
Comment = { fg = C.muted, italic = true },
|
||||
String = { fg = C.green },
|
||||
Boolean = { fg = C.accent, bold = true, italic = true },
|
||||
Number = { fg = C.accent },
|
||||
|
||||
-- syntax color
|
||||
Constant = { fg = C.syntax },
|
||||
Function = { fg = C.syntax },
|
||||
Type = { fg = C.syntax },
|
||||
Statement = { fg = C.syntax },
|
||||
Identifier = { fg = C.syntax },
|
||||
Operator = { fg = C.syntax },
|
||||
PreProc = { fg = C.syntax },
|
||||
Special = { fg = C.syntax },
|
||||
Delimiter = { fg = C.syntax },
|
||||
Todo = { fg = C.syntax },
|
||||
Title = { fg = C.syntax },
|
||||
Underlined = { fg = C.syntax },
|
||||
|
||||
-- diffs
|
||||
Added = { fg = C.green },
|
||||
Removed = { fg = C.red },
|
||||
Changed = { fg = C.yellow },
|
||||
|
||||
-- diagnostics
|
||||
DiagnosticInfo = { fg = C.blue },
|
||||
DiagnosticWarn = { fg = C.yellow },
|
||||
DiagnosticError = { fg = C.red },
|
||||
DiagnosticDeprecated = { fg = C.magenta },
|
||||
DiagnosticUnderlineError = { fg = C.syntax, underline = true },
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,31 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.get(C)
|
||||
return {
|
||||
terminal_color_0 = { fg = C.black },
|
||||
terminal_color_8 = { fg = C.black },
|
||||
|
||||
terminal_color_1 = { fg = C.red },
|
||||
terminal_color_9 = { fg = C.red },
|
||||
|
||||
terminal_color_2 = { fg = C.green },
|
||||
terminal_color_10 = { fg = C.green },
|
||||
|
||||
terminal_color_3 = { fg = C.yellow },
|
||||
terminal_color_11 = { fg = C.yellow },
|
||||
|
||||
terminal_color_4 = { fg = C.blue },
|
||||
terminal_color_12 = { fg = C.blue },
|
||||
|
||||
terminal_color_5 = { fg = C.magenta },
|
||||
terminal_color_13 = { fg = C.magenta },
|
||||
|
||||
terminal_color_6 = { fg = C.cyan },
|
||||
terminal_color_14 = { fg = C.cyan },
|
||||
|
||||
terminal_color_7 = { fg = C.white },
|
||||
terminal_color_15 = { fg = C.white },
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,14 +0,0 @@
|
||||
local M = {
|
||||
name = "invero",
|
||||
variant = "light",
|
||||
mode = "ansi",
|
||||
exclude_integrations = {},
|
||||
}
|
||||
|
||||
function M.load()
|
||||
local setup = require("themes." .. M.name .. ".setup")
|
||||
setup.reset(M)
|
||||
setup.apply(M)
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,53 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
local modes = {
|
||||
ansi = {
|
||||
black = 0,
|
||||
red = 1,
|
||||
green = 2,
|
||||
yellow = 3,
|
||||
blue = 4,
|
||||
magenta = 5,
|
||||
cyan = 6,
|
||||
white = 7,
|
||||
},
|
||||
default = {
|
||||
black = 238,
|
||||
red = 196,
|
||||
green = 35,
|
||||
yellow = 221,
|
||||
blue = 27,
|
||||
magenta = 125,
|
||||
cyan = 30,
|
||||
white = 255,
|
||||
},
|
||||
}
|
||||
|
||||
local shared_palette = {
|
||||
gray_dark = 245,
|
||||
gray = 247,
|
||||
gray_light = 253,
|
||||
orange = 166,
|
||||
orange_light = 180,
|
||||
yellow_light = 180,
|
||||
blue_light = 153,
|
||||
slate_indigo = 60,
|
||||
}
|
||||
|
||||
---Get color palette
|
||||
---@param mode '"ansi"'|'"default"'
|
||||
---@return table
|
||||
function M.get(mode)
|
||||
local mode_palette = modes[mode]
|
||||
if not mode_palette then
|
||||
vim.notify(
|
||||
string.format('Invalid palette mode: "%s" (valid: ansi, default)', tostring(mode)),
|
||||
vim.log.levels.WARN,
|
||||
{ title = "palette" }
|
||||
)
|
||||
mode_palette = modes.default
|
||||
end
|
||||
return vim.tbl_extend("force", mode_palette, shared_palette)
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,72 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.reset(theme)
|
||||
vim.opt.background = (theme.variant == "light") and "light" or "dark"
|
||||
vim.g.colors_name = theme.name
|
||||
end
|
||||
|
||||
local function list_integrations(theme_name)
|
||||
local path = vim.fn.stdpath("config") .. "/lua/themes/" .. theme_name .. "/groups/integrations/"
|
||||
|
||||
local files = {}
|
||||
for name, type in vim.fs.dir(path) do
|
||||
if type == "file" then
|
||||
local mod_name = vim.fn.fnamemodify(name, ":r")
|
||||
table.insert(files, mod_name)
|
||||
end
|
||||
end
|
||||
return files
|
||||
end
|
||||
|
||||
function M.apply(theme)
|
||||
local base = "themes." .. theme.name
|
||||
local P = require(base .. ".palette").get(theme.mode)
|
||||
local C = require(base .. ".colors").get(P)
|
||||
|
||||
local modules = {
|
||||
require(base .. ".groups.editor"),
|
||||
require(base .. ".groups.syntax"),
|
||||
require(base .. ".groups.terminal"),
|
||||
}
|
||||
|
||||
local exclude = theme.exclude_integrations or {}
|
||||
|
||||
local function should_load(name)
|
||||
return not vim.tbl_contains(exclude, name)
|
||||
end
|
||||
|
||||
-- auto-discover integrations
|
||||
for _, plugin in ipairs(list_integrations(theme.name)) do
|
||||
if should_load(plugin) then
|
||||
local ok_mod, mod = pcall(require, base .. ".groups.integrations." .. plugin)
|
||||
if ok_mod then
|
||||
table.insert(modules, mod)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply highlights
|
||||
for _, mod in ipairs(modules) do
|
||||
local groups = mod.get(C) or {}
|
||||
for group, opts in pairs(groups) do
|
||||
if type(opts) ~= "table" then
|
||||
print("Non-table opts detected in group:", group, "value:", vim.inspect(opts))
|
||||
end
|
||||
local hl = {}
|
||||
|
||||
for k, v in pairs(opts) do
|
||||
if k == "fg" then
|
||||
hl.ctermfg = v
|
||||
elseif k == "bg" then
|
||||
hl.ctermbg = v
|
||||
else
|
||||
hl[k] = v -- bold, italic, underline, sp, etc.
|
||||
end
|
||||
end
|
||||
|
||||
vim.api.nvim_set_hl(0, group, hl)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,39 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M.map(mode, lhs, rhs, opts)
|
||||
local options = { silent = true, noremap = true }
|
||||
|
||||
if opts then
|
||||
options = vim.tbl_extend("force", options, opts)
|
||||
end
|
||||
|
||||
if type(mode) == "table" then
|
||||
for _, m in ipairs(mode) do
|
||||
vim.keymap.set(m, lhs, rhs, options)
|
||||
end
|
||||
else
|
||||
vim.keymap.set(mode, lhs, rhs, options)
|
||||
end
|
||||
end
|
||||
|
||||
function M.nmap(lhs, rhs, opts)
|
||||
M.map("n", lhs, rhs, opts)
|
||||
end
|
||||
|
||||
function M.imap(lhs, rhs, opts)
|
||||
M.map("i", lhs, rhs, opts)
|
||||
end
|
||||
|
||||
function M.vmap(lhs, rhs, opts)
|
||||
M.map("v", lhs, rhs, opts)
|
||||
end
|
||||
|
||||
function M.tmap(lhs, rhs, opts)
|
||||
M.map("t", lhs, rhs, opts)
|
||||
end
|
||||
|
||||
function M.cmap(lhs, rhs, opts)
|
||||
M.map("c", lhs, rhs, opts)
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -1,105 +0,0 @@
|
||||
-- Window Creation/Closing
|
||||
Ctrl-w s - Split window horizontally
|
||||
Ctrl-w v - Split window vertically
|
||||
Ctrl-w n - Create new window horizontally with empty buffer
|
||||
Ctrl-w c - Close current window
|
||||
Ctrl-w o - Close all windows except current one
|
||||
|
||||
-- Window Navigation
|
||||
Ctrl-w h - Move to window on the left
|
||||
Ctrl-w j - Move to window below
|
||||
Ctrl-w k - Move to window above
|
||||
Ctrl-w l - Move to window on the right
|
||||
|
||||
-- Window Moving/Rearranging
|
||||
Ctrl-w H - Move current window to far left
|
||||
Ctrl-w J - Move current window to bottom
|
||||
Ctrl-w K - Move current window to top
|
||||
Ctrl-w L - Move current window to far right
|
||||
Ctrl-w r - Rotate windows downward/rightward
|
||||
Ctrl-w R - Rotate windows upward/leftward
|
||||
Ctrl-w x - Exchange current window with next one
|
||||
|
||||
-- Window Resizing
|
||||
Ctrl-w = - Make all windows equal size
|
||||
Ctrl-w _ - Maximize height of current window
|
||||
Ctrl-w | - Maximize width of current window
|
||||
Ctrl-w > - Increase width by 1 column
|
||||
Ctrl-w < - Decrease width by 1 column
|
||||
Ctrl-w + - Increase height by 1 row
|
||||
Ctrl-w - - Decrease height by 1 row
|
||||
|
||||
-- Window Special Commands
|
||||
Ctrl-w T - Move current window to new tab
|
||||
Ctrl-w } - Preview definition in new window
|
||||
Ctrl-w z - Close preview window
|
||||
Ctrl-w ] - Split window and jump to definition
|
||||
Ctrl-w f - Split window and edit file under cursor
|
||||
Ctrl-w i - Split window and show declaration
|
||||
Ctrl-w ^ - Split window and edit alternate file
|
||||
|
||||
-- Tab
|
||||
gt :tabnext - Go to next tab
|
||||
gT :tabprevious - Go to previous tab
|
||||
{n}gt :tabnext {n} - Go to tab number {n}
|
||||
<Leader>tn :tabnew - Create a new tab - Suggested
|
||||
<Leader>tc :tabclose - Close current tab - Suggested
|
||||
<Leader>to :tabonly - Close all other tabs - Suggested
|
||||
<Leader>t{n} {n}gt - Go to tab {n} - Suggested
|
||||
<Leader>tm. :tabmove +1 - Move tab right - Suggested
|
||||
<Leader>tm, :tabmove -1 - Move tab left - Suggested
|
||||
|
||||
-- Buffer
|
||||
<Leader>bl :ls - List all buffers - Suggested
|
||||
<Leader>bd :bdelete - Delete current buffer - Suggested
|
||||
<Leader>bn :bnext - Go to next buffer - Suggested
|
||||
<Leader>bp :bprevious - Go to previous buffer - Suggested
|
||||
<Leader>b{n} :buffer {n} - Go to buffer {n} - Suggested
|
||||
<Leader>bb :b<Space> - Start buffer selection - Suggested
|
||||
<Leader>bo :bufdo bd|1bd - Delete all other buffers - Suggested
|
||||
|
||||
-- Telescope
|
||||
<Leader>sf telescope.find_files - Search Files
|
||||
<Leader>sg telescope.live_grep - Search by Grep
|
||||
<Leader>sb telescope.buffers - Search Buffers
|
||||
<Leader>sh telescope.help_tags - Search Help
|
||||
<Leader>sp telescope.projects - Search Projects
|
||||
<Leader>sm telescope.marks - Search Marks
|
||||
<Leader>sc telescope.commands - Search Commands
|
||||
<Leader>sk telescope.keymaps - Search Keymaps
|
||||
<Leader>ss telescope.git_status - Search Git Status
|
||||
<Leader>sw telescope.grep_string - Search current Word
|
||||
<Leader>sd telescope.diagnostics - Search Diagnostics
|
||||
<Leader>sr telescope.lsp_references - Search References
|
||||
|
||||
-- Neo-tree
|
||||
<Leader>e :Neotree toggle - Explorer Toggle
|
||||
<Leader>E :Neotree focus - Explorer Focus
|
||||
<Leader>ef :Neotree float - Explorer Float
|
||||
<Leader>eb :Neotree buffers - Explorer Buffers
|
||||
<Leader>eg :Neotree git_status - Explorer Git
|
||||
|
||||
-- Harpoon
|
||||
<Leader>h harpoon_ui.toggle_menu - Harpoon Menu
|
||||
<Leader>m harpoon_mark.add_file - Mark File
|
||||
<Leader>1 harpoon_ui.nav_file(1) - Harpoon File 1
|
||||
<Leader>2 harpoon_ui.nav_file(2) - Harpoon File 2
|
||||
<Leader>3 harpoon_ui.nav_file(3) - Harpoon File 3
|
||||
<Leader>4 harpoon_ui.nav_file(4) - Harpoon File 4
|
||||
<Leader>hn harpoon_ui.nav_next - Harpoon Next
|
||||
<Leader>hp harpoon_ui.nav_prev - Harpoon Previous
|
||||
|
||||
-- Terminal
|
||||
<Leader>tet :terminal cd %:h - Terminal in This dir
|
||||
<Leader>ter :terminal - Terminal Regular
|
||||
<Leader>tec :!cd %:h && - Terminal Command
|
||||
<Esc> <C-\><C-n> - Terminal Normal Mode
|
||||
<C-w> <C-\><C-n><C-w> - Terminal Window Command
|
||||
|
||||
-- LSP
|
||||
gd vim.lsp.buf.definition - Goto Definition
|
||||
gr vim.lsp.buf.references - Goto References
|
||||
K vim.lsp.buf.hover - Hover Documentation
|
||||
<Leader>rn vim.lsp.buf.rename - Rename
|
||||
<Leader>ca vim.lsp.buf.code_action - Code Action
|
||||
<Leader>f vim.lsp.buf.format - Format
|
||||
78
config/macos/alacritty/alacritty.toml
Normal file
78
config/macos/alacritty/alacritty.toml
Normal file
@@ -0,0 +1,78 @@
|
||||
[env]
|
||||
# TERM = "xterm-256color"
|
||||
|
||||
[font]
|
||||
size = 14
|
||||
normal = { family = "SF Mono", style = "Regular" }
|
||||
bold = { family = "SF Mono", style = "Bold" }
|
||||
italic = { family = "SF Mono", style = "Regular Italic" }
|
||||
bold_italic = { family = "SF Mono", style = "Bold Italic" }
|
||||
|
||||
# normal = { family = "Maple Mono", style = "Regular" }
|
||||
# bold = { family = "Maple Mono", style = "Bold" }
|
||||
# italic = { family = "Maple Mono", style = "Italic" }
|
||||
# bold_italic = { family = "Maple Mono", style = "Bold Italic" }
|
||||
# offset = { x = -1, y = 0 }
|
||||
|
||||
[window]
|
||||
padding = { x = 2, y = 0 }
|
||||
dynamic_padding = true
|
||||
# resize_increments = true
|
||||
|
||||
[keyboard]
|
||||
bindings = [
|
||||
# Create new window
|
||||
{ action = "SpawnNewInstance", key = "N", mods = "Command" },
|
||||
# Jump back one word
|
||||
{ key = "Left", mods = "Alt", chars = "\u001bb" },
|
||||
# Jump forward one word
|
||||
{ key = "Right", mods = "Alt", chars = "\u001bf" },
|
||||
# Move to start of line
|
||||
{ key = "Left", mods = "Command", chars = "\u0001" },
|
||||
# Move to end of line
|
||||
{ key = "Right", mods = "Command", chars = "\u0005" },
|
||||
# Delete backwards
|
||||
{ key = "Back", mods = "Alt", chars = "\u001B\u007F" }, # word
|
||||
{ key = "Back", mods = "Command", chars = "\u0015" }, # line
|
||||
# Delete forwards
|
||||
{ key = "Delete", mods = "Alt", chars = "\u001Bd" }, # word
|
||||
{ key = "Delete", mods = "Command", chars = "\u000B" } # line
|
||||
]
|
||||
|
||||
[scrolling]
|
||||
multiplier = 1
|
||||
|
||||
[general]
|
||||
live_config_reload = true
|
||||
|
||||
[colors.primary]
|
||||
background = "#eeeeee"
|
||||
foreground = "#444444"
|
||||
|
||||
[colors.cursor]
|
||||
text = "#eeeeee"
|
||||
cursor = "#005fff"
|
||||
|
||||
[colors.selection]
|
||||
text = "#434343"
|
||||
background = "#e0e0e0"
|
||||
|
||||
[colors.normal]
|
||||
black = "#000000"
|
||||
red = "#aa3731"
|
||||
green = "#448c27"
|
||||
yellow = "#cb9000"
|
||||
blue = "#325cc0"
|
||||
magenta = "#7a3e9d"
|
||||
cyan = "#0083b2"
|
||||
white = "#bbbbbb"
|
||||
|
||||
[colors.bright]
|
||||
black = "#000000"
|
||||
red = "#aa3731"
|
||||
green = "#448c27"
|
||||
yellow = "#cb9000"
|
||||
blue = "#325cc0"
|
||||
magenta = "#7a3e9d"
|
||||
cyan = "#0083b2"
|
||||
white = "#bbbbbb"
|
||||
27
config/macos/alacritty/themes/alabaster.toml
Normal file
27
config/macos/alacritty/themes/alabaster.toml
Normal file
@@ -0,0 +1,27 @@
|
||||
[colors.primary]
|
||||
background = '#F7F7F7'
|
||||
foreground = '#434343'
|
||||
|
||||
[colors.cursor]
|
||||
text = '#F7F7F7'
|
||||
cursor = '#434343'
|
||||
|
||||
[colors.normal]
|
||||
black = '#000000'
|
||||
red = '#AA3731'
|
||||
green = '#448C27'
|
||||
yellow = '#CB9000'
|
||||
blue = '#325CC0'
|
||||
magenta = '#7A3E9D'
|
||||
cyan = '#0083B2'
|
||||
white = '#BBBBBB'
|
||||
|
||||
[colors.bright]
|
||||
black = '#777777'
|
||||
red = '#F05050'
|
||||
green = '#60CB00'
|
||||
yellow = '#FFBC5D'
|
||||
blue = '#007ACC'
|
||||
magenta = '#E64CE6'
|
||||
cyan = '#00AACB'
|
||||
white = '#FFFFFF'
|
||||
@@ -1,81 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# ~/bin/vm
|
||||
#
|
||||
# SSH helper script for connecting to VMs or workstations.
|
||||
# Usage:
|
||||
# vm [--no-tmux] <host>
|
||||
#
|
||||
# Host patterns:
|
||||
# personal-orb -> ssh $USER@personal@orb
|
||||
# personal-utm -> ssh $USER@personal.utm.local
|
||||
# personal-workstation -> ssh $USER@personal.workstation.lan
|
||||
#
|
||||
# Optional:
|
||||
# --no-tmux -> skips attaching to tmux session
|
||||
|
||||
# TMP: Tmux will be disabled (switch to 0 to enable it again)
|
||||
skip_tmux=0
|
||||
|
||||
# Check for --no-tmux flag
|
||||
if [[ "$1" == "--no-tmux" ]]; then
|
||||
skip_tmux=1
|
||||
shift
|
||||
fi
|
||||
|
||||
full="$1"
|
||||
shift # remove host from args
|
||||
|
||||
user="$USER"
|
||||
host="$full"
|
||||
|
||||
# Split user@host if explicitly specified
|
||||
if [[ "$full" == *@* ]]; then
|
||||
user="${full%@*}"
|
||||
host="${full#*@}"
|
||||
fi
|
||||
|
||||
# Map host patterns to SSH target and machine type
|
||||
case "$host" in
|
||||
*-orb)
|
||||
ssh_host="${host%-orb}@orb"
|
||||
TARGET_MACHINE="orb"
|
||||
;;
|
||||
*-utm)
|
||||
ssh_host="${host%-utm}.utm.local"
|
||||
TARGET_MACHINE="utm"
|
||||
ssh_identity="$HOME/.ssh/id_ed25519_internal"
|
||||
;;
|
||||
*-workstation)
|
||||
ssh_host="${host%-workstation}.workstation.lan"
|
||||
TARGET_MACHINE="workstation"
|
||||
ssh_identity="$HOME/.ssh/id_ed25519_internal"
|
||||
;;
|
||||
*)
|
||||
echo "Error: unknown host pattern '$host'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Always use "default" tmux session
|
||||
tmux_session="default"
|
||||
|
||||
# Build SSH command safely using an array
|
||||
ssh_cmd=(ssh -tt)
|
||||
|
||||
# Include identity file if needed
|
||||
[[ -n "$ssh_identity" ]] && ssh_cmd+=(-i "$ssh_identity" -o IdentitiesOnly=yes)
|
||||
|
||||
# Add target user and host
|
||||
ssh_cmd+=("$user@$ssh_host")
|
||||
|
||||
# Add tmux session unless skipped
|
||||
if [[ $skip_tmux -eq 0 ]]; then
|
||||
ssh_cmd+=("tmux" "new-session" "-As" "$tmux_session" "-e" "TARGET_MACHINE=$TARGET_MACHINE")
|
||||
else
|
||||
# Pass through any extra args user supplied
|
||||
ssh_cmd+=("$@")
|
||||
fi
|
||||
|
||||
# echo "Executing: ${ssh_cmd[*]}" >&2
|
||||
exec "${ssh_cmd[@]}"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
file=/tmp/vm-switch.txt
|
||||
|
||||
# Ensure the file exists
|
||||
touch "$file"
|
||||
|
||||
echo "Listening on $file ..."
|
||||
tail -n0 -F "$file" | while read vm; do
|
||||
[ -n "$vm" ] && echo "Switch requested: $vm" && ~/bin/work "$vm" &
|
||||
done
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
orbctl list > /tmp/vmlist.txt
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Usage: work <vm>
|
||||
vm="$1"
|
||||
if [ -z "$vm" ]; then
|
||||
echo "Usage: work <vm>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec vm "${vm}-orb"
|
||||
|
||||
13
config/macos/borders/bordersrc
Executable file
13
config/macos/borders/bordersrc
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
options=(
|
||||
order=above
|
||||
width=2.0
|
||||
hidpi=on
|
||||
active_color=0xff2b2b2b
|
||||
inactive_color=0xff2b2b2b
|
||||
# inactive_color=0x00000000
|
||||
whitelist="wezterm-gui"
|
||||
)
|
||||
|
||||
borders "${options[@]}"
|
||||
BIN
config/macos/ghostty/Ghostty.icns
Normal file
BIN
config/macos/ghostty/Ghostty.icns
Normal file
Binary file not shown.
33
config/macos/ghostty/config
Normal file
33
config/macos/ghostty/config
Normal file
@@ -0,0 +1,33 @@
|
||||
#term = xterm-256color
|
||||
theme = Invero Day
|
||||
|
||||
# Font
|
||||
font-family = "Maple Mono"
|
||||
font-size = 13
|
||||
font-thicken = true
|
||||
font-thicken-strength = 120
|
||||
font-feature = -liga, -dlig, -calt
|
||||
|
||||
adjust-underline-thickness = 1
|
||||
adjust-strikethrough-thickness = 1
|
||||
adjust-overline-thickness = 1
|
||||
adjust-box-thickness = 1
|
||||
adjust-cell-width = -7%
|
||||
adjust-cell-height = -2
|
||||
|
||||
# Cursor
|
||||
cursor-style = block
|
||||
cursor-style-blink = false
|
||||
mouse-hide-while-typing = true
|
||||
shell-integration-features = ssh-terminfo,ssh-env,no-cursor
|
||||
|
||||
# Window
|
||||
window-height = 80
|
||||
window-width = 128
|
||||
window-padding-x = 4
|
||||
window-padding-y = 0
|
||||
window-padding-color = extend
|
||||
macos-titlebar-style = native
|
||||
macos-icon = custom
|
||||
|
||||
window-inherit-working-directory = false
|
||||
22
config/macos/ghostty/themes/Invero Day
Normal file
22
config/macos/ghostty/themes/Invero Day
Normal file
@@ -0,0 +1,22 @@
|
||||
palette = 0=#444444
|
||||
palette = 1=#ff0000
|
||||
palette = 2=#00af5f
|
||||
palette = 3=#d75f00
|
||||
palette = 4=#005fff
|
||||
palette = 5=#5f5f87
|
||||
palette = 6=#afd7ff
|
||||
palette = 7=#eeeeee
|
||||
palette = 8=#444444
|
||||
palette = 9=#ff0000
|
||||
palette = 10=#00af5f
|
||||
palette = 11=#d75f00
|
||||
palette = 12=#005fff
|
||||
palette = 13=#5f5f87
|
||||
palette = 14=#afd7ff
|
||||
palette = 15=#eeeeee
|
||||
|
||||
background = #eeeeee
|
||||
foreground = #444444
|
||||
cursor-color = #005fff
|
||||
selection-background = #dadada
|
||||
selection-foreground = #444444
|
||||
@@ -1,21 +1,25 @@
|
||||
tap "homebrew/bundle"
|
||||
tap "homebrew/services"
|
||||
brew "bash"
|
||||
brew "dnsmasq", restart_service: :changed
|
||||
brew "neovim"
|
||||
cask "daisydisk"
|
||||
brew "tmux"
|
||||
cask "brave-browser"
|
||||
cask "bruno"
|
||||
cask "dbeaver-community"
|
||||
cask "discord"
|
||||
cask "firefox"
|
||||
cask "font-maple-mono"
|
||||
cask "font-maple-mono-nf"
|
||||
cask "ghostty"
|
||||
cask "google-chrome"
|
||||
cask "karabiner-elements"
|
||||
cask "linearmouse"
|
||||
cask "obsidian"
|
||||
cask "macfuse"
|
||||
cask "orbstack"
|
||||
cask "proton-drive"
|
||||
cask "protonvpn"
|
||||
cask "rectangle"
|
||||
cask "slack"
|
||||
cask "sol"
|
||||
cask "spotify"
|
||||
cask "utm"
|
||||
cask "visual-studio-code"
|
||||
cask "sublime-text"
|
||||
cask "utm@beta"
|
||||
cask "zoom"
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"global": { "show_in_menu_bar": false },
|
||||
"profiles": [
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"identifiers": { "is_keyboard": true },
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "non_us_backslash" },
|
||||
"to": [{ "key_code": "grave_accent_and_tilde" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "Default profile",
|
||||
"selected": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"global": { "show_in_menu_bar": false },
|
||||
"profiles": [
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"identifiers": { "is_keyboard": true },
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "non_us_backslash" },
|
||||
"to": [{ "key_code": "grave_accent_and_tilde" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifiers": {
|
||||
"is_keyboard": true,
|
||||
"product_id": 49164,
|
||||
"vendor_id": 7276
|
||||
},
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "left_command" },
|
||||
"to": [{ "key_code": "left_option" }]
|
||||
},
|
||||
{
|
||||
"from": { "key_code": "left_option" },
|
||||
"to": [{ "key_code": "left_command" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "Default profile",
|
||||
"selected": true,
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "caps_lock" },
|
||||
"to": [{ "key_code": "left_control" }]
|
||||
}
|
||||
],
|
||||
"virtual_hid_keyboard": { "keyboard_type_v2": "ansi" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"profiles": [
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"identifiers": { "is_keyboard": true },
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "non_us_backslash" },
|
||||
"to": [{ "key_code": "grave_accent_and_tilde" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifiers": {
|
||||
"is_keyboard": true,
|
||||
"product_id": 49164,
|
||||
"vendor_id": 7276
|
||||
},
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "left_command" },
|
||||
"to": [{ "key_code": "left_option" }]
|
||||
},
|
||||
{
|
||||
"from": { "key_code": "left_option" },
|
||||
"to": [{ "key_code": "left_command" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "Default profile",
|
||||
"selected": true,
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "caps_lock" },
|
||||
"to": [{ "key_code": "left_control" }]
|
||||
}
|
||||
],
|
||||
"virtual_hid_keyboard": { "keyboard_type_v2": "ansi" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"global": { "show_in_menu_bar": false },
|
||||
"profiles": [
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"identifiers": { "is_keyboard": true },
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "non_us_backslash" },
|
||||
"to": [{ "key_code": "grave_accent_and_tilde" }]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifiers": {
|
||||
"is_keyboard": true,
|
||||
"product_id": 49164,
|
||||
"vendor_id": 7276
|
||||
},
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "left_command" },
|
||||
"to": [{ "key_code": "left_option" }]
|
||||
},
|
||||
{
|
||||
"from": { "key_code": "left_option" },
|
||||
"to": [{ "key_code": "left_command" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "Default profile",
|
||||
"selected": true,
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "caps_lock" },
|
||||
"to": [{ "key_code": "left_control" }]
|
||||
}
|
||||
],
|
||||
"virtual_hid_keyboard": { "keyboard_type_v2": "ansi" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"profiles": [
|
||||
{
|
||||
"name": "Default profile",
|
||||
"selected": true,
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "caps_lock" },
|
||||
"to": [{ "key_code": "left_control" }]
|
||||
}
|
||||
],
|
||||
"virtual_hid_keyboard": { "keyboard_type_v2": "iso" }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4,38 +4,20 @@
|
||||
{
|
||||
"devices": [
|
||||
{
|
||||
"identifiers": { "is_keyboard": true },
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "non_us_backslash" },
|
||||
"to": [{ "key_code": "grave_accent_and_tilde" }]
|
||||
}
|
||||
]
|
||||
"identifiers": {
|
||||
"is_keyboard": true,
|
||||
"product_id": 50475,
|
||||
"vendor_id": 1133
|
||||
},
|
||||
"ignore_vendor_events": true
|
||||
},
|
||||
{
|
||||
"identifiers": {
|
||||
"is_keyboard": true,
|
||||
"product_id": 49164,
|
||||
"vendor_id": 7276
|
||||
"product_id": 50504,
|
||||
"vendor_id": 1133
|
||||
},
|
||||
"simple_modifications": [
|
||||
{
|
||||
"from": { "key_code": "left_command" },
|
||||
"to": [{ "key_code": "left_option" }]
|
||||
},
|
||||
{
|
||||
"from": { "key_code": "left_option" },
|
||||
"to": [{ "key_code": "left_command" }]
|
||||
},
|
||||
{
|
||||
"from": { "key_code": "escape" },
|
||||
"to": [{ "key_code": "grave_accent_and_tilde" }]
|
||||
},
|
||||
{
|
||||
"from": { "key_code": "grave_accent_and_tilde" },
|
||||
"to": [{ "key_code": "escape" }]
|
||||
}
|
||||
]
|
||||
"ignore_vendor_events": true
|
||||
}
|
||||
],
|
||||
"name": "Default profile",
|
||||
@@ -46,7 +28,7 @@
|
||||
"to": [{ "key_code": "left_control" }]
|
||||
}
|
||||
],
|
||||
"virtual_hid_keyboard": { "keyboard_type_v2": "ansi" }
|
||||
"virtual_hid_keyboard": { "keyboard_type_v2": "iso" }
|
||||
}
|
||||
]
|
||||
}
|
||||
54
config/macos/kitty/choose_tab.py
Normal file
54
config/macos/kitty/choose_tab.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# ~/.config/kitty/choose_tab.py
|
||||
from kitty.boss import get_boss
|
||||
from kittens.tui.handler import Handler
|
||||
from kittens.tui.loop import Loop
|
||||
|
||||
|
||||
class TabPicker(Handler):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
boss = get_boss()
|
||||
win = boss.active_window
|
||||
self.osw = win.os_window if win else None
|
||||
self.tabs = list(self.osw.tabs) if self.osw else []
|
||||
self.index = 0
|
||||
|
||||
def draw(self, screen):
|
||||
screen.clear()
|
||||
if not self.tabs:
|
||||
screen.write_line("No tabs. Esc to exit.")
|
||||
else:
|
||||
screen.write_line("Choose a tab (↑/↓ Enter Esc)")
|
||||
for i, t in enumerate(self.tabs):
|
||||
mark = "●" if t is self.osw.active_tab else " "
|
||||
sel = ">" if i == self.index else " "
|
||||
title = t.title or f"Tab {i+1}"
|
||||
screen.write_line(f"{sel} {mark} {title}")
|
||||
screen.refresh()
|
||||
|
||||
def on_key(self, event):
|
||||
if not self.tabs:
|
||||
if event.key in ("escape", "enter"):
|
||||
self.quit_loop()
|
||||
return
|
||||
k = event.key
|
||||
if k in ("up", "k"):
|
||||
self.index = (self.index - 1) % len(self.tabs)
|
||||
elif k in ("down", "j"):
|
||||
self.index = (self.index + 1) % len(self.tabs)
|
||||
elif k == "enter":
|
||||
self.osw.set_active_tab(self.tabs[self.index])
|
||||
self.quit_loop()
|
||||
elif k == "escape":
|
||||
self.quit_loop()
|
||||
self.refresh()
|
||||
|
||||
|
||||
def main(args):
|
||||
# Correct signature for older Kitty: pass the class name and a title string
|
||||
Loop(TabPicker, "choose_tab").run()
|
||||
|
||||
|
||||
def handle_result(args, answer, target_window_id, boss):
|
||||
pass
|
||||
|
||||
35
config/macos/kitty/invero.conf
Normal file
35
config/macos/kitty/invero.conf
Normal file
@@ -0,0 +1,35 @@
|
||||
# vim:ft=kitty
|
||||
|
||||
background #eeeeee
|
||||
foreground #444444
|
||||
cursor #005fff
|
||||
cursor_text_color #eeeeee
|
||||
selection_background #dadada
|
||||
selection_foreground #444444
|
||||
url_color #005fff
|
||||
|
||||
# Tabs
|
||||
active_tab_background #005fff
|
||||
active_tab_foreground #eeeeee
|
||||
inactive_tab_background #dadada
|
||||
inactive_tab_foreground #9e9e9e
|
||||
|
||||
# normal
|
||||
color0 #444444
|
||||
color1 #ff0000
|
||||
color2 #00af5f
|
||||
color3 #d75f00
|
||||
color4 #005fff
|
||||
color5 #5f5f87
|
||||
color6 #afd7ff
|
||||
color7 #eeeeee
|
||||
|
||||
# bright
|
||||
color8 #444444
|
||||
color9 #ff0000
|
||||
color10 #00af5f
|
||||
color11 #d75f00
|
||||
color12 #005fff
|
||||
color13 #5f5f87
|
||||
color14 #afd7ff
|
||||
color15 #eeeeee
|
||||
BIN
config/macos/kitty/kitty.app.icns
Normal file
BIN
config/macos/kitty/kitty.app.icns
Normal file
Binary file not shown.
73
config/macos/kitty/kitty.conf
Normal file
73
config/macos/kitty/kitty.conf
Normal file
@@ -0,0 +1,73 @@
|
||||
include invero.conf
|
||||
|
||||
# term xterm-256color
|
||||
enable_audio_bell no
|
||||
cursor_shape block
|
||||
wheel_scroll_multiplier 1.0
|
||||
touch_scroll_multiplier 1.0
|
||||
wheel_scroll_min_lines 1
|
||||
shell_integration no-cursor
|
||||
cursor_blink_interval 0
|
||||
|
||||
remember_window_position yes
|
||||
remember_window_size yes
|
||||
|
||||
# Font
|
||||
font_family Maple Mono
|
||||
font_size 13.0
|
||||
# disable_ligatures always
|
||||
|
||||
# undercurl_style thick-sparse
|
||||
|
||||
modify_font cell_width 94%
|
||||
modify_font cell_height -2px
|
||||
# modify_font baseline 2px
|
||||
|
||||
# modify_font underline_thickness 180%
|
||||
# modify_font underline_position 2px
|
||||
# modify_font strikethrough_positon 2px
|
||||
text_composition_strategy legacy
|
||||
# underline_exclusion 0
|
||||
|
||||
placement_strategy top
|
||||
window_margin_width 0 0
|
||||
window_padding_width 0 4
|
||||
|
||||
# modify_font cell_height -1
|
||||
# modify_font cell_width 90%
|
||||
|
||||
# Navigation / editing
|
||||
# Make Option act as Alt on macOS
|
||||
macos_option_as_alt yes
|
||||
|
||||
# Use explicit bytes (no ambiguity), not \x1bb etc.
|
||||
map opt+left send_text all \x1b\x62
|
||||
map opt+right send_text all \x1b\x66
|
||||
map cmd+left send_text all \x01
|
||||
map cmd+right send_text all \x05
|
||||
map opt+backspace send_text all \x1b\x7f
|
||||
map cmd+backspace send_text all \x15
|
||||
map opt+delete send_text all \x1b\x64
|
||||
map cmd+delete send_text all \x0b
|
||||
|
||||
# New window / tab
|
||||
map cmd+n new_os_window
|
||||
map cmd+t new_tab
|
||||
|
||||
map cmd+1 goto_tab 1
|
||||
map cmd+2 goto_tab 2
|
||||
map cmd+3 goto_tab 3
|
||||
map cmd+4 goto_tab 4
|
||||
map cmd+5 goto_tab 5
|
||||
map cmd+6 goto_tab 6
|
||||
map cmd+7 goto_tab 7
|
||||
map cmd+8 goto_tab 8
|
||||
map cmd+9 goto_tab 9
|
||||
|
||||
|
||||
# BEGIN_KITTY_FONTS
|
||||
# font_family family="JetBrains Mono"
|
||||
bold_font auto
|
||||
italic_font auto
|
||||
bold_italic_font auto
|
||||
# END_KITTY_FONTS
|
||||
BIN
config/macos/rectangle/com.knollsoft.Rectangle.plist
Normal file
BIN
config/macos/rectangle/com.knollsoft.Rectangle.plist
Normal file
Binary file not shown.
BIN
config/macos/sol/mmkv.default
Executable file
BIN
config/macos/sol/mmkv.default
Executable file
Binary file not shown.
BIN
config/macos/sol/mmkv.default.crc
Executable file
BIN
config/macos/sol/mmkv.default.crc
Executable file
Binary file not shown.
36
config/macos/wezterm/colors/Invero Day.toml
Normal file
36
config/macos/wezterm/colors/Invero Day.toml
Normal file
@@ -0,0 +1,36 @@
|
||||
[colors]
|
||||
background = "#eeeeee"
|
||||
foreground = "#444444"
|
||||
cursor_bg = "#005fff"
|
||||
cursor_border = "#9e9e9e"
|
||||
cursor_fg = "#eeeeee"
|
||||
selection_bg = "#dadada"
|
||||
selection_fg = "#444444"
|
||||
split = "#005fff"
|
||||
compose_cursor = "#d75f00"
|
||||
scrollbar_thumb = "#9e9e9e"
|
||||
|
||||
copy_mode_active_highlight_bg = { Color = "#dadada" }
|
||||
copy_mode_active_highlight_fg = { Color = "#d75f00" }
|
||||
copy_mode_inactive_highlight_bg = { Color = "#eeeeee" }
|
||||
copy_mode_inactive_highlight_fg = { Color = "#d75f00" }
|
||||
|
||||
ansi = ["#444444", "#ff0000", "#00af5f", "#d75f00", "#005fff", "#5f5f87", "#afd7ff", "#eeeeee"]
|
||||
brights = ["#444444", "#ff0000", "#00af5f", "#d75f00", "#005fff", "#5f5f87", "#afd7ff", "#eeeeee"]
|
||||
|
||||
[colors.tab_bar]
|
||||
inactive_tab_edge = "#ff0000"
|
||||
background = "#444444"
|
||||
|
||||
[colors.tab_bar.active_tab]
|
||||
fg_color = "#eeeeee"
|
||||
bg_color = "#444444"
|
||||
intensity = "Bold"
|
||||
|
||||
[colors.tab_bar.inactive_tab]
|
||||
fg_color = "#9e9e9e"
|
||||
bg_color = "#444444"
|
||||
|
||||
[colors.tab_bar.inactive_tab_hover]
|
||||
fg_color = "#dadada"
|
||||
bg_color = "#444444"
|
||||
72
config/macos/wezterm/wezterm.lua
Normal file
72
config/macos/wezterm/wezterm.lua
Normal file
@@ -0,0 +1,72 @@
|
||||
local wezterm = require("wezterm")
|
||||
local config = wezterm.config_builder()
|
||||
local act = wezterm.action
|
||||
|
||||
-- General
|
||||
config.term = "wezterm"
|
||||
config.color_scheme = "Invero Day"
|
||||
config.use_ime = false
|
||||
|
||||
-- Font
|
||||
config.font = wezterm.font({ family = "Maple Mono NF", weight = "Medium" })
|
||||
config.font_size = 13
|
||||
config.harfbuzz_features = { "calt=0", "clig=0", "liga=0" } -- disables alternates and ligatures
|
||||
config.underline_position = -4
|
||||
config.underline_thickness = 3
|
||||
|
||||
-- Appearance
|
||||
config.bold_brightens_ansi_colors = false
|
||||
config.window_padding = { left = "0.5cell", right = "0.5cell", top = 6, bottom = 0 }
|
||||
config.window_content_alignment = { horizontal = "Center", vertical = "Top" }
|
||||
config.cell_width = 0.9
|
||||
config.line_height = 0.9
|
||||
|
||||
-- Tabs
|
||||
config.use_fancy_tab_bar = false
|
||||
config.show_new_tab_button_in_tab_bar = false
|
||||
config.hide_tab_bar_if_only_one_tab = true
|
||||
|
||||
-- Events
|
||||
wezterm.on("toggle-tabbar", function(window, _)
|
||||
local overrides = window:get_config_overrides() or {}
|
||||
if overrides.enable_tab_bar == false then
|
||||
wezterm.log_info("tab bar shown")
|
||||
overrides.enable_tab_bar = true
|
||||
else
|
||||
wezterm.log_info("tab bar hidden")
|
||||
overrides.enable_tab_bar = false
|
||||
end
|
||||
window:set_config_overrides(overrides)
|
||||
end)
|
||||
|
||||
-- Keybindings
|
||||
config.keys = {
|
||||
{ mods = "OPT", key = "LeftArrow", action = act.SendString("\x1bb") }, -- Jump back one word
|
||||
{ mods = "OPT", key = "RightArrow", action = act.SendString("\x1bf") }, -- Jump forward one word
|
||||
{ mods = "CMD", key = "LeftArrow", action = act.SendString("\x01") }, -- Move to start of line
|
||||
{ mods = "CMD", key = "RightArrow", action = act.SendString("\x05") }, -- Move to end of line
|
||||
{ mods = "OPT", key = "Backspace", action = act.SendString("\x1b\x7f") }, -- Delete previous word
|
||||
{ mods = "CMD", key = "Backspace", action = act.SendString("\x15") }, -- Delete previous line
|
||||
{ mods = "OPT", key = "Delete", action = act.SendString("\x1bd") }, -- Delete next word
|
||||
{ mods = "CMD", key = "Delete", action = act.SendString("\x0b") }, -- Delete next line
|
||||
{ mods = "CMD", key = "n", action = act.SpawnWindow }, -- New window
|
||||
{ mods = "CMD", key = "t", action = act.SpawnCommandInNewTab({ cwd = wezterm.home_dir }) }, -- New tab
|
||||
{ mods = "SUPER|SHIFT", key = "LeftArrow", action = act({ MoveTabRelative = -1 }) }, -- Move tab left
|
||||
{ mods = "SUPER|SHIFT", key = "RightArrow", action = act({ MoveTabRelative = 1 }) }, -- Move tab right
|
||||
{ mods = "SUPER|SHIFT", key = "b", action = act.EmitEvent("toggle-tabbar") },
|
||||
{ mods = "SUPER|SHIFT", key = "o", action = wezterm.action.ShowTabNavigator },
|
||||
{
|
||||
mods = "SUPER|SHIFT",
|
||||
key = "r",
|
||||
action = wezterm.action.PromptInputLine({
|
||||
description = "Enter new tab title",
|
||||
action = wezterm.action_callback(function(window, pane, line)
|
||||
if line then
|
||||
window:active_tab():set_title(line)
|
||||
end
|
||||
end),
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
return config
|
||||
@@ -1,40 +0,0 @@
|
||||
live_config_reload = true
|
||||
|
||||
[env]
|
||||
TERM = "xterm-256color"
|
||||
|
||||
[font]
|
||||
normal = { family = "SF Mono", style = "Regular" }
|
||||
size = 12
|
||||
offset = { x = 0, y = 0 }
|
||||
|
||||
[window]
|
||||
decorations_theme_variant = "Dark"
|
||||
padding = { x = 4, y = 0 }
|
||||
dynamic_padding = false
|
||||
resize_increments = true
|
||||
|
||||
[keyboard]
|
||||
bindings = [
|
||||
# Create new window
|
||||
{ action = "SpawnNewInstance", key = "N", mods = "Command" },
|
||||
# Jump back one word
|
||||
{ key = "Left", mods = "Alt", chars = "\u001bb" },
|
||||
# Jump forward one word
|
||||
{ key = "Right", mods = "Alt", chars = "\u001bf" },
|
||||
# Move to start of line
|
||||
{ key = "Left", mods = "Command", chars = "\u0001" },
|
||||
# Move to end of line
|
||||
{ key = "Right", mods = "Command", chars = "\u0005" },
|
||||
|
||||
# Delete backwards
|
||||
{ key = "Back", mods = "Alt", chars = "\u001B\u007F" }, # word
|
||||
{ key = "Back", mods = "Command", chars = "\u0015" }, # line
|
||||
|
||||
# Delete forwards
|
||||
{ key = "Delete", mods = "Alt", chars = "\u001Bd" }, # word
|
||||
{ key = "Delete", mods = "Command", chars = "\u000B" } # line
|
||||
]
|
||||
|
||||
[scrolling]
|
||||
multiplier = 1
|
||||
1
config/shared/barg-parser
Submodule
1
config/shared/barg-parser
Submodule
Submodule config/shared/barg-parser added at d0344b6c56
@@ -1,97 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Test black and white
|
||||
echo "=== Black and White ==="
|
||||
printf "Normal text\n"
|
||||
printf "\e[1mBold text\e[0m\n"
|
||||
printf "\e[7mReverse text\e[0m\n\n"
|
||||
|
||||
# Test 4-bit ANSI (16 colors)
|
||||
echo "=== 4-bit ANSI Colors (16 colors) ==="
|
||||
echo "Foreground colors:"
|
||||
for i in {30..37}; do
|
||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
||||
done
|
||||
echo -e "\n"
|
||||
|
||||
echo "Background colors:"
|
||||
for i in {40..47}; do
|
||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
||||
done
|
||||
echo -e "\n"
|
||||
|
||||
echo "Bright foreground colors:"
|
||||
for i in {90..97}; do
|
||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
||||
done
|
||||
echo -e "\n"
|
||||
|
||||
echo "Bright background colors:"
|
||||
for i in {100..107}; do
|
||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
||||
done
|
||||
echo -e "\n\n"
|
||||
|
||||
# Test 8-bit ANSI (256 colors)
|
||||
echo "=== 8-bit ANSI Colors (256 colors) ==="
|
||||
echo "16 System Colors:"
|
||||
for i in {0..15}; do
|
||||
printf "\e[48;5;${i}m \e[0m"
|
||||
if [ $((($i + 1) % 8)) == 0 ]; then
|
||||
echo
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
||||
echo "216 RGB Colors:"
|
||||
for i in {16..231}; do
|
||||
printf "\e[48;5;${i}m \e[0m"
|
||||
if [ $((($i - 15) % 36)) == 0 ]; then
|
||||
echo
|
||||
fi
|
||||
done
|
||||
echo
|
||||
|
||||
echo "24 Grayscale Colors:"
|
||||
for i in {232..255}; do
|
||||
printf "\e[48;5;${i}m \e[0m"
|
||||
if [ $((($i - 231) % 12)) == 0 ]; then
|
||||
echo
|
||||
fi
|
||||
done
|
||||
echo -e "\n"
|
||||
|
||||
# Test 24-bit true color
|
||||
echo "=== 24-bit True Color (16.7 million colors) ==="
|
||||
echo "RGB Color Gradient:"
|
||||
awk 'BEGIN{
|
||||
s="/\\";
|
||||
for (colnum = 0; colnum<77; colnum++) {
|
||||
r = 255-(colnum*255/76);
|
||||
g = (colnum*510/76);
|
||||
b = (colnum*255/76);
|
||||
if (g>255) g = 510-g;
|
||||
printf "\033[48;2;%d;%d;%dm", r,g,b;
|
||||
printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
|
||||
printf "%s\033[0m", substr(s,colnum%2+1,1);
|
||||
}
|
||||
printf "\n";
|
||||
}'
|
||||
|
||||
echo "RGB Color Bars:"
|
||||
for r in 0 127 255; do
|
||||
for g in 0 127 255; do
|
||||
for b in 0 127 255; do
|
||||
printf "\e[48;2;${r};${g};${b}m \e[0m"
|
||||
done
|
||||
printf " "
|
||||
done
|
||||
echo
|
||||
done
|
||||
echo
|
||||
|
||||
# Print terminal information
|
||||
echo "=== Terminal Information ==="
|
||||
echo "TERM: $TERM"
|
||||
echo "COLORTERM: $COLORTERM"
|
||||
echo "Reported colors (tput colors): $(tput colors)"
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/zsh
|
||||
|
||||
echo "Press any key combination. Press Ctrl+C to exit."
|
||||
while true; do
|
||||
result=""
|
||||
escape_sequence=""
|
||||
read -sk 1 key
|
||||
if [[ $key == $'\x1b' ]]; then
|
||||
escape_sequence+="^["
|
||||
while read -sk 1 -t 0.01 next_key; do
|
||||
escape_sequence+="$next_key"
|
||||
done
|
||||
result="$escape_sequence"
|
||||
else
|
||||
result="$key"
|
||||
fi
|
||||
echo -E "Key: $result"
|
||||
done
|
||||
@@ -1,327 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
source './parse_image_ref.sh'
|
||||
|
||||
REGISTRY="registry.tomastm.com"
|
||||
REGISTRY_ABBR="tm0"
|
||||
PROJECT_DIR="$HOME/projects"
|
||||
PROJECT_ABBR="p"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: dev <command> [options] <name>
|
||||
|
||||
Commands:
|
||||
create -i, --image <image> -p, --project <path> <name>
|
||||
exec <name> [-- <cmd>...]
|
||||
connect <name>
|
||||
list
|
||||
info <name>
|
||||
stop [--kill] <name>
|
||||
rm [--force|-f] <name>
|
||||
|
||||
Notes:
|
||||
- 'exec' treats the LAST argument as <name>; everything before it is the command to run.
|
||||
- If already inside tmux, 'connect' switches to the session; otherwise it attaches.
|
||||
- New tmux panes/windows created in a session always run inside the container.
|
||||
- within tmux that need <name>: info, stop, rm, restore, connect
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf 'Error: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
resolve_path() {
|
||||
local path="$1"
|
||||
if command -v realpath >/dev/null 2>&1; then
|
||||
realpath "$path"
|
||||
else
|
||||
echo "$(cd "$(dirname "$path")" && pwd)/$(basename "$path")"
|
||||
fi
|
||||
}
|
||||
|
||||
docker_container_exists() {
|
||||
local name="$1"
|
||||
docker container ls -a --format '{{.Names}}' | grep -Fqx "$name"
|
||||
}
|
||||
|
||||
docker_container_running() {
|
||||
local name="$1"
|
||||
docker container ls --format '{{.Names}}' | grep -Fqx "$name"
|
||||
}
|
||||
|
||||
docker_image_present() {
|
||||
local ref="$1"
|
||||
docker image inspect "$ref" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
cmd_create() {
|
||||
local image_arg="" project_arg=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-i | --image)
|
||||
[[ $# -ge 2 ]] || fail "Missing value for $1"
|
||||
image_arg="$2"
|
||||
shift 2
|
||||
;;
|
||||
-p | --project)
|
||||
[[ $# -ge 2 ]] || fail "Missing value for $1"
|
||||
project_arg="$2"
|
||||
shift 2
|
||||
;;
|
||||
-*) usage ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check args
|
||||
local name_arg="${1:-}"
|
||||
if [[ -z "$name_arg" || -z "$image_arg" || -z "$project_arg" ]]; then
|
||||
fail "Missing arguments"
|
||||
fi
|
||||
|
||||
# Check container name
|
||||
local cname="dev-$name_arg"
|
||||
if docker_container_exists "$cname"; then
|
||||
fail "Container already exists: "$cname" (from name "$name_arg")"
|
||||
fi
|
||||
|
||||
# Check project path
|
||||
local project_path
|
||||
project_path="$(resolve_path "$project_arg")"
|
||||
if [[ ! -d "$project_path" ]]; then
|
||||
fail "Invalid project path: $project_path"
|
||||
fi
|
||||
|
||||
# Check image
|
||||
IFS=' ' read -r image_ref image_repo image_tag image_label <<<"$(parse_image_ref "$image_arg")"
|
||||
if ! docker_image_present "$image_ref"; then
|
||||
fail $'Image not found locally.\nTry:\n\t- docker pull '"$image_ref"
|
||||
fi
|
||||
|
||||
# Run (= create and start container)
|
||||
cmd=(
|
||||
docker run -d
|
||||
--name "$cname"
|
||||
--label dev=true
|
||||
--network host
|
||||
--init # run tini as PID 1 to handle signals & reap zombies for cleaner container shutdown
|
||||
-v "$project_path:/workspace"
|
||||
-v /var/run/docker.sock:/var/run/docker.sock
|
||||
)
|
||||
|
||||
[[ -d "$HOME/.ssh" ]] && cmd+=(-v "$HOME/.ssh:$CONTAINER_HOME/.ssh:ro")
|
||||
[[ -f "$HOME/.npmrc" ]] && cmd+=(-v "$HOME/.npmrc:$CONTAINER_HOME/.npmrc:ro")
|
||||
[[ -d "$HOME/.npm" ]] && cmd+=(-v "$HOME/.npm:$CONTAINER_HOME/.npm")
|
||||
|
||||
docker_gid="$(getent group docker | cut -d: -f3 || true)"
|
||||
[[ -n "$docker_gid" ]] && cmd+=(--group-add "$docker_gid")
|
||||
|
||||
cmd+=("$image_ref" sleep infinity)
|
||||
"${cmd[@]}"
|
||||
|
||||
echo "$cname"
|
||||
}
|
||||
|
||||
cmd_exec() {
|
||||
# usage: exec <name> [-- <cmd>...]
|
||||
|
||||
local name="$1"
|
||||
[[ -n "$name" ]] || fail "Missing project name"
|
||||
shift
|
||||
|
||||
local cname="dev-$name"
|
||||
if ! docker_container_running "$cname"; then
|
||||
fail "Container $cname not running"
|
||||
fi
|
||||
|
||||
if [[ "$1" == "--" ]]; then
|
||||
shift
|
||||
local args=("$@")
|
||||
if [[ -t 1 ]]; then
|
||||
docker exec -it "$cname" "${args[@]}"
|
||||
else
|
||||
docker exec "$cname" "${args[@]}"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
# No command provided -> open a shell
|
||||
docker exec -it "$cname" zsh -l ||
|
||||
docker exec -it "$cname" bash -l ||
|
||||
docker exec -it "$cname" sh
|
||||
}
|
||||
|
||||
cmd_connect() {
|
||||
# usage: connect [--from] <name>
|
||||
|
||||
local from_name=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-f | --from)
|
||||
[[ $# -ge 2 ]] || fail "Missing value for $1"
|
||||
from_name="$2"
|
||||
shift 2
|
||||
;;
|
||||
-*) usage ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
local name="${1:from_name}"
|
||||
[[ -n "$name" ]] || fail "Missing project name"
|
||||
|
||||
local cname="dev-$name"
|
||||
if ! docker_container_exists "$cname"; then
|
||||
fail "Container does not exist: ${cname}. Run: dev create ..."
|
||||
fi
|
||||
|
||||
if ! docker_container_running "$cname"; then
|
||||
docker start "$cname" >/dev/null
|
||||
fi
|
||||
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
echo "tmux not found; falling back to direct exec"
|
||||
exec "$0" exec "$name"
|
||||
fi
|
||||
|
||||
local image_ref
|
||||
image_ref="$(docker container inspect "$cname" --format '{{ .Config.Image }}')"
|
||||
IFS=' ' read -r _image_ref image_repo image_tag image_label <<<"$(parse_image_ref "$image_ref")"
|
||||
|
||||
local tname="dev:$name"
|
||||
if ! tmux has-session -t "$tname" 2>/dev/null; then
|
||||
tmux new-session -ds "$tname" -e "DEV_IMAGE=$image_label" "$0 exec \"$name\""
|
||||
tmux set-option -t "$tname" default-command "$0 exec \"$name\""
|
||||
fi
|
||||
|
||||
if [[ -n "${TMUX-}" ]]; then
|
||||
tmux switch-client -t "$tname"
|
||||
else
|
||||
tmux attach -t "$tname"
|
||||
fi
|
||||
}
|
||||
|
||||
shorten_project_path() {
|
||||
local project="$1"
|
||||
|
||||
# Case 1: path is under PROJECT_DIR
|
||||
if [[ "$project" == "$PROJECT_DIR"* ]]; then
|
||||
project="~/$PROJECT_ABBR${project#$PROJECT_DIR}"
|
||||
# Case 2: path is under HOME (but not PROJECT_DIR)
|
||||
elif [[ "$project" == "$HOME"* ]]; then
|
||||
project="~${project#$HOME}"
|
||||
fi
|
||||
|
||||
echo "$project"
|
||||
}
|
||||
|
||||
cmd_list() {
|
||||
{
|
||||
echo "NAME|IMAGE|PROJECT|STATUS"
|
||||
docker ps -a --filter "label=dev=true" \
|
||||
--format '{{.Label "dev.name"}}|{{.Image}}|{{.Label "dev.project_path"}}|{{.Status}}'
|
||||
} | while IFS='|' read -r fname image project status; do
|
||||
# Shorten registry prefix
|
||||
image="${image/$REGISTRY\//$REGISTRY_ABBR/}"
|
||||
|
||||
# Shorten project path
|
||||
project="$(shorten_project_path "$project")"
|
||||
|
||||
echo "$fname|$image|$project|$status"
|
||||
done | column -t -s '|'
|
||||
}
|
||||
|
||||
cmd_stop() {
|
||||
local kill_flag=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--kill)
|
||||
kill_flag=1
|
||||
shift
|
||||
;;
|
||||
-*) usage ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
local name="${1:-}"
|
||||
[[ -n "$name" ]] || fail "Missing project name"
|
||||
local cname="dev-$name"
|
||||
|
||||
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
||||
|
||||
if ((kill_flag)); then
|
||||
echo "Killing container $cname..."
|
||||
docker kill "$cname"
|
||||
else
|
||||
echo "Stopping container $cname..."
|
||||
docker stop "$cname"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_rm() {
|
||||
local force_flag=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--force | -f)
|
||||
force_flag=1
|
||||
shift
|
||||
;;
|
||||
-*) usage ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
local name="${1:-}"
|
||||
[[ -n "$name" ]] || fail "Missing project name"
|
||||
local cname="dev-$name"
|
||||
|
||||
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
||||
|
||||
if ((force_flag)); then
|
||||
echo "Removing container $cname (force)..."
|
||||
docker rm -f "$cname"
|
||||
else
|
||||
echo "Removing container $cname..."
|
||||
docker rm "$cname"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_respawn() {
|
||||
local name="${1:-}"
|
||||
[[ -n "$name" ]] || fail "Missing project name"
|
||||
local cname="dev-$name"
|
||||
|
||||
panes=$(tmux list-panes -t "$cname" -s -F "#{session_name}:#{window_index}.#{pane_index}")
|
||||
|
||||
for pane in $panes; do
|
||||
echo "Respawning $pane..."
|
||||
tmux respawn-pane -t "$pane"
|
||||
done
|
||||
}
|
||||
|
||||
cmd_test() {
|
||||
echo "Script dev is working fine!"
|
||||
}
|
||||
|
||||
main() {
|
||||
local cmd="${1:-}"
|
||||
shift || true
|
||||
case "$cmd" in
|
||||
create) cmd_create "$@" ;;
|
||||
connect) cmd_connect "$@" ;;
|
||||
exec) cmd_exec "$@" ;;
|
||||
list) cmd_list ;;
|
||||
stop) cmd_stop "$@" ;;
|
||||
rm) cmd_rm "$@" ;;
|
||||
respawn) cmd_respawn "$@" ;;
|
||||
test) cmd_test "$@" ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
REGISTRY="registry.tomastm.com"
|
||||
DEFAULT_IMAGE="base-debian"
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 -i <image>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
while getopts ":i:" opt; do
|
||||
case ${opt} in
|
||||
i )
|
||||
IMAGE="${OPTARG}"
|
||||
;;
|
||||
\? )
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
IMAGE="${IMAGE:-$DEFAULT_IMAGE}"
|
||||
FULL_IMAGE_NAME="${REGISTRY}/${IMAGE}"
|
||||
|
||||
docker run --rm -it \
|
||||
--network host \
|
||||
-v "$HOME/.ssh:/home/dev/.ssh" \
|
||||
-v "$PWD:/workspace" \
|
||||
--init \
|
||||
--entrypoint /bin/zsh \
|
||||
"$FULL_IMAGE_NAME"
|
||||
12
config/shared/bin/dev-tmux-wrapper.sh
Executable file
12
config/shared/bin/dev-tmux-wrapper.sh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
/home/tomas/bin/dev "$@" 2>&1
|
||||
exit_code=$?
|
||||
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
echo ""
|
||||
echo "Command: $*"
|
||||
echo "Failed: exit $exit_code"
|
||||
fi
|
||||
|
||||
exit $exit_code
|
||||
612
config/shared/bin/flow
Executable file
612
config/shared/bin/flow
Executable file
@@ -0,0 +1,612 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
source "$HOME/.local/bin/barg"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
SPEC=(
|
||||
"command;flow;DevFlow CLI - Manage instances and development containers"
|
||||
"note;Use 'flow <command> --help' for command-specific options"
|
||||
|
||||
"command;enter;Connect to a development instance via SSH"
|
||||
"note;Target format: [user@]namespace@platform (e.g., 'personal@orb' or 'root@personal@orb')"
|
||||
"argument;user,u;type:option;help:SSH user (overrides user in target)"
|
||||
"argument;namespace,n;type:option;help:Instance namespace (overrides namespace in target)"
|
||||
"argument;platform,p;type:option;help:Platform name (overrides platform in target)"
|
||||
"argument;session,s;type:option;default:default;help:Development session name (default: 'default')"
|
||||
"argument;no-tmux;type:flag;dest:no_tmux;default:false;help:Skip tmux attachment on connection"
|
||||
"argument;dry-run,d;type:flag;dest:dry_run;default:false;help:Show SSH command without executing"
|
||||
"argument;target,t;required;help:Target instance in format [user@]namespace@platform"
|
||||
"argument;ssh-args;type:rest;dest:ssh_args;help:Additional SSH arguments (after --)"
|
||||
"end"
|
||||
|
||||
"command;sync;Git tools"
|
||||
"command;check;Check all projects status"
|
||||
"end"
|
||||
"end"
|
||||
|
||||
"command;dotfiles;Manage repository dotfiles and git submodules"
|
||||
"command;init;Initialize and set up all submodules"
|
||||
"note;Equivalent to: git submodule update --init --recursive"
|
||||
"end"
|
||||
"command;pull;Update all submodules to latest remote commits"
|
||||
"note;Equivalent to: git submodule update --remote --recursive"
|
||||
"end"
|
||||
"command;urls;Synchronize submodule URLs"
|
||||
"note;Equivalent to: git submodule sync --recursive"
|
||||
"end"
|
||||
"command;reset;Reset submodules to the recorded commits"
|
||||
"note;Equivalent to: git submodule update --init --recursive --force"
|
||||
"end"
|
||||
"command;status;Show current submodule status"
|
||||
"note;Equivalent to: git submodule status --recursive"
|
||||
"end"
|
||||
"command;all;Run URLs sync, initialization, and remote update in one step"
|
||||
"note;Equivalent to: git submodule sync --recursive && git submodule update --init --recursive && git submodule update --remote --recursive"
|
||||
"end"
|
||||
"end"
|
||||
|
||||
"command;create;Create and start a new development container"
|
||||
"argument;image,i;required;type:option;help:Container image to use (with optional tag)"
|
||||
"argument;project,p;type:option;help:Path to local project directory"
|
||||
"argument;name;required;help:Container name"
|
||||
"end"
|
||||
|
||||
"command;exec;Execute a command or open a shell in a container"
|
||||
"argument;name;required;help:Container name"
|
||||
"argument;cmd;type:rest;help:Command to execute inside container (after --)"
|
||||
"end"
|
||||
|
||||
"command;connect;Attach or switch to the container’s tmux session"
|
||||
"note;When already inside tmux, switches to the target session instead of reattaching."
|
||||
"note;New tmux panes or windows in the session automatically start inside the container."
|
||||
"argument;from,f;type:option;dest:name;help:Optional source container name"
|
||||
"argument;name;required;help:Target container name"
|
||||
"end"
|
||||
|
||||
"command;list;Display all development containers and their status"
|
||||
"end"
|
||||
|
||||
"command;stop;Stop or kill a running development container"
|
||||
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||
"argument;kill;type:flag;help:Use kill instead of graceful stop"
|
||||
"argument;name;required;help:Target container name"
|
||||
"end"
|
||||
|
||||
"command;remove,rm;Remove a development container"
|
||||
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||
"argument;force,f;type:flag;help:Force removal of container"
|
||||
"argument;name;required;help:Target container name"
|
||||
"end"
|
||||
|
||||
"command;respawn;Restart all tmux panes for a development session"
|
||||
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||
"argument;name;required;help:Session or container name"
|
||||
"end"
|
||||
|
||||
"command;test;Verify that the dev script is functioning"
|
||||
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||
"argument;name;help:Target container name"
|
||||
"end"
|
||||
|
||||
"end"
|
||||
)
|
||||
|
||||
DEFAULT_REGISTRY="registry.tomastm.com"
|
||||
DEFAULT_TAG="latest"
|
||||
PROJECT_DIR="$HOME/projects"
|
||||
PROJECT_ABBR="p"
|
||||
|
||||
fail() {
|
||||
printf 'Error: %b\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
resolve_path() {
|
||||
local path="${1:-$(dirname "${BASH_SOURCE[0]}")}"
|
||||
if command -v realpath >/dev/null 2>&1; then
|
||||
realpath "$path"
|
||||
else
|
||||
echo "$(cd "$(dirname "$path")" && pwd)/$(basename "$path")"
|
||||
fi
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2178,SC2128
|
||||
parse_image_ref() {
|
||||
local input="$1"
|
||||
|
||||
local image_ref registry repo tag label
|
||||
|
||||
if [[ $input == */* ]]; then
|
||||
local prefix="${input%%/*}"
|
||||
if [[ "$prefix" == "docker" ]]; then
|
||||
input="docker.io/library/${input#*/}"
|
||||
elif [[ "$prefix" == "tm0" ]]; then
|
||||
input="${DEFAULT_REGISTRY}/${input#*/}"
|
||||
fi
|
||||
|
||||
registry="${input%%/*}"
|
||||
input=${input#*/}
|
||||
else
|
||||
registry="$DEFAULT_REGISTRY"
|
||||
fi
|
||||
|
||||
if [[ "${input##*/}" == *:* ]]; then
|
||||
tag="${input##*:}"
|
||||
input="${input%:*}"
|
||||
else
|
||||
tag="$DEFAULT_TAG"
|
||||
fi
|
||||
|
||||
repo="${registry}/${input}"
|
||||
repo="${repo#*/}"
|
||||
image_ref="${registry}/${repo}:${tag}"
|
||||
|
||||
label="${registry%.*}"
|
||||
label="${label##*.}/${repo##*/}"
|
||||
|
||||
echo "$image_ref $repo $tag $label"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
docker_container_exists() {
|
||||
local cname="$(get_cname)"
|
||||
docker container ls -a --format '{{.Names}}' | grep -Fqx "$cname"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
docker_container_running() {
|
||||
local cname="$(get_cname)"
|
||||
docker container ls --format '{{.Names}}' | grep -Fqx "$cname"
|
||||
}
|
||||
|
||||
docker_image_present() {
|
||||
local ref="$1"
|
||||
docker image inspect "$ref" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
get_cname() {
|
||||
printf "%s" "dev-${name_arg#dev-}"
|
||||
}
|
||||
|
||||
cmd() {
|
||||
barg_usage
|
||||
}
|
||||
|
||||
cmd_dotfiles_init() {
|
||||
echo "[dotfiles] Initializing submodules..."
|
||||
git submodule update --init --recursive
|
||||
}
|
||||
|
||||
cmd_dotfiles_pull() {
|
||||
echo "[dotfiles] Updating submodules to latest remote commits..."
|
||||
git submodule update --remote --recursive
|
||||
}
|
||||
|
||||
cmd_dotfiles_urls() {
|
||||
echo "[dotfiles] Syncing submodule URLs..."
|
||||
git submodule sync --recursive
|
||||
}
|
||||
|
||||
cmd_dotfiles_reset() {
|
||||
echo "[dotfiles] Resetting submodules to recorded commits..."
|
||||
git submodule update --init --recursive --force
|
||||
}
|
||||
|
||||
cmd_dotfiles_status() {
|
||||
echo "[dotfiles] Submodule status:"
|
||||
git submodule status --recursive
|
||||
}
|
||||
|
||||
cmd_dotfiles_all() {
|
||||
echo "[dotfiles] Syncing URLs..."
|
||||
git submodule sync --recursive
|
||||
|
||||
echo "[dotfiles] Initializing submodules..."
|
||||
git submodule update --init --recursive
|
||||
|
||||
echo "[dotfiles] Updating submodules to latest remote commits..."
|
||||
git submodule update --remote --recursive
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_enter() {
|
||||
# VARS: user_arg, namespace_arg, platform_arg, target_arg, session_arg, no_tmux_arg, dry_run_arg, ssh_args_arg
|
||||
|
||||
# Do not run inside instance
|
||||
if [[ -n "$DF_NAMESPACE" && -n "$DF_PLATFORM" ]]; then
|
||||
fail "It is not recommended to run this command inside an instance.\nCurrently inside: $(tput bold)${DF_NAMESPACE}@${DF_PLATFORM}$(tput sgr0)"
|
||||
fi
|
||||
|
||||
local -A CONFIG_HOST=(
|
||||
[orb.host]="<namespace>@orb"
|
||||
[utm.host]="<namespace>.utm.local"
|
||||
[core.host]="<namespace>.core.lan"
|
||||
)
|
||||
|
||||
local df_platform=""
|
||||
local df_namespace=""
|
||||
local df_user=""
|
||||
|
||||
# Parse target: get user, namespace, platform
|
||||
if [[ "$target_arg" == *@* ]]; then
|
||||
df_platform="${target_arg##*@}"
|
||||
target_arg="${target_arg%@*}"
|
||||
fi
|
||||
|
||||
if [[ "$target_arg" == *@* ]]; then
|
||||
df_namespace="${target_arg##*@}"
|
||||
df_user="${target_arg%@*}"
|
||||
else
|
||||
df_namespace="${target_arg}"
|
||||
df_user="${USER}"
|
||||
fi
|
||||
|
||||
if [[ -n "$platform_arg" ]]; then
|
||||
df_platform="$platform_arg"
|
||||
fi
|
||||
if [[ -n "$namespace_arg" ]]; then
|
||||
df_namespace="$namespace_arg"
|
||||
fi
|
||||
if [[ -n "$user_arg" ]]; then
|
||||
df_user="$user_arg"
|
||||
fi
|
||||
|
||||
# Resolve host, identity (maybe check what would the host be in order to use .ssh/config)
|
||||
local host_config="${CONFIG_HOST[${df_platform}.host]}"
|
||||
local ssh_host="${host_config//<namespace>/$df_namespace}"
|
||||
if [[ -z "$ssh_host" ]]; then
|
||||
fail "Invalid platform: ${df_platform}"
|
||||
fi
|
||||
|
||||
# Build ssh cmd: ssh + identity + tmux + envs
|
||||
local ssh_cmd=(ssh -tt "${df_user}@${ssh_host}")
|
||||
|
||||
if [[ "$no_tmux_arg" == "false" ]]; then
|
||||
# TODO: instead of tmux,maybe use "flow" in order to attach to dev container too
|
||||
ssh_cmd+=("tmux" "new-session" "-As" "$session_arg"
|
||||
"-e" "DF_NAMESPACE=$df_namespace"
|
||||
"-e" "DF_PLATFORM=$df_platform")
|
||||
fi
|
||||
|
||||
# Run or dryrun?
|
||||
if [[ "$dry_run_arg" == "true" ]]; then
|
||||
echo "Dry run command:"
|
||||
printf '%q ' "${ssh_cmd[@]}"
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exec "${ssh_cmd[@]}"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_sync_check() {
|
||||
local base_dir="$HOME/projects"
|
||||
local -a needs_action=()
|
||||
local -a not_git=()
|
||||
|
||||
for repo in "$base_dir"/*; do
|
||||
[ -d "$repo" ] || continue
|
||||
local git_dir="$repo/.git"
|
||||
|
||||
if [ ! -d "$git_dir" ]; then
|
||||
not_git+=("$(basename "$repo")")
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "=== $(basename "$repo") ==="
|
||||
cd "$repo" || continue
|
||||
|
||||
local action_required=0
|
||||
|
||||
git fetch --all --quiet || true
|
||||
local branch
|
||||
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "HEAD")
|
||||
|
||||
# --- Uncommitted or untracked changes ---
|
||||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||||
echo "Uncommitted changes:"
|
||||
git status --short
|
||||
action_required=1
|
||||
elif [ -n "$(git ls-files --others --exclude-standard)" ]; then
|
||||
echo "Untracked files:"
|
||||
git ls-files --others --exclude-standard
|
||||
action_required=1
|
||||
else
|
||||
echo "No uncommitted or untracked changes."
|
||||
fi
|
||||
|
||||
# --- Unpushed commits on current branch ---
|
||||
if git rev-parse --abbrev-ref "${branch}@{u}" >/dev/null 2>&1; then
|
||||
local unpushed
|
||||
unpushed=$(git rev-list --oneline "${branch}@{u}..${branch}")
|
||||
if [ -n "$unpushed" ]; then
|
||||
echo "Unpushed commits on ${branch}:"
|
||||
echo "$unpushed"
|
||||
action_required=1
|
||||
else
|
||||
echo "No unpushed commits on ${branch}."
|
||||
fi
|
||||
else
|
||||
echo "No upstream set for ${branch}."
|
||||
action_required=1
|
||||
fi
|
||||
|
||||
# --- Unpushed branches ---
|
||||
local unpushed_branches=()
|
||||
while IFS= read -r b; do
|
||||
if git rev-parse --abbrev-ref "${b}@{u}" >/dev/null 2>&1; then
|
||||
local ahead
|
||||
ahead=$(git rev-list --count "${b}@{u}..${b}")
|
||||
if [ "$ahead" -gt 0 ]; then
|
||||
unpushed_branches+=("$b ($ahead ahead)")
|
||||
fi
|
||||
else
|
||||
unpushed_branches+=("$b (no upstream)")
|
||||
fi
|
||||
done < <(git for-each-ref --format='%(refname:short)' refs/heads)
|
||||
|
||||
if [ "${#unpushed_branches[@]}" -gt 0 ]; then
|
||||
echo "Unpushed branches:"
|
||||
printf ' %s\n' "${unpushed_branches[@]}"
|
||||
action_required=1
|
||||
else
|
||||
echo "No unpushed branches."
|
||||
fi
|
||||
|
||||
echo
|
||||
((action_required)) && needs_action+=("$(basename "$repo")")
|
||||
done
|
||||
|
||||
echo "=== SUMMARY ==="
|
||||
if [ "${#needs_action[@]}" -gt 0 ]; then
|
||||
echo "Projects needing action:"
|
||||
printf ' %s\n' "${needs_action[@]}" | sort -u
|
||||
else
|
||||
echo "All repositories clean and synced."
|
||||
fi
|
||||
|
||||
if [ "${#not_git[@]}" -gt 0 ]; then
|
||||
echo
|
||||
echo "Directories without Git repositories:"
|
||||
printf ' %s\n' "${not_git[@]}" | sort -u
|
||||
fi
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_create() {
|
||||
# VARS: name_arg, image_arg, project_arg
|
||||
|
||||
# Check if container name already exists
|
||||
local cname="$(get_cname)"
|
||||
if docker_container_exists "$cname"; then
|
||||
printf -v msg 'Container already exists: "%s" (from name "%s")' "$cname" "$name_arg"
|
||||
fail "$msg"
|
||||
fi
|
||||
|
||||
# Check if project path is valid
|
||||
local project_path
|
||||
project_path="$(resolve_path "$project_arg")"
|
||||
if [[ ! -d "$project_path" ]]; then
|
||||
fail "Invalid project path: $project_path"
|
||||
fi
|
||||
|
||||
# Check image
|
||||
IFS=' ' read -r image_ref _ _ _ <<<"$(parse_image_ref "$image_arg")"
|
||||
if ! docker_image_present "$image_ref"; then
|
||||
printf -v msg 'Image not found locally.\nTry:\n\t- docker pull %s' "$image_ref"
|
||||
fail "$msg"
|
||||
fi
|
||||
|
||||
# Run (= create and start container)
|
||||
cmd=(
|
||||
docker run -d
|
||||
--name "$cname"
|
||||
--label dev=true
|
||||
--label "dev.name=$name_arg"
|
||||
--label "dev.project_path=$project_path"
|
||||
--label "dev.image_ref=$image_ref"
|
||||
--network host
|
||||
--init # run tini as PID 1 to handle signals & reap zombies for cleaner container shutdown
|
||||
-v "$project_path:/workspace"
|
||||
-v /var/run/docker.sock:/var/run/docker.sock
|
||||
)
|
||||
|
||||
[[ -d "$HOME/.ssh" ]] && cmd+=(-v "$HOME/.ssh:$CONTAINER_HOME/.ssh:ro")
|
||||
[[ -f "$HOME/.npmrc" ]] && cmd+=(-v "$HOME/.npmrc:$CONTAINER_HOME/.npmrc:ro")
|
||||
[[ -d "$HOME/.npm" ]] && cmd+=(-v "$HOME/.npm:$CONTAINER_HOME/.npm")
|
||||
|
||||
docker_gid="$(getent group docker | cut -d: -f3 || true)"
|
||||
[[ -n "$docker_gid" ]] && cmd+=(--group-add "$docker_gid")
|
||||
|
||||
cmd+=("$image_ref" sleep infinity)
|
||||
"${cmd[@]}"
|
||||
|
||||
printf "Created and started container: %s" "$cname"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_connect() {
|
||||
# VARS: name_arg
|
||||
|
||||
local cname="$(get_cname)"
|
||||
if ! docker_container_exists "$cname"; then
|
||||
fail "Container does not exist: ${cname}. Run: dev create ..."
|
||||
fi
|
||||
|
||||
if ! docker_container_running "$cname"; then
|
||||
docker start "$cname" >/dev/null
|
||||
fi
|
||||
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
echo "tmux not found; falling back to direct exec"
|
||||
exec "$0" exec "$cname"
|
||||
fi
|
||||
|
||||
local image_ref
|
||||
image_ref="$(docker container inspect "$cname" --format '{{ .Config.Image }}')"
|
||||
IFS=' ' read -r _image_ref _ _ image_label <<<"$(parse_image_ref "$image_ref")"
|
||||
|
||||
if ! tmux has-session -t "$cname" 2>/dev/null; then
|
||||
tmux new-session -ds "$cname" \
|
||||
-e "DF_IMAGE=$image_label" \
|
||||
-e "DF_NAMESPACE=$DF_NAMESPACE" \
|
||||
-e "DF_PLATFORM=$DF_PLATFORM" \
|
||||
"$0 exec \"$name_arg\""
|
||||
tmux set-option -t "$cname" default-command "$0 exec \"$name_arg\""
|
||||
fi
|
||||
|
||||
if [[ -n "${TMUX-}" ]]; then
|
||||
tmux switch-client -t "$cname"
|
||||
else
|
||||
tmux attach -t "$cname"
|
||||
fi
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_exec() {
|
||||
# VARS: name_arg, cmd_arg
|
||||
|
||||
local cname="$(get_cname)"
|
||||
if ! docker_container_running "$cname"; then
|
||||
fail "Container $cname not running"
|
||||
fi
|
||||
|
||||
if [[ -n "$cmd_arg" ]]; then
|
||||
if [[ -t 0 ]]; then
|
||||
docker exec -it "$cname" "${cmd_arg}"
|
||||
else
|
||||
docker exec "$cname" "${cmd_arg}"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
# No command provided -> open a shell
|
||||
docker exec --detach-keys "ctrl-q,ctrl-p" -it "$cname" zsh -l ||
|
||||
docker exec --detach-keys "ctrl-q,ctrl-p" -it "$cname" bash -l ||
|
||||
docker exec --detach-keys "ctrl-q,ctrl-p" -it "$cname" sh
|
||||
}
|
||||
|
||||
shorten_project_path() {
|
||||
local project=$1
|
||||
local home=${HOME%/}
|
||||
local projdir=${PROJECT_DIR%/}
|
||||
|
||||
# Case 1: under PROJECT_DIR
|
||||
if [[ -n ${projdir} && $project == "$projdir"/* ]]; then
|
||||
# shellcheck disable=SC2088
|
||||
project="~/$PROJECT_ABBR${project#"$projdir"}"
|
||||
|
||||
# Case 2: equals HOME
|
||||
elif [[ $project == "$home" ]]; then
|
||||
project="~"
|
||||
|
||||
# Case 3: under HOME (but not PROJECT_DIR)
|
||||
elif [[ $project == "$home"/* ]]; then
|
||||
project="~${project#"$home"}"
|
||||
fi
|
||||
|
||||
printf '%s\n' "$project"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_list() {
|
||||
# VARS:
|
||||
|
||||
{
|
||||
echo "NAME|IMAGE|PROJECT|STATUS"
|
||||
docker ps -a --filter "label=dev=true" \
|
||||
--format '{{.Label "dev.name"}}|{{.Image}}|{{.Label "dev.project_path"}}|{{.Status}}'
|
||||
} | while IFS='|' read -r fname image project status; do
|
||||
# Shorten registry prefix
|
||||
image="${image/$REGISTRY\//$REGISTRY_ABBR/}"
|
||||
|
||||
# Shorten project path
|
||||
project="$(shorten_project_path "$project")"
|
||||
|
||||
echo "$fname|$image|$project|$status"
|
||||
done | column -t -s '|'
|
||||
}
|
||||
|
||||
tmux_fallback_to_default_if_in_session() {
|
||||
# If inside tmux and current session matches the given one,
|
||||
# switch to or create 'default' before proceeding.
|
||||
local target_session="$1"
|
||||
|
||||
[[ -z "${TMUX-}" ]] && return 0 # not in tmux, nothing to do
|
||||
|
||||
local current_session
|
||||
current_session="$(tmux display-message -p '#S')"
|
||||
|
||||
if [[ "$current_session" == "$target_session" ]]; then
|
||||
if ! tmux has-session -t default 2>/dev/null; then
|
||||
tmux new-session -ds default
|
||||
fi
|
||||
tmux switch-client -t default
|
||||
fi
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_stop() {
|
||||
# VARS: kill_arg name_arg
|
||||
local cname
|
||||
cname="$(get_cname)"
|
||||
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
||||
|
||||
if [[ "$kill_arg" == "true" ]]; then
|
||||
echo "Killing container $cname..."
|
||||
docker kill "$cname"
|
||||
else
|
||||
echo "Stopping container $cname..."
|
||||
docker stop "$cname"
|
||||
fi
|
||||
|
||||
tmux_fallback_to_default_if_in_session "$cname"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_remove() {
|
||||
# VARS: force_arg name_arg
|
||||
local cname
|
||||
cname="$(get_cname)"
|
||||
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
||||
|
||||
if [[ "$force_arg" == "true" ]]; then
|
||||
echo "Removing container $cname (force)..."
|
||||
docker rm -f "$cname"
|
||||
else
|
||||
echo "Removing container $cname..."
|
||||
docker rm "$cname"
|
||||
fi
|
||||
|
||||
tmux_fallback_to_default_if_in_session "$cname"
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_respawn() {
|
||||
# VARS: name_arg
|
||||
local cname
|
||||
cname="$(get_cname)"
|
||||
panes=$(tmux list-panes -t "$cname" -s -F "#{session_name}:#{window_index}.#{pane_index}")
|
||||
|
||||
for pane in $panes; do
|
||||
echo "Respawning $pane..."
|
||||
tmux respawn-pane -t "$pane"
|
||||
done
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2154,SC2155
|
||||
cmd_test() {
|
||||
# VARS: name_arg
|
||||
|
||||
echo "Script dev is working fine!"
|
||||
if [[ -n "$name_arg" ]]; then
|
||||
get_cname
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
barg_run SPEC[@] "$@"
|
||||
39
config/shared/bin/sync-theme
Executable file
39
config/shared/bin/sync-theme
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
declare -A THEME=(
|
||||
["ghostty.url"]="https://raw.githubusercontent.com/triimdev/invero.nvim/refs/heads/main/extras/ghostty/invero_day"
|
||||
["ghostty.dir"]="$HOME/.config/ghostty/themes"
|
||||
["ghostty.name"]="Invero Day"
|
||||
|
||||
["wezterm.url"]="https://raw.githubusercontent.com/triimdev/invero.nvim/refs/heads/main/extras/wezterm/invero_day.toml"
|
||||
["wezterm.dir"]="$HOME/.config/wezterm/colors"
|
||||
["wezterm.name"]="Invero Day.toml"
|
||||
)
|
||||
|
||||
theme="${1:-}"
|
||||
|
||||
if [[ -z "$theme" ]]; then
|
||||
echo "Usage: $0 <theme>"
|
||||
echo "Available themes: $(printf '%s\n' "${!THEME[@]}" | cut -d. -f1 | sort -u | tr '\n' ' ')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${THEME[$theme.url]+x}" ]]; then
|
||||
echo "Unknown theme '$theme'. Available: $(printf '%s\n' "${!THEME[@]}" | cut -d. -f1 | sort -u | tr '\n' ' ')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
url="${THEME[$theme.url]}"
|
||||
dir="${THEME[$theme.dir]}"
|
||||
name="${THEME[$theme.name]}"
|
||||
path="${dir}/${name}"
|
||||
|
||||
mkdir -p "$dir"
|
||||
|
||||
if curl -fsSL -o "$path" "$url"; then
|
||||
echo "Theme downloaded to $path"
|
||||
else
|
||||
echo "Failed to download theme for '$theme'."
|
||||
exit 1
|
||||
fi
|
||||
48
config/shared/bin/test-true-color
Executable file
48
config/shared/bin/test-true-color
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo
|
||||
awk 'BEGIN{
|
||||
s="/\\/\\/\\/\\/\\"; s=s s s s s s s s;
|
||||
for (colnum = 0; colnum<77; colnum++) {
|
||||
r = 255-(colnum*255/76);
|
||||
g = (colnum*510/76);
|
||||
b = (colnum*255/76);
|
||||
if (g>255) g = 510-g;
|
||||
printf "\033[48;2;%d;%d;%dm", r,g,b;
|
||||
printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
|
||||
printf "%s\033[0m", substr(s,colnum+1,1);
|
||||
}
|
||||
printf "\n";
|
||||
}'
|
||||
|
||||
# --- Environment diagnostics -------------------------------------------------
|
||||
echo
|
||||
echo "──────────────────────────────"
|
||||
echo " Environment and Tmux Details "
|
||||
echo "──────────────────────────────"
|
||||
echo "TERM: ${TERM}"
|
||||
echo "COLORTERM: ${COLORTERM:-undefined}"
|
||||
echo
|
||||
|
||||
if command -v tmux >/dev/null && tmux info &>/dev/null; then
|
||||
echo "Tmux RGB/Tc capabilities:"
|
||||
tmux info | grep -E "RGB|Tc" || echo "(none found)"
|
||||
echo
|
||||
echo "Tmux server terminal options:"
|
||||
tmux show-options -s | grep terminal || echo "(none found)"
|
||||
else
|
||||
echo "Tmux not running or unavailable."
|
||||
fi
|
||||
|
||||
# --- Underline capability test -----------------------------------------------
|
||||
echo
|
||||
echo "Underline styles test:"
|
||||
printf '\x1b[58:2::255:0:0m' # red underline color
|
||||
printf '\x1b[4:1msingle ' # single underline
|
||||
printf '\x1b[4:2mdouble ' # double underline
|
||||
printf '\x1b[4:3mcurly ' # curly underline
|
||||
printf '\x1b[4:4mdotted ' # dotted underline
|
||||
printf '\x1b[4:5mdashed ' # dashed underline
|
||||
printf '\x1b[0m\n'
|
||||
|
||||
echo
|
||||
@@ -1,16 +0,0 @@
|
||||
font=monospace:size=10
|
||||
pad=4x0
|
||||
[key-bindings]
|
||||
# scrollback-up-page=Shift+Page_Up Shift+KP_Page_Up
|
||||
# scrollback-up-half-page=none
|
||||
# scrollback-up-line=none
|
||||
# scrollback-down-page=Shift+Page_Down Shift+KP_Page_Down
|
||||
# scrollback-down-half-page=none
|
||||
# scrollback-down-line=none
|
||||
# scrollback-home=none
|
||||
# scrollback-end=none
|
||||
clipboard-copy=Control+c XF86Copy
|
||||
clipboard-paste=Control+v XF86Paste
|
||||
|
||||
[text-bindings]
|
||||
\x03=Mod4+c
|
||||
@@ -1,42 +0,0 @@
|
||||
# Terminal
|
||||
term = xterm-256color
|
||||
|
||||
# Fonts
|
||||
font-family = "Maple Mono NF"
|
||||
#font-size = 14
|
||||
font-thicken = true
|
||||
#font-thicken-strength = 2
|
||||
adjust-box-thickness = 2
|
||||
|
||||
# Window
|
||||
window-padding-x = 0
|
||||
window-padding-y = 0
|
||||
window-height = 50
|
||||
window-width = 120
|
||||
window-step-resize = true
|
||||
window-padding-balance = false
|
||||
# window-padding-color = extend
|
||||
|
||||
# Icon
|
||||
macos-icon = custom
|
||||
|
||||
# Cursor
|
||||
cursor-style = block
|
||||
cursor-style-blink = false
|
||||
mouse-hide-while-typing = true
|
||||
shell-integration-features = no-cursor
|
||||
|
||||
# Font/Cell quality
|
||||
window-colorspace = srgb
|
||||
alpha-blending = linear-corrected
|
||||
macos-titlebar-style = native
|
||||
|
||||
adjust-cell-width = -1
|
||||
#adjust-cell-height = -2
|
||||
|
||||
# Theme
|
||||
background = #eeeeee
|
||||
foreground = #434343
|
||||
window-theme = auto
|
||||
background-opacity = 1
|
||||
background-blur = false
|
||||
@@ -1,10 +1,19 @@
|
||||
[init]
|
||||
defaultBranch = main
|
||||
[user]
|
||||
name = Tomas Mirchev
|
||||
email = contact@tomastm.com
|
||||
[pull]
|
||||
rebase = true
|
||||
name = Tomas Mirchev
|
||||
email = contact@tomastm.com
|
||||
[core]
|
||||
editor = nvim
|
||||
editor = nvim
|
||||
excludesfile = ~/.gitignore
|
||||
[init]
|
||||
defaultBranch = main
|
||||
[pull]
|
||||
rebase = true
|
||||
[push]
|
||||
default = current
|
||||
autoSetupRemote = true
|
||||
[remote]
|
||||
pushDefault = origin
|
||||
[alias]
|
||||
amend = commit -a --amend --no-edit
|
||||
rename = branch -m
|
||||
|
||||
|
||||
21
config/shared/gitignore
Normal file
21
config/shared/gitignore
Normal file
@@ -0,0 +1,21 @@
|
||||
.DS_Store
|
||||
*.swp
|
||||
*.swo
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
.env
|
||||
.env.*
|
||||
build/
|
||||
dist/
|
||||
build/
|
||||
tmp/
|
||||
temp/
|
||||
logs/
|
||||
*.log
|
||||
.cache/
|
||||
coverage/
|
||||
.devflow/
|
||||
.dev-flow/
|
||||
@@ -1,161 +0,0 @@
|
||||
-- Helper function for key mappings
|
||||
local function map(mode, lhs, rhs, opts)
|
||||
local options = { silent = true, noremap = true }
|
||||
|
||||
if opts then
|
||||
options = vim.tbl_extend("force", options, opts)
|
||||
end
|
||||
|
||||
if type(mode) == "table" then
|
||||
for _, m in ipairs(mode) do
|
||||
vim.keymap.set(m, lhs, rhs, options)
|
||||
end
|
||||
else
|
||||
vim.keymap.set(mode, lhs, rhs, options)
|
||||
end
|
||||
end
|
||||
|
||||
-- Mode-specific mapping functions
|
||||
local function nmap(lhs, rhs, opts) map("n", lhs, rhs, opts) end
|
||||
local function imap(lhs, rhs, opts) map("i", lhs, rhs, opts) end
|
||||
local function vmap(lhs, rhs, opts) map("v", lhs, rhs, opts) end
|
||||
local function tmap(lhs, rhs, opts) map("t", lhs, rhs, opts) end
|
||||
vim.opt.signcolumn = "no"
|
||||
|
||||
|
||||
-- Map Leader
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = " "
|
||||
|
||||
-- Use Nerd Font
|
||||
vim.g.have_nerd_font = true
|
||||
|
||||
-- Add vertical line
|
||||
-- vim.opt.colorcolumn = "100"
|
||||
|
||||
-- Enable TrueColor
|
||||
vim.opt.termguicolors = true
|
||||
|
||||
-- Disable Neovim background
|
||||
vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
|
||||
vim.api.nvim_set_hl(0, "NormalFloat", { bg = "none" })
|
||||
|
||||
-- Scroll lines/columns
|
||||
vim.opt.mousescroll = "hor:1,ver:1"
|
||||
|
||||
-- Set indentation preferences
|
||||
vim.opt.expandtab = true -- Convert tabs to spaces
|
||||
vim.opt.shiftwidth = 2 -- Number of spaces for auto-indent
|
||||
vim.opt.tabstop = 2 -- Number of spaces a tab counts for
|
||||
vim.opt.softtabstop = 2 -- Number of spaces a tab counts for when editing
|
||||
vim.opt.autoindent = true -- Copy indent from current line when starting new line
|
||||
vim.opt.smartindent = true -- Do smart autoindenting when starting a new line
|
||||
|
||||
-- Disable line wrapping
|
||||
vim.opt.wrap = false
|
||||
|
||||
-- Enable break indent
|
||||
vim.opt.breakindent = true
|
||||
|
||||
-- Make line numbers default
|
||||
vim.opt.number = true
|
||||
vim.opt.relativenumber = true
|
||||
|
||||
-- Enable mouse mode, can be useful for resizing splits for example
|
||||
vim.opt.mouse = "a"
|
||||
|
||||
-- Full path on status line
|
||||
vim.opt.statusline = "%F%m%r%h%w%=%l,%c %P"
|
||||
|
||||
-- Sync clipboard between OS and Neovim
|
||||
vim.schedule(function()
|
||||
vim.opt.clipboard = "unnamedplus"
|
||||
end)
|
||||
|
||||
-- Save undo history
|
||||
vim.opt.undofile = true
|
||||
|
||||
-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
|
||||
vim.opt.ignorecase = true
|
||||
vim.opt.smartcase = true
|
||||
|
||||
-- Decrease update time
|
||||
vim.opt.updatetime = 250
|
||||
|
||||
-- Decrease mapped sequence wait time
|
||||
-- Displays which-key popup sooner
|
||||
vim.opt.timeoutlen = 300
|
||||
|
||||
-- Configure how new splits should be opened
|
||||
vim.opt.splitright = true
|
||||
vim.opt.splitbelow = true
|
||||
|
||||
-- Sets how neovim will display certain whitespace characters in the editor.
|
||||
vim.opt.list = true
|
||||
vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" }
|
||||
|
||||
-- Preview substitutions live, as you type
|
||||
vim.opt.inccommand = "split"
|
||||
|
||||
-- Show which line your cursor is on
|
||||
vim.opt.cursorline = true
|
||||
|
||||
-- Minimal number of screen lines to keep above and below the cursor
|
||||
vim.opt.scrolloff = 10
|
||||
|
||||
-- Highlight when yanking (copying) text
|
||||
vim.api.nvim_create_autocmd("TextYankPost", {
|
||||
callback = function()
|
||||
vim.highlight.on_yank()
|
||||
end,
|
||||
})
|
||||
|
||||
-- Keymaps
|
||||
|
||||
nmap("<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
|
||||
|
||||
imap("jk", "<Esc>", { desc = "Exit insert mode with jk" })
|
||||
nmap("<Esc>", "<cmd>nohlsearch<CR>", { desc = "Clear highlights" })
|
||||
|
||||
-- Prevent "x" from overriding the register
|
||||
nmap("x", '"_x')
|
||||
|
||||
-- Window Navigation
|
||||
nmap("<C-h>", "<C-w>h", { desc = "Move focus to the left window" })
|
||||
nmap("<C-l>", "<C-w>l", { desc = "Move focus to the right window" })
|
||||
nmap("<C-j>", "<C-w>j", { desc = "Move focus to the lower window" })
|
||||
nmap("<C-k>", "<C-w>k", { desc = "Move focus to the upper window" })
|
||||
|
||||
-- Tab management
|
||||
nmap("<Leader>tn", ":tabnew<CR>", { desc = "[T]ab [N]ew" })
|
||||
nmap("<Leader>tc", ":tabclose<CR>", { desc = "[T]ab [C]lose" })
|
||||
nmap("<Leader>to", ":tabonly<CR>", { desc = "[T]ab [O]nly" })
|
||||
nmap("<Leader>tl", ":tabnext<CR>", { desc = "[T]ab Next" })
|
||||
nmap("<Leader>th", ":tabprevious<CR>", { desc = "[T]ab Previous" })
|
||||
nmap("<Leader>tm.", ":tabmove +1<CR>", { desc = "[T]ab [M]ove Right" })
|
||||
nmap("<Leader>tm,", ":tabmove -1<CR>", { desc = "[T]ab [M]ove Left" })
|
||||
for i = 1, 9 do
|
||||
nmap(string.format("<Leader>%d", i), string.format("%dgt", i), { desc = string.format("[T]ab %d", i) })
|
||||
end
|
||||
|
||||
-- Buffer Management
|
||||
nmap("<Leader>bl", ":ls<CR>", { desc = "[B]uffer [L]ist" })
|
||||
nmap("<Leader>bd", ":bdelete<CR>", { desc = "[B]uffer [D]elete" })
|
||||
nmap("]b", ":bnext<CR>", { desc = "[B]uffer [N]ext" })
|
||||
nmap("[b", ":bprevious<CR>", { desc = "[B]uffer [P]revious" })
|
||||
nmap("<Leader>bb", ":b<Space>", { desc = "[B]uffer Select" })
|
||||
nmap("<Leader>bo", ":bufdo bd|1bd<CR>", { desc = "[B]uffer Delete Others" })
|
||||
|
||||
-- Terminal
|
||||
nmap("<Leader>tet", function()
|
||||
vim.cmd("terminal")
|
||||
vim.cmd("startinsert")
|
||||
end, { desc = "[T]erminal" })
|
||||
nmap("<leader>ter", function()
|
||||
local buf_dir = vim.fn.expand("%:p:h")
|
||||
vim.cmd("edit term://" .. buf_dir .. "//zsh")
|
||||
vim.cmd("startinsert")
|
||||
end, { desc = "[T]erminal [R]elative" })
|
||||
tmap("<Esc>", "<C-\\><C-n>", { desc = "Terminal Normal Mode" })
|
||||
tmap("jk", "<C-\\><C-n>", { desc = "Terminal Normal Mode" })
|
||||
tmap("<C-w>", "<C-\\><C-n><C-w>", { desc = "Terminal Window Command" })
|
||||
1
config/shared/nvim
Submodule
1
config/shared/nvim
Submodule
Submodule config/shared/nvim added at 4419f2e5f3
@@ -4,11 +4,14 @@ set -g prefix C-Space
|
||||
bind C-Space send-prefix
|
||||
|
||||
##### General #####
|
||||
set -s default-terminal "tmux-256color"
|
||||
# set -s default-terminal "tmux-256color"
|
||||
# set -sa terminal-overrides "$term:rgb"
|
||||
|
||||
set -s escape-time 10
|
||||
set -s focus-events on
|
||||
set -s set-clipboard on
|
||||
|
||||
# set -g default-command "${SHELL}"
|
||||
set -g base-index 1 # window index
|
||||
set -g renumber-windows on # window index
|
||||
set -g history-limit 10000
|
||||
@@ -17,15 +20,16 @@ set -g mouse on
|
||||
set -g set-titles on
|
||||
set -g set-titles-string "#S"
|
||||
|
||||
# set -g remain-on-exit on
|
||||
|
||||
set -gw pane-base-index 1 # pane index
|
||||
set -gw synchronize-panes on
|
||||
|
||||
##### Appearance #####
|
||||
set -g status-style fg=black,bg=default
|
||||
set -g window-status-current-style fg=blue,bold
|
||||
set -g message-style fg=blue,bg=default
|
||||
set -g status-left "#[fg=blue,bold][#S] "
|
||||
set -g status-right "host:#H | machine:#{?TARGET_MACHINE,#{TARGET_MACHINE},local}"
|
||||
set -g status-left "#[fg=blue,bold][#{s/^dev-//:#{session_name}}] "
|
||||
set -g status-right " #{?DF_IMAGE,#{DF_IMAGE} | ,}#{?DF_NAMESPACE,#{DF_NAMESPACE},#H}@#{?DF_PLATFORM,#{DF_PLATFORM},local}"
|
||||
set -g status-left-length 50
|
||||
set -g status-right-length 50
|
||||
set -g pane-active-border-style fg=blue
|
||||
@@ -56,3 +60,9 @@ bind c confirm-before -p "kill-pane \#P? (y/n)" kill-pane
|
||||
##### Misc #####
|
||||
bind r source-file ~/.tmux.conf \; display "Reloaded!"
|
||||
|
||||
unbind d
|
||||
bind e detach
|
||||
|
||||
bind d command-prompt -I "dev " 'run-shell "/home/tomas/bin/dev-tmux-wrapper.sh %1 --from #{session_name}"'
|
||||
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
-- wezterm.lua configuration file
|
||||
local wezterm = require 'wezterm'
|
||||
|
||||
-- This table will hold the configuration.
|
||||
local config = {}
|
||||
|
||||
-- In newer versions of wezterm, use the config_builder which will
|
||||
-- help provide clearer error messages
|
||||
if wezterm.config_builder then
|
||||
config = wezterm.config_builder()
|
||||
end
|
||||
|
||||
-- Environment variables
|
||||
config.term="xterm-256color"
|
||||
config.set_environment_variables = {
|
||||
TERM = "xterm-256color",
|
||||
}
|
||||
|
||||
-- Font configuration
|
||||
config.font = wezterm.font('JetBrainsMono Nerd Font', {weight = 'Bold'})
|
||||
-- config.freetype_render_target = "HorizontalLcd"
|
||||
-- config.freetype_load_flags = 'NO_HINTING'
|
||||
-- config.freetype_load_target = "Light"
|
||||
config.bold_brightens_ansi_colors = false
|
||||
|
||||
local act = wezterm.action
|
||||
|
||||
config.font_size = 14
|
||||
-- Alacritty's offset translates to cell_width and line_height in wezterm
|
||||
-- Since your offset is 0, we're keeping default values
|
||||
|
||||
-- Window configuration
|
||||
config.window_padding = {
|
||||
left = 4,
|
||||
right = 4,
|
||||
top = 0,
|
||||
bottom = 0,
|
||||
}
|
||||
-- config.window_decorations = "RESIZE|TITLE|MACOS_USE_BACKGROUND_COLOR_AS_TITLEBAR_COLOR|MACOS_FORCE_ENABLE_SHADOW" -- Similar to decorations_theme_variant = "Dark"
|
||||
config.window_decorations = "TITLE|RESIZE"
|
||||
config.use_resize_increments = false
|
||||
-- Wezterm doesn't have direct equivalents for dynamic_padding and resize_increments
|
||||
-- but we can set related options
|
||||
|
||||
-- Keyboard bindings
|
||||
config.keys = {
|
||||
{key="LeftArrow", mods="SUPER|SHIFT", action=wezterm.action{MoveTabRelative=-1}},
|
||||
{key="RightArrow", mods="SUPER|SHIFT", action=wezterm.action{MoveTabRelative=1}},
|
||||
|
||||
-- Create new window
|
||||
{
|
||||
key = 'n',
|
||||
mods = 'CMD',
|
||||
action = wezterm.action.SpawnWindow,
|
||||
},
|
||||
-- Jump back one word (Alt+Left)
|
||||
{
|
||||
key = 'LeftArrow',
|
||||
mods = 'ALT',
|
||||
action = wezterm.action.SendString('\x1bb'),
|
||||
},
|
||||
-- Jump forward one word (Alt+Right)
|
||||
{
|
||||
key = 'RightArrow',
|
||||
mods = 'ALT',
|
||||
action = wezterm.action.SendString('\x1bf'),
|
||||
},
|
||||
-- Move to start of line (Cmd+Left)
|
||||
{
|
||||
key = 'LeftArrow',
|
||||
mods = 'CMD',
|
||||
action = wezterm.action.SendString('\x01'),
|
||||
},
|
||||
-- Move to end of line (Cmd+Right)
|
||||
{
|
||||
key = 'RightArrow',
|
||||
mods = 'CMD',
|
||||
action = wezterm.action.SendString('\x05'),
|
||||
},
|
||||
-- Delete backwards word (Alt+Backspace)
|
||||
{
|
||||
key = 'Backspace',
|
||||
mods = 'ALT',
|
||||
action = wezterm.action.SendString('\x1b\x7f'),
|
||||
},
|
||||
-- Delete backwards line (Cmd+Backspace)
|
||||
{
|
||||
key = 'Backspace',
|
||||
mods = 'CMD',
|
||||
action = wezterm.action.SendString('\x15'),
|
||||
},
|
||||
-- Delete forwards word (Alt+Delete)
|
||||
{
|
||||
key = 'Delete',
|
||||
mods = 'ALT',
|
||||
action = wezterm.action.SendString('\x1bd'),
|
||||
},
|
||||
-- Delete forwards line (Cmd+Delete)
|
||||
{
|
||||
key = 'Delete',
|
||||
mods = 'CMD',
|
||||
action = wezterm.action.SendString('\x0b'),
|
||||
},
|
||||
}
|
||||
|
||||
return config
|
||||
51
config/shared/zsh
Normal file
51
config/shared/zsh
Normal file
@@ -0,0 +1,51 @@
|
||||
export PATH="$PATH:$HOME/.local/bin:$HOME/bin"
|
||||
export LANG=en_US.UTF-8
|
||||
export LC_CTYPE=en_US.UTF-8
|
||||
export LC_COLLATE=C
|
||||
|
||||
# eval "$(dircolors)"; echo "$LS_COLORS"
|
||||
export LS_COLORS='rs=0:di=01;34:ln=01;33:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32'
|
||||
|
||||
HISTFILE=$HOME/.zsh_history
|
||||
HISTSIZE=10000
|
||||
SAVEHIST=10000
|
||||
|
||||
setopt auto_cd interactive_comments prompt_subst share_history
|
||||
setopt append_history hist_ignore_dups hist_ignore_all_dups hist_reduce_blanks
|
||||
|
||||
autoload -Uz compinit
|
||||
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case-insensitive
|
||||
zstyle ':completion:*' use-cache on
|
||||
zstyle ':completion:*' cache-path ~/.zsh/cache
|
||||
compinit
|
||||
|
||||
git_prompt_info() {
|
||||
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
local branch=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD)
|
||||
echo " %F{green}($branch)%f"
|
||||
fi
|
||||
}
|
||||
PROMPT='%n@%m%f %F{blue}%~%f$(git_prompt_info) $ '
|
||||
|
||||
autoload -U up-line-or-beginning-search down-line-or-beginning-search
|
||||
zle -N up-line-or-beginning-search
|
||||
zle -N down-line-or-beginning-search
|
||||
bindkey '^[[A' up-line-or-beginning-search
|
||||
bindkey '^[OA' up-line-or-beginning-search
|
||||
bindkey '^[[B' down-line-or-beginning-search
|
||||
bindkey '^[OB' down-line-or-beginning-search
|
||||
bindkey '^U' backward-kill-line
|
||||
|
||||
if command -v nvim >/dev/null 2>&1; then
|
||||
alias vim='nvim'
|
||||
fi
|
||||
|
||||
case "$OSTYPE" in
|
||||
linux*) alias ls='ls --color=auto --group-directories-first' ;;
|
||||
darwin*) alias ls='ls --color=auto' ;;
|
||||
esac
|
||||
|
||||
alias ll='ls -lF'
|
||||
alias lla='ll -a'
|
||||
alias ld='ls -ld */'
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# -----------------------------
|
||||
# OS-specific aliases for ls
|
||||
# -----------------------------
|
||||
OS_TYPE=$(uname)
|
||||
if [[ "$OS_TYPE" == "Linux" ]]; then
|
||||
alias ls='ls --color=auto --group-directories-first'
|
||||
elif [[ "$OS_TYPE" == "Darwin" ]]; then
|
||||
alias ls='ls --color=auto'
|
||||
fi
|
||||
|
||||
alias ll='ls -lF'
|
||||
alias lla='ll -a'
|
||||
alias ld='ls -ld */'
|
||||
|
||||
# -----------------------------
|
||||
# Vim / Neovim
|
||||
# -----------------------------
|
||||
if command -v nvim >/dev/null 2>&1; then
|
||||
alias vim='nvim'
|
||||
fi
|
||||
|
||||
# -----------------------------
|
||||
# Git aliases
|
||||
# -----------------------------
|
||||
alias g='git'
|
||||
alias ga='git add'
|
||||
alias gaa='git add --all'
|
||||
alias gb='git branch'
|
||||
alias gcm='git commit -m'
|
||||
alias gam='git commit -am'
|
||||
alias gco='git checkout'
|
||||
alias gd='git diff'
|
||||
alias gf='git fetch'
|
||||
alias gl='git pull'
|
||||
alias gp='git push'
|
||||
alias gst='git status'
|
||||
alias glg='git log --graph --oneline --decorate --all'
|
||||
alias gm='git merge'
|
||||
alias grb='git rebase'
|
||||
alias grs='git reset'
|
||||
alias grv='git remote -v'
|
||||
alias tree='tree -I node_modules'
|
||||
|
||||
# -----------------------------
|
||||
# Other
|
||||
# -----------------------------
|
||||
alias k='kubectl'
|
||||
@@ -1,15 +0,0 @@
|
||||
# -----------------------------
|
||||
# ZLE functions
|
||||
# -----------------------------
|
||||
autoload -U up-line-or-beginning-search
|
||||
autoload -U down-line-or-beginning-search
|
||||
zle -N up-line-or-beginning-search
|
||||
zle -N down-line-or-beginning-search
|
||||
|
||||
bindkey '^[[A' up-line-or-beginning-search
|
||||
bindkey '^[OA' up-line-or-beginning-search
|
||||
bindkey '^[[B' down-line-or-beginning-search
|
||||
bindkey '^[OB' down-line-or-beginning-search
|
||||
|
||||
bindkey '^U' backward-kill-line
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# -----------------------------
|
||||
# Git prompt function
|
||||
# -----------------------------
|
||||
git_prompt_info() {
|
||||
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
local branch=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD)
|
||||
echo " %F{green}($branch)%f"
|
||||
fi
|
||||
}
|
||||
|
||||
# -----------------------------
|
||||
# Set prompt
|
||||
# -----------------------------
|
||||
PROMPT='%n@%m%f %F{blue}%~%f$(git_prompt_info) $ '
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# -----------------------------
|
||||
# PATH
|
||||
# -----------------------------
|
||||
export PATH="$PATH:$HOME/bin"
|
||||
|
||||
# -----------------------------
|
||||
# Locales
|
||||
# -----------------------------
|
||||
export LANGUAGE="en_US:en"
|
||||
export LANG=en_US.UTF-8
|
||||
export LC_ALL=en_US.UTF-8
|
||||
|
||||
# -----------------------------
|
||||
# Autocomplete
|
||||
# -----------------------------
|
||||
autoload -Uz compinit && compinit
|
||||
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case insensitive
|
||||
|
||||
# -----------------------------
|
||||
# Shell options
|
||||
# -----------------------------
|
||||
setopt autocd
|
||||
setopt share_history
|
||||
setopt interactivecomments
|
||||
setopt PROMPT_SUBST # Enable dynamic prompt expansion
|
||||
|
||||
# -----------------------------
|
||||
# Disable conflicting builtins
|
||||
# -----------------------------
|
||||
disable log
|
||||
|
||||
# -----------------------------
|
||||
# History
|
||||
# -----------------------------
|
||||
HISTFILE=${ZDOTDIR:-$HOME}/.zsh_history
|
||||
HISTSIZE=2000
|
||||
SAVEHIST=1000
|
||||
setopt HIST_IGNORE_ALL_DUPS
|
||||
|
||||
# -----------------------------
|
||||
# Source modular components
|
||||
# -----------------------------
|
||||
CONFIG_DIR="$HOME/.config/zsh"
|
||||
|
||||
[ -f "$CONFIG_DIR/aliases" ] && source "$CONFIG_DIR/aliases"
|
||||
[ -f "$CONFIG_DIR/prompt" ] && source "$CONFIG_DIR/prompt"
|
||||
[ -f "$CONFIG_DIR/keybindings" ] && source "$CONFIG_DIR/keybindings"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
export EDITOR="nvim"
|
||||
export VISUAL="nvim"
|
||||
if [ -f "$HOME/.config/zsh/zshrc" ]; then
|
||||
source "$HOME/.config/zsh/zshrc"
|
||||
else
|
||||
echo "Warning: ~/.config/zsh/zshrc not found, skipping custom Zsh configuration."
|
||||
fi
|
||||
|
||||
@@ -10,7 +10,7 @@ import shutil
|
||||
DOTFILES_DIR = Path(__file__).parent
|
||||
SETUPS_DIR = DOTFILES_DIR / "setups"
|
||||
CONFIG_DIR = DOTFILES_DIR / "config"
|
||||
CONFIG_PATH = DOTFILES_DIR / "config.json"
|
||||
CONFIG_PATH = DOTFILES_DIR / "manifest.json"
|
||||
|
||||
def load_config():
|
||||
if not CONFIG_PATH.exists():
|
||||
@@ -63,8 +63,8 @@ def get_environment_packages(config, env, search_package=None):
|
||||
if not isinstance(link_from, str) or not isinstance(link_to, str):
|
||||
raise ValueError("`link` should follow the structure: `{ from: str, to: str }`")
|
||||
|
||||
if len(link_from.split("/")) != 2:
|
||||
raise ValueError("`link.from` should be '<env>/<package>'")
|
||||
# if len(link_from.split("/")) != 2:
|
||||
# raise ValueError("`link.from` should be '<env>/<package>'")
|
||||
|
||||
package["link"] = {
|
||||
"from": Path(CONFIG_DIR / link_from).expanduser(),
|
||||
|
||||
184
manifest.json
Normal file
184
manifest.json
Normal file
@@ -0,0 +1,184 @@
|
||||
{
|
||||
"template": {
|
||||
"bin": {
|
||||
"link": {
|
||||
"from": "shared/bin",
|
||||
"to": "~/bin"
|
||||
}
|
||||
},
|
||||
"barg": {
|
||||
"link": {
|
||||
"from": "shared/barg-parser/barg",
|
||||
"to": "~/.local/bin/barg"
|
||||
}
|
||||
},
|
||||
"htop": {
|
||||
"link": {
|
||||
"from": "shared/htop",
|
||||
"to": "~/.config/htop"
|
||||
}
|
||||
},
|
||||
"git": {
|
||||
"link": {
|
||||
"from": "shared/git",
|
||||
"to": "~/.gitconfig"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"link": {
|
||||
"from": "shared/gitignore",
|
||||
"to": "~/.gitignore"
|
||||
}
|
||||
},
|
||||
"zsh": {
|
||||
"link": {
|
||||
"from": "shared/zsh",
|
||||
"to": "~/.zshrc"
|
||||
}
|
||||
},
|
||||
"tmux": {
|
||||
"link": {
|
||||
"from": "shared/tmux",
|
||||
"to": "~/.tmux.conf"
|
||||
}
|
||||
},
|
||||
"nvim": {
|
||||
"link": {
|
||||
"from": "shared/nvim",
|
||||
"to": "~/.config/nvim"
|
||||
}
|
||||
}
|
||||
},
|
||||
"environments": {
|
||||
"linux": [
|
||||
{
|
||||
"package": "window-tagger",
|
||||
"link": {
|
||||
"from": "linux/kwin_window-tagger",
|
||||
"to": "~/.config/window-tagger"
|
||||
}
|
||||
}
|
||||
],
|
||||
"macos": [
|
||||
"git",
|
||||
"gitignore",
|
||||
"zsh",
|
||||
"tmux",
|
||||
"nvim",
|
||||
"bin",
|
||||
"barg",
|
||||
{
|
||||
"package": "sol",
|
||||
"link": {
|
||||
"from": "macos/sol",
|
||||
"to": "~/.config/sol"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "borders",
|
||||
"link": {
|
||||
"from": "macos/borders",
|
||||
"to": "~/.config/borders"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "karabiner",
|
||||
"link": {
|
||||
"from": "macos/karabiner",
|
||||
"to": "~/.config/karabiner"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "linearmouse",
|
||||
"link": {
|
||||
"from": "macos/linearmouse",
|
||||
"to": "~/.config/linearmouse"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "rectangle",
|
||||
"link-comment": "Needs manual import from config/macos/linearmouse"
|
||||
},
|
||||
{
|
||||
"package": "wezterm",
|
||||
"link": {
|
||||
"from": "macos/wezterm",
|
||||
"to": "~/.config/wezterm"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "alacritty",
|
||||
"link": {
|
||||
"from": "macos/alacritty",
|
||||
"to": "~/.config/alacritty"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "ghostty",
|
||||
"link": {
|
||||
"from": "macos/ghostty",
|
||||
"to": "~/.config/ghostty"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "kitty",
|
||||
"link": {
|
||||
"from": "macos/kitty",
|
||||
"to": "~/.config/kitty"
|
||||
}
|
||||
}
|
||||
],
|
||||
"linux-vm": [
|
||||
"bin",
|
||||
"barg",
|
||||
"gitignore",
|
||||
{
|
||||
"package": "htop",
|
||||
"install": "sudo apt install -y htop"
|
||||
},
|
||||
{
|
||||
"package": "git",
|
||||
"install": "sudo apt install -y git"
|
||||
},
|
||||
{
|
||||
"package": "zsh",
|
||||
"install": "sudo apt install -y zsh",
|
||||
"post-link": "./scripts/linux-setup_zsh.sh"
|
||||
},
|
||||
{
|
||||
"package": "tmux",
|
||||
"install": "sudo apt install -y tmux"
|
||||
},
|
||||
{
|
||||
"package": "nvim",
|
||||
"post-install": "echo 'Neovim needs setup'"
|
||||
}
|
||||
],
|
||||
"container": [
|
||||
"bin",
|
||||
"barg",
|
||||
"gitignore",
|
||||
{
|
||||
"package": "htop",
|
||||
"install": "sudo apt install -y htop"
|
||||
},
|
||||
{
|
||||
"package": "git",
|
||||
"install": "sudo apt install -y git"
|
||||
},
|
||||
{
|
||||
"package": "zsh",
|
||||
"install": "sudo apt install -y zsh",
|
||||
"post-link": "./scripts/linux-setup_zsh.sh"
|
||||
},
|
||||
{
|
||||
"package": "tmux",
|
||||
"install": "sudo apt install -y tmux"
|
||||
},
|
||||
{
|
||||
"package": "nvim",
|
||||
"post-install": "echo 'Neovim needs setup'"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
196
scripts/macos-defaults.sh
Executable file
196
scripts/macos-defaults.sh
Executable file
@@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Close any open System Preferences panes, to prevent them from overriding
|
||||
# settings we’re about to change
|
||||
osascript -e 'tell application "System Preferences" to quit'
|
||||
|
||||
# Ask for the administrator password upfront
|
||||
sudo -v
|
||||
|
||||
# Keep-alive: update existing `sudo` time stamp until `.macos` has finished
|
||||
while true; do
|
||||
sudo -n true
|
||||
sleep 60
|
||||
kill -0 "$$" || exit
|
||||
done 2>/dev/null &
|
||||
|
||||
# Save to disk (not to iCloud) by default
|
||||
defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false
|
||||
|
||||
# Disable the “Are you sure you want to open this application?” dialog
|
||||
defaults write com.apple.LaunchServices LSQuarantine -bool false
|
||||
|
||||
# Disable Typing features
|
||||
defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false
|
||||
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
|
||||
defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false
|
||||
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
|
||||
defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false
|
||||
|
||||
# Disable press-and-hold for keys in favor of key repeat
|
||||
defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false
|
||||
defaults write NSGlobalDomain KeyRepeat -int 2
|
||||
defaults write NSGlobalDomain InitialKeyRepeat -int 15
|
||||
|
||||
defaults write NSGlobalDomain AppleLanguages -array "en" "es" "bg"
|
||||
defaults write NSGlobalDomain AppleLocale -string "en_US@rg=eszzzz"
|
||||
|
||||
## Finder
|
||||
|
||||
# Screenshots/captures
|
||||
defaults write com.apple.screencapture location -string "${HOME}/Pictures/Screenshots"
|
||||
defaults write com.apple.screencapture style -string "display"
|
||||
defaults write com.apple.screencapture target -string "file"
|
||||
defaults write com.apple.screencapture video -int 1
|
||||
|
||||
# Finder
|
||||
# Interface elements
|
||||
defaults write com.apple.finder ShowPathbar -bool true
|
||||
defaults write com.apple.finder ShowStatusBar -bool true
|
||||
defaults write com.apple.finder ShowSidebar -bool true
|
||||
defaults write com.apple.finder ShowRecentTags -bool false
|
||||
|
||||
# View and sorting
|
||||
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv"
|
||||
defaults write com.apple.finder FXPreferredSearchViewStyle -string "Nlsv"
|
||||
defaults write com.apple.finder _FXSortFoldersFirst -bool true
|
||||
defaults write com.apple.finder FXPreferredGroupBy -string "None"
|
||||
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
|
||||
|
||||
# Behavior
|
||||
defaults write com.apple.finder NewWindowTarget -string "PfHm"
|
||||
defaults write com.apple.finder FXOpenFoldersInTabs -bool true
|
||||
defaults write com.apple.finder FXRemoveOldTrashItems -bool false
|
||||
defaults write com.apple.finder FXShowAllExtensions -bool true
|
||||
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool true
|
||||
defaults write com.apple.finder FXRemoveICloudDriveWarning -bool true
|
||||
defaults write com.apple.finder FXWarnBeforeEmptyingTrash -bool true
|
||||
|
||||
# Desktop icons (none)
|
||||
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool false
|
||||
defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool false
|
||||
defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool false
|
||||
defaults write com.apple.finder ShowConnectedServersOnDesktop -bool false
|
||||
|
||||
# Tags
|
||||
defaults write com.apple.finder FavoriteTagNames -array
|
||||
|
||||
# iCloud
|
||||
defaults write com.apple.finder FXICloudDriveEnabled -bool false
|
||||
|
||||
# Finder: show all filename extensions
|
||||
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
|
||||
|
||||
# Avoid creating .DS_Store files on network or USB volumes
|
||||
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
|
||||
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
|
||||
|
||||
## Dock
|
||||
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Reset preferences
|
||||
# rm -f ~/Library/Preferences/com.apple.dock.plist
|
||||
|
||||
# Reset Dock layout
|
||||
defaults write com.apple.dock persistent-apps -array
|
||||
defaults write com.apple.dock persistent-others -array
|
||||
|
||||
# Basic Dock preferences
|
||||
defaults write com.apple.dock autohide -bool true
|
||||
defaults write com.apple.dock autohide-delay -float 0
|
||||
defaults write com.apple.dock autohide-time-modifier -float 0.4
|
||||
defaults write com.apple.dock enterMissionControlByTopWindowDrag -bool false
|
||||
defaults write com.apple.dock expose-group-apps -bool true
|
||||
defaults write com.apple.dock mineffect -string "scale"
|
||||
defaults write com.apple.dock minimize-to-application -bool false
|
||||
defaults write com.apple.dock orientation -string "bottom"
|
||||
defaults write com.apple.dock show-process-indicators -bool false
|
||||
defaults write com.apple.dock show-recents -bool false
|
||||
defaults write com.apple.dock showAppExposeGestureEnabled -bool true
|
||||
defaults write com.apple.dock showDesktopGestureEnabled -bool false
|
||||
defaults write com.apple.dock showLaunchpadGestureEnabled -bool false
|
||||
defaults write com.apple.dock tilesize -int 38
|
||||
|
||||
# Add Brave Browser
|
||||
defaults write com.apple.dock persistent-apps -array-add \
|
||||
"<dict>
|
||||
<key>tile-data</key>
|
||||
<dict>
|
||||
<key>file-data</key>
|
||||
<dict>
|
||||
<key>_CFURLString</key>
|
||||
<string>/Applications/Brave Browser.app</string>
|
||||
<key>_CFURLStringType</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>tile-type</key>
|
||||
<string>file-tile</string>
|
||||
</dict>"
|
||||
|
||||
# Add Ghostty
|
||||
defaults write com.apple.dock persistent-apps -array-add \
|
||||
"<dict>
|
||||
<key>tile-data</key>
|
||||
<dict>
|
||||
<key>file-data</key>
|
||||
<dict>
|
||||
<key>_CFURLString</key>
|
||||
<string>/Applications/Ghostty.app</string>
|
||||
<key>_CFURLStringType</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>tile-type</key>
|
||||
<string>file-tile</string>
|
||||
</dict>"
|
||||
|
||||
# Add Screenshots directory (display as folder, show as grid)
|
||||
defaults write com.apple.dock persistent-others -array-add \
|
||||
"<dict>
|
||||
<key>tile-data</key>
|
||||
<dict>
|
||||
<key>displayas</key>
|
||||
<integer>1</integer>
|
||||
<key>showas</key>
|
||||
<integer>2</integer>
|
||||
<key>file-data</key>
|
||||
<dict>
|
||||
<key>_CFURLString</key>
|
||||
<string>/Users/tomas/Pictures/Screenshots</string>
|
||||
<key>_CFURLStringType</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>tile-type</key>
|
||||
<string>directory-tile</string>
|
||||
</dict>"
|
||||
|
||||
# Add Downloads directory (display as folder, show as grid)
|
||||
defaults write com.apple.dock persistent-others -array-add \
|
||||
"<dict>
|
||||
<key>tile-data</key>
|
||||
<dict>
|
||||
<key>displayas</key>
|
||||
<integer>1</integer>
|
||||
<key>showas</key>
|
||||
<integer>2</integer>
|
||||
<key>file-data</key>
|
||||
<dict>
|
||||
<key>_CFURLString</key>
|
||||
<string>/Users/tomas/Downloads</string>
|
||||
<key>_CFURLStringType</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>tile-type</key>
|
||||
<string>directory-tile</string>
|
||||
</dict>"
|
||||
|
||||
# Apply changes
|
||||
killall Finder &>/dev/null
|
||||
killall Dock &>/dev/null
|
||||
echo "Setup complete."
|
||||
@@ -14,10 +14,6 @@ fi
|
||||
|
||||
NEW_HOSTNAME="$1"
|
||||
|
||||
if ! sudo -v; then
|
||||
echo "Sudo access required. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir ~/projects
|
||||
# /bin/bash ./scripts/linux-setup_sudoers.sh
|
||||
|
||||
Reference in New Issue
Block a user