My Terminal
August 26, 2026 ยท View on GitHub
The applied terminal varies by the host OS:
Additionally, the ๐งฉ Extra setup covers what I run on top of the terminal itself: Nerd Fonts, herdr (agent multiplexer) and NeoVim (text editor).
This repo only does not list my IDE: VS Code settings.
๐ Warp
Warp - my main terminal for macOS.
๐จ Appearance
- Theme:
Fancy Dracula - Prompt:
Shell prompt (PS1) - Font:
JetBrainsMono Nerd Font Mono12 (see ๐ฃ Nerd Fonts)
โ๏ธ Zsh settings
- Framework: Oh My Zsh
- Prompt: Starship
- If you have installed conda, I suggest to disable printing environment names, as they will be displayed already by Starship:
conda config --set changeps1 False
- If you have installed conda, I suggest to disable printing environment names, as they will be displayed already by Starship:
Plugins
Oh My Zsh plugins:
- aws
- colored-man-pages
- copyfile
- copypath
- docker
- docker-compose
- dotenv
- fzf
- git
- globalias
- helm
- istioctl
- jsontools
- kubectl
- pip
- poetry
- python
- sudo
- terraform
- virtualenv
- vscode
External plugins:
- zsh-autosuggestions โ fish-like autosuggestions for Zsh
- zsh-syntax-highlighting โ fish shell like syntax highlighting for Zsh
Shell aliases
Note
Since 2024/01/07, I keep my core text-expansion config in my-espanso-config.
I recommend keeping aliases in the ~/.aliases file, and then source this file in your respective profile file through source ~/.aliases. Keep in mind that a bunch of aliases is already configured through the aforementioned Oh My Zsh plugins, which you can quickly check using the aliases plugin.
general:
alias aliases='code ~/.aliases'โ quickly open~/.aliasesin VS Codealias lisl='eza -hla --icons'โ betterlswith ezaalias list='eza -hlas time --icons'โ betterlswith eza (ordered by time)alias treee='br -c :pt'โ bettertreewith brootalias path='echo -e ${PATH//:/\\n}'โ show all directories in the PATH variable, one per linealias ports='netstat -a | grep -i "listen"'โ show all open ports and the processes using themalias reload='source ~/.zshrc'โ reload the configuration file for zshalias zshrc='code ~/.zshrc'โ quickly open~/.zshrcin VS Code
kubernetes:
alias k8s-get-pods='kubectl get pods --all-namespaces'โ get the list of all podsalias k8s-get-services='kubectl get services --all-namespaces'โ get the list of all services
macOS:
alias cleanup="find . -type f -name '*.DS_Store' -ls -delete"โ find and delete all.DS_Storefiles in the current directory and all subdirectories
functions:
-
check if a website is up or down:
function website-status(){ curl -Is "\$1" | head -n 1 } -
open finder in the current folder:
function openfinder(){ open -a Finder "\$1"; }
Shell tools
You can find a list of my recommended shell tools in my other repo.
๐ iTerm2
iTerm2 - my alternative terminal for macOS.
๐จ Appearance
- Theme: Dracula PRO
- iTerm2 theme size:
Compact - Font:
JetBrainsMono Nerd Font Mono12 (see ๐ฃ Nerd Fonts)
โจ Extras
Extra iTerm2 configuration:
- Jump between words with
โฅ+โ/โ- Settings > Profiles > Keys > Key Mappings > +
- Keyboard shortcut:
โฅ โ, Action:Send Escape Sequence, Esc+:b - Keyboard shortcut:
โฅ โ, Action:Send Escape Sequence, Esc+:f
- Keyboard shortcut:
- Settings > Profiles > Keys > Key Mappings > +
- Delete words with
โฅ+BACKSPACE- Settings > Profiles > Keys > General
- Left and Right option keys: change from
NormaltoEsc+
- Left and Right option keys: change from
- Settings > Profiles > Keys > General
๐ฅ Windows Terminal
Windows Terminal - my main terminal for Windows.
๐จ Appearance

- Theme: Dracula PRO (with
"brightBlack": "#8F89B4"as I have reasoned here) - Background opacity:
80% - Font:
JetBrainsMono Nerd Font Mono11 (see ๐ฃ Nerd Fonts)
โ๏ธ Profiles
Command Prompt
Git Bash
Install Git Bash from here.
Add profile to Windows Terminal:
- Name:
Git Bash - Command line:
%PROGRAMFILES%/Git/bin/bash.exe -i -l - Starting directory:
%USERPROFILE% - Icon:
%PROGRAMFILES%/Git/mingw64/share/git/git-for-windows.ico
Extras:
- Prompt: Starship
- To be able to activate conda environments, you may also need to set a system variable:
PYTHONIOENCODING=utf8
.bash_profile:
# Set Starship theme
eval "$(starship init bash)"
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
eval "$('/c/Users/pawel/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')"
# <<< conda initialize <<<
PowerShell 7
I am using PowerShell 7 in addition to the native Windows PowerShell 5.
Extras:
$PROFILE:
# Set Starship
Invoke-Expression (&starship init powershell)
# Show navigable menu of all options when hitting Tab
Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete
# Autocompletion for arrow keys
Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward
WSL - Ubuntu 22.04 (LTS)
Install Ubuntu:
- Set a default version of WSL:
wsl --set-default-version 2. - Install Ubuntu 22.04 LTS.
Setup the environment:
- Start with
sudo apt updateandsudo apt upgrade. - Install Zsh, Oh My Zsh and Starship.
- Copy the โ๏ธ Zsh settings.
Extras:
- Disable beep sound in Windows Terminal settings for the Ubuntu Profile (
Advanced>Bell notification style) - If you have installed conda, I suggest to disable printing environment names, as they will be displayed already by Starship:
conda config --set changeps1 False.
๐ค Termux
Termux - my main terminal for Android installed from F-Droid.
๐จ Appearance

UI modified with Termux:Styling (obtained from F-Droid):
- Theme:
Dracula - Font:
FiraCode(JetBrains Mono does not support icons ofeza --icons) - Keyboard: Gboard
โ๏ธ Setup
- Install F-Droid, and use it to install Termux with Termux:Styling.
- Open up Termux and start with
apt updateandapt upgrade. - Install extra packages:
pkg install git,pkg install pythonandpkg install vim. - Install Zsh (
pkg install zsh), Oh My Zsh and Starship (pkg install starship). - Copy the โ๏ธ Zsh settings.
- Optionally, install further tools such as Tool-X.
๐งฉ Extra setup
Layers that sit on top of whichever terminal I am in, so they are OS agnostic.
๐ฃ Nerd Fonts
Every terminal here uses JetBrainsMono Nerd Font Mono, which is JetBrains Mono patched by Nerd Fonts. The unpatched font carries no icon glyphs.
It has to be v3 or newer. v3 moved the Material Design icons to U+F0000+, which is where current tools look for them: Neovim's file explorer, eza --icons, yazi, lazygit.
brew install --cask font-jetbrains-mono-nerd-font
Warning
Remove any v2 build you installed earlier, rather than leaving both. v2 files are named ... Nerd Font Complete ....ttf and declare the same family name as v3, so macOS may keep resolving to the old one and the new glyphs never appear:
ls ~/Library/Fonts | grep Complete
Move those out of ~/Library/Fonts, then fully quit and reopen the terminal. Warp is where this bites hardest, since it has no font fallback and draws only what the selected font provides. iTerm2 falls back to another installed font and hides the problem, so check its profile still points at a font that exists.
๐ herdr
herdr - my agent multiplexer, running inside whichever terminal I am on.
๐จ Appearance
- Theme:
dracula - Font: inherited from the host terminal, so
JetBrainsMono Nerd Font Monoeverywhere
โ๏ธ Setup
-
Install herdr:
# macOS / Linux brew install herdr # or, without Homebrew curl -fsSL https://herdr.dev/install.sh | shOn Windows:
irm https://herdr.dev/install.ps1 | iex. -
Run
herdrto create or attach to the persistent session.CTRL+Bis the prefix key, soCTRL+Bthen?lists every binding, andCTRL+BthenQdetaches while leaving the agents running. Useherdr --session <name>for a second isolated session, andherdr --remote <ssh-target>to attach to a server running on another machine. -
Apply the Dracula theme in
~/.config/herdr/config.toml:[theme] name = "dracula" -
Install the plugins I use:
# git-aware, read-only file browser in a split pane herdr plugin install smarzban/herdr-file-viewer # review agent-written diffs in a sidebar and send line comments back to the agent herdr plugin install persiyanov/herdr-reviewrBoth are bound in
~/.config/herdr/config.toml:[[keys.command]] key = "prefix+f" type = "plugin_action" command = "herdr-file-viewer.open-file-viewer" description = "open file viewer in split" [[keys.command]] key = "prefix+shift+f" type = "plugin_action" command = "herdr-file-viewer.open-file-viewer-tab" description = "open file viewer in tab" [[keys.command]] key = "prefix+d" type = "plugin_action" command = "persiyanov.reviewr.toggle" description = "toggle reviewr diff pane"Config changes are picked up with
herdr server reload-config, orCTRL+BthenSHIFT+R.reviewr keeps its own config in
~/.config/herdr/plugins/config/persiyanov.reviewr/config.toml, which it re-reads on every refresh:theme = "dracula" default_scope = "branch"branchdiffs against the merge-base with the default branch, so a review still shows the agent's work once it has been committed. The defaultuncommittedscope only covers the working tree. -
Optionally, wire up the agent CLIs you use:
herdr integration install claude. Runherdr integrationto see the rest (codex,cursor,copilot,opencode,grok, and more). -
Optionally, add Zsh completions:
mkdir -p ~/.zfunc herdr completion zsh > ~/.zfunc/_herdrThen add
fpath=(~/.zfunc $fpath)to~/.zshrc, above the line that sources Oh My Zsh.
๐ง Neovim
Neovim - my main text editor used within the terminal of any OS.
๐จ Appearance
- Neovim config: LazyVim
- Theme:
dracula - Font:
JetBrainsMono Nerd Font Mono12, and it has to be Nerd Fonts v3 or newer, otherwise the file explorer renders without icons
This setup used to be NvChad with the
chadraculatheme. I moved to LazyVim because its config layout has stayed stable for years, while NvChad has gone through breaking restructures (v1 โ v2 โ v2.5) that each required rewriting the config from scratch.
โ๏ธ Setup
-
Make sure you have set up the local terminal of your OS (ideally as in this repo).
-
Install Neovim 0.11 or newer (
nvim --version). -
Back up any existing config and install the LazyVim starter:
mv ~/.config/nvim{,.bak} mv ~/.local/share/nvim{,.bak} mv ~/.local/state/nvim{,.bak} mv ~/.cache/nvim{,.bak} git clone https://github.com/LazyVim/starter ~/.config/nvim rm -rf ~/.config/nvim/.git rm -f ~/.config/nvim/lua/plugins/example.lua -
Enable the language support I use, by adding these imports to the
spectable in~/.config/nvim/lua/config/lazy.lua:{ import = "lazyvim.plugins.extras.lang.typescript" }, { import = "lazyvim.plugins.extras.lang.json" }, { import = "lazyvim.plugins.extras.lang.markdown" }, { import = "lazyvim.plugins.extras.lang.clangd" }, { import = "lazyvim.plugins.extras.formatting.prettier" },In the same file, set the fallback colourscheme so the first launch does not flash Tokyo Night:
install = { colorscheme = { "dracula", "habamax" } }, -
Apply the Dracula theme in
~/.config/nvim/lua/plugins/colorscheme.lua:return { { "AndresYague/dracula.nvim", lazy = false, priority = 1000, opts = { style = "default", -- "default" | "soft" | "day" styles = { comments = { italic = true }, }, }, }, { "LazyVim/LazyVim", opts = { colorscheme = "dracula" }, }, } -
Add the HTML/CSS language servers in
~/.config/nvim/lua/plugins/lsp.lua(Lua, TypeScript, C and the formatters already come from step 4):return { { "neovim/nvim-lspconfig", opts = { servers = { html = {}, cssls = {} } }, }, { "nvim-treesitter/nvim-treesitter", opts = { ensure_installed = { "css" } }, }, { "mason-org/mason.nvim", opts = { ensure_installed = { "html-lsp", "css-lsp" } }, }, } -
Add
jkas an escape shortcut in~/.config/nvim/lua/plugins/editor.lua:return { { "max397574/better-escape.nvim", event = "InsertEnter", opts = {}, }, } -
Add diffview.nvim in
~/.config/nvim/lua/plugins/git.lua. LazyVim's gitsigns already covers single-file hunks, while this gives a file panel and a side-by-side view over a whole changeset, which is how I review what a coding agent wrote:return { { "sindrets/diffview.nvim", cmd = { "DiffviewOpen", "DiffviewClose", "DiffviewFileHistory", "DiffviewToggleFiles" }, keys = { { "<leader>gv", "<cmd>DiffviewOpen<cr>", desc = "Diffview (working tree)" }, { "<leader>gV", "<cmd>DiffviewFileHistory %<cr>", desc = "Diffview (file history)" }, { -- Everything on this branch, committed work included. The working-tree -- view above goes blank once an agent has committed its changes. "<leader>gm", function() local base = vim.trim(vim.fn.system("git symbolic-ref --quiet --short refs/remotes/origin/HEAD")) if vim.v.shell_error ~= 0 or base == "" then base = "origin/main" end vim.cmd("DiffviewOpen " .. base .. "...HEAD") end, desc = "Diffview (vs base branch)", }, }, opts = { enhanced_diff_hl = true, view = { -- 3-way merge conflicts are easier to read with the base shown. merge_tool = { layout = "diff3_mixed" }, }, keymaps = { view = { { "n", "q", "<cmd>DiffviewClose<cr>", { desc = "Close Diffview" } } }, file_panel = { { "n", "q", "<cmd>DiffviewClose<cr>", { desc = "Close Diffview" } } }, file_history_panel = { { "n", "q", "<cmd>DiffviewClose<cr>", { desc = "Close Diffview" } } }, }, }, }, }qcloses any of the panels. Note that:DiffviewOpen <rev>with a single revision compares the working tree against that revision, so a branch passed on its own shows its additions as removals. Thebase...branchrange is the one that matches what a merge request displays. -
Optionally, if you use GitLab, add a
:MR <id>command at the top of that samegit.lua, above thereturn. It asks glab for the merge request's branches, fetches them, and opens the range in the right order, so reviewing an MR needs no checkout and no typing out refs:vim.api.nvim_create_user_command("MR", function(opts) local id = opts.args local raw = vim.fn.system({ "glab", "mr", "view", id, "--output", "json" }) if vim.v.shell_error ~= 0 then return vim.notify("glab failed for MR " .. id .. ":\n" .. raw, vim.log.levels.ERROR) end local ok, mr = pcall(vim.json.decode, raw) if not ok or not mr.source_branch then return vim.notify("Could not read branches for MR " .. id, vim.log.levels.ERROR) end vim.notify(("MR !%s: %s <- %s"):format(id, mr.target_branch, mr.source_branch)) vim.fn.system({ "git", "fetch", "origin", mr.source_branch, mr.target_branch }) vim.cmd(("DiffviewOpen origin/%s...origin/%s"):format(mr.target_branch, mr.source_branch)) end, { nargs = 1, desc = "Diffview for a GitLab merge request" }) -
Reload files that changed outside Neovim, in
~/.config/nvim/lua/config/autocmds.lua. LazyVim only does this onFocusGained, which a herdr pane switch does not always produce, so a file an agent rewrote in another pane can stay stale:vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI", "BufEnter" }, { group = vim.api.nvim_create_augroup("checktime_on_idle", { clear = true }), callback = function() if vim.o.buftype == "" and vim.fn.mode() == "n" then vim.cmd("silent! checktime") end end, }) -
Append my keybindings to
~/.config/nvim/lua/config/keymaps.lua:local map = vim.keymap.set -- Enter command mode without reaching for Shift map("n", ";", ":", { desc = "Enter command mode", nowait = true }) -- CTRL+N opens the file explorer (LazyVim ships the snacks explorer, not neo-tree) map("n", "<C-n>", function() Snacks.explorer({ cwd = LazyVim.root() }) end, { desc = "Explorer (root dir)" }) -
Start Neovim with
nvim. lazy.nvim bootstraps itself and installs everything on the first launch. Use:Lazyto manage plugins,:LazyExtrasto browse the other language packs, and:checkhealthto confirm the install. -
Optionally, apply Neovim in your IDE, such as in VS Code through the VSCode Neovim extension.