Skip to content(if available)orjump to list(if available)

I Use My Terminal

I Use My Terminal

75 comments

·June 23, 2025

benreesman

This is a nice setup. It's got tmux and fzf and rg and zoxide and clean-looking nvim. I'd recommend atuin, starship, bat, glow, duf, dogdns, viddy, gum/sesh, dust, btop et all if you don't have them, there's a long tail. The Awesome Terminal XYZ lists on Github have them all.

atuin is make-or-break, its a bigger deal than zoxide and being a coder without zoxide is like being an athlete with shoes for a different sport.

asciinema is a better way to do terminal videos.

Its weird that this is weird now: having your tools wired in used to be called "being a programmer". VSCode and Zed and Cursor and shit are useful additions to the toolbox, you gotta know that stuff by heart now too and you have to know which LLM to use for what, but these things are the new minimum, they aren't a replacement for anything. Even with Claude Code running hot at 4am when the PID controller is wide open, sometimes its going to trash your tree (and if it doesnt youve got it on too short a leash to be faster than gptel) and without magit? gl.

If you think you're faster than OP with stock Cursor? Get them to make a video of how to use an LLM with chops.

kragen

Being a programmer is not about configuring your development environment. It never has been. I know a relatively accomplished programmer whose preferred development environment is Unix with the ex editor, and plenty of beginners whose whizbang IDEs completely fail to compensate for their lack of understanding.

That's not to say that tooling doesn't matter at all. Just that, historically, it's been a relatively minor factor. Maybe LLMs have changed that, or are about to.

An athlete with shoes for a different sport might run 5% slower. In a winner-takes-all competitive environment, that's fatal. Most programmers, however, win by collaboration, and on a relatively smooth fitness landscape, not a winner-takes-all spike. Even in winner-takes-all regions like startups, failure always results from bigger errors than using QWERTY keyboards instead of Dvorak or vim instead of VSCode (or vice versa).

tmountain

Nice list of commands. I would add fd (author: sharkdp) to the list. It’s a find replacement, and it has great ergonomics. Also, atuin is probably the single biggest upgrade to my cli. It helps me dig up esoteric incantations that I ran six months ago with ease.

robenkleene

I love this, I've been iterating on workflows like this for something like a decade now. Over time I've tried to peel back as many of my custom layers as possible, because all of those layers have a maintenance cost.

Stock Vim (without `tmux`) can actually do most of what's shared in this post with `rg --vimgrep restore_tool | vim -c cb -` (`vim -c cb -` is my favorite feature in Vim; I find it strange that it's so rarely used or talked about).

(Since re-running the `rg` search can be undesirable, and I often like to analyze results in a terminal before opening them in Vim. I use a custom `tmux` command to copy the output of the last command [using this trick that involves adding a Unicode character to your prompt https://ianthehenry.com/posts/tmux-copy-last-command/], then I send that into Vim with e.g., `tmux saveb - | vim -c cb -`.)

msgodel

Ten years ago I threw out my massive multi-file, multi-package vim config and have been slowly building up a much simpler vimrc about 1-2 lines a year. I completely agree, defaults in old software are almost always there for a reason and you should try to understand that before changing them.

johnmaguire

> (`vim -c cb -` is my favorite feature in Vim; I find it strange that it's so rarely used or talked about).

Care to explain what it does? Trying `ls | vim -` and `ls | vim -c cb -` I don't immediately see a difference.

robenkleene

`cb[uffer]` processes the current buffer as a compile buffer, which will find `grep` format matching lines (i.e., at a minimum starting with `<path>:<line-number>:<column-number>`) and populate the quickfix list with them, and jump to the first match.

E.g., your example doesn't do anything because `ls` doesn't output `grep` format lines. So try piping the output of `grep` (you'll need flags for the line number and column number with `grep`, hence the `--vimgrep` flag above) matching the above format (or you could try `ls | sed 's/$/:0:0/' | vim -c cb -`, which will hack `ls` output to grep, and is occasionally useful).

(Note that the above hints at another useful tip, `grep` parsing is only part of what `cb[uffer]` does, it can also parse compile output, e.g., something like `gcc foo.c | vim -c cb -` will jump to the first compile error in your program and put the rest of the errors in the quickfix list).

thom

Every vim/tmux user has created an ad hoc, informally-specified, bug-ridden, admittedly probably quite fast implementation of half of Emacs.

grep_name

As someone who uses both vim/tmux and emacs for certain things (and spent years configuring and working only in emacs), my emacs setup is WAY more ad hoc, informally specified, and bug ridden than my vim+tmux setup ;)

b0a04gl

vim+tmux setups usually lean on system primitives = pipes, files, signals, scrollback so the tooling tends to stay transparent across environments. that gives them an edge in portability and debugging, especially over ssh or in constrained shells. it's just lets your workflows shaped around different guarantees so natively, it naturally makes building your own vim config an obvious choice

iLemming

> especially over ssh

Emacs has TRAMP mode - stands for “Transparent Remote (file) Access, Multiple Protocol", it lets you:

- Edit files as if they were local: /ssh:user@host:/path/to/file

- Chain connections: /ssh:jumphost|ssh:target:/file for bastion hosts

- Access Docker containers: /docker:container:/etc/config

- Edit Kubernetes pods: /kubectl:pod:/app/settings

- Sudo seamlessly: /sudo::/etc/hosts or /ssh:host|sudo::/etc/config

- And even combine them: /ssh:server|docker:container|sudo::/etc/nginx/nginx.conf

What you get? Transparent integration - Dired, Magit, etc, they just work. There's no context switching - you stay in your configured Emacs environment. Your keybindings, packages, customizations remain the same. It's multiprotocol: Supports SSH, FTP, SMB, ADB (Android), and more.

> Emacs

gertlex

I really appreciate this method of sharing workflows. Well catered to the audience. Actually was slightly hoping there'd be sound to the vid, too, but reading the list of actions after-the-fact was reasonable. I learned a few things I could do and/or approach differently in my own flows.

You mentioned the arcane keyboard shortcuts of tmux. I'm curious if you or others here have tried/use byobu (which I think of as a wrapper around tmux, basing most commands on the F# row). I was shown it a decade ago and have used it since (after a couple prior years of primitive tmux use).

jynelson

glad you've enjoyed it :) i was trying to find something that was clear while still being easy to skim.

> You mentioned the arcane keyboard shortcuts of tmux.

oh, i've remapped almost all the shortcuts in tmux. `ctrl-k` is not the default prefix and `h` is not the default key for "select pane left".

i haven't tried byobu but from skimming the readme i expect it not to have a ton other than nicer default key bindings, and i'd rather not add more layers to my terminal.

pxc

If you don't want to write a giant regex like this yourself, there are some ready-made tmux plugins that add things like this to copy-mode.

https://github.com/tmux-plugins/tmux-fpp

https://github.com/tmux-plugins/tmux-copycat

https://github.com/Morantron/tmux-fingers

https://github.com/tmux-plugins/tmux-urlview

Any configuration or plugin that leans on the built-ins is probably going to be faster, so consider that w/r/t tmux-copycat.

I also really like tmux-resurrect, which saves and restores sessions for you; tmux-continuum, which runs those automatically; and the tmux-zen plugin for Oh-My-Fish:

https://github.com/tmux-plugins/tmux-resurrect

https://github.com/tmux-plugins/tmux-continuum

https://github.com/sagebind/tmux-zen/tree/master

It's pretty easy to get a very nice tmux setup going!

jynelson

yeah, i got the original regex from tmux-copycat. but a) that regex doesn't handle `:` and b) copycat builds its own "viewer" abstraction on top of saving and restoring the pane state, which means that you can only have one action per search. my thing allows you to use normal tmux configuration syntax to bind actions to the files that are highlighted, because it reuses tmux's built-in search. note how all these plugins are either only supporting copy/paste or building their own "modes" on top, because tmux gives you very little control over highlights unless you use the built-in search.

happytoexplain

The entire blog post being in lowercase distracted me more than I thought it would.

dr_kiszonka

I am with you when it comes to texts for humans.

However, for speed, I have recently abandoned capitalization and punctuation when interacting with LLMs, unless they are critical for clarity. I wonder if this is why many folks in the AI crowd write everything in lowercase.

gouggoug

It's also interesting to see that the author themselves are clearly fighting against their own instinct to use uppercase: the first 2 items in the "here's what happens in that video:" list use uppercase.

jynelson

that's voice-to-text on iOS, i haven't found a way to turn off the auto-caps yet.

incognito124

Huh interesting, I didn't even notice that

RestartKernel

It's a stylistic choice you sometimes see people commit to. Porter Robinson (a DJ) does the same thing, and it's always struck me as a bit indulgent.

furyofantares

Kids these days. That's how many of us who grew up online in the 90s to early aughts have been doing things for 30+ years.

I think many of us abandoned it when we went professional. Or abandoned it in those contexts but still do it in others. I don't do it on HN, clearly - but I do it almost everywhere else. It's much more natural to me to skip capitals.

I believe there was also a period in the transition to ubiquitous smartphones where it wasn't an option to turn off auto-caps, or maybe there just wasn't the fine-grained control of which auto-correct you use on mobile devices that there is now. I suspect that killed some all-lowercase habits. I think that's why I ended up with a "normal" style on HN where I use caps and normal punctuation (I don't usually use periods for sentences that terminate a paragraph outside of HN.)

happytoexplain

I'm 40, but the only place I have ever abandoned proper casing is in the specific case of single-sentence text/chatroom messages (and later, 4chan posts), where I also omit the period. And even then, I only abandon sentence-casing - e.g. "I", proper nouns, etc are still capitalized. I never adopted that style in other places though, like forums. And I'm definitely not used to seeing entire chunks of prose in this more extreme version of that format (no uppercases at all, rather than just no sentence-casing).

furyofantares

Well I certainly didn't say all of us! Most people our age didn't live their whole life on forums/IRC/etc and even those who did, didn't necessarily pick that up. But also many of us did! I don't recall any forums back then where everyone did it; but I don't recall any where nobody did either.

jynelson

i see a bunch of people saying things like "you can do this in vim or emacs". it's true, you can do fuzzy finding and panes/tabs in an editor. but then you are in a box. anything that involves interacting with the terminal requires either a dedicated plugin or opening another nested terminal emulator (e.g. `:terminal` in vim). one of the things i get from my setup that's not mentioned in this post is that i can hit `git show HEAD` <highlight files and choose one> <tab> and that will put the file name in the command. this works for arbitrary commands, not just git, because it works by doing meta-processing on the terminal.

umanwizard

Just to be clear, although you can use emacs from a terminal, it’s not the default and not what most people do. So a terminal emulator opened in emacs isn’t really “nested”

jynelson

sure. this still ties you to emacs as an editor though. the interesting part of emacs to me is the meta-programming with buffers, not the editor itself; i want to be able to plug-and-play editors and keep the meta-programming.

jonjacky

The article title is actually "How I use my terminal"

progbits

This is a HN "feature" removing How if it's the first word in the title. It serves no purpose other than generating confusion, with mods saying this somehow stops clickbait. How, you wonder? Nobody knows.

Stratoscope

Reminder to anyone submitting an article: you have two hours to edit the title to fix these alterations.

rbanffy

I believe these changes are intended to defang some clickbaity titles, but you are right that it maims some perfectly good ones.

littlerbooks

Weird. I see a post titled "How to store Go pointers from assembly" literally three posts below this one.

happytoexplain

I believe the submitter can manually reject the auto-modified title, but they have to notice that it was modified.

(I could be wrong about that)

null

[deleted]

Hard_Space

Thought that this was going to be a 'There Will Be Blood' spoof.

(In case not obvious, current title is 'I use my terminal')

null

[deleted]

IAmBroom

I use your sudo?

adolph

I use your

  sudo !!

osmsucks

I thought this was going to be a blog post about somebody using a terminal emulator they wrote.

fitsumbelay

noticed this too after skimming the post, feels like the full title = "I use my terminal (and so should you )"

Plus one for pro-terminal posts. As a chromebooker I've found that all I need is terminal and browser. Switching to my Mac OS seems kinda maximalist and I rarely use much outside of the terminal and, you know, more browsers

babelfish

HN will automatically trim some common prefixes and suffixes from title submissions

indigodaddy

This is cool and fine, but I just use a browser accessible Linux desktop using KASM for a Docker image-based/isolated/ephemeral (except for homedir/profile persistence) “local development with full Linux desktop” environment that I can use from anywhere.

And for package persistence I have an extra configuration to use Brew. It all works beautifully and very fast/no noticeably latency on a capable VM/vps etc:

https://docs.linuxserver.io/images/docker-kasm/

https://gist.github.com/jgbrwn/3787259bc7d00fce3fdd4b5bd579c...

https://gist.github.com/jgbrwn/28645fcf4ac5a4176f715a6f9b170...

jynelson

one of the things i want from a terminal is to run things in a dev container by default and have an explicit button for syncing the changes in that container to the host. the difference between this and messing with docker is that it uses the host system as the base layer.

indigodaddy

gotcha, so more of a develop locally in a docker container and then push/deploy to Prod kinda thing. I like it. Could actually do same workflow with a KASM workspace using a Docker Rootless image which allows you to use docker.

b0a04gl

terminal scrollback is the only UI we don't treat as queryable state. op's setup shows how much context we're missing away a lot of rg output, file paths, stack traces, build logs they're all already right there in cluttered state.

if shells exposed a scrollback api with line refs and structural tagging, we could annotate paths, link to buffers, diff last two runs, all without re executing anything. that would cut through half the indirection in current workflows. tmux's regex jump is a hack but it hints at a deeper model. scrollback should be its own memory layer

msgodel

That's the tty or the thing on the other end of the pty (ie your VTE like Xterm) which would have to do that. The shell has no access to any of it.

There is an xterm command for writing the scrollback buffer to a file so in theory if you wanted a hack to enable it today you could use that + grep (or even trigger it with something xdotool if you wanted to automate it.)

jynelson

yes!! one of the things i really want from a terminal is structured metadata, it allows you to build so much on top. right now anything remotely close requires parsing a bunch of ansi escapes.

Analemma_

PowerShell got so close to doing this, and then they fumbled it right at the finish line by having terminal objects be binary data instead of structured objects in some kind of serialized format. PowerShell is honestly awesome for a bunch of reasons and getting to query pipe objects instead of parsing them is great, but the binary blobs hold it back from being perfect.

Several attempts have been made to do similar things in Unix, but there's a massive ecosystem problem: four decades of classic tooling has to be totally rewritten to get this kind of support. I don't see it happening without some kind of industry champion who can throw their weight around to force it on people.

jynelson

i have ideas about how to strangler-pattern this so that it doesn't require a "flag day" where everyone switches over at once. i have about 15 paragraphs of this written up locally i need to turn into a blog post ^^

klntsky

It is sad that we have to know how to configure tens of small utilities just to be productive. I ended up using emacs with some packages that I configure minimally, after spending a few hundreds of hours on ricing the shell, file managers, tmux, etc

agentultra

Emacs is why I can't go back to terminals.

iLemming

With Emacs one can do some shit in terminal that otherwise would just sound absurd. Like

- in Emacs' Eshell, one can pipe results in and out of buffers, e.g., you can run a command, then pipe it to grep/ripgrep, then pipe the results into a buffer (without any intermediate files).

- Conversely, you can read a buffer content and pipe it into a command.

- Or you can do simple calculations, you just need to use prefix notation e.g. `* 3 42` or `(* 2 pi)`.

- You can run regular emacs functions, like `dired .` or `magit-status`, `find-file ~/foo` or `(calendar)`.

- Or you can use Emacs vars and functions directly, e.g., `cd $org-directory`, or `cd (projectile-project-root)`, or `mkdir (format-time-string "backup-%Y%m%d")`

- You can absolutely delegate some (potentially long running) tasks to run in an outside terminal. I wrote this command eshell-send-detached-input-to-kitty¹, it uses Kitty Terminal's socket control feature.

There are integrations that you can only dream about, one recent example is John Wiegley (creator of Eshell) and Karthik (author of gptel package) having to experiment with piping things in and out of LLMs.

Sure, the backwards is also possible - you can emacs from a terminal, but terminaling from inside emacs is way more cooler.

___

¹ https://github.com/agzam/.doom.d/blob/main/modules/custom/sh...

vyaa

I haven’t delved into emacs yet. Don’t you still have it configure it and all its tools?

umanwizard

emacs is a lot easier to configure than anything else IMO because it’s self-documenting. If you want to know how to use or configure some command it’s trivially easy to jump to the source code of that command and just see how it works (or modify it, step through it with a debugger, etc). You can’t do that in any other environment as far as I’m aware.

That said, yeah, it certainly doesn’t Just Work out of the box the way something like vscode does.

kjkjadksj

I make do with just nano and basic pane/window/sockets in tmux. Certainly didn’t put in a few hundred hours learning this. Not even a few hundred minutes.

bowsamic

I hate configuring things. I tried to use PyCharm and it works great until it doesn't, then it's a nightmare. For example, the ruff support is non-existent and the only plugin is broken as hell. I think at some point you just have to accept it won't be perfect, but it is sad because I can "imagine" the perfect IDE. I just don't have the time or energy to make it reality, and apparently neither do Jetbrains

iLemming

I don't think it's Jetbrain's fault, even though I have not used their products for almost a decade. Python ecosystem is finicky - too many options - it's hard to decide which things you want and need - black or yapf or ruff, flake8, rope, mypy, pydocstyle, pylint, jedi; there are multiple lsp server options (none of which is ideal), you get to know things like what the heck 'preload' plugin is - the docstring for lsp-pylsp-plugins-preload-enabled just says "Enable or disable the plugin", etc.

Trying to bootstrap a Python setup "that just works™" is also a common struggle e.g. in Emacs world. Python tools are just a bunch of contraptions built with fiddlesticks and bullcrap. Anyone who tells you differently either already have learned how to navigate that confusing world and totally forgot "the beginner's journey"; or too new and have not tussled with its tooling just yet; or simply don't know any better.

add-sub-mul-div

The title is messed up. It's the most HN-coded thing to take something that isn't a problem and overconfidently apply automation to it and make it worse.