entering text in the terminal is complicated https://jvns.ca/blog/2024/07/08/readline/
@b0rk One to add to your list, in the emacs bindings you can use Ctrl-P for previous command (i.e.= up arrow)
@cscaim yea i intentionally left out almost all of the keyboard shortcuts because I don't use them
someone in the replies elsewhere pointed out that Ctrl+J = 10 in the ASCII table = LF ("line feed") = Enter (because J is the 10th letter of the alphabet)
so Ctrl+J is the same as pressing enter
which I don't have any practical use for but is kind of cool
(edit: some corrections in this reply: https://pgh.social/@ben/112752235264922484)
@b0rk This isn't quite right in a few ways. LF is decimal 10, ascii 0x0a. It is 10 because it's the 10th letter of the alphabet, though. But it's not the same as pressing enter except in cooked tty modes, where the terminal driver converts the return key (^M, \r, ASCII 13 / 0x0d) to a newline (^J, LF, 10/0xa) which your program then sees as its input.
@b0rk Very nice article, (I haven't quite finished yet).
I wanted to point out that ctrl-U is NOT delete the whole line for readline (long ago I had expected it to be that and got surprised).
It is:
unix-line-discard (C-u)
Kill backward from point to the beginning of the line.
The killed text is saved on the kill-ring.
Which you will ONLY discover if you use it after having moved your cursor to the middle (or front) of the line. In which case you'll need to followup w/ ctrl-K
@b0rk NP, sorry if that came off as "reply guy". I once spent a weekend curled up with stty.
@ben not at all, appreciate it -- edited the original post to link to your comment
@b0rk You use ctrl-j in some contexts in Emacs for what I think is roughly that reason? I think it’s things like regex find/replace where you can’t hit enter or you’ll execute the command prematurely? My memory is a bit fuzzy.
@b0rk yes, direct mapping from ctrl codes to characters. Many quirks in this “table” - a lot more than the original “ASCII”.
also someone elsewhere left a comment like "I CAN’T BELIEVE IT TOOK HER 15 YEARS TO LEARN BASIC READLINE COMMANDS". those comments are very silly and I'm going to keep writing “it took me 15 years to learn this basic thing" forever because I think it's important for people to know that it's normal to take a long time to learn “basic" things
@b0rk haha yeah I have been doing this a lot longer than 15 years and this is the first time I have really _thought_ about how terminals work
one thing I don't get is: If ^W isn't handled by readline (or friends), what *is* doing it? How do backspace and word-backspace work?
How... does character entry work at all??
@njvack honestly I didn't dig into that in the post largely because I don't understand it well either, I think it's the "unix terminal driver", but like what is that?? how does it work? it's a weak point for me and I'm hoping to understand it at some point
@b0rk great writeup! I learned quite a bit, even though like you I have been using the command line for 15+ years. Had heard of most of this stuff before but didn't really every dig into a deeper understanding, just considered it all "arcane terminal crap, probably sucks for legacy reasons". rlwrap was a really cool thing to learn about though, had never heard of it until reading your post.
@b0rk Comments like that (which I have heard over and over and over all the way back to my baby web dev days making my first website in 2004) only end up ensuring that overly sensitive autodidacts such as myself write off programming as a viable hobby/career forever…
@b0rk 💯 That comment is so 🤦♀️. I use a lot of things every day and do not have the time to become an expert on every single one of them, use a tiny fraction of what is possible with readline, bash, (n)vim, … That makes your approach so interesting, because you choose a topic and then do: “Well, I maybe somehow know this exists, maybe even use some of it often, but now I really want to know what's going on and maybe write a zine on it.”
@HeptaSean i wrote a thread about why I only write zines about topics that I already feel confident with recently https://social.jvns.ca/@b0rk/112631771170300190
@b0rk I learned about control-e in terminal to move to the end of the line after decades of using control-a to get to the beginning of the line. 🤷🏻
@dax i think those people are very real and i really appreciate them but I’m not one of them
@b0rk I've been doing this for 10 years longer than *that* and there was news to me in this article too. Thanks for all the great information and thanks for not letting these asinine commenters stop you, modeling this sort of openness to new information is super important.
(I accidentally discovered the *particular* fact in question early on by accident, because I'm a long-time Emacs user, and muscle-memory just had me trying those navigation keys…)
@b0rk I recently started trying Atuin and am in transition from bash to fish as my shell, but found some slightly buggy behaviour using bash with atuin. Has it been relatively smooth for you? I'm still unsure how I feel about it; I like the functionality but occasional like UI bugs and minor delay loading history has added some friction .
@mattcen I only use it with fish — it has been pretty smooth but I also use it infrequently, maybe only every other day. i mostly rely on fish’s default history features instead so if I’m going into atuin I don’t mind if it’s a little slow
@mattcen i do think atuin is a bit “heavier” than i’d prefer for searching my history in general, i only use it if I can’t immediately find the thing with my normal history search
@b0rk@social.jvns.ca I know you omitted the ones you don't personally use, but I find Ctrl-K quite useful as well for clearing out everything after the cursor. This is really useful when you are using the same commands for different things (Ctrl-A, navigate to the end of the bit you want to keep, Ctrl-K).
I teach this guy along with the others you mentioned in your post to people new to shells because these really do help with text task automation :) Nice to have a (readable and friendly) source for these
@addison yeah I think you're right that Ctrl-K is “next on the list" of most useful shortcuts to learn
@b0rk @njvack It helps to remember that a tty used to just be an RS-232 serial line. A character would come in, an interrupt would get generated, and the tty handler would read the char from a register and put it in a buffer for the attached program to eventually read(). That's raw mode. Cooked is when the driver kept a line-buffer, and would interpret chars as they came over the wire - printable? echo and place in buffer; ^J?, send buffer on to consumer to read(), ^U, kill buffer and start over
@b0rk @njvack Then X11 came along and we needed a tty-like abstraction to attach these newfangled terminal windows to processes, because all the I/O and job control was wired to talk to a tty-shaped device. And some new side channels were added (e.g. SIGWINCH). So there are a ton of ioctls() to talk to the driver and control/interrogate exactly what kind of tty it really is.
@b0rk @njvack One other thing that was an A-ha! moment for me back in the day was learning that stty uses an ioctl() to determine the tty behind stdin, so you can redirect from another tty (assuming you have permission) to see its settings. So, assuming /dev/ttys000 is a different window, I can 'stty -a < /dev/ttys000' and see how the flags change between cat, bash, and vim for example.
@b0rk Thank you for the article. Fun to read.
I recently tried to move from macOS to Linux (i3) and for the most part was pretty straight forward but one thing that killed me was the lack of readline support at the UI level. Specifically, when working with chrome/brave in the url input text area.
I am so use to ctrl+a ctrl+e ctrl+k. For the most part it works fine in macOS on all the UI tools.
Am I missing something? Has anyone experienced this? Did you find a workaround?
@drio i’m not sure but my guess is that ctrl a does “select all” so it would be too weird for it to do something else