{"slug": "claude-code-in-practice-rethinking-terminal-workflows-from-zsh-autocomplete-to", "title": "[Claude Code in Practice] Rethinking Terminal Workflows: From zsh Autocomplete to Search and Diff Toolchains", "summary": "A developer revamped their terminal workflow to improve both human and AI-assisted command-line efficiency, installing lightweight zsh plugins for autocomplete and history search, and adopting modern alternatives like eza, bat, and zoxide. They also integrated these tools with Claude Code's permission system to reduce manual approval prompts for read-only commands, using the fewer-permission-prompts skill to whitelist safe operations.", "body_md": "When using Claude Code for tasks, there have always been two minor frictions that I hadn't seriously addressed until now.\n\nThe first is that the shell itself is too bare-bones: there's nothing in `~/.zshrc`\n\nexcept for two lines of `PATH`\n\n. No auto-completion, no command history. Navigating history requires pressing the up arrow repeatedly, and even then, similar commands must be manually edited. The second is when collaborating with Claude Code, some commands that are clearly read-only and have no side effects (listing files, checking versions, curling a README) require a manual \"allow\" click every time. This back-and-forth breaks the flow.\n\nThis post records the process of tackling both issues at once: how tools were chosen, what pitfalls were encountered, and how it was eventually integrated with Claude Code's permission system.\n\nI haven't installed oh-my-zsh and didn't want to carry a whole framework for just two features, so I picked the two smallest, sufficient packages:\n\n`Ctrl+Space`\n\nor `→`\n\nto accept.\n\n```\nbrew install zsh-autosuggestions zsh-completions\n```\n\nCombined with history settings, the up/down keys can filter history based on current input instead of just scrolling through everything:\n\n```\n# --- Command History Settings ---\nHISTFILE=~/.zsh_history\nHISTSIZE=10000\nSAVEHIST=10000\nsetopt SHARE_HISTORY # Share history across multiple terminal windows\nsetopt HIST_IGNORE_DUPS\nsetopt HIST_IGNORE_ALL_DUPS\nsetopt HIST_FIND_NO_DUPS\nsetopt INC_APPEND_HISTORY # Write to history file immediately upon command entry\n\nautoload -Uz up-line-or-beginning-search down-line-or-beginning-search\nzle -N up-line-or-beginning-search\nzle -N down-line-or-beginning-search\nbindkey \"^[[A\" up-line-or-beginning-search\nbindkey \"^[[B\" down-line-or-beginning-search\n```\n\nAfter installing the packages and adding the settings, theoretically, restarting the terminal should work—but it wasn't that smooth.\n\nOnce auto-completion was set up, I added colors as well:\n\n`ls -G`\n\n: Different colors for folders, executables, and links.`grep --color=auto`\n\n: Highlights matched keywords in red.\n\n```\nexport CLICOLOR=1\nexport LSCOLORS=GxFxCxDxBxegedabagaced\nalias grep='grep --color=auto'\n\nsource /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh\n```\n\nHandled fonts too: Ghostty's config file (`~/Library/Application Support/com.mitchellh.ghostty/config.ghostty`\n\n) didn't specify a font size and defaulted to the system's 13. Adding `font-size = 16`\n\nsolved it.\n\n`ls`\n\n, `cat`\n\n, and `cd`\n\nwith Smarter Versions\nColor and auto-completion are infrastructure; next, I added modern alternatives for three common commands. The selection criterion was simple: **single executable, no background daemon, and no impact on startup speed.**\n\n| Command | Alternative | Benefit |\n|---|---|---|\n`ls` |\n`eza --icons` |\nColor, icons, tree structure (`lt` ) |\n`cat` |\n`bat --paging=never` |\nSyntax highlighting, line numbers |\n`cd` (helper) |\n`zoxide` |\nRemembers frequent folders; `z proj` jumps directly |\n\nI evaluated `fzf`\n\nbut didn't install it this time—my current habits don't require fuzzy searching history/files yet. I'll add it if I feel a bottleneck later.\n\nThe previous items were for \"user experience\"; this one is for \"Claude Code speed.\" Claude Code's built-in search tool already uses ripgrep (`rg`\n\n), and `jq`\n\nis already installed, so these three were missing:\n\n`find`\n\n; simple syntax, fast, especially noticeable when listing files.`difft`\n\n): Syntax-aware diff. It recognizes when a function has been moved rather than deleted and rewritten.\n\n```\nbrew install fd ast-grep difftastic git-delta\n```\n\n`git-delta`\n\nis mainly for human-readable `git diff`\n\n. It's unrelated to Claude Code, but I installed it anyway.\n\nA new problem emerged after installing the tools: the first time Claude Code calls these new commands, it still asks for permission. Using the `fewer-permission-prompts`\n\nskill to scan recent session transcripts, I identified frequently run, truly read-only commands and compiled a whitelist:\n\n```\n{\n  \"permissions\": {\n    \"allow\": [\n      \"Bash(curl -s https://raw.githubusercontent.com/*)\",\n      \"Bash(curl -s \\\"https://api.github.com/*)\",\n      \"Bash(brew list*)\",\n      \"Bash(xcodes list*)\",\n      \"Bash(xcodebuild -version)\",\n      \"Bash(curl -sI *)\",\n      \"Bash(difft *)\",\n      \"Bash(delta *)\"\n    ]\n  }\n}\n```\n\n`fd`\n\n, `rg`\n\n, and `jq`\n\nare not on the list, not because they were missed, but because Claude Code already includes them as built-in, auto-allowed read-only commands.\n\n`compinit`\n\ncomplaining about \"insecure directories\"\nAfter installing packages and restarting the terminal, the first launch showed:\n\n```\nzsh compinit: insecure directories, run compaudit for list.\n```\n\n`compaudit`\n\nrevealed the issue was that the `/opt/homebrew/share`\n\ndirectory permissions were too open (group write access). `compinit`\n\nchecks permissions before loading completion scripts; if any directory is \"writable by others,\" it refuses to load to prevent malicious scripts from being injected into the completion path. The fix is the official Homebrew recommendation:\n\n```\nchmod go-w /opt/homebrew/share\nchmod -R go-w /opt/homebrew/share/zsh\nrm -f ~/.zcompdump*\n```\n\nClearing the cache to let it rebuild solved the problem.\n\n`zsh-syntax-highlighting`\n\nmust be the last line\nThe official documentation is clear: this line must be the **last thing executed** in `.zshrc`\n\n. If placed before `zsh-autosuggestions`\n\nor other `bindkey`\n\nsettings, syntax highlighting and auto-suggestions may interfere, and key bindings might fail. I specifically moved it to the very end of the file.\n\n`ast-grep`\n\nwas intentionally left out of the whitelist\n`ast-grep`\n\nis missing from the whitelist on purpose. By default, it's a read-only search, but adding the `-U`\n\n/ `--update-all`\n\nflag allows it to rewrite files. Permission rules use prefix matching, so I can't allow only the \"no `-U`\n\n\" usage. Opening a broad rule like `Bash(ast-grep *)`\n\ntheoretically allows file-modifying usage as well.\n\nThis aligns with the original logic for `sed`\n\n: only \"read-only expressions\" are auto-allowed; any usage with in-place editing still prompts for permission. Rather than re-evaluating the risk, I followed the same standard.\n\nThis terminal environment overhaul was essentially about optimizing \"human typing\" and \"Claude Code execution\" separately:\n\n`zsh-autosuggestions`\n\n+ history filtering means almost no re-typing repetitive commands.`eza`\n\n, and `bat`\n\nmake outputs instantly readable.`zoxide`\n\nreplaces memorizing paths, and `fd`\n\nreplaces the slow `find`\n\n.`ast-grep`\n\nadds structural search that plain text matching can't do, and `difftastic`\n\nmakes diff results closer to actual changes.`ast-grep -U`\n\n).The core principle for tool selection remained the same: single executable, no background daemons, and avoiding frameworks where possible. The real time-consumer was deciding \"whether to whitelist this\"—speed is secondary; the priority is ensuring a command that can modify files isn't accidentally wrapped in a seemingly safe, generic rule.", "url": "https://wpnews.pro/news/claude-code-in-practice-rethinking-terminal-workflows-from-zsh-autocomplete-to", "canonical_source": "https://dev.to/evanlin/claude-code-in-practice-rethinking-terminal-workflows-from-zsh-autocomplete-to-search-and-diff-4jdk", "published_at": "2026-08-14 16:56:08+00:00", "updated_at": "2026-08-14 17:05:35.173293+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-agents"], "entities": ["Claude Code", "zsh", "eza", "bat", "zoxide", "ripgrep", "difftastic", "git-delta"], "alternates": {"html": "https://wpnews.pro/news/claude-code-in-practice-rethinking-terminal-workflows-from-zsh-autocomplete-to", "markdown": "https://wpnews.pro/news/claude-code-in-practice-rethinking-terminal-workflows-from-zsh-autocomplete-to.md", "text": "https://wpnews.pro/news/claude-code-in-practice-rethinking-terminal-workflows-from-zsh-autocomplete-to.txt", "jsonld": "https://wpnews.pro/news/claude-code-in-practice-rethinking-terminal-workflows-from-zsh-autocomplete-to.jsonld"}}