workbench§
Everything I open to get work done. fish in Ghostty, uv, bun and fnm for the languages, Zed to write code, and a handful of apps. Almost all of it installs with one curl or one paru line, and I keep forgetting which one, so they’re all written down here.

fastfetch on this machine.
The machine§
An ASUS ROG Zephyrus G14 from 2022, the GA402RJ.
| CPU | AMD Ryzen 9 6900HS, 8 cores, 16 threads, up to 4.9 GHz |
| GPU | Radeon RX 6700S, plus the Radeon 680M inside the CPU |
| Memory | 38.4 GiB, as the system sees it |
| Disk | 1 TB, btrfs |
| Screen | 14”, 2560×1600 at 120 Hz, scaled 1.5× |
| Second screen | a 24” Samsung (LF24T35), 1920×1080 at 60 Hz |
CachyOS set up the drivers for both GPUs on its own, there’s more on that in desktop.
The shell§
The shell is fish, version 4.9. It suggests commands from history as you type and knows the flags of most programs, with no setup.
What CachyOS already sets up§
CachyOS ships its own fish config, the cachyos-fish-config package, and my config.fish loads it on the first line. It brings:
- a notification when a long command finishes. Anything that takes more than 10 seconds pops a notification when it’s done, through the done plugin.
lswith icons.ls,la,llandltare all eza, folders first.- man pages in color, piped through bat.
!!and!$like in bash.sudo !!reruns the last command with sudo.- a pile of aliases, like
update(picks the fastest mirrors, then updates),cleanup(removes orphan packages) andjctl(errors from this boot’s log). fastfetchevery time a terminal opens. I turned this one off.
What I added§
This is my whole config.fish:
source /usr/share/cachyos-fish-config/cachyos-config.fish
# overwrite greeting to disable fastfetch
function fish_greeting # (1)!
end
# bun
set --export BUN_INSTALL "$HOME/.bun" # (2)!
set --export PATH $BUN_INSTALL/bin $PATH
# aws
set --export AWS_PROFILE ranqia-prod # (3)!
set --export AWS_REGION us-east-1
# Added by jcode installer
if not contains "/home/adeildo/.local/bin" $PATH
set -gx PATH "/home/adeildo/.local/bin" $PATH
end
# Pi
fish_add_path "/home/adeildo/.local/share/fnm/node-versions/v24.19.0/installation/bin" # (4)!
- The CachyOS config defines
fish_greetingto runfastfetch. Defining it again, empty, wins because it comes later. Terminals open straight to the prompt now. - The bun installer wrote these two lines.
- The AWS profile and region I use for work, so the
awsCLI and Terraform pick them up without flags. - Pi’s installer wrote this one. It installs Pi with the
npmfrom Node 24.19.0 and puts that folder on thePATH, so if I ever switch the default Node version, this line needs to change too.
Everything else fish loads comes from conf.d/. That’s where installers leave their files: fnm’s lives there, and so does the fish wrapper for claude-code-profiles.
The prompt§
The prompt is Tide. I install it with fisher, which is in the Arch repos, and then run the setup wizard:
The wizard shows real previews and you pick with the keyboard. Mine ended up on one line, with no frame:
- left side, the Arch icon, the folder I’m in and the git branch, with counts for staged, changed and untracked files.
- right side, things that only show up when they matter. The exit code of a command that failed, how long a slow command took, the Python virtualenv, the Node version inside a Node project, and the AWS profile.
Languages§
Each language gets its own manager, installed from its own script and not from pacman. They live in my home folder and don’t get in the way of the system packages.
uv manages Python versions, virtualenvs and packages, all in one tool.
It lands in ~/.local/bin, which is already on the PATH. When I need a new package in a project, it’s always uv add, never a hand edit to pyproject.toml, so the lockfile stays in sync.
bun runs JavaScript and TypeScript, installs packages and runs scripts, and it’s fast at all of it.
It installs into ~/.bun, adds two lines to config.fish (the ones marked above) and drops its completions in ~/.config/fish/completions/. The global packages I install with bun add -g are mostly agent tools, they get their own page in agents.
This is the one I always forget the name of. It’s fnm, Fast Node Manager. It does the same job as nvm, reads the same .nvmrc and .node-version files, but it’s a single Rust binary and it works in fish without any adapter.
The script installs into ~/.local/share/fnm and, when your shell is fish, writes ~/.config/fish/conf.d/fnm.fish. Then:
My default is Node 24.19.0.
Make it switch versions by itself
The installer sets fnm up without --use-on-cd, so walking into a project with a .nvmrc doesn’t change the Node version. I only noticed while writing this page. Adding the flag to the line in conf.d/fnm.fish fixes it:
Now cd into a project picks the version from its .nvmrc or .node-version, and says so when that version isn’t installed yet.
Editor§
I write code and open files in Zed.
That puts the app in ~/.local/zed.app and the zed command in ~/.local/bin. It updates itself. zed . opens the current folder.
The settings file is the one thing I copy to every new machine. Here’s what each part does, grouped:
"languages": {
"Python": {
"tab_size": 4,
"format_on_save": "on",
"language_servers": ["ty", "ruff"] // (1)!
},
"TypeScript": {
"tab_size": 2,
"format_on_save": "on",
"inlay_hints": { "enabled": false } // (2)!
},
"TSX": { "inlay_hints": { "enabled": false } }
}
- By default Zed runs basedpyright and ruff on Python, and keeps ty turned off. This list replaces the default completely. ty checks the types, ruff lints and formats, and basedpyright never starts. Both come from Astral, the same people behind uv.
- The inline type hints are on everywhere else, but not in TypeScript.
Saving a Python file runs ruff’s formatter and sorts the imports. That second part is Zed’s default for Python, I didn’t have to add it.
| Setting | What it does |
|---|---|
theme: DankShell Dark Transparent |
the theme DMS writes with the wallpaper colors, so Zed changes along with everything else |
icon_theme: Material Icon Theme |
the file icons from VS Code’s Material theme |
buffer_font_family: JetBrainsMono Nerd Font Mono |
JetBrains Mono, with the Nerd Font icons |
buffer_font_weight: 350 |
a bit thinner than the regular 400 |
buffer_font_features: calt, liga |
ligatures, so => and != render as one symbol |
ui_font_size: 17 |
menus and panels one point bigger than the default |
colorize_brackets |
rainbow brackets, each nesting level gets a color |
indent_guides.coloring: indent_aware |
the indent lines are colored by depth too |
show_whitespaces: trailing |
dots only for spaces left at the end of a line |
unnecessary_code_fade: 0.4 |
unused imports and variables fade a bit more |
gutter.folds: false |
no fold arrows next to the line numbers |
gutter.min_line_number_digits: 0 |
the gutter is only as wide as the line numbers need |
gutter.git_gutter_width: 5 px |
the git change bars have a fixed width |
soft_wrap: editor_width |
long lines wrap at the edge of the window |
show_wrap_guides: false |
no vertical ruler at 80 columns |
| Setting | What it does |
|---|---|
project_panel.dock: left |
the file tree on the left, like VS Code |
git_panel, outline_panel, collaboration_panel: left |
every panel on the left too |
terminal.dock: right |
the terminal opens on the right, next to the code |
bottom_dock_layout: left_aligned |
the bottom dock starts at the left edge of the window |
project_panel.hide_root |
no root folder row at the top of the tree |
project_panel.indent_size: 13 |
a tighter tree, 13 px per level |
project_panel.entry_spacing: standard |
less space between the files in the tree |
active_pane_modifiers.inactive_opacity: 0.7 |
splits I’m not typing in are dimmed |
title_bar.button_layout: “” |
no minimize, maximize and close buttons, niri doesn’t need them |
title_bar.show_branch_status_icon |
the branch icon in the title bar shows the git status |
status_bar.show_active_file |
the name of the open file at the bottom |
tab_bar.show_nav_history_buttons: false |
no back and forward arrows in the tab bar |
search.button, debugger.button: false |
two fewer buttons in the status bar |
tabs.file_icons, tabs.git_status |
tabs get the file icon and turn yellow or green when the file changed |
tabs.show_diagnostics: errors |
tabs mark files that have errors |
file_finder.modal_max_width: medium |
a wider file finder, so long paths fit |
| Setting | What it does |
|---|---|
base_keymap: VSCode |
VS Code shortcuts, the ones my hands already know |
autosave: on_focus_change |
a file saves when I switch to another tab or panel |
use_smartcase_search |
search ignores case, until I type a capital letter |
scroll_sensitivity: 2 |
scrolls twice as far per wheel step |
autoscroll_on_clicks |
clicking near the edge of the editor scrolls it |
hide_mouse: never |
the mouse stays visible while I type |
inlay_hints.enabled |
inline type and parameter hints, off by default |
diagnostics.inline.enabled |
errors show at the end of the line, not only on hover |
git.inline_blame.padding: 1 |
the blame text sits right after the code |
default_open_behavior, cli_default_open_behavior: new_window |
each project opens in its own window, and with niri that means its own column |
session.trust_all_worktrees |
skips the “do you trust this folder?” question. Project settings and language servers start on their own, so only turn it on if you only open code you trust |
| Setting | What it does |
|---|---|
disable_ai |
turns off every AI feature in Zed. The agent panel, the inline assistant and edit predictions are all gone |
edit_predictions.provider: none |
no autocomplete suggestions from a model |
telemetry.diagnostics, telemetry.metrics: false |
no crash reports and no usage data sent to Zed |
The file still has an agent section with models and a Claude Code server, from before I turned AI off. With disable_ai on, none of it runs. My AI work happens in the terminal, see agents.
The whole settings.json
download it and drop it in ~/.config/zed/settings.json.
// Zed settings
//
// For information on how to configure Zed, see the Zed
// documentation: https://zed.dev/docs/configuring-zed
//
// To see all of Zed's default settings without changing your
// custom settings, run `zed: open default settings` from the
// command palette (cmd-shift-p / ctrl-shift-p)
{
"preview_tabs": {
"enable_preview_from_file_finder": false,
"enabled": true
},
"tab_bar": {
"show_pinned_tabs_in_separate_row": false,
"show_tab_bar_buttons": true,
"show_nav_history_buttons": false,
"show": true
},
"debugger": {
"button": false
},
"search": {
"button": false
},
"status_bar": {
"show_active_file": true,
"line_endings_button": false,
"active_language_button": true
},
"relative_line_numbers": "disabled",
"colorize_brackets": true,
"lsp_document_colors": "inlay",
"auto_signature_help": false,
"scroll_beyond_last_line": "one_page",
"markdown_preview_font_family": "Noto Sans",
"buffer_font_weight": 350.0,
"default_open_behavior": "new_window",
"proxy": "",
"diff_view_style": "split",
"agent_servers": {
"claude-acp": {
"default_config_options": {
"mode": "auto",
"effort": "medium"
},
"type": "registry"
}
},
"disable_ai": true,
"base_keymap": "VSCode",
"cli_default_open_behavior": "new_window",
"outline_panel": {
"dock": "left",
},
"collaboration_panel": {
"dock": "left",
},
"terminal": {
"button": true,
"font_family": "JetBrainsMono Nerd Font Mono",
"default_height": 350.0,
"font_size": 13.0,
"dock": "right"
},
"agent": {
"tool_permissions": {
"tools": {
"write_file": {
"default": "allow",
},
},
},
"inline_assistant_model": {
"provider": "copilot_chat",
"model": "gpt-5.2-codex",
"enable_thinking": false,
},
"default_profile": "write",
"dock": "right",
"default_height": 400,
"default_model": {
"enable_thinking": true,
"provider": "copilot_chat",
"model": "claude-haiku-4.5",
},
},
"tabs": {
"file_icons": true,
"git_status": true,
"show_diagnostics": "errors",
},
"git_panel": {
"collapse_untracked_diff": true,
"dock": "left",
"tree_view": false,
},
"file_finder": {
"modal_max_width": "medium",
},
"project_panel": {
"git_status_indicator": false,
"diagnostic_badges": false,
"folder_indicator": "icon",
"entry_spacing": "standard",
"dock": "left",
"hide_root": true,
"auto_fold_dirs": true,
"indent_size": 13.0,
"git_status": true,
"show_diagnostics": "all",
},
"title_bar": {
"button_layout": "",
"show_menus": false,
"show_user_picture": true,
"show_user_menu": true,
"show_onboarding_banner": true,
"show_branch_status_icon": true,
},
"seed_search_query_from_cursor": "always",
"centered_layout": {
"right_padding": 0.1,
"left_padding": null,
},
"active_pane_modifiers": {
"inactive_opacity": 0.7,
},
"telemetry": {
"diagnostics": false,
"metrics": false,
},
"git": {
"path_style": "file_name_first",
"hunk_style": "staged_hollow",
"branch_picker": {
"show_author_name": true
},
"blame": {
"show_avatar": true
},
"git_gutter": "tracked_files",
"diff_base": "head",
"inline_blame": {
"min_column": 0,
"location": "inline",
"show_commit_summary": false,
"padding": 1,
},
},
"inlay_hints": {
"enabled": true,
"show_type_hints": true,
"show_parameter_hints": true,
"show_other_hints": true,
},
"edit_predictions": {
"mode": "subtle",
"provider": "none",
},
"diagnostics": {
"button": true,
"inline": {
"padding": 1,
"enabled": true,
},
},
"show_whitespaces": "trailing",
"allow_rewrap": "in_comments",
"toolbar": {
"code_actions": false,
},
"gutter": {
"min_line_number_digits": 0,
"folds": false,
"breakpoints": true,
"runnables": true,
"git_gutter_width": {
"custom": 5.0
},
"line_numbers": true,
},
"indent_guides": {
"background_coloring": "disabled",
"coloring": "indent_aware",
},
"scrollbar": {
"show": "auto",
"git_diff": true,
"diagnostics": "all",
"selected_symbol": true,
},
"use_smartcase_search": true,
"autoscroll_on_clicks": true,
"scroll_sensitivity": 2.0,
"autosave": "on_focus_change",
"cursor_shape": "bar",
"buffer_line_height": "comfortable",
"buffer_font_family": "JetBrainsMono Nerd Font Mono",
"buffer_font_features": { "calt": true, "liga": true },
"preferred_line_length": 80,
"show_wrap_guides": false,
"unnecessary_code_fade": 0.4,
"hide_mouse": "never",
"soft_wrap": "editor_width",
"icon_theme": {
"mode": "system",
"light": "Material Icon Theme",
"dark": "Material Icon Theme",
},
"session": {
"trust_all_worktrees": true,
},
"bottom_dock_layout": "left_aligned", // espaço que terminal ocupa.
"ui_font_size": 17.0,
"buffer_font_size": 15.0,
"theme": {
"mode": "system",
"light": "DankShell Light",
"dark": "DankShell Dark Transparent",
},
"languages": {
"Python": {
"tab_size": 4,
"format_on_save": "on",
"colorize_brackets": true,
"language_servers": [
// Enable ty and ruff,
// Other built-in servers (basedpyright, pyright, pylsp)
// are disabled by being omitted from this list.
"ty",
"ruff",
],
},
"TypeScript": {
"tab_size": 2,
"format_on_save": "on",
"colorize_brackets": true,
"inlay_hints": { "enabled": false },
},
"TSX": { "inlay_hints": { "enabled": false } },
},
"lsp": {},
}
Extensions§
Zed already understands the big languages by itself. Extensions fill in the rest, and I install them from the extensions page (Ctrl+Shift+X).
| Extension | What it adds |
|---|---|
| Material Icon Theme | the file icons |
| oxc | Oxlint and Oxfmt, a linter and a formatter for JavaScript and TypeScript, written in Rust |
| Comment | highlights TODO, FIXME, NOTE and friends inside comments |
| Git Firefly | colors for .gitignore, .gitattributes, git config and the interactive rebase file |
| Dockerfile | Dockerfile and Docker Compose |
| Terraform | Terraform and HCL |
| Prisma | Prisma schemas |
| SQL | SQL highlighting |
| TOML | TOML, for pyproject.toml and friends |
| Make | Makefiles |
| HTML | HTML |
| Emmet | Emmet abbreviations, ul>li*3 then Tab |
| QML | QML, the language DMS and its plugins are written in |
Apps§
-
Google Chrome
The regular, stable Chrome. It’s in the AUR as
google-chrome. -
Ghostty
The terminal, opened with Super+Enter. It came with the DMS installer, and its theme is
dankcolors, which DMS generates from the wallpaper. Font is JetBrains Mono Nerd Font at 12. -
Nautilus
GNOME’s file manager. Plain, and it looks great with the DMS colors. It’s also what opens when an app asks me to pick a file, see desktop.
-
Discord
Straight from the Arch repos.
-
Spotify
From the AUR. What’s playing is also what paints the system, with Music Theme.
-
Steam
From the Arch repos.
cachyos-gaming-metaadds CachyOS’s own Proton and Wine next to it.
All of them in one go:
paru comes with CachyOS. It works like pacman, but it also builds packages from the AUR, which is where Chrome and Spotify live.
Command-line tools§
The rest of what I installed by hand, straight from paru:
| Package | What for |
|---|---|
github-cli |
gh, for pull requests from the terminal. It’s also git’s login for GitHub |
docker docker-compose docker-buildx |
containers. My user is in the docker group, so no sudo |
aws-cli-v2 terraform sops jq |
work infrastructure. sops keeps secrets encrypted inside the repo |
tailscale |
the Tailscale VPN |
amdgpu_top |
what each GPU is doing, per process |
dua-cli |
finds what’s eating the disk, dua i for the interactive view |
ttf-jetbrains-mono-nerd |
the font in the terminal and in Zed |