Entering text in the terminal is complicated
The article delves into text input complexities in terminals, categorizing input modes and offering tips like using Ctrl+A for line navigation. Understanding input systems enhances efficiency in the command line.
Read original articleThe article discusses the complexities of entering text in the terminal, highlighting challenges such as inconsistent text handling across different programs. It categorizes text input modes into baseline tools, readline library users, libedit users, and programs with custom input systems. The author shares tips and insights on navigating these modes, including using Ctrl+A and Ctrl+E for line navigation, identifying readline usage with Ctrl+R, and leveraging rlwrap to enhance programs lacking readline support. Additionally, the article touches on the origins of keybindings, vi mode support in shells, and the benefits of custom input systems over readline. It emphasizes the importance of understanding the input system in use to enhance efficiency and predictability when working in the command line environment. The post acknowledges the complexity of text input in terminals and hints at additional complexities like ssh, tmux, and unicode handling that were not covered in detail.
Related
Advanced text features and PDF
The post explores complex text features in PDFs, covering Unicode, glyph representation, kerning, and font challenges. It emphasizes tools like Harfbuzz and CapyPDF for accurate text handling in PDFs.
Things you didn't know about GNU readline (2019)
The GNU Readline library, maintained by Chet Ramey, enhances command-line interfaces with efficient line editing and customization options, benefiting users of Bash and other programs. Ramey's volunteer efforts drive continuous development.
Vim Registers: The Good, the Bad, and the Ugly Parts (2013)
Registers in Vim offer versatility for macros and data storage. Drawbacks include incomplete clipboard history and confusing terminology. Author suggests improvements for a more efficient workflow, acknowledging Vim's usefulness.
Chr – terminal editor inspired by Turbo Pascal editor from 1997
A terminal-based text editor "chr" on GitHub mimics desktop editors' shortcuts, blending modern GUI with retro text mode. Developed with Tui Widget, it welcomes contributions. Installation involves cloning, building, and compiling.
Modern IDEs are magic. Why still use Vim, Emacs? (2020)
The enduring Vim vs. Emacs debate reflects users' resistance to change and preference for familiar tools. Vim's simplicity and customization attract efficiency-focused users, while some find switching to IDEs challenging. Personal preference determines the choice between traditional editors and modern IDEs.
Here's some stuff that's missing:
Within shell scripts, you can use `stty` to change a lot of stuff about the terminal, including how it deals with inputs. You can rewire all of these defaults and behaviors.
Here's an experiment I did a while ago using sh and stty: https://gist.github.com/alganet/63f1dbc97b8fd35f7bb14ec30f79...
It is able to capture and understand most keyboard combinations and even mouse gestures (hold/drag/drop) from within the shell in any VT100-compatible terminal (mintty, xterm, Terminal.app, vscode, so many others).
Runnable demo:
bash -c "$(curl -L https://git.io/fjToH)"
Run it and press some keys or move the mouse. Use Ctrl+W to exit. It supports zsh and ksh too, but not dash or other shells lacking `read -rn1`.---
Here's another funny thing:
`vi | cat -v`
If you pipe an interactive program to `cat -v`, you can see which VT100 escapes that program is using. I learned a lot from how vi does it.Here's a video:
https://github.com/colmmacc/jot/raw/master/jot-demo.mp4
and the CVS repository for the Unix terminal IM client it is part of is at: https://c-hey.redbrick.dcu.ie/src/c-hey_cvs_latest/
It tracks and redraws your cursor when you move up and down between lines, and also pays attention to SIGWINCH to redraw things when the terminal size changes. I've never had the time to rewrite it in Rust, but I'd like to and then release it as a small library.It's always surprised me that nobody else has done this.
+ wide characters
+ different keyboard modes causing the same key press to be presented by different ANSI escape sequences
+ different TTY states (eg local echo)
+ different OSs having subtly different syscalls for changing TTY states
+ differing support for terminal emulation (most these days roughly emulate xterm, but even there, none aim for 100% be compatibility)
+ a lack of a consensus on how to check for features provided by a terminal (some use ANSI escape sequences and wait for an ansi sequence to be returned from the term (that’s how the old VTs worked), some check $TERM (that’s how the first wave of terminal emulation was detected), some terms expose themselves as xterm and ignore the VT feature sequences, but set other env vars. it’s honestly a bigger mess than the user-agent string.
…and this is assuming a POSIX system. Things get doubly interesting when you throw Windows into the mix
[...] there are actually a few features that you get for free just from your terminal, without the program needing to do anything special at all.
The things you get for free are: [...]
- backspace
- Ctrl+W, to delete the previous word
- Ctrl+U, to delete the whole line
Linux noob here, so this may be a stupid question, but how does that work under the hood?
The documentation for fgets() says [1]:
> Reads at most count - 1 characters from the given file stream and stores them in the character array pointed to by str. Parsing stops if a newline character is found (in which case str will contain that newline character) or if end-of-file occurs.
Does that mean that, by default, fgets() blocks until the user enters a newline and, before they do, it lets them edit the line buffer using the backspace, CTRL+W and CTRL+U shortcuts?
But there seems to be no guarantee that a program is using fgets() to read an entire line - it could also set count to 2 and read individual characters. Those could not be "unread" anymore when a backspace occurs. Is there some magic that lets fgets() buffer characters internally in such a situation, or would the backspace/line editing functionality just be broken then?
The dash shell does in fact support an editing mode if compiled with libedit. Debian derivatives do not do so (likely for concerns of space). They very much should, as people who start with bash will have much to unlearn.
The POSIX standard also specifies "set -o vi" as an optional extension. Every shell claiming POSIX-compatibility must support set -o vi if the shell implements this editing mode (so ignore inputrc if it pleases you).
"[set -o] vi: Allow shell command line editing using the built-in vi editor. Enabling vi mode shall disable any other command line editing mode provided as an implementation extension."
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...
It's not just entering text. The entire experience is complicated. It's a Concorde jet cockpit[1] (with no labels too), when 95% of the population just wants to fly their drone around[2].
[1]https://qph.cf2.quoracdn.net/main-qimg-2566f4c91b894e4169d77... [2]https://media.thedroningcompany.com/images/tincy/WQZpC56vqMp...
https://pliszko.com/blog/post/2021-10-31-natural-text-editin...
- control-w, which julia mentions in the post, to delete the last word
- control-o: when you're recalling a line from history, edited or no, runs the line and recalls the following line from history. so you can run a sequence of five commands from history by navigating to the first one and hitting control-o five times
- control-r: search backwards in time through your history as you type a search string. control-r again jumps to the previous hit, control-s goes back forward in time. hitting enter or control-o executes it
On Linux, every Terminal app I’ve used stubbornly refuses to copy when I press Ctrl-C, demanding I press Ctrl-Shift-C. When I paste, if I forget my manners and use Ctrl-V instead of Ctrl-Shift-V, I am punished by getting a weird character when I start typing again. And I am constantly pressing Ctrl-V because of muscle memory since no other app works this way.
Is there any terminal app for Linux that does things the Windows Terminal way and won’t slap me on the wrist for Improper Teletype Usage?
The closest thing I saw to what I have in mind is this: https://github.com/letoram/cat9/ but more in a way of interface.
And the curse of bad defaults strikes again (daily).
After the realization that this is a weird default you don't train yourself for 15 years, but change it to your comfortable/common keybinds!
Give me arrows, tab, Ctrl+(R/C/D/W) etc and its a great.
But I agree with the point that different systems have their own implementation which could lead to frustration.
I am working on set of servers only accessible through PAM and those admins don't allow anything. It gets so frustrating.
I feel a lot of the frustration also comes from shifting to unfamiliar environment. Like I work on those restricted servers and am cursing the admins, but when I switch to Ubuntu's terminal I am thanking the gods for liberation.
Edit: more complete list here: https://jblevins.org/log/kbd
Edit 2: can't believe I forgot Ctrl-D, which is forward delete.
This really resonated with me: even though entering some text and editing it is a very "basic" task, it took me maybe 15 years of using the terminal every single day to get used to using Ctrl+A to go to the beginning of the line (or Ctrl+E for the end)."
Only took me a year or so to get used to using "v" in vi mode and fc. I am not a "developer" but I prefer textmode command line to GUI. I do not use X11/Wayland/etc.
I learned sh on NetBSD which I still think is one of the best shells available. It's fast. vi mode is the default. People may disagree but I think for editing single a line of text, i.e., a "command", vi mode offers more precision. For example, being able to jump directly to a particular column number.
https://web.archive.org/web/20240528201424if_/https://pubs.o...
#list previous commands
fc -l
#edit 5th command on the list
fc 5
IMO, as a dumb computer user who is not a "developer", this is not complicated. I think terminal emulators are complicated, though. I do not use them.I believe fc came to POSIX from ksh.
For me, it is not that UNIX is objectively good. It is that the available alternatives are still comparatively bad.
That looks like some cognitive problem or ADHD. (Obviously, completely unrelated to intellect.)
> some programs (cat, nc, git commit --, etc) don’t support using arrow keys at all: if you press arrow keys, you’ll just see ^[[D^[[D^[[C^[[C^
I've long argued that the readline-like functionality should be in the kernel. The POSIX line discipline should be replaced or augmented with full blown editing with history recall.
Imagine rlwrap, but always there, all the time, in the TTY driver.
There are downsides, because history wants to be contextual and persistent. The kernel knows what process is making the read() call on the TTY, though, so that could be somehow arranged. Certain new security issues come up also.
Ctrl+LeftArrow and Ctrl+RightArrow also work with every readline-compatible shell and they are much more intuitive, especially if you are not used to terminal text editors.
> it’s very inconsistent between programs
Readline or emulations thereof are pretty common and the de-facto standard. But of course programs can do their own thing if they want to - it's not like GUI text eidtors all have consistent shortcuts.
cat / nc / etc. are not editors at all and therefore don't provide those shortcuts. They take an input stream and forward it.
Nowadays, programs should be hard-coded to accept ANSI sequences and ignore TERM (unless they need to make some fine-grained distinction like do we have 256 color xterm compatibility).
Those programs will never have that problem of not understanding arrow keys.
> Because I’m a vim user, It took me a very long time to understand where these keybindings come from
libreadline supports a basic vi mode. In bash, `set -o vi` lets you use vim-style editing. It is a lifesaver.
https://jvns.ca/blog/2022/07/20/pseudoterminals/
(It's a great article, and I'm fairly surprised the post doesn't directly link to it)
The older I get, the less patient I become with finding out some user experience sucks because of GPL / non-GPL knife fights.
It's been thirty-nine years now. I think the GPL was useful at its origin, but now the benefits of open-source are proven out, the world is deeply interconnected via the Internet, and it's a hindrance to have some code burden other code with requirements. I, for one, don't expect to write any further GPL code in my lifetime. I'd rather code be maximally unencumbered from interoperation.
But...
> "I’ve always thought that vi mode seems really cool, but for some reason even though I’m a vim user I didn’t really like using it when I tried it."
Really, that seems weird to me.
I use zsh (btw) and the problem she describes is a non-issue. And I am not a pro. (Sorry, Julia).
Related
Advanced text features and PDF
The post explores complex text features in PDFs, covering Unicode, glyph representation, kerning, and font challenges. It emphasizes tools like Harfbuzz and CapyPDF for accurate text handling in PDFs.
Things you didn't know about GNU readline (2019)
The GNU Readline library, maintained by Chet Ramey, enhances command-line interfaces with efficient line editing and customization options, benefiting users of Bash and other programs. Ramey's volunteer efforts drive continuous development.
Vim Registers: The Good, the Bad, and the Ugly Parts (2013)
Registers in Vim offer versatility for macros and data storage. Drawbacks include incomplete clipboard history and confusing terminology. Author suggests improvements for a more efficient workflow, acknowledging Vim's usefulness.
Chr – terminal editor inspired by Turbo Pascal editor from 1997
A terminal-based text editor "chr" on GitHub mimics desktop editors' shortcuts, blending modern GUI with retro text mode. Developed with Tui Widget, it welcomes contributions. Installation involves cloning, building, and compiling.
Modern IDEs are magic. Why still use Vim, Emacs? (2020)
The enduring Vim vs. Emacs debate reflects users' resistance to change and preference for familiar tools. Vim's simplicity and customization attract efficiency-focused users, while some find switching to IDEs challenging. Personal preference determines the choice between traditional editors and modern IDEs.