entering text in the terminal is complicated https://jvns.ca/blog/2024/07/08/readline/
233 comments
@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 @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 Oh my! This brings memories of ‘\n’ vs. “\r\n” handling back to me, and not in a good way. https://stackoverflow.com/a/3821814/375 @b0rk Funny that the J character also looks a bit like the ↵ character :) And the fact that `j` is VIM key to move the cursor down! Coincidence? I think not! @b0rk Also Ctrl-H is the backspace character (no matter what your backspace key enters), Ctrl-I is horizontal tab, and Ctrl-L is form feed. That's also why Ctrl-L is so often the “clear/reset screen” command. @Ange @b0rk You can still use Control-D to exit a shell, Control-G sounds a bell and Control-H is either backspace or delete depending on what kind of computer you're using. I've always been a bit weirded out about all of that. For those born in the current millennium: pressing Enter is ^M "Carriage Return" because with out linotype machines, that would make sure you didn't type past the paper. Only you also needed the bar to roll, so you had ^J "Line Feed". For a while systems would send ^M^J when you pressed the enter key, and some still do (Windows). Others just shortened down to ^J with the ^M implied. ^K, ^L, & ^Y are their own stories too. @b0rk The important corrolary: control-m is carriage return. Once in a while I encounter a situation in which hitting enter sends LF, but I'm talking to something (usually a tiny-brain embedded device) that expects CR and only CR to end an input line. @b0rk one practical use for it is if your terminal becomes wonky. For example, characters not echoing and enter key not actually working. I've seen this when interrupting an ssh connection before being fully established. You can type 'stty sane' followed by a Ctrl+J and get it back. I do this at least four to five times a year. @b0rk I recall that back in the day, when termcap databases were less complete or had worse defaults, there were some systems that I used to telnet/rsh/ssh into (I forget exactly what era this was) where I couldn't use the backspace key but could use Ctrl-H to backspace. Kind of a fuzzy memory, so I may be getting the exact details incorrect, but these kind random things occasionally do come in handy. @b0rk it is just how it was designed. control plus keys of ascii lines 4x and 5x gives characters in lines 0 and 1 (block C0).And esc will gives lines 8 and 9 so block C1. But now we uses the “7 bits alias” so esc as control [. Much history but less ideal in modern world. usefulness to know c-j? imho just on binary/hex dumps 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 Anyone who isn't still learning things 15 or more years into their career—even “basic” things (these are not basic)—is so deep in a rut that they can no longer see out of it. @b0rk 💯 normal and appreciated, I knew you were going to knock that whole terminal piece out of the park. Well played! @b0rk wow! people love to make people feel bad on purpose! thanks for doing what you do to normalize actually needing to learn :) @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 I’ve been coding for 40 years. I still learn new things every day. And forget other ones every day. We’re people, not books. @b0rk right? That sort of commentary serves no purpose. And there's always new stuff to learn. There's probably even a better way to do my go-to readline use case, one I haven't discovered yet: ``` @b0rk I've been using variants of the unix command line for 25 years and I'm still stumbling into new things. Nobody knows *everything*. @b0rk There are lots of 'basic' things I will never learn. Assuming otherwise seems presumptive at best, basically! @b0rk I just found out yesterday there are terminal extensions to get key up events in the terminal. I naively thought for the last 20 years those were already there. https://sw.kovidgoyal.net/kitty/keyboard-protocol/ @b0rk there is something particularly juvenile about people assuming there is one particular order or traversal for how people should learn things – that if someone else doesn’t know a particular bit they are BEHIND or BELOW or BASIC. it’s NORMAL that we all encounter the staggering diversity of technical details at different times and stages and it doesn’t mean something fundamental about your place in the hiearchy. @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 there is something a little funny to me about how i was (and effectively now am) going to reply to this about how while i am very seasoned with computers and running infrastructure i struggled with git for a long time and so this post resonated with me but your pinned toot is about your zine “how git works”!!! which i think i will now have to check out @b0rk you're an internet treasure Julia, thanks for doing what u do. You're like that kid in class that when a teacher explains something complex in a horrible way raises their hand and says "actually I didn't get any of that" and prompts every other student (who don't feel confident enough to admit they didn't understand) to lower their guard and go "yeah no, please explain that again". Publicly admitting ignorance is so powerful! Nothing that you don't know already of course :D @b0rk Python 3.13 (in beta) has a new custom input editing method inspired by ipython, rather than using readline or libedit https://docs.python.org/3.13/whatsnew/3.13.html#a-better-interactive-interpreter @b0rk my favorite is ctrl-g or ASCII character 8 the BEL character. Yes it rings the bell 🛎️ in your terminal. @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 tangentially related: at least some readline sequences (eg Ctrl-A and Ctrl-E for sure) work on OSX not only in the terminal but in Apple-supplied apps which work with text (Notes, TextEdit, Mail, etc) but not /all/ apps; notably Outlook Mail on OSX doesn’t process those sequences. Hugely shocking, I know. @b0rk Yup, and oddly enough, this had been essentially resolved in the 90ies with Plan 9, but people stuck with systems that still keep reminding us of teletypes, core memory, tape drives and all that retro stuff. @b0rk As someone in the computer industry since 1984, the terminal was the ONLY way to do things, so you just got used to it or found some other line of work. This idea that working in the terminal is complicated is a different perspective. Thanks. @b0rk Yet another reason everyone should use Emacs! (Seriously though, if you’re a touch typist, the key bindings are extremely well thought out) @b0rk if for some reason you don’t have rlwrap, socat can also do this (with READLINE on the “left” and EXEC on the right), even supporting a custom history file. @b0rk you would have so much fun in the Ghostty beta. @mitchellh is always deep in the weeds fighting with terminal oddities. @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 . @b0rk this historical article on multics emacs has a fascinating section about the performance impact of interactive programs on the mainframes of the time. it's interesting to remember that terminals were computing. entities in their own right, with local state and whatnot.... which is not a picture you see much anymore. @b0rk The Korn shell supported command-line editing and a weird flavor of history editing (check out the `fc` command), and the POSIX.2 shell was based on ksh, so support for both `emacs` and `vi` modes in interactive shells is pretty much universal except in antique or deliberately minimal shells. Technically it's optional but the Standard says what the supported keybindings are in both modes. @b0rk Btw, most of the readline keybindings are similar in Emacs, but as a tip, if you want to know what a keybinding does in Emacs, open Emacs vanilla (`emacs -Q`) then press Ctrl-h and then k. This will ask you to press a keybinding and it will give you its definition. @b0rk fascinating! I was wondering if readline copied emacs or vice versa, and now I know! I wonder if long time emacs users (as opposed to vi users) find the terminal more intuitive? @b0rk You’re a hero for writing this stuff up and your style is great. Thanks for being awesome! @b0rk I didn't ever hear about ctrl+u, ctrl+w, ctrl+r, etc, so yes, that stuff is definitely hard. I wonder though, why are arrow keys printing those characters when pressed in a non-interactive input prompt? hmm, I think I gotta read some C to find that out, maybe. This post is very interesting, bookmarked it @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). @b0rk I probably wouldn't know the readline commands if I weren't an Emacs user. And even as an Emacs user, I have about 8 readline commands in muscle memory and that's good enough. @b0rk Dang, I learned so many useful commands from your post and the links it provides. Thank you so much! @b0rk thanks for the post. I learned new things from it. I love your approach to learning. I did a similar investigation some time ago. In the end I made a game in the terminal to make it more interesting. :) |
@b0rk omg I didn't know rlwrap existed and I am having IDEAS thank you for this post