initial dotfiles
This commit is contained in:
commit
a11473e308
20 changed files with 2831 additions and 0 deletions
88
CLAUDE.md
Normal file
88
CLAUDE.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Overview
|
||||
|
||||
Dotfiles repo managing configs for WezTerm, Neovim, and Zsh (oh-my-zsh + p10k) with symlinks. Cross-platform: EndeavourOS (primary desktop) and Windows.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
dotfiles/
|
||||
├── zsh/
|
||||
│ ├── .zshrc # Zsh config (oh-my-zsh, p10k, aliases, plugins)
|
||||
│ ├── .p10k.zsh # Powerlevel10k prompt config
|
||||
│ └── custom/themes/ # Custom bira-nerd themes
|
||||
├── wezterm/
|
||||
│ └── wezterm.lua # WezTerm config (CovenantUI color scheme, JetBrainsMono Nerd Font)
|
||||
├── nvim/ # Neovim config (lazy.nvim, IDE-like setup)
|
||||
│ ├── init.lua
|
||||
│ └── lua/
|
||||
│ ├── options.lua
|
||||
│ ├── keymaps.lua
|
||||
│ └── plugins/
|
||||
│ ├── colorscheme.lua # catppuccin mocha
|
||||
│ ├── ui.lua # lualine, bufferline, indent-blankline
|
||||
│ ├── explorer.lua # neo-tree (<leader>e)
|
||||
│ ├── telescope.lua # fuzzy finder (<leader>ff/fg/fb/fr)
|
||||
│ ├── treesitter.lua # syntax highlighting
|
||||
│ ├── lsp.lua # mason + lspconfig + nvim-cmp (bash, python, C#)
|
||||
│ └── editor.lua # autopairs, which-key, gitsigns
|
||||
├── bootstrap.sh # Linux setup script
|
||||
└── bootstrap.ps1 # Windows setup script (requires admin)
|
||||
```
|
||||
|
||||
## Bootstrap / Setup
|
||||
|
||||
```bash
|
||||
# Linux — installs oh-my-zsh, powerlevel10k, zsh plugins, then symlinks everything
|
||||
bash bootstrap.sh
|
||||
|
||||
# Windows (PowerShell, run as Administrator)
|
||||
.\bootstrap.ps1
|
||||
```
|
||||
|
||||
On Linux, symlinks are created:
|
||||
- `~/.zshrc` → `zsh/.zshrc`
|
||||
- `~/.p10k.zsh` → `zsh/.p10k.zsh`
|
||||
- `~/.oh-my-zsh/custom/themes/*.zsh-theme` → `zsh/custom/themes/`
|
||||
- `~/.wezterm.lua` → `wezterm/wezterm.lua`
|
||||
- `~/.config/nvim` → `nvim/`
|
||||
|
||||
Neovim plugins install automatically on first `nvim` launch (lazy.nvim bootstraps itself).
|
||||
|
||||
## Key Conventions
|
||||
|
||||
- **No dotfile managers** — symlinks only, managed by bootstrap scripts.
|
||||
- **OS detection in configs**, not in bootstrap:
|
||||
- WezTerm: `wezterm.target_triple`
|
||||
- Neovim: `vim.loop.os_uname()`
|
||||
- **System clipboard by default** — `y`/`p` in Neovim use the OS clipboard (`unnamedplus`).
|
||||
- **Space as leader key** in Neovim.
|
||||
|
||||
## Neovim Key Mappings
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>e` | Toggle file tree |
|
||||
| `<leader>o` | Reveal current file in tree |
|
||||
| `<leader>ff` | Find files |
|
||||
| `<leader>fg` | Search text in project |
|
||||
| `<leader>fb` | Switch open buffers |
|
||||
| `<leader>fr` | Recent files |
|
||||
| `<S-l>` / `<S-h>` | Next / prev buffer |
|
||||
| `<leader>x` | Close buffer |
|
||||
| `K` | Hover LSP docs |
|
||||
| `gd` | Go to definition |
|
||||
| `<leader>rn` | Rename symbol |
|
||||
| `<leader>ca` | Code actions |
|
||||
| `<leader>d` | Line diagnostics |
|
||||
| `jk` | Exit insert mode |
|
||||
|
||||
## Zsh Plugins (installed by bootstrap.sh)
|
||||
|
||||
- `zsh-autosuggestions`
|
||||
- `zsh-syntax-highlighting`
|
||||
- `zsh-completions`
|
||||
- `fast-syntax-highlighting`
|
||||
22
CONTEXT.md
Normal file
22
CONTEXT.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Dotfiles Setup
|
||||
|
||||
Managing configs for WezTerm, Neovim, Zsh (oh-my-zsh + p10k) in a single Git repo with symlinks.
|
||||
Cross-platform: EndeavourOS (primary desktop) and Windows.
|
||||
|
||||
## Approach
|
||||
- Single repo, symlinks to expected config locations
|
||||
- OS detection handled in config files themselves (no chezmoi or similar tools)
|
||||
- WezTerm: `wezterm.target_triple` for OS branching in Lua
|
||||
- Neovim: `vim.loop.os_uname()` for OS branching in Lua
|
||||
|
||||
## Bootstrap
|
||||
- Linux: `bootstrap.sh` creates symlinks
|
||||
- Windows: `bootstrap.ps1` creates symlinks (requires admin for SymbolicLink)
|
||||
|
||||
## Structure
|
||||
dotfiles/
|
||||
├── wezterm/wezterm.lua
|
||||
├── nvim/
|
||||
├── zsh/.zshrc
|
||||
├── bootstrap.sh
|
||||
└── bootstrap.ps1
|
||||
38
bootstrap.ps1
Normal file
38
bootstrap.ps1
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Dotfiles Bootstrap (Windows)
|
||||
# Run as Administrator (required for symbolic links without Developer Mode)
|
||||
#Requires -RunAsAdministrator
|
||||
|
||||
$DOTFILES = $PSScriptRoot
|
||||
|
||||
function New-Link {
|
||||
param([string]$Src, [string]$Dst)
|
||||
$dir = Split-Path $Dst
|
||||
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
||||
if (Test-Path $Dst) { Remove-Item $Dst -Force -Recurse }
|
||||
# Use Junction for directories, SymbolicLink for files
|
||||
if (Test-Path $Src -PathType Container) {
|
||||
New-Item -ItemType Junction -Path $Dst -Target $Src | Out-Null
|
||||
} else {
|
||||
New-Item -ItemType SymbolicLink -Path $Dst -Target $Src | Out-Null
|
||||
}
|
||||
Write-Host " linked: $Dst"
|
||||
}
|
||||
|
||||
Write-Host "=== Dotfiles Bootstrap (Windows) ==="
|
||||
|
||||
# ── Oh My Posh (Windows alternative to oh-my-zsh + p10k) ─────────────────────
|
||||
# NOTE: Windows uses PowerShell, not Zsh. The .zshrc / p10k configs only apply
|
||||
# on Linux/WSL. Install Oh My Posh separately if desired:
|
||||
# winget install JanDeDobbeleer.OhMyPosh
|
||||
|
||||
# ── Symlinks ──────────────────────────────────────────────────────────────────
|
||||
Write-Host "Creating symlinks..."
|
||||
|
||||
# WezTerm: reads from $HOME\.wezterm.lua
|
||||
New-Link "$DOTFILES\wezterm\wezterm.lua" "$env:USERPROFILE\.wezterm.lua"
|
||||
|
||||
# Neovim: reads from $env:LOCALAPPDATA\nvim
|
||||
New-Link "$DOTFILES\nvim" "$env:LOCALAPPDATA\nvim"
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Done! Neovim plugins will install automatically on first launch."
|
||||
64
bootstrap.sh
Executable file
64
bootstrap.sh
Executable file
|
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
DOTFILES="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
link() {
|
||||
local src="$1" dst="$2"
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
ln -sf "$src" "$dst"
|
||||
echo " linked: $dst"
|
||||
}
|
||||
|
||||
echo "=== Dotfiles Bootstrap (Linux) ==="
|
||||
|
||||
# ── Oh My Zsh ─────────────────────────────────────────────────────────────────
|
||||
if [ ! -d "$HOME/.oh-my-zsh" ]; then
|
||||
echo "Installing oh-my-zsh..."
|
||||
RUNZSH=no CHSH=no sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||
else
|
||||
echo "oh-my-zsh already installed, skipping"
|
||||
fi
|
||||
|
||||
# ── Powerlevel10k ─────────────────────────────────────────────────────────────
|
||||
if [ ! -d "$HOME/.powerlevel10k" ]; then
|
||||
echo "Cloning powerlevel10k..."
|
||||
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "$HOME/.powerlevel10k"
|
||||
else
|
||||
echo "powerlevel10k already installed, skipping"
|
||||
fi
|
||||
|
||||
# ── Zsh plugins ───────────────────────────────────────────────────────────────
|
||||
ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}"
|
||||
|
||||
clone_plugin() {
|
||||
local name="$1" url="$2"
|
||||
if [ ! -d "$ZSH_CUSTOM/plugins/$name" ]; then
|
||||
echo "Cloning plugin: $name"
|
||||
git clone --depth=1 "$url" "$ZSH_CUSTOM/plugins/$name"
|
||||
else
|
||||
echo "Plugin already exists: $name"
|
||||
fi
|
||||
}
|
||||
|
||||
clone_plugin zsh-autosuggestions https://github.com/zsh-users/zsh-autosuggestions
|
||||
clone_plugin zsh-syntax-highlighting https://github.com/zsh-users/zsh-syntax-highlighting
|
||||
clone_plugin zsh-completions https://github.com/zsh-users/zsh-completions
|
||||
clone_plugin fast-syntax-highlighting https://github.com/zdharma-continuum/fast-syntax-highlighting
|
||||
|
||||
# ── Symlinks ──────────────────────────────────────────────────────────────────
|
||||
echo "Creating symlinks..."
|
||||
|
||||
link "$DOTFILES/zsh/.zshrc" "$HOME/.zshrc"
|
||||
link "$DOTFILES/zsh/.p10k.zsh" "$HOME/.p10k.zsh"
|
||||
|
||||
for theme in "$DOTFILES/zsh/custom/themes"/*.zsh-theme; do
|
||||
link "$theme" "$ZSH_CUSTOM/themes/$(basename "$theme")"
|
||||
done
|
||||
|
||||
link "$DOTFILES/wezterm/wezterm.lua" "$HOME/.wezterm.lua"
|
||||
link "$DOTFILES/nvim" "$HOME/.config/nvim"
|
||||
|
||||
echo ""
|
||||
echo "Done! Restart your shell to apply changes."
|
||||
echo "Neovim plugins will install automatically on first launch of nvim."
|
||||
16
nvim/init.lua
Normal file
16
nvim/init.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- Bootstrap lazy.nvim (auto-installs on first launch)
|
||||
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
||||
if not vim.loop.fs_stat(lazypath) then
|
||||
vim.fn.system({
|
||||
"git", "clone", "--filter=blob:none",
|
||||
"https://github.com/folke/lazy.nvim.git",
|
||||
"--branch=stable", lazypath,
|
||||
})
|
||||
end
|
||||
vim.opt.rtp:prepend(lazypath)
|
||||
|
||||
require("options")
|
||||
require("keymaps")
|
||||
require("lazy").setup("plugins", {
|
||||
change_detection = { notify = false },
|
||||
})
|
||||
33
nvim/lua/keymaps.lua
Normal file
33
nvim/lua/keymaps.lua
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
local map = vim.keymap.set
|
||||
|
||||
-- Space as leader key (must be set before lazy loads plugins)
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = " "
|
||||
|
||||
-- ── File ────────────────────────────────────────────────────────────────────
|
||||
map("n", "<leader>w", "<cmd>w<cr>", { desc = "Save file" })
|
||||
map("n", "<leader>q", "<cmd>q<cr>", { desc = "Quit" })
|
||||
map("n", "<leader>Q", "<cmd>qa<cr>", { desc = "Quit all" })
|
||||
|
||||
-- ── Buffers ─────────────────────────────────────────────────────────────────
|
||||
map("n", "<S-l>", "<cmd>bnext<cr>", { desc = "Next buffer" })
|
||||
map("n", "<S-h>", "<cmd>bprev<cr>", { desc = "Prev buffer" })
|
||||
map("n", "<leader>x", "<cmd>bd<cr>", { desc = "Close buffer" })
|
||||
|
||||
-- ── Window navigation (Ctrl + hjkl) ─────────────────────────────────────────
|
||||
map("n", "<C-h>", "<C-w>h", { desc = "Window left" })
|
||||
map("n", "<C-j>", "<C-w>j", { desc = "Window down" })
|
||||
map("n", "<C-k>", "<C-w>k", { desc = "Window up" })
|
||||
map("n", "<C-l>", "<C-w>l", { desc = "Window right" })
|
||||
|
||||
-- ── Editing quality of life ──────────────────────────────────────────────────
|
||||
map("i", "jk", "<Esc>", { desc = "Exit insert mode" }) -- quick escape
|
||||
map("n", "<Esc>", "<cmd>nohl<cr>", { desc = "Clear search highlight" })
|
||||
|
||||
-- Keep indent when tabbing in visual mode
|
||||
map("v", "<", "<gv")
|
||||
map("v", ">", ">gv")
|
||||
|
||||
-- Move selected lines up/down
|
||||
map("v", "<A-j>", ":m '>+1<cr>gv=gv", { desc = "Move selection down" })
|
||||
map("v", "<A-k>", ":m '<-2<cr>gv=gv", { desc = "Move selection up" })
|
||||
41
nvim/lua/options.lua
Normal file
41
nvim/lua/options.lua
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
local opt = vim.opt
|
||||
|
||||
-- Line numbers
|
||||
opt.number = true
|
||||
opt.relativenumber = true
|
||||
opt.cursorline = true
|
||||
opt.signcolumn = "yes" -- always show (prevents layout shifting with LSP)
|
||||
|
||||
-- Indentation (spaces, 2-wide by default; LSP/treesitter adjusts per language)
|
||||
opt.tabstop = 2
|
||||
opt.shiftwidth = 2
|
||||
opt.expandtab = true
|
||||
opt.smartindent = true
|
||||
|
||||
-- Search
|
||||
opt.ignorecase = true
|
||||
opt.smartcase = true -- case-sensitive when query has uppercase
|
||||
opt.hlsearch = true
|
||||
|
||||
-- System clipboard — y/p work with Ctrl+C/Ctrl+V from other apps
|
||||
opt.clipboard = "unnamedplus"
|
||||
|
||||
-- Splits open in natural directions
|
||||
opt.splitbelow = true
|
||||
opt.splitright = true
|
||||
|
||||
-- Appearance
|
||||
opt.termguicolors = true
|
||||
opt.wrap = false
|
||||
opt.scrolloff = 8 -- keep 8 lines visible above/below cursor
|
||||
|
||||
-- Files & undo
|
||||
opt.swapfile = false
|
||||
opt.undofile = true -- persistent undo across sessions
|
||||
|
||||
-- Performance
|
||||
opt.updatetime = 250 -- faster CursorHold (used by LSP hover)
|
||||
opt.timeoutlen = 300 -- faster which-key popup
|
||||
|
||||
-- Mouse support
|
||||
opt.mouse = "a"
|
||||
11
nvim/lua/plugins/colorscheme.lua
Normal file
11
nvim/lua/plugins/colorscheme.lua
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
return {
|
||||
{
|
||||
"catppuccin/nvim",
|
||||
name = "catppuccin",
|
||||
priority = 1000, -- load before everything else
|
||||
config = function()
|
||||
require("catppuccin").setup({ flavour = "mocha" })
|
||||
vim.cmd.colorscheme("catppuccin")
|
||||
end,
|
||||
},
|
||||
}
|
||||
40
nvim/lua/plugins/editor.lua
Normal file
40
nvim/lua/plugins/editor.lua
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
-- Editor quality-of-life: auto-pairs, key hints, git signs
|
||||
return {
|
||||
|
||||
-- Auto-close brackets, quotes, etc.
|
||||
{
|
||||
"windwp/nvim-autopairs",
|
||||
event = "InsertEnter",
|
||||
config = true,
|
||||
},
|
||||
|
||||
-- Press <leader> and wait to see all available keybindings
|
||||
{
|
||||
"folke/which-key.nvim",
|
||||
event = "VeryLazy",
|
||||
config = function()
|
||||
require("which-key").setup({})
|
||||
end,
|
||||
},
|
||||
|
||||
-- Git change indicators in the gutter + hunk actions
|
||||
-- <leader>gp → preview hunk diff
|
||||
-- <leader>gb → blame current line
|
||||
{
|
||||
"lewis6991/gitsigns.nvim",
|
||||
config = function()
|
||||
require("gitsigns").setup({
|
||||
signs = {
|
||||
add = { text = "▎" },
|
||||
change = { text = "▎" },
|
||||
delete = { text = "" },
|
||||
topdelete = { text = "" },
|
||||
changedelete = { text = "▎" },
|
||||
},
|
||||
})
|
||||
local map = vim.keymap.set
|
||||
map("n", "<leader>gp", "<cmd>Gitsigns preview_hunk<cr>", { desc = "Preview hunk" })
|
||||
map("n", "<leader>gb", "<cmd>Gitsigns blame_line<cr>", { desc = "Git blame line" })
|
||||
end,
|
||||
},
|
||||
}
|
||||
28
nvim/lua/plugins/explorer.lua
Normal file
28
nvim/lua/plugins/explorer.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
-- File tree (Neo-tree)
|
||||
-- <leader>e → toggle
|
||||
-- <leader>o → focus/reveal current file
|
||||
return {
|
||||
{
|
||||
"nvim-neo-tree/neo-tree.nvim",
|
||||
branch = "v3.x",
|
||||
dependencies = {
|
||||
"nvim-lua/plenary.nvim",
|
||||
"nvim-tree/nvim-web-devicons",
|
||||
"MunifTanjim/nui.nvim",
|
||||
},
|
||||
config = function()
|
||||
require("neo-tree").setup({
|
||||
window = { width = 30 },
|
||||
filesystem = {
|
||||
filtered_items = {
|
||||
hide_dotfiles = false, -- show dotfiles (useful for configs)
|
||||
hide_gitignored = true,
|
||||
},
|
||||
follow_current_file = { enabled = true }, -- auto-reveal open file
|
||||
},
|
||||
})
|
||||
vim.keymap.set("n", "<leader>e", "<cmd>Neotree toggle<cr>", { desc = "Toggle file tree" })
|
||||
vim.keymap.set("n", "<leader>o", "<cmd>Neotree reveal<cr>", { desc = "Reveal file in tree" })
|
||||
end,
|
||||
},
|
||||
}
|
||||
123
nvim/lua/plugins/lsp.lua
Normal file
123
nvim/lua/plugins/lsp.lua
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
-- LSP stack:
|
||||
-- mason → installs language servers automatically
|
||||
-- lspconfig → configures them
|
||||
-- nvim-cmp → completion popup
|
||||
-- LuaSnip → snippet engine (required by cmp)
|
||||
--
|
||||
-- LSP keymaps (active when a file has an attached language server):
|
||||
-- K → hover documentation
|
||||
-- gd → go to definition
|
||||
-- gr → list references
|
||||
-- <leader>rn → rename symbol
|
||||
-- <leader>ca → code actions (quick fixes, imports, etc.)
|
||||
-- <leader>d → show line diagnostics
|
||||
-- [d / ]d → jump to prev/next diagnostic
|
||||
return {
|
||||
|
||||
-- ── Mason: auto-installs language servers ──────────────────────────────────
|
||||
{
|
||||
"williamboman/mason.nvim",
|
||||
config = function()
|
||||
require("mason").setup()
|
||||
end,
|
||||
},
|
||||
{
|
||||
"williamboman/mason-lspconfig.nvim",
|
||||
dependencies = { "williamboman/mason.nvim" },
|
||||
config = function()
|
||||
require("mason-lspconfig").setup({
|
||||
ensure_installed = {
|
||||
"bashls", -- Bash
|
||||
"pyright", -- Python
|
||||
"omnisharp", -- C#
|
||||
},
|
||||
automatic_installation = true,
|
||||
})
|
||||
end,
|
||||
},
|
||||
|
||||
-- ── Completion ─────────────────────────────────────────────────────────────
|
||||
{
|
||||
"hrsh7th/nvim-cmp",
|
||||
dependencies = {
|
||||
"hrsh7th/cmp-nvim-lsp", -- LSP completions
|
||||
"hrsh7th/cmp-buffer", -- words from current buffer
|
||||
"hrsh7th/cmp-path", -- file paths
|
||||
"L3MON4D3/LuaSnip", -- snippet engine
|
||||
"saadparwaiz1/cmp_luasnip",
|
||||
},
|
||||
config = function()
|
||||
local cmp = require("cmp")
|
||||
local luasnip = require("luasnip")
|
||||
|
||||
cmp.setup({
|
||||
snippet = {
|
||||
expand = function(args) luasnip.lsp_expand(args.body) end,
|
||||
},
|
||||
mapping = cmp.mapping.preset.insert({
|
||||
["<C-Space>"] = cmp.mapping.complete(),
|
||||
["<CR>"] = cmp.mapping.confirm({ select = true }),
|
||||
["<Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif luasnip.expand_or_jumpable() then
|
||||
luasnip.expand_or_jump()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { "i", "s" }),
|
||||
["<S-Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item()
|
||||
elseif luasnip.jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, { "i", "s" }),
|
||||
}),
|
||||
sources = cmp.config.sources({
|
||||
{ name = "nvim_lsp" },
|
||||
{ name = "luasnip" },
|
||||
}, {
|
||||
{ name = "buffer" },
|
||||
{ name = "path" },
|
||||
}),
|
||||
})
|
||||
end,
|
||||
},
|
||||
|
||||
-- ── LSP config ─────────────────────────────────────────────────────────────
|
||||
{
|
||||
"neovim/nvim-lspconfig",
|
||||
dependencies = {
|
||||
"williamboman/mason-lspconfig.nvim",
|
||||
"hrsh7th/cmp-nvim-lsp",
|
||||
},
|
||||
config = function()
|
||||
local lspconfig = require("lspconfig")
|
||||
local capabilities = require("cmp_nvim_lsp").default_capabilities()
|
||||
|
||||
-- Keymaps applied whenever an LSP attaches to a buffer
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
callback = function(ev)
|
||||
local map = vim.keymap.set
|
||||
local opts = function(desc) return { buffer = ev.buf, desc = desc } end
|
||||
|
||||
map("n", "K", vim.lsp.buf.hover, opts("Hover docs"))
|
||||
map("n", "gd", vim.lsp.buf.definition, opts("Go to definition"))
|
||||
map("n", "gr", vim.lsp.buf.references, opts("References"))
|
||||
map("n", "<leader>rn", vim.lsp.buf.rename, opts("Rename symbol"))
|
||||
map("n", "<leader>ca", vim.lsp.buf.code_action, opts("Code action"))
|
||||
map("n", "<leader>d", vim.diagnostic.open_float, opts("Line diagnostics"))
|
||||
map("n", "[d", vim.diagnostic.goto_prev, opts("Prev diagnostic"))
|
||||
map("n", "]d", vim.diagnostic.goto_next, opts("Next diagnostic"))
|
||||
end,
|
||||
})
|
||||
|
||||
lspconfig.bashls.setup({ capabilities = capabilities })
|
||||
lspconfig.pyright.setup({ capabilities = capabilities })
|
||||
lspconfig.omnisharp.setup({ capabilities = capabilities })
|
||||
end,
|
||||
},
|
||||
}
|
||||
35
nvim/lua/plugins/telescope.lua
Normal file
35
nvim/lua/plugins/telescope.lua
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
-- Fuzzy finder — search files, text, buffers, recent files
|
||||
-- <leader>ff → find files
|
||||
-- <leader>fg → search text in project (live grep)
|
||||
-- <leader>fb → open buffers
|
||||
-- <leader>fr → recently opened files
|
||||
-- <leader>fh → help tags
|
||||
return {
|
||||
{
|
||||
"nvim-telescope/telescope.nvim",
|
||||
tag = "0.1.x",
|
||||
dependencies = {
|
||||
"nvim-lua/plenary.nvim",
|
||||
-- Optional: native FZF sorter for faster matching
|
||||
{ "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
|
||||
},
|
||||
config = function()
|
||||
local telescope = require("telescope")
|
||||
local builtin = require("telescope.builtin")
|
||||
|
||||
telescope.setup({
|
||||
defaults = {
|
||||
path_display = { "smart" },
|
||||
},
|
||||
})
|
||||
pcall(telescope.load_extension, "fzf") -- load fzf if compiled ok
|
||||
|
||||
local map = vim.keymap.set
|
||||
map("n", "<leader>ff", builtin.find_files, { desc = "Find files" })
|
||||
map("n", "<leader>fg", builtin.live_grep, { desc = "Search in project" })
|
||||
map("n", "<leader>fb", builtin.buffers, { desc = "Open buffers" })
|
||||
map("n", "<leader>fr", builtin.oldfiles, { desc = "Recent files" })
|
||||
map("n", "<leader>fh", builtin.help_tags, { desc = "Help tags" })
|
||||
end,
|
||||
},
|
||||
}
|
||||
20
nvim/lua/plugins/treesitter.lua
Normal file
20
nvim/lua/plugins/treesitter.lua
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
-- Treesitter: better syntax highlighting and code understanding
|
||||
return {
|
||||
{
|
||||
"nvim-treesitter/nvim-treesitter",
|
||||
build = ":TSUpdate",
|
||||
config = function()
|
||||
require("nvim-treesitter.configs").setup({
|
||||
ensure_installed = {
|
||||
"lua", "vim", "vimdoc",
|
||||
"python", "bash",
|
||||
"c_sharp",
|
||||
"json", "yaml", "toml", "markdown",
|
||||
},
|
||||
auto_install = true,
|
||||
highlight = { enable = true },
|
||||
indent = { enable = true },
|
||||
})
|
||||
end,
|
||||
},
|
||||
}
|
||||
31
nvim/lua/plugins/ui.lua
Normal file
31
nvim/lua/plugins/ui.lua
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
-- Status line, buffer tabs, indent guides
|
||||
return {
|
||||
{
|
||||
"nvim-lualine/lualine.nvim",
|
||||
dependencies = { "nvim-tree/nvim-web-devicons" },
|
||||
config = function()
|
||||
require("lualine").setup({ options = { theme = "catppuccin" } })
|
||||
end,
|
||||
},
|
||||
|
||||
{
|
||||
"akinsho/bufferline.nvim",
|
||||
version = "*",
|
||||
dependencies = { "nvim-tree/nvim-web-devicons" },
|
||||
config = function()
|
||||
require("bufferline").setup({
|
||||
options = {
|
||||
diagnostics = "nvim_lsp", -- show LSP error counts on tabs
|
||||
},
|
||||
})
|
||||
end,
|
||||
},
|
||||
|
||||
{
|
||||
"lukas-reineke/indent-blankline.nvim",
|
||||
main = "ibl",
|
||||
config = function()
|
||||
require("ibl").setup()
|
||||
end,
|
||||
},
|
||||
}
|
||||
135
wezterm/wezterm.lua
Normal file
135
wezterm/wezterm.lua
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
local wezterm = require("wezterm")
|
||||
local config = wezterm.config_builder()
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Colors — CovenantUI
|
||||
-- ─────────────────────────────────────────────
|
||||
config.colors = {
|
||||
foreground = "#00d4e8",
|
||||
background = "#000d0f",
|
||||
cursor_bg = "#00c8e0",
|
||||
cursor_fg = "#000d0f",
|
||||
cursor_border = "#00c8e0",
|
||||
selection_fg = "#000d0f",
|
||||
selection_bg = "#007a8a",
|
||||
|
||||
ansi = {
|
||||
"#001418", -- black → surface bg
|
||||
"#ff2244", -- red → alert / danger
|
||||
"#b8ff00", -- green → chartreuse data
|
||||
"#ffaa00", -- yellow → warning amber
|
||||
"#007a8a", -- blue → dim cyan
|
||||
"#005f6a", -- magenta → deeper dim cyan
|
||||
"#00c8e0", -- cyan → header cyan
|
||||
"#00d4e8", -- white → text
|
||||
},
|
||||
|
||||
brights = {
|
||||
"#002830", -- bright black
|
||||
"#ff4466", -- bright red
|
||||
"#ccff00", -- bright green
|
||||
"#ffcc00", -- bright yellow
|
||||
"#00c8e0", -- bright blue
|
||||
"#007a8a", -- bright magenta
|
||||
"#00e5ff", -- bright cyan
|
||||
"#e0faff", -- bright white
|
||||
},
|
||||
|
||||
tab_bar = {
|
||||
background = "#000d0f",
|
||||
active_tab = {
|
||||
bg_color = "#001418",
|
||||
fg_color = "#00d4e8",
|
||||
intensity = "Normal",
|
||||
underline = "None",
|
||||
italic = false,
|
||||
strikethrough = false,
|
||||
},
|
||||
inactive_tab = {
|
||||
bg_color = "#000d0f",
|
||||
fg_color = "#005f6a",
|
||||
},
|
||||
inactive_tab_hover = {
|
||||
bg_color = "#001418",
|
||||
fg_color = "#007a8a",
|
||||
},
|
||||
new_tab = {
|
||||
bg_color = "#000d0f",
|
||||
fg_color = "#005f6a",
|
||||
},
|
||||
new_tab_hover = {
|
||||
bg_color = "#001418",
|
||||
fg_color = "#00c8e0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Font
|
||||
-- ─────────────────────────────────────────────
|
||||
config.font = wezterm.font("JetBrainsMono Nerd Font")
|
||||
config.font_size = 14
|
||||
config.line_height = 1.0
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Window
|
||||
-- ─────────────────────────────────────────────
|
||||
config.initial_cols = 120
|
||||
config.initial_rows = 30
|
||||
|
||||
config.window_decorations = "RESIZE"
|
||||
config.hide_tab_bar_if_only_one_tab = true
|
||||
config.window_background_opacity = 0.85
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Padding
|
||||
-- ─────────────────────────────────────────────
|
||||
config.window_padding = {
|
||||
left = 10,
|
||||
right = 10,
|
||||
top = 6,
|
||||
bottom = 6,
|
||||
}
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Cursor
|
||||
-- ─────────────────────────────────────────────
|
||||
config.cursor_blink_rate = 400
|
||||
config.default_cursor_style = "BlinkingBlock"
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Performance
|
||||
-- ─────────────────────────────────────────────
|
||||
config.max_fps = 144
|
||||
config.prefer_egl = true
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Scrollback & behavior
|
||||
-- ─────────────────────────────────────────────
|
||||
config.scrollback_lines = 2000
|
||||
config.scroll_to_bottom_on_input = true
|
||||
config.audible_bell = "Disabled"
|
||||
config.window_close_confirmation = "NeverPrompt"
|
||||
|
||||
-- ─────────────────────────────────────────────
|
||||
-- Key bindings
|
||||
-- ─────────────────────────────────────────────
|
||||
config.keys = {
|
||||
{
|
||||
key = "w",
|
||||
mods = "ALT",
|
||||
action = wezterm.action.CloseCurrentPane { confirm = false },
|
||||
},
|
||||
{
|
||||
key = "d",
|
||||
mods = "ALT",
|
||||
action = wezterm.action.SplitHorizontal { domain = "CurrentPaneDomain" },
|
||||
},
|
||||
{
|
||||
key = "d",
|
||||
mods = "ALT|SHIFT",
|
||||
action = wezterm.action.SplitVertical { domain = "CurrentPaneDomain" },
|
||||
},
|
||||
}
|
||||
|
||||
return config
|
||||
1720
zsh/.p10k.zsh
Normal file
1720
zsh/.p10k.zsh
Normal file
File diff suppressed because it is too large
Load diff
130
zsh/.zshrc
Normal file
130
zsh/.zshrc
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
|
||||
# Initialization code that may require console input (password prompts, [y/n]
|
||||
# confirmations, etc.) must go above this block; everything else may go below.
|
||||
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
|
||||
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
|
||||
fi
|
||||
|
||||
# =========================
|
||||
# Zsh base / Oh My Zsh
|
||||
# =========================
|
||||
|
||||
export ZSH="$HOME/.oh-my-zsh"
|
||||
ZSH_THEME_NEWLINE_BEFORE_PROMPT=false
|
||||
ZSH_THEME="bira-nerd"
|
||||
|
||||
plugins=(
|
||||
git
|
||||
zsh-autosuggestions
|
||||
zsh-syntax-highlighting
|
||||
zsh-completions
|
||||
)
|
||||
|
||||
source $ZSH/oh-my-zsh.sh
|
||||
|
||||
# =========================
|
||||
# General environment
|
||||
# =========================
|
||||
|
||||
export EDITOR="nvim"
|
||||
export VISUAL="nvim"
|
||||
|
||||
# Better history
|
||||
HISTSIZE=50000
|
||||
SAVEHIST=50000
|
||||
HISTFILE="$HOME/.zsh_history"
|
||||
setopt SHARE_HISTORY
|
||||
setopt INC_APPEND_HISTORY
|
||||
setopt HIST_IGNORE_DUPS
|
||||
setopt HIST_IGNORE_ALL_DUPS
|
||||
setopt HIST_FIND_NO_DUPS
|
||||
setopt HIST_REDUCE_BLANKS
|
||||
|
||||
# =========================
|
||||
# Completion tuning
|
||||
# =========================
|
||||
|
||||
autoload -Uz compinit
|
||||
# Speed up compinit by caching, but rebuild if needed
|
||||
if [[ -n $ZDOTDIR && -f $ZDOTDIR/.zcompdump || -f ~/.zcompdump ]]; then
|
||||
compinit
|
||||
else
|
||||
compinit -C
|
||||
fi
|
||||
|
||||
zstyle ':completion:*' menu select
|
||||
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' 'r:|=*' 'l:|=* r:|=*'
|
||||
zstyle ':completion:*' group-name ''
|
||||
zstyle ':completion:*:descriptions' format '%F{yellow}-- %d --%f'
|
||||
|
||||
# =========================
|
||||
# Prompt / colors / quality of life
|
||||
# =========================
|
||||
|
||||
# Use modern ls colors
|
||||
export LS_COLORS="$LS_COLORS:di=1;34:ln=36:so=35:pi=33:ex=1;32:bd=34;46:cd=34;43:su=37;41:sg=30;43:tw=30;42:ow=34;42"
|
||||
|
||||
# Aliases
|
||||
alias ls='eza --icons --group-directories-first'
|
||||
alias ll='eza -lh --icons --group-directories-first --git'
|
||||
alias la='eza -lha --icons --group-directories-first --git'
|
||||
alias tree='eza --tree --icons'
|
||||
alias ..='cd ..'
|
||||
alias ...='cd ../..'
|
||||
alias grep='grep --color=auto'
|
||||
alias c='clear'
|
||||
alias please='sudo $(fc -ln -1)'
|
||||
|
||||
# Pacman helpers (EndeavourOS / Arch)
|
||||
alias pacs='sudo pacman -S'
|
||||
alias pacr='sudo pacman -Rns'
|
||||
alias pacu='sudo pacman -Syu'
|
||||
alias yayu='yay -Syu --noconfirm'
|
||||
|
||||
# Git shortcuts
|
||||
alias gs='git status -sb'
|
||||
alias gl='git log --oneline --graph --decorate'
|
||||
alias gc='git commit'
|
||||
alias gco='git checkout'
|
||||
alias gp='git push'
|
||||
alias gpl='git pull'
|
||||
|
||||
# =========================
|
||||
# Keybindings / history search
|
||||
# =========================
|
||||
|
||||
bindkey -e # emacs-style
|
||||
# Up/down search by history based on current input
|
||||
autoload -Uz up-line-or-history down-line-or-history
|
||||
zle -N up-line-or-history
|
||||
zle -N down-line-or-history
|
||||
bindkey '^[[A' up-line-or-history
|
||||
bindkey '^[[B' down-line-or-history
|
||||
|
||||
# =========================
|
||||
# Autosuggestions & highlighting tweaks
|
||||
# =========================
|
||||
|
||||
# Make autosuggestions subtle
|
||||
ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8'
|
||||
|
||||
# Ensure syntax highlighting is loaded last (safety net)
|
||||
if [ -f "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]; then
|
||||
source "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
|
||||
fi
|
||||
|
||||
# =========================
|
||||
# Path fixes (non-invasive)
|
||||
# =========================
|
||||
|
||||
# Add user-local bin dirs if they exist
|
||||
[[ -d "$HOME/.local/bin" ]] && path=("$HOME/.local/bin" $path)
|
||||
[[ -d "$HOME/bin" ]] && path=("$HOME/bin" $path)
|
||||
|
||||
export PATH
|
||||
|
||||
source ~/.powerlevel10k/powerlevel10k.zsh-theme
|
||||
[[ -f ~/.p10k.zsh ]] && source ~/.p10k.zsh
|
||||
|
||||
# opencode
|
||||
export PATH=/home/user/.opencode/bin:$PATH
|
||||
38
zsh/custom/themes/bira-custom.zsh-theme
Normal file
38
zsh/custom/themes/bira-custom.zsh-theme
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
local return_code="%(?..%{$fg[red]%}%? ↵%{$reset_color%})"
|
||||
local user_host="%B%(!.%{$fg[red]%}.%{$fg[green]%})%n@%m%{$reset_color%} "
|
||||
local user_symbol='%(!.#.$)'
|
||||
local current_dir="%B%{$fg[blue]%}%~ %{$reset_color%}"
|
||||
local conda_prompt='$(conda_prompt_info)'
|
||||
|
||||
local vcs_branch='$(git_prompt_info)$(hg_prompt_info)'
|
||||
local rvm_ruby='$(ruby_prompt_info)'
|
||||
local venv_prompt='$(virtualenv_prompt_info)'
|
||||
if [[ "${plugins[@]}" =~ 'kube-ps1' ]]; then
|
||||
local kube_prompt='$(kube_ps1)'
|
||||
else
|
||||
local kube_prompt=''
|
||||
fi
|
||||
|
||||
ZSH_THEME_RVM_PROMPT_OPTIONS="i v g"
|
||||
|
||||
PROMPT="╭─${conda_prompt}${user_host}${current_dir}${rvm_ruby}${vcs_branch}${venv_prompt}${kube_prompt}
|
||||
╰─%B${user_symbol}%b "
|
||||
RPROMPT="%B${return_code}%b"
|
||||
|
||||
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%}‹"
|
||||
ZSH_THEME_GIT_PROMPT_SUFFIX="› %{$reset_color%}"
|
||||
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%}●%{$fg[yellow]%}"
|
||||
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[yellow]%}"
|
||||
|
||||
ZSH_THEME_HG_PROMPT_PREFIX="$ZSH_THEME_GIT_PROMPT_PREFIX"
|
||||
ZSH_THEME_HG_PROMPT_SUFFIX="$ZSH_THEME_GIT_PROMPT_SUFFIX"
|
||||
ZSH_THEME_HG_PROMPT_DIRTY="$ZSH_THEME_GIT_PROMPT_DIRTY"
|
||||
ZSH_THEME_HG_PROMPT_CLEAN="$ZSH_THEME_GIT_PROMPT_CLEAN"
|
||||
|
||||
ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[red]%}‹"
|
||||
ZSH_THEME_RUBY_PROMPT_SUFFIX="› %{$reset_color%}"
|
||||
|
||||
ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX="%{$fg[green]%}‹"
|
||||
ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX="› %{$reset_color%}"
|
||||
ZSH_THEME_VIRTUALENV_PREFIX="$ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX"
|
||||
ZSH_THEME_VIRTUALENV_SUFFIX="$ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX"
|
||||
87
zsh/custom/themes/bira-nerd-2.zsh-theme
Normal file
87
zsh/custom/themes/bira-nerd-2.zsh-theme
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# =======================================================
|
||||
# bira-nerd.zsh-theme — custom prompt for JetBrainsMono Nerd Font
|
||||
# =======================================================
|
||||
|
||||
# --- Git / VCS styling ---
|
||||
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[yellow]%} %{$reset_color%}"
|
||||
ZSH_THEME_GIT_PROMPT_SUFFIX=""
|
||||
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[red]%} %{$reset_color%}"
|
||||
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[green]%} %{$reset_color%}"
|
||||
|
||||
ZSH_THEME_HG_PROMPT_PREFIX="$ZSH_THEME_GIT_PROMPT_PREFIX"
|
||||
ZSH_THEME_HG_PROMPT_SUFFIX="$ZSH_THEME_GIT_PROMPT_SUFFIX"
|
||||
ZSH_THEME_HG_PROMPT_DIRTY="$ZSH_THEME_GIT_PROMPT_DIRTY"
|
||||
ZSH_THEME_HG_PROMPT_CLEAN="$ZSH_THEME_GIT_PROMPT_CLEAN"
|
||||
|
||||
# --- Timer hooks ---
|
||||
preexec() {
|
||||
CMD_START=$EPOCHREALTIME
|
||||
}
|
||||
|
||||
precmd() {
|
||||
# ---------------- LEFT SIDE ----------------
|
||||
local user_host="%B%(!.%{$fg[red]%}.%{$fg[green]%}) %n@%m%{$reset_color%} "
|
||||
local current_dir="%B%{$fg[blue]%} %~%{$reset_color%}"
|
||||
local vcs_branch='$(git_prompt_info)$(hg_prompt_info)'
|
||||
local left="╭─${user_host}${current_dir}${vcs_branch}"
|
||||
|
||||
# ---------------- RIGHT SIDE ----------------
|
||||
# Python venv name
|
||||
local venv_right=""
|
||||
if [[ -n "$VIRTUAL_ENV" ]]; then
|
||||
venv_right="%F{magenta}(${VIRTUAL_ENV:t})%f "
|
||||
fi
|
||||
|
||||
# Time
|
||||
local time_str="%F{242}%D{%H:%M:%S}%f"
|
||||
|
||||
# Duration (time taken for last command)
|
||||
local dur_str=""
|
||||
if [[ -n "$CMD_START" ]]; then
|
||||
local diff=$(( EPOCHREALTIME - CMD_START ))
|
||||
local secs=${diff%.*}
|
||||
local ms=${diff#*.}
|
||||
if (( secs > 0 )); then
|
||||
dur_str="%F{33}${secs}s%f"
|
||||
else
|
||||
dur_str="%F{33}${ms:0:2}ms%f"
|
||||
fi
|
||||
else
|
||||
dur_str="%F{33}0ms%f"
|
||||
fi
|
||||
|
||||
# Exit code (only visible if non-zero)
|
||||
local rc_str="%(?..%F{red}%?↵%f)"
|
||||
|
||||
local right="${venv_right}${time_str} ${dur_str} ${rc_str}"
|
||||
|
||||
# --- Manual right alignment on FIRST line ---
|
||||
local plain_left=${left//\%\{*%\}/}
|
||||
local plain_right=${right//\%\{*%\}/}
|
||||
local pad=$(( COLUMNS - ${#plain_left} - ${#plain_right} ))
|
||||
(( pad < 1 )) && pad=1
|
||||
local spaces="${(l:${pad}:: :)}"
|
||||
|
||||
# Two-line layout:
|
||||
# Line 1 = left + right
|
||||
# Line 2 = command symbol
|
||||
PROMPT="${left}${spaces}${right}\n
|
||||
╰─>%B%(!.#.$)%b "
|
||||
|
||||
RPROMPT="FITTE"
|
||||
CMD_START=""
|
||||
}
|
||||
|
||||
__RPROMPT='$(vi_mode_prompt_info)%{$(echotc UP 1)%}$(_git_time_since_commit) $(git_prompt_status) ${_return_status}%{$(echotc DO 1)%}'
|
||||
if [[ -z $RPROMPT ]]; then
|
||||
RPROMPT=$__RPROMPT
|
||||
else
|
||||
RPROMPT="${RPROMPT} ${__RPROMPT}"
|
||||
fi
|
||||
|
||||
# --- Optional stylistic bits ---
|
||||
ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg[red]%}‹"
|
||||
ZSH_THEME_RUBY_PROMPT_SUFFIX="› %{$reset_color%}"
|
||||
ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX="%{$fg[green]%}‹"
|
||||
ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX="› %{$reset_color%}"
|
||||
|
||||
131
zsh/custom/themes/bira-nerd.zsh-theme
Normal file
131
zsh/custom/themes/bira-nerd.zsh-theme
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# bira-nerd: Clean Bira-style 2-line prompt with Nerd icons
|
||||
# Line 1 (left): user@host, cwd, git, pyenv, venv
|
||||
# Line 1 (right): (venv) time duration exit code
|
||||
# Line 2: ╰─$ (root gets #)
|
||||
# No extra blank lines. No column-width hacks.
|
||||
|
||||
setopt prompt_subst
|
||||
|
||||
########################################
|
||||
# Helpers
|
||||
########################################
|
||||
|
||||
# Git: branch + dirty/clean
|
||||
_bira_nerd_git() {
|
||||
command git rev-parse --is-inside-work-tree &>/dev/null || return
|
||||
|
||||
local branch dirty
|
||||
branch=$(
|
||||
command git symbolic-ref --quiet --short HEAD 2>/dev/null ||
|
||||
command git rev-parse --short HEAD 2>/dev/null
|
||||
) || return
|
||||
|
||||
if ! command git diff --quiet --ignore-submodules --cached 2>/dev/null ||
|
||||
! command git diff --quiet --ignore-submodules 2>/dev/null; then
|
||||
dirty="%F{red}%f"
|
||||
else
|
||||
dirty="%F{green}%f"
|
||||
fi
|
||||
|
||||
echo "%F{yellow}%f ${branch} ${dirty}"
|
||||
}
|
||||
|
||||
# pyenv: show active version if not "system"
|
||||
_bira_nerd_pyenv() {
|
||||
command -v pyenv &>/dev/null || return
|
||||
local v
|
||||
v=$(pyenv version-name 2>/dev/null) || return
|
||||
[[ -n "$v" && "$v" != "system" ]] || return
|
||||
echo " ${v}"
|
||||
}
|
||||
|
||||
########################################
|
||||
# Timing
|
||||
########################################
|
||||
|
||||
preexec() {
|
||||
BIRA_NERD_START=$EPOCHREALTIME
|
||||
}
|
||||
|
||||
########################################
|
||||
# precmd: build first line (no printing)
|
||||
########################################
|
||||
|
||||
precmd() {
|
||||
local left git_info pyenv_info vp
|
||||
|
||||
# Start with top-left glyph
|
||||
left="╭─"
|
||||
|
||||
# conda (if available)
|
||||
if (( $+functions[conda_prompt_info] )); then
|
||||
left+="$(conda_prompt_info)"
|
||||
fi
|
||||
|
||||
# user@host with icon (includes trailing space)
|
||||
local user_host="%B%(!.%F{red}.%F{green}) %n@%m%f%b "
|
||||
# cwd with folder icon (no trailing space)
|
||||
local current_dir="%B%F{blue} %~%f%b"
|
||||
|
||||
left+="${user_host}${current_dir}"
|
||||
|
||||
# git info
|
||||
git_info="$(_bira_nerd_git)"
|
||||
[[ -n "$git_info" ]] && left+=" ${git_info}"
|
||||
|
||||
# pyenv info
|
||||
pyenv_info="$(_bira_nerd_pyenv)"
|
||||
[[ -n "$pyenv_info" ]] && left+=" %F{magenta}${pyenv_info}%f"
|
||||
|
||||
# left-side venv (oh-my-zsh virtualenv plugin, if present)
|
||||
if (( $+functions[virtualenv_prompt_info] )); then
|
||||
vp="$(virtualenv_prompt_info)"
|
||||
[[ -n "$vp" ]] && left+=" ${vp}"
|
||||
fi
|
||||
|
||||
# ---------- RIGHT SIDE SEGMENTS ----------
|
||||
|
||||
local -a right_parts
|
||||
|
||||
# (venv) from raw $VIRTUAL_ENV on the right
|
||||
if [[ -n "$VIRTUAL_ENV" ]]; then
|
||||
right_parts+=( "%F{magenta}(${VIRTUAL_ENV:t})%f" )
|
||||
fi
|
||||
|
||||
# time
|
||||
right_parts+=( "%F{242}%D{%H:%M:%S}%f" )
|
||||
|
||||
# duration of last command
|
||||
if [[ -n "$BIRA_NERD_START" ]]; then
|
||||
local diff secs ms
|
||||
diff=$(( EPOCHREALTIME - BIRA_NERD_START ))
|
||||
secs=${diff%.*}
|
||||
ms=${diff#*.}
|
||||
if (( secs > 0 )); then
|
||||
right_parts+=( "%F{33}${secs}s%f" )
|
||||
else
|
||||
right_parts+=( "%F{33}${ms:0:2}ms%f" )
|
||||
fi
|
||||
fi
|
||||
|
||||
# exit code (only when non-zero)
|
||||
right_parts+=( "%(?..%F{red}%?↵%f)" )
|
||||
|
||||
# Join right segments with single spaces
|
||||
local right="${(j: :)right_parts}"
|
||||
|
||||
# Final first line: left + ONE space + right
|
||||
BIRA_NERD_LINE1="${left} ${right}"
|
||||
|
||||
# reset timer
|
||||
BIRA_NERD_START=""
|
||||
}
|
||||
|
||||
########################################
|
||||
# Two-line prompt
|
||||
########################################
|
||||
|
||||
PROMPT='${BIRA_NERD_LINE1}
|
||||
╰─%B%(!.#.$)%b '
|
||||
RPROMPT=''
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue