13 ms·
Things you didn't know about GNU readline (2019)
- sodapopcan 2y agoThis is cool, I didn't actually know you could configure Readline so the title is apt for me :D Much like in the article I'm also a Vim user who excited to try Vim mode at the command line and I almost instantly hated it. I suppose it's almost required to mention tpope's rsi.vim[0] which gives you Readline bindings in insert and command modes. I've adopted Readline everywhere in my OS except in Vim normal mode which I believe is not too uncommon for many folks. [0] https://github.com/tpope/vim-rsi https://github.com/tpope/vim-rsi
- tux1968 2y agoTpope's naming of those bindings is meant as a bit of a joke, maybe? I've always felt that Emacs bindings was leading to Repetitive Strain Injury; and really appreciate being able to use Vim bindings, even at the shell prompt.
- ramses0 2y agotpope has $DIETY-tier naming skills: `fuGITive`, `scriptEASE`, `PATHoGEN`
- sodapopcan 2y agoWow, I never put script ease together, I figured he was purely being lude, lol. I feel a bit dumb but thanks for pointing it out!
- ldmosquera 2y agoYou left the very best out: dadbod.vim (a DB helper)
- sodapopcan 2y agoI'm gonna go ahead and be a stinky and say I'm lukewarm on DadBod (as a name, the plugin is awesome). It's just a reference to a well-liked tweet he made and otherwise the only thing it really has to do with databases are the initials. I actually remember he released it under a different name and someone opened and issue saying it was a missed opportunity to call it "dadbod," lol. Other good ones with more double meanings: - PROJECTionist - unimPAIRed - COMMENTary
- sodapopcan 2y agoThe name is certainly a joke but the plugin is not. There is certainly nothing wrong with using Vim bindings on the command line if you're into it! 'tis the beauty of configuration.
- sham1 2y agoPeople do like to talk about emacs bindings causing RSI, usually to rib on the editor and to keep the tradition of the editor wars going. However, there really isn't all that much evidence for it, is there? Of course it's often in jest and somewhat famously the plural of anecdote is data, but it would be nice to know if there actually is something to the RSI. Ergonomics is complicated enough as-is.
- sodapopcan 2y agoMy only evidence is that my RSI got better once I started using Vim full time. Of course, Vim forced me to learn to touch-type and I also never used Emacs, but I'm just going to go ahead and attribute the cured RSI 100% to Vim and assume every other editor causes it. That's my "research" tells me, at least! :D :D ;)
- loulouxiv 2y agoDid not know of this plugin but my life changed when I realized that pressing ALT+<key> registers as pressing Esc then pressing the key. Therefore in insert mode I just do ALT+I to go to start of line, ALT+A to go to end of line, ALT+o / ALT+O are also useful
- kstrauser 2y agoIt's a relief seeing readline pulled in as a dependency for some command line tool: ahhh, there's going to be at least a reasonable amount of command history and editing features available. To remind yourself how much we take for granted, play with `psql --no-readline` some time and see how awful it is to lose the ability to up-arrow get the last query back, edit it, and send it again.
- joezydeco 2y agoI get a sense of dread when I see readline pulled in as a dependency because now I'm GPL3.
- enriquto 2y agoI don't understand. Are you afraid of being able to see the source code of the program you are going to use? You are not forced to look at it, if you don't want to.
- cyberax 2y agoYeah, you don't. GPLv3 means that you can't use it with the code you write for your job. And there are cases where readline can sneak into the codebase through unintended routes.
- tpoacher 2y ago> It's a relief seeing readline pulled in as a dependency for some command line tool (emphasis mine)
- kstrauser 2y agoGPLv3 means you can't use it with code that you distribute outside your organization without complying with its license. It's not an issue for internal tooling. I know you get the distinction, but I hear too often that "we can't use GPLv3 software at work" from people who aren't clear on it.
- gray_-_wolf 2y ago> Also, without some sort of indicator, Vim’s modal design is awkward here—it’s very easy to forget which mode you’re in. That is why I have this in inputrc: set editing-mode vi set show-mode-in-prompt on set vi-ins-mode-string + set vi-cmd-mode-string :
- sre2 2y agoYou could easily improve upon that. For example the following will change the cursor to a block in emacs mode, an underline in vi-command and a line in vi-insert in most terminals. set show-mode-in-prompt on set emacs-mode-string \1\e[1 q\2 set vi-cmd-mode-string \1\e[3 q\2 set vi-ins-mode-string \1\e[5 q\2 The worst thing about the bash config of readline is that bash disables the key combinations for going from emacs-mode to vi-mode (ctrl-alt-j) and back (ctrl-e). They work everywhere else (where I've checked anyways) and you can't turn it on again in inputrc, you have to bind it in your .bashrc, all that because the bash developers think it would be too confusing to have it work the same in bash as anywhere else were you have readline support.
- tristan957 2y agoWhat's the bind incantation in the bashrc you recommend? Here is what I tried: bind -m vi-command 'Control-e: emacs-editing-mode' bind -m emacs 'M-C-j: vi-editing-mode' The second keybind does not seem to work. If I just make it control-j, it works. For some reason the meta is throwing it off.
- sre2 2y agoYou are looking for bind -m emacs-meta '"\C-j": vi-editing-mode' and possibly adding bind -m vi-insert '"\C-e": emacs-editing-mode'
- tristan957 2y agoThe default keybind is control-meta-j though. My comment was in reference to me not being able to get that to work.
- meribold 2y agoTo make Less (the pager program) behave a bit more as if it used Readline (it doesn't), one can create a `~/.config/lesskey` file with these contents: #line-edit ^A home ^E end ^F right ^B left ^P up ^N down ^D delete ^W word-backspace \ed word-delete \ef word-right I think a relatively recent version of Less is required.
- kickaha 2y agoHoly GOD all these years of wasting time on HN have finally paid off! THANK YOU FOR SHARING THIS
- meribold 2y agoSome more good ideas for Readline configuration: https://www.topbug.net/blog/2017/07/31/inputrc-for-humans/ https://www.topbug.net/blog/2017/07/31/inputrc-for-humans/
- strbean 2y agoThis is nostalgic. For a Systems Programming course, I had the following assignment: - Implement readline(3) - If you have any questions, see the man page. - Extra credit: implement all GNU extensions.
- 20after4 2y agoWhat a great assignment. I would have loved that class.
- strbean 2y agoA cool way to structure the class, but hurt by the fact that the professor steadfastly refused to provide anything beyond the man pages. Even the lectures consisted of him putting a man page up on the projector and reading it aloud, verbatim.
- tpoacher 2y agoAlong the same lines, I find this little utility in standard linux repos to be amazing. Try it on ed: `rlwrap ed`. Package: rlwrap [...] Homepage: https://github.com/hanslub42/rlwrap Description-en: readline feature command line wrapper This package provides a small utility that uses the GNU readline library to allow the editing of keyboard input for any other command. Input history is remembered across invocations, separately for each command; history completion and search work as in bash and completion word lists can be specified on the command line.
- microtonal 2y agorlwrap is a life-saver. Back when I was a graduate student, I contributed a system that was written in SICStus Prolog 3. SICStus was (probably still is) a great Prolog interpreter, but its REPL interface was quite bare-bones. `rlwrap`-ing SICStus made it so much nicer!
- tristan957 2y agoI'm still not understanding rlwrap. Could you describe more about what I should notice running the ed command you posted.
- assbuttbuttass 2y agorlwrap provides line-editing capabilities including ctrl-a, ctrl-e, and up and down arrows to recall previous commands
- kragen 2y agorlwrap is fantastic. here's a multichannel text chat system for other people who can ssh to the same host, with command-line editing, cross-session history, and logging provided by rlwrap: #!/bin/sh # Simple chat system frontend, wrapping gyap in rlwrap and maybe ssh. : ${GYAP_LOGFILE=$HOME/gyap.log} ${GYAP_COMMAND=gyap} if [ "$#" -eq 0 ]; then rlwrap -C gyap -l "$GYAP_LOGFILE" "$GYAP_COMMAND" "$@" else host=$1; shift rlwrap -C gyap -l "$GYAP_LOGFILE" ssh "$host" "$GYAP_COMMAND" "$@" fi the actual chat system is another 10-line shell script called `gyap` #!/bin/sh : Simple chat system. cf. rgyap. ${nick=${1-$USER}} ${chan=${2-/var/tmp/chat}} echo "Chatting on $chan as <$nick> (override with $0 \$nick [\$chan])" touch "$chan" && chmod 666 "$chan" 2>/dev/null sign() { echo "$(date +%T) * $nick signed $1 ($(date +%05Y-%m-%d))" >> "$chan" } echo "Press ^R if a chat line appears as you are typing. Recently:" tail -Fn 16 "$chan" & pid=$?; trap "sign off; sleep .1; kill $pid" 0 sign on; while read t; do echo "$(date +%T) <$nick> $t"; done >> "$chan" from http://canonical.org/~kragen/sw/dev3/gyap http://canonical.org/~kragen/sw/dev3/gyap and http://canonical.org/~kragen/sw/dev3/rgyap http://canonical.org/~kragen/sw/dev3/rgyap it's not secure of course; anyone can spoof anyone else or fill up your /var/tmp disk, or read the log without signing onto the channel it would be nice to have rlwrap options to customize tab-completion, for example for expanding to recently-mentioned nicks or slapping someone around a bit with a large trout
- galenelias 2y agoShout-out to the clink project, which brings a modern shell experience (including Readline) to Windows' cmd.exe. This is the most advanced shell I have across Mac/Linux/Windows, which is always a bit surprising. It's extremely extensible and has some pretty incredible functionality written for it (also by the maintainer). https://github.com/chrisant996/clink https://github.com/chrisant996/clink
- chasil 2y agoI just use the busybox port to Windows. https://frippery.org/busybox/index.html https://frippery.org/busybox/index.html
- bbminner 2y agoBash uses readline, right? So > Tens of thousands of people probably use it every day without thinking about it. seems like an understatement.
- olau 2y agoSome years ago I helped diagnose an O(n²) bug in readline. For years, I had problems pasting many lines of SQL in a psql session. It would slow down as it worked through the characters. One day the same happened in another shell, and it dawned on my that this was probably a problem with readline. So I fired up a profiler and sure enough, something inside readline was recalculating something upon each character input with the work done proportional to all the characters already input. I sent my findings to the mailing list, and Chet Ramey fixed it. In the process, I discovered that wonky editing of long lines when resizing a terminal window was also fixable. When you resize, you change the line width, so readline needs to take that into account when it wraps the long lines. I think it did have code to do that at the time, but it just didn't kick in for some reason. Can't remember the details, but it does seem to work fine in psql today. That was another multi-year annoyance.
- ramses0 2y agoRemiss for not mentioning "rlwrap": https://github.com/hanslub42/rlwrap https://github.com/hanslub42/rlwrap ...basically "readline in a can" that you can use to improve text input of other programs. I forget if it was RMS or ESR that really wanted to hold "readline" away from corporations, so it's licensed as GPLv3 (not v2), and he explicitly wanted it to _not_ be LGPL (ie: embeddable). My crazy readline/bash tip is `ESC, .` (or maybe `alt+.`, I'm not 100% sure, random search result here: https://gist.github.com/tuxfight3r/60051ac67c5f0445efee https://gist.github.com/tuxfight3r/60051ac67c5f0445efee ). Basically it up-arrows through the last "word" of previous commands, adding it to the current command. Example: mkdir foo cd `esc, .` => cd foo vim bar.txt cp `esc, .` baz.txt => cp bar.txt baz.txt It's crucial in that it reduces the number of keystrokes, and avoids typing errors completely, as you're "recalling" something rather than re-typing. I'm also in the same boat as the author in that `set -o vi` doesn't quite do it for me (although I consider myself an expert in vi). What I tend to do instead is: C-a # <cr> => go to the beginning of the line and insert a comment char fc => "fix command", see "help fc" (it's a built-in) ...basically it invokes: `$EDITOR "$( history | tail -1 )"` and whatever you save/quit will get executed as a command. This lets me intentionally "damage" a command, but then get into `vim` to "fix it up" (eg: `dw, cw, df/, etc...`). Remove the comment from the beginning of the line to execute it, or keep it there to take the command back "out" of `vim` so you can keep building it up.
- wild_egg 2y agoI've always used !$ to get the last word of the previous command like so: mkdir -p foo/bar cd !$ # => cd foo/bar I suppose the advantage of `ESC, .` is universality since it'd work inside any readline prompt? Not sure how frequently I actually need to do that outside of bash but going to keep it back of mind in case I do, thanks
- ramses0 2y agoI like the interactive nature of esc-., you can keep "up arrowing", to a value a few commands ago and crucially: edit the value. (add/remove `tgz`, etc)
- 2y ago
- chasil 2y agoDebian dash is a minimal POSIX shell that also is able to implement "set -o vi" (as suggested by POSIX.2). http://gondor.apana.org.au/~herbert/dash/ http://gondor.apana.org.au/~herbert/dash/ The dash shell doesn't use GNU Readline to implement "set -o vi" but instead uses "libedit": https://thrysoee.dk/editline/ https://thrysoee.dk/editline/ Debian does not appear to link dash with libedit, so command line editing is disabled. They should consider doing so, and offering dash as an interactive shell. This would give people fewer bashisms to unlearn when they need to write portable scripts for the POSIX shell. The dash shell is actually reasonably pleasant for interactive use when compiled with libedit.
- andrewshadura 2y ago"They" have considered it and tried it, but had to revert the change. Dash is in Debian primarily for scripts, not for interactive usage. If you want to use dash with libedit, you have to compile it yourself, unfortunately.
- 1vuio0pswjnm7 2y ago"The dash shell is actually reasonably pleasant for interactive use when compiled with libedit." For me it's the preferred interactive shell. When compiling dash with libedit, I edit dash source to enable tabcomplete. Then it feels more like NetBSD. I've been running an experiment using busybox bash instead of dash as both interactive and scripting shell; have discovered numerous busybox idiosyncracies as a result. One thing I like about busybox bash is it's command history search: Ctrl-r. A bit faster than libedit. NB. "set -o vi" can be abbreviated to "set -V"
- chasil 2y agoI understand that busybox bash is specific to the windows port.
- 1vuio0pswjnm7 2y agobusybox "ash" is littered with "bash-like" features. Searching command history using Ctrl-R is just one of many. IMO, it has enough changes from NetBSD sh and Debian sh that it is neither ash nor bash. Regardless, I should have referred to it as "busybox ash". Apologies for the inadvertence. busybox includes a config option to include a "bash" applet name that points to "ash"; typing "busybox" one will then see "bash" listed as an applet, but is the same shell Sometimes when compiling software, authors insist on using bash scripts at compile-time rather than sh scripts. Trying to use busybox ash to run these scripts will fail because there is no applet called "bash". There might be another workaround but I find it useful to compile busybox to include a "bash" applet name.
- jlv2 2y ago"Tens of thousands of people probably use it every day without thinking about it." Probably tens of millions at this point.
- apitman 2y agoThis is way off topic but 2 hours ago I was trying to figure out how to read a single line from stdio using Rust/tokio and failed to figure it out in a reasonable time. It was infuriating.
- kstrauser 2y agoI could stand to hear more about this. What problem were you running into?
- apitman 2y agoBasically googling "tokio read line" didn't lead me to uncle's solution.
- ComputerGuru 2y agolet mut line = String::new(); std::io::stdin().read_line(&mut line).unwrap(); And I just looked it up and it's right there in the docs, too: https://doc.rust-lang.org/std/io/struct.Stdin.html https://doc.rust-lang.org/std/io/struct.Stdin.html You basically shouldn't use `tokio::io::stdin()` for what you want, as is documented at https://docs.rs/tokio/latest/tokio/io/fn.stdin.html https://docs.rs/tokio/latest/tokio/io/fn.stdin.html > For interactive uses, it is recommended to spawn a thread dedicated to user input and use blocking IO directly in that thread. So the code under tokio would be let line = rt.spawn_blocking(|| { use std::io::stdin; let mut buffer = String::new(); stdin().read_line(&mut buffer).unwrap() }).await.unwrap();
- apitman 2y agoYeah std::io is what I ended up using, but it felt like I might be doing something wrong. Wasn't sure if using blocking IO would mess with tokio. Your answer seems to indicate that intuition was correct, and I should be wrapping it in spawn_blocking. That all makes sense, it would just be nice if your comment was at the top of the google search results.
- mklein994 2y ago> Also, without some sort of indicator, Vim’s modal design is awkward here—it’s very easy to forget which mode you’re in. With `bash`, you can show which mode you're in by putting this in your `~/.inputrc`: show-mode-in-prompt on It makes your prompt look like this: [foo@bar ~]$ # before turning it on @[foo@bar ~]$ # after @[foo@bar ~]$ set -o vi (ins)[foo@bar ~]$ # and after I press esc: (cmd)[foo@bar ~]$ Customize these with `emacs-mode-string`, `vi-ins-mode-string`, and `vi-cmd-mode-string`.
- gumby 2y ago^U in readline isn't an emacs command (that keystroke does something else in emacs); it's the old teletype protocol for line input. So if you aren't using readline, ^U deletes everything back to the beginning of the line. Readline preserves that because us pre-readline old farts have it wired into our fingers. Before display terminals there were just printing terminals: IIRC # deleted a character and @ everything to the beginning of the line. This goes back to Multics and was carried forward in early releases of Unix at Bell Labs. This is obviously pretty inconvenient when you have a display terminal but I am pretty sure that code remains in the bowels of the BSD TTY IO system at least and can probably be enabled. Maybe it even survived into linux for some compatibility reasons. Also I WUZ THERE and I think Chet has it backwards on the POSIX controls issue: bfox talked about the TWENEX line input JSYS that had that stuff built in (I believe it was also, perhaps even earlier, in VMS, and maybe TENEX, and surely he had talked to some of those folks too)
- uncletaco 2y agoOne thing trying to work with Guix over the last five years taught me is how much I take for granted all the little things that come packaged extra. I was using guix for about a month before I learned that readline was the package that allowed me to do a lot of the extra commands like ctrl-c etc.
- usr1106 2y agoThe article feels incomplete for not not mentioning the bash built-in called bind. It allows you to work with the reeadline bindings. I use Ctrl-R a lot to find previous commands from my shell history. Often I have to press Ctrl-R several or even many times to find the right one. And then it happens that I overshoot and would like to change the search direction. Unfortunately forward-search-history is on Ctrl-S, which is overloaded by flow control. Occasionally I use flow control, so I cannot remove that. What solution are others using to get forward-search-history?
- lohfu 2y agofzf has pretty killer history fuzzy search. Just load its keybindings in your .bashrc
- wswope 2y agoIf you’re open to a paradigm shift, I can’t recommend atuin highly enough. It’s truly the pinnacle of shell history tooling, but requires a ~1-2 day muscle-memory learning curve. https://atuin.sh/ https://atuin.sh/
- klibertp 2y agoOne important characteristic of this `readline(const char*)` call is that it blocks. So, if you're trying to write a REPL for a language that uses green threads for concurrency - I'm looking at you, GNU Smalltalk - then DON'T. At least not from the main thread.
- BeetleB 2y agoReadline is good, but once I started using the xonsh shell, and prompt_toolkit, going back to Readline always feels a bit lacking.
- godelski 2y ago> Ramey has now worked on Bash and Readline for well over a decade. He has never once been compensated for his work I just want to remind everyone of the xz hack. The lesson here is that a few people maintain projects that are critical to our infrastructure. You may be familiar with the XKCD comic[0], but this makes it look like the unpaid single/few maintainer critical projects are rare. These people are generally unpaid and that has big ramifications. Sure, it makes them susceptible to bribes and more prone to hostile takeovers (however you view xz), but there's more. It means these works are simply a work of passion, and they are working on them in their spare time. We all know here that that time is less and has lower priority than our work time. So you're more likely to be rushed and make mistakes, or not be able to fix things fast enough, and so on. Is this really the way we want this infrastructure to be maintained? Startups have more stability than this and are more likely to pass the "CEO hit by a bus" rule[1]. Not to mention the difficulties of transitioning when the dev wants to retire or move onto something else. This does lead to issues, and while we've solved them in the past, that doesn't mean we can't do better. Surely they deserve some compensation. We have 8 companies which are worth over a trillion dollars and certainly all 8 use readline. Are you telling me that these companies can't collectively kick back $200k/yr. That's literally what Elon makes in 10 minutes if he gets 5% on his wealth. I find it hard to believe we don't have enough money to fund possibly thousands of these projects (if there are that many, but there are likely that many people). It only takes Ballmer 16 minutes and there are 20 people who can do it in 30 minutes or less (~50 for 1hr). Collectively the top 10 make 230 million per day for doing nothing. I think we have the money. (remember, we're talking about products that these companies are using. This isn't just a "pure donation," as these things have clear market value and the loss of the maintenance will result in these companies also losing money) At the least, I'd like to remind everyone that the company you work for likely offers some matching donation. If you're at one of the big tech, they do. [0] https://xkcd.com/2347/ https://xkcd.com/2347/ [1] If your CEO, or any single specific employee, is hit by a bus and can no longer work, does the entire company also collapse?
- jeffrallen 2y agoCtrl-k kills the rest of the line. Ctrl-u kills the entire line. Ctrl-y yanks stuff back in from your kill ring. Esc-y will then replace the stuff with the previous item in the kill ring. Ctrl-arrows moves a word at a time. Ctrl-r starts a reverse interactive search through the history. Use any editing key, like ctrl-e to start working on the current search result.
- akira2501 2y agoCtrl-c aborts input and leaves the previous partially edited line visible. Ctrl-g cancels Ctrl-r searches. So if you want to search and then search again you can clear the history position with Ctrl-g. Ctrl-s moves forward if you went too far with Ctrl-r. Ctrl-r twice in a row retrieves the previous search. Alt-u upper cases. Alt-l lower cases. Alt-c capitalizes. From current position to end of word.
- geophile 2y agoI was writing a command-line tool in Python, and wanted bash-like line editing capabilities. And then I realized that there was a Python wrapper for readline. Problem solved!
- hollerith 2y agoThat's nice, but if GNU readline disappeared from my Linux install I probably wouldn't notice.
- oska 2y agoLovely opening paragraph : > I sometimes think of my computer as a very large house. I visit this house every day and know most of the rooms on the ground floor, but there are bedrooms I’ve never been in, closets I haven’t opened, nooks and crannies that I’ve never explored. I feel compelled to learn more about my computer the same way anyone would feel compelled to see a room they had never visited in their own home.
- 1vuio0pswjnm7 2y agoIME socat readline prog always feels faster than rlwrap prog
- TZubiri 2y agoSome years ago I sent a bug report to the email listed at the end of a man page. I don't recall what the bug was, I also don't recall why the video I sent showcasing the bug had my national anthem in the background. But it sparked a nice bug report exchange. That he is doing this for no pay and for the passion of providing software to users all around the world fits.
- globular-toast 2y ago> One thing I’ve done is reconfigured Ctrl-K. Normally it deletes from the cursor to the end of the line, but I rarely do that. I would recommend against this. I delete from the cursor to the end of the line all the time. Maybe more in Emacs than readline, but still You can already delete the whole line by issuing C-a then C-k. I also do this all the time and that key combo is as easy for me to type as any two letter word. Remapping C-k means you now have two ways to kill the whole line and no way to kill from the cursor. But worse: you're teaching yourself a keyboard setup that only you use. You'll be lost on somebody else's computer, or any time you don't have your config installed. The standard readline bindings turn up in sometimes surprising places and it's a joy when you realise you're already trained to use some system or software you've never used before. I'm surprised the article doesn't also mention C-y. After you've C-k killed something it goes on to the "kill ring". Press C-y to bring it back! (You can bring more than the most recent thing back, but you now have the key words to look this up yourself).
- anovikov 2y agoGreat thing, but it is GPL... there is libedit that's LGPL and while isn't a complete replacement, is good enough.