17 ms·
Everything you ever wanted to know about terminals
- MontyCarloHall 4y agoOff-topic, but it would be nice if HN could properly parse the Punycode encoding of internationalized domain names, so rather than the URL appearing as xn--rpa.cc, it appeared properly as ʞ.cc
- gibolt 4y agoShowing the real url, followed by the Punycode url in brackets would be even better
- donatj 4y agoInterestingly it's not even showing in Chrome for me. Shows fine in Safari. I wonder if Chrome considers the upside down "LATIN SMALL LETTER TURNED K" potentially deceptive. They've apparently got a whole document about what Chrome will and won't display https://chromium.googlesource.com/chromium/src/+/main/docs/idn.md https://chromium.googlesource.com/chromium/src/+/main/docs/i...
- DyslexicAtheist 4y agothere are tools like dnscrypt-proxy or nfq which allow you to sinkhole any punicode dns domains (before DoH became a thing) and I'm glad that some browsers still show this as xn-- as it's now the only defense that stands between users clicking on hxxps://аррӏе.com instead of https://apple.com https://apple.com punicode was a terrible idea to allow in DNS.
- MontyCarloHall 4y ago>punicode was a terrible idea to allow in DNS This is a very western-centric viewpoint. Most of the world does not use the Latin alphabet as its primary writing system.
- DyslexicAtheist 4y agoit is a security centric view point not a "Western" one.
- MontyCarloHall 4y agoThe solution is prohibiting characters that can easily be confused (across all writing systems), not banning Punycode altogether.
- Beltalowda 4y agoOr just allow only using a single script. A domain in all Cyrillic: great! Mixing Latin & Cyrillic: nono. In practice, browsers already check for this and display the "raw" punycode if they detect mixed script usage, but I wish such domains would not be registrable at all. These checks are somewhat complex and difficult, and easy to get wrong.
- duskwuff 4y ago> Or just allow only using a single script. This would still let some homographs through. In particular, Cyrillic has a lot of characters which are confusingly similar to, or even indistinguishable from, Latin characters (e.g. "авсекморѕтѵху").
- Beltalowda 4y agoRight; you can construct "арр.com" or "аррꙆе.com" from that limited subset. Those should be valid domains though IMHO; maybe show the used script in the address bar? I think users might be confused by that though and/or just ignore it, so idk. Then again, displaying "xn--80a6aa.com" and "xn--80ak6aa9058r.com" is pretty confusing too.
- lupire 4y agoUnicode domain names are a security threat, due to homographs.
- kevin_thibedeau 4y agoUpgrade to Firefox and you'll only see the punycode.
- hoseja 4y agoI specifically want to see unicode and firefox isn't letting me.
- seszett 4y agoAs far as I know, most browsers only display the Unicode character on a whitelisted set of TLDs that have rules to prevent homographs. .cc isn't part of this list and I only see the punycode.
- eric4smith 4y agoJesus - now I’m afraid to know. But kudos what a wonderful resource. It seems less and less people want to use the terminal. All the new developers I notice want to stay in the IDE and almost never want to get their “hands dirty”. Thanks for writing that great resource.
- csdvrx 4y ago> but i swear to god developers have so completely forgotten how terminals work that i might be one of a handful of people left on earth who actually has the knowledge to, so they all just layer their bullshit on top of ncurses (which should never have survived the '90s) instead and it's maddening. Actually, yes, understanding the tty in detail seems to become a dark art. However it's the best way to do complex things quickly: I did use some of these tricks like storing and then restoring the cursor position to have the time at which a command stop executing ABOVE the command itself and next to the time it started executing in https://github.com/csdvrx/bash-timestamping-sqlite https://github.com/csdvrx/bash-timestamping-sqlite I had to, because I was using MSYS2 and the time to execute a command was a limiting factor in Windows before WSL2.
- melissalobos 4y agoIt looks like you have done a lot of work with sixels based on your github too. Have you ever written anything about that?
- csdvrx 4y ago> Have you ever written anything about that? No, WYSIWYG: I don't bother much more than that with explaining how it's done: the source code + the comments + the github page already give all the details away to whoever wants to dig deeper. I'm not much into social media or self promotion either: if people like what I do, they'll use it - I don't care much more than that, as everything was written for myself and my selfish needs first. The tty/sixel world is very small world anyway, we generally know and recognize eachother, so we know where to look for cool new stuff :)
- jart 4y agoNot just sixels but she also has the most superior tool for rendering images as unicode blocks. https://github.com/csdvrx/derasterize https://github.com/csdvrx/derasterize
- csdvrx 4y agooh hello there :) To be fair it was more like a joint venture between us!
- ghostpepper 4y agooff topic but I would love a version of this with a more "plain" colors/ punctuation/formatting. finding it very hard to read / navigate anyway the content looks good so will try to find time to sit down and read this "essay" soon
- nohackeratall 4y agoSome actual visual examples would've been nice, too. There is just text that describes what it would look like but, as we all know, one picture is worth a thousand words.
- deleted 4y ago[deleted]
- boneitis 4y agoAll the code is there. Even a multiframe GIF or video capture wouldn't do their code (and blog post/rant) complete justice. The final example is both a total treat and a beast. I encourage anyone with any interest to chuck the code into GCC and behold the interactive experience for themself.
- mmanfrin 4y agoThe colors are very distracting on my monitor.
- csdvrx 4y ago> The colors are very distracting on my monitor. It's interesting, because I sometimes also find colors distracting, so for my Vim and other terminal tools I make an intensive use of text attributes (like bold, italic, underline and their various combinations) Your comment may incentivize me to release my monochrome vimrc: it looks quite good on mintty/msys2 or Windows Terminal, and still very decent with xterm!
- ghostpepper 4y ago
- timw4mail 4y agoI could take this a lot more seriously if capital letters were properly used.
- kompatible 4y agoIsn't worrying about someone else's grammatical use of capitalization when the piece is understood anyway a little too pedantic?
- timw4mail 4y agoI find the text more awkward to read without capital letters starting sentences, especially in paragraph form.
- giraffe_lady 4y ago
- vo2maxer 4y agoI can’t agree more. An author who can’t be bothered to follow well established forms of style, grammar, and punctuation in a technical article somehow deflates whatever else they have to say even if accurate. It’s not as if they are trying to emulate the works of E. E. Cummings, James Joyce, or Arno Schmidt.
- giraffe_lady 4y agoy'all are the most boring people on the planet istg. in the entire legion of internet writers making in depth technical content there is what, one who deviates from the conventions and you can't handle it. This author is a much much better writer than average for free technical content! They have an interesting, unique style! The typography and punctuation are part of that style! It would be tangibly worse if they adhered to the (bad, and also arbitrary!) typographical conventions of raw html just to please a bunch of square-ass nerds. Shit just makes me sad seriously.
- jjoonathan 4y agoI was aware of the ANSI escape sequences and even used them directly in scripts on occasion, but I still used ncurses "where it mattered" because I didn't know about compatibility. I didn't want to risk Windows or a random flavor of linux I'd never heard of or a group of anti-VT100 enthusiasts getting upset because I didn't use an agreed upon compatibility layer. From the tone of this piece I gather that the ANSI escape codes are actually standard enough to target. Cool! Thanks for the heads up.
- Beltalowda 4y ago> From the tone of this piece I gather that the ANSI escape codes are actually standard enough to target. termfo[1] comes with a "termfo" CLI utility which – among other things – can group terminals by escape code; for example "termfo find-cap save_cursor" shows that almost all terminals use "\x1b7", with just a few very old ones using something different (full output is a bit long, but it's at [2]). It's useful to check "can I safely hard-code this escape code?" But like you said: for ANSI it's pretty safe to just hard-code most codes, especially the common ones, but never hurts to check. [1]: https://github.com/arp242/termfo https://github.com/arp242/termfo [2]: https://pastebin.com/raw/pVHGR6aZ https://pastebin.com/raw/pVHGR6aZ
- duskwuff 4y ago> From the tone of this piece I gather that the ANSI escape codes are actually standard enough to target. Correct. Hardware terminals are extinct in the wild, and essentially all software terminals (including the Windows terminal!) now support a reasonable subset of "extended VT100" terminal control sequences. Some of the weirder features of the VT100 (like double-high/double-wide text or VT52 compatibility mode) are usually omitted, and some features which were added in later DEC terminals (like color) are often added.
- GekkePrutser 4y agoThe different features omitted and added are precisely one of the reasons you'd still want to be using an abstraction library. Otherwise you end up having to stick with the lowest common denominator, or having the user figure out how to enable each terminal feature in every app individually. These libraries were invented with good reason. Even now there's big differences between terminal emulators. Especially when you take modern features like images into account, there's like 6 different ways of doing it as some terminals have invented their own (kitty for one) and there's more standard ones like sixels which come originally from the Dec VT340 series. Though they were ridiculously slow on that hardware so it didn't take off until much later.
- jl6 4y agoThe author seems to really not like ncurses. But why? Is there something wrong with it?
- lupire 4y agoThe article has no pictures of what it is selling, so it just seems like a rant, as suggested by the opening profanity. I don't see how I can use what they are saying to make a TUI.
- giraffe_lady 4y agoAre you trying? I've been brutally bashing my head against some ancient telnet shit recently and this actually was concretely helpful and I could apply it immediately. The tone and presentation seem calculated to annoy HN readers (nice) but this article has a bunch of difficult-to-uncover details with just enough context to apply them if you actually have a use for them and a desire to.
- GekkePrutser 4y agoThe only reason I found in the article was "because jesus f. christ" (near the end). Therefore I assume the author has religious objections against nurses. /s In fact they mention various issues with their approach that nurses would fix automatically and without the user having to configure stuff in the app: > sadly, true color isn't supported on many terminals, urxvt tragically included. for this reason, your program should never rely on it, and abstract these settings away to be configured by the user. Apparently they don't care about the great terminal-independence ncurses offers because these ANSI sequences will only work fully on terminal emulators. And as they mention even those differ in supported features. Ncurses was created precisely to abstract these differences. It's not just good for "obscure dumb terminals from 1983". It would also be quite a pain having to deal with terminal resize events etc when building a TUI. And no, doing a full screen rewrite for each minor update does not make for smooth TUIs. Yes modern hardware is fast but sometimes you're on a slow SSH connection. Personally I still use real terminals too at times (I own a real VT520 and love it) and apps that are totally ignoring termcap/terminfo are super annoying. But I know this is niche. PS: Also from the article: > also, i have effectively zero pull in the tech community and am also kind of a controversial character who is liable to give projects a bad reputation, which i don't normally care about Gee, I wonder why...
- ntoskrnl 4y agoI was working on terminal code recently and had a hell of a time finding anything approaching an authoritative spec or reference docs. The best I found was this: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html https://invisible-island.net/xterm/ctlseqs/ctlseqs.html I'd recommend that over the wikipedia link in the article, since wikipedia seems to be missing some things.
- hnlmorg 4y agoYou couldn't find an authoritative spec because there isn't a universal standard. Lots of terminal emulators differ in different ways.
- metroholografix 4y agohttps://www.ecma-international.org/publications-and-standards/standards/ecma-48/ https://www.ecma-international.org/publications-and-standard...
- hnlmorg 4y agoNot all terminal emulators follow that completely. Most only include a subset and some include their own proprietary escape codes too (like iTerm and Terminology have codes for rendering images. tmux has an escape code for changing the session title). Then there's other specs not included in that doc even outside of the aforementioned proprietary codes. Like Sixel, conventions on non-POSIX terminals, etc. Also lets not forget the popular-but-not-standardised conventions like the hyperlink escape codes (which I personally think shouldn't exist in the first place....but that's another topic entirely). Even standard ASCII characters can differ from one platform to another. Backspace being a classic example: ISO 646 describe it as ^H whereas ASCII 1963 has it as ^? This mess of differing compatibilities is exactly why termcap is a thing. Being an author of a readline library, this is a topic quite close to my heart :)
- easrng 4y agohTerm and also IIRC kitty have image-rendering escape sequences too.
- whartung 4y agoYou can't have "everything you wanted to know about terminals" with absolutely no mention of terminfo and (previously) termcap. You don't necessarily need ncurses to have a portable smart terminal experience, but you do need terminfo. ncurses magic relies on the lore stored in terminfo, which contains all of the obscure escape sequences and other information about the disparate world of terminals. They're maintained as a combined package, but you don't need ncurses to drive the screen. You can get the codes yourself if that's what you want to do. You can use tput to make colorful labels in shell scripts. While much of the world has moved on to the One Terminal running on the One OS, not everyone has.
- JoshTriplett 4y agoAs the article states: > being compatible only with ANSI-capable terminals is a feature, not a bug Driving old hardware terminals (as opposed to terminal emulators) is a fun stunt, not something of actual modern value. Every modern terminal emulator supports ANSI escape sequences. Some features are supported by a subset of terminals, but you can either 1) probe for those features by asking the terminal, which some terminals support, or 2) try them and have graceful degradation if they're not supported, or 3) have configuration options to use them, or 4) don't use them. For every one case in which terminfo allows you to support some obscure non-ANSI terminal, there are many many more cases where terminfo won't happen to have a definition of the user's terminal (or won't know all the capabilities of the user's terminal) and you'll have less functionality than if you just used ANSI escapes. This is especially true over SSH and similar.
- deleted 4y ago[deleted]
- nicoburns 4y ago> Every modern terminal emulator supports ANSI escape sequences Is this true on Windows? My understanding is that quite a few TUI libraries don't have windows support.
- JoshTriplett 4y ago
- cek 4y agoI built a cross platform app to print 'pretty formatted' source code [1]. I didn't want to re-invent the wheel on formatting source code, so looked at all the existing libraries. Originally I figured formatting to HTML, and then building a print-friendly HTML render would work. But this proved super challenging. I tried a dozen HTML engines (including Chromium) but none gave me enough control to render just a single page of the original source file. Then I noticed Pygments, a Python-based library for pretty formatting source code, has an option to output an ANSI formatted file. I quickly found a bunch of libraries that could render ANSI formatted text to a print canvas. In the end, I put the original source code file through 'pygmentize -16m -o tempfile.an` (`16m` is the 16M color terminal ANSI formatter) and pipe the `tempfile.an` through a print-optimized renderer to actually print the source code. ANSI escapes FTW! [1] WinPrint - https://github.com/tig/winprint https://github.com/tig/winprint [2] https://pygments.org/ https://pygments.org/
- darrenf 4y ago> Originally I figured formatting to HTML, and then building a print-friendly HTML render would work. But this proved super challenging. [...] none gave me enough control to render just a single page of the original source file Nothing like as powerful as your app and entirely tangential to the topic of ANSI escapes, but my preferred way to generate HTML from source code is simply: vim +TOhtml +wq +q path/to/source/file.ext That will save an HTML version at `path/to/source/file.ext.html` (conforming to my .vimrc's syntax settings, theme, etc) and I'm happy enough with my browser or system's print dialog to go from there.
- bblough 4y agoThat is awesome. I've been using vim for years and never knew it had a command for this. I guess I should do more spelunking through the docs. Thanks!
- broses 4y agoA while ago I was trying to find a way to make my terminal scroll back up after a command executed, so that if the output was long I could read it from the top without having to scroll up manually. There are ways to get yours shell to print something after the command executes, so I just needed to find an ansi escape sequence that would scroll up. Unfortunately I didn't see any sequences that do this. Anyone have any ideas?
- bowmessage 4y agoMaybe pipe output of every command into a script that invokes $PAGER when the output is long enough?
- rustyminnow 4y agoless has a flag for that: (the gnu version does at least) -F or --quit-if-one-screen Causes less to automatically exit if the entire file can be displayed on the first screen. So one could just pipe everything through `less -F`. If a different $PAGER is preferred, well that'll be a little more involved. (Also handy: add in `-X` to leave the contents on the screen when you exit less)
- bowmessage 4y agoNeat! Thanks for the tips.
- hnlmorg 4y agoOnce it's scrolled off the top of the screen you're basically at the mercy of your terminal emulator's scrollback history. Some might have an escape sequence available to recall it but I there isn't any standard way of doing it. You'd be better off piping into less / more / most. These are called "pagers" and are designed to do this. eg cat large-file | grep common-phrase | less
- bee_rider 4y agoPiping to less is essentially the standard way to do this. your_command_here | less It will capture the output and let you scroll up and down. Otherwise, this would really be a feature of the terminal, and not necessarily required to be supported (it makes sense when you consider that many early real terminals literally printed the output to paper -- who needs scroll-back, just look up the tape! And repeating previously shown output would result in a confusing print-out). However, if your terminal emulator doesn't have a scroll-back, you could try something like tmux, or alternatively gnu screen. These add lots of little features to the terminal (a buffer to scroll back, split terminals, persistence so you can detach and reattach) (tmux is more modern feeling, IMO).
- shric 4y agoThis will be obvious to any C programmer, but the macro[1] used throughout the article only "works" on string literals and arrays, not pointers. Also, it will include the null terminator. Probably won't do any harm but quite silly if you're redirecting to a file for example. I'd subtract one, or use strlen which would cover the pointer case above and I'd hope a modern compiler would elide the call on a string literal anyway. [1] #define szstr(str) str,sizeof(str)
- sophacles 4y agoThe author seems not to be aware of the recent TUI rennaisance[1]. There are libraries like termbox and blessings (python) that are a middle-ground between full ncurses and adding your own ansi codes. There are a lot of modern TUI frameworks like tui-go or tui-rs that bring common GUI conventions back to the TUI (heck there are TUI programming libraries that are designed to be similar to react) - these too tend to be a lot nicer than working with ncurses. Definitely worth checking out the full landscape these days if you're going to dive into making your console programs prettier. [1] My words, I just coined that name (although I wouldn't be surprised if others had said it too). I mean that in the last ~decade there has been a lot of TUI work in the background, with lots of new programs and some pretty stunning results. I blame unicode - once the web folks realized they could use something like font-awesome instead of sprite-sheets (or maybe as a pre-build sprite sheet?), and the "icons in a font" movement took hold, terminal programs got a lot prettier too. It makes sense, its the same font/font renderer provided by the system no matter if the app is a browser or terminal emulator.
- cek 4y agoWhile we're piling on the TUI renaissance, check out Terminal.Gui, a cross-platform library that makes building great terminal UI's easy: https://github.com/migueldeicaza/gui.cs https://github.com/migueldeicaza/gui.cs (Disclaimer, I maintain Terminal.gui).
- hprotagonist 4y agoor rich/textual, for python, which really heap the shiny up high!
- tambourine_man 4y agoOK, this is nuts. How are they doing smooth scrolling? I want that on tmux bad. I'm suddenly really excited for what can be done on TUIs. Like I was some 40 years ago. Edit: and you can write CSS instead of curses? That's seriously cool.
- michaelsbradley 4y agoMake sure to check out Notcurses! https://github.com/dankamongmen/notcurses#readme https://github.com/dankamongmen/notcurses#readme demo: https://www.youtube.com/watch?v=dcjkezf1ARY https://www.youtube.com/watch?v=dcjkezf1ARY
- knorker 4y agoYeah this is very very far from "everything". Among many things it doesn't speak of ptys. And terminfo, pty, ctty, process groups, and the rendering width of a utf-8 string, and, and and… > i might be one of a handful of people left on earth who actually has the knowledge to Uh, no. Anyone on BBSes in the 90s is very aware of ANSI, thank you. And we've not died off yet. And honestly it's really not that hard at all. Even on the topic of terminals this is not even the hardest aspect of it. > i have effectively zero pull in the tech community If you think there's all there's to terminals, yet you act as if you know it all, then you shouldn't have any pull. I would also not accept any pull request that looked even remotely like their example code. Here's a more interesting article about a less understood aspect of terminals: http://www.linusakesson.net/programming/tty/index.php http://www.linusakesson.net/programming/tty/index.php
- userbinator 4y agoFor a second after I read the title, before I saw the domain, I thought that Linus had written a followup article to his original -- very popular on HN -- one. https://hn.algolia.com/?query=The%20TTY%20demystified&sort=byDate&dateRange=all&type=story&storyText=false&prefix&page=0 https://hn.algolia.com/?query=The%20TTY%20demystified&sort=b...
- jart 4y ago> Uh, no. Anyone on BBSes in the 90s is very aware of ANSI, thank you. And we've not died off yet. You guys should be more vocal. When you have great knowledge like that, you can't just keep it to yourself as a fond memory. People wouldn't be saying what the OP said if more of the oldskool crowd was out there blogging and mentoring the younger generation.
- knorker 4y agoIt's not just a fond memory. I use it in my open source. Other people use it. It's not obscure. One thing I actually agree with the author about is that these escape codes are the only relevant thing. Outside of retro computing nobody should care about supporting anything else. Other programs doing this are not exactly in short supply. Anyone can do "ls --color /bin/ls | hexdump -C" and see the secret sauce. I blog about various things, partly to help out people who are less experienced. But I don't pretend what I write about is some sort of lost art, that "only a handful of people know". Like "how do I make bold text in linux terminal" gives as second result this: https://askubuntu.com/questions/528928/how-to-do-underline-bold-italic-strikethrough-color-background-and-size-i https://askubuntu.com/questions/528928/how-to-do-underline-b..., which also links to https://misc.flogisoft.com/bash/tip_colors_and_formatting https://misc.flogisoft.com/bash/tip_colors_and_formatting. Searching on youtube I immediately got this, for those who prefer in video form: https://www.youtube.com/watch?v=OL21-EnsNjQ https://www.youtube.com/watch?v=OL21-EnsNjQ And it manages to do this without the pure arrogance of "i might be one of a handful of people left on earth who actually has the knowledge". Seriously, this whole article could just have been just: "Q: How do I output more than just print black&white text to the terminal? A: ANSI escape codes. See https://en.wikipedia.org/wiki/ANSI_escape_code https://en.wikipedia.org/wiki/ANSI_escape_code" Not "everything you wanted to know about terminals". Like, "how does Ctrl-C work? What's flow control?". No, this post is entirely about ANSI codes. What's extra frustrating is that you too are calling this "oldskool crowd". I'm just not that old, and this just isn't forgotten. It's simply another tool that people use when they need to solve the problem of colors, etc. Just because many people don't know how a malloc()/new becomes a mmap or sbrk doesn't make it "oldskool". It's simply a thing that many people have not learned yet, because they haven't needed to. If and when they need to it's quite documented and many others know it, if they want more hand holding. Like say I didn't know how garbage collectors worked. I don't go "Oh you older generation of lisp programmers, you need to blog more and teach us younglings, so that we can understand the languages that we use". Sure, blogging etc about GCs is good, but who would be arrogant enough to just write an article about "old gen and new gen" and call it "everything you ever wanted to know about GC" and claim that they are one of the handful of people who understand GCs.
- Tr3nton 4y agoI'm sure this is very interesting but I couldn't make it past the first sentence. I'm sure there's a term for someone who writes like this, but all I could think was "redditspeak," or otherwise stale tryhard wacky. Forcibly inserting so much 'character' into your sentences that your syntax implodes.
- deleted 4y ago[deleted]
- voidhorse 4y agoI’m not sure if there’s a term yet. I like to call the general vibe (colors, unnecessary font variations, “I’m gods gift to humanity and all you people and your years of hard work are idiotic and beneath me, even though I have yet to do anything life changing” attitude): programmer wishing they were postmodern artist.
- coastflow 4y agoGood candidates for relevant terms may include "stream of consciousness" as a narrative style [0], with a writing tone that is "highly informal" and "colloquial" with "vulgarity" (from the inclusion of "fuck" and other profane words) throughout [1]. The author additionally uses the writing technique of "enallage", defined as a "slight deliberate grammatical mistake that makes a sentence stand out," [2] from the article excerpt: "in other words, we need to use termios. the ugly side of termios." In other words: the author writes in a highly informal, colloquial tone with a stream of consciousness narrative style. The article is notable for its vulgarity and usage of enallage to achieve its exceptionally high degree of informality. The author is reminiscent of James Joyce as an experienced C programmer. [0] https://liberalarts.oregonstate.edu/wlf/what-stream-consciousness https://liberalarts.oregonstate.edu/wlf/what-stream-consciou... [1] https://english.stackexchange.com/questions/29720/whats-the-difference-between-informal-colloquial-slang-and-vulgar https://english.stackexchange.com/questions/29720/whats-the-... [2] https://www.thoughtco.com/what-is-enallage-1690647 https://www.thoughtco.com/what-is-enallage-1690647
- barrkel 4y agoThis seems to only cover output. At least as interesting, from a usability perspective, is input - making sure that keyboard shortcuts work, in so far as they can be represented. It's not hard to find yourself with an incorrectly configured terminal on a modern Linux distro. For example, try running emacs inside tmux inside rxvt-unicode and find out how Ctrl/Shift/Ctrl+Shift with arrow keys are bound.
- kazinator 4y agoHere is something I learned only several weeks ago. While working on Pipe Watch, I strayed into reading the standard. * The ESC [ command start sequence is actually a compromise for 7 bit systems. The [ character is not chosen by accident. It has an obvious positional relationship to ESC in the ASCII code which is why, informally, Ctrl-[ is the same as ESC. * If you have an 8-bit-clean channel to the terminal, only a single character is required: the "upper escape" from the C1 control character set (0x80 to 0x9F). This character, 128 + 27 or 0x9B is called CSI: control sequence introducer, which is basically its role in these terminal control sequences. Thus ESC [ is just an alternative way of encoding CSI for 7 bit. E.g instead of CSI 4 A, you use ESC [ 4 A.
- duskwuff 4y ago> If you have an 8-bit-clean channel to the terminal, only a single character is required: the "upper escape" from the C1 control character set (0x80 to 0x9F). I'd avoid using this. It conflicts badly with UTF-8's use of 0x80 through 0xBF as continuation characters.
- kazinator 4y agoI don't entirely buy the argument because in a regular ASCII control sequence like ESC[5A, you have the same problem. All those characters have a role outside of the signaling, so if either side is in an unexpected state, they get misinterpreted. This is just the risk of in-band signaling. Of course, if the terminal is ignorant of UTF-8 then this is a nonstarter, because whenever CIS occurs as a continuation byte, it will be misinterpreted. If the terminal is ignorant of UTF-8, why would you send UTF-8 to it, though? If it's going to be interpreting UTF-8 as some branch of ISO Latin, the display will be a mess. If the terminal and host do handle UTF-8, then this CSI signaling is just an extension of the state machine. It's also nice and simple that, in the absence of any data loss or synchronization error, the CSI code is unambiguously not part of any valid UTF-8 character (except as the second or subsequent byte where the receiver is in the right state to interpret it that way). In my experience, it's the terminal->host direction where you get mixups, whereby the terminal generates some escape sequence like for an arrow key, but the host is not in the right state, and interprets part of it as data. This is exacerbated by a situation in which the host supports ESC as a UI command. CSI solves the abmbiguity between the control sequence start and ESC just being ESC.
- WalterGR 4y agoMy understanding is that control codes for [every possible modifier key combination] + ['standard' US keyboard keys] aren't all standardized. Is that correct? I seem to recall having a hell of a time trying to figure out which key combinations Emacs could understand and why (keyboard -> OS -> terminal emulator -> protocol -> program.) Are there any proposals? Workarounds? Proofs-of-concept?
- csdvrx 4y ago> Is that correct? It's not exactly like that - it's more like there are competing "standards" and interpretations of these standards, and sometimes supporting one means not supporting the other. Fortunately, such things are rare, and can be addressed by GUI options. Take for example SGR1 for "bold/intense" text: read the whole issue that came to Microsoft Terminal team in 2018 up to its most recent discussions on https://github.com/microsoft/terminal/issues/109 https://github.com/microsoft/terminal/issues/109 then check the "simpler" version in wikipedia https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_.28Select_Graphic_Rendition.29_parameters https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_.28Select... and you will realize there's no "right" answer between bold and bright (or both!), just different preferences and interpretations of the standards.
- WalterGR 4y agoIt sounds like you’re talking about output, not input. Are there standards to represent, for example, Ctrl+Alt+* (I.e. Ctrl+Alt+Shift+8) ? Additionally with cursor keys, Insert, Delete, Backspace, F1 - F12, etc. I’ve searched several times for such standards before but never had any luck…
- csdvrx 4y ago> It sounds like you’re talking about output, not input. Sorry if I misunderstood your question! However, for inputs the situation is essentially similar: the standards again depend on the terminal, and there can be multiple interpretation than can be conflicting. Take for example Control-H and Control-? : which is delete and which is backspace depend on the terminal you use! > I’ve searched several times for such standards before but never had any luck… There are sources, mostly Thomas E. Dickey (of xterm fame) but personally, I try to take an emulator and make it behave to what my fingers are doing with the minimum level of configuration. To follow up on Control-H and Control-?, here's what my .inputrc does: ### Delete to the right will be remapped to Delete "\e[3~": delete-char # keypad on . #"\eOn": delete-char # Special case for VT100 (borks backspace -> make it conditional) $if term=vt100 "\C-?": delete-char $endif ### Delete to left will be remapped to Backspace "\C-?": backward-delete-char # keypad on 5 #"\eOu": backward-delete-char # Special case for VT100 (borks backspace -> make it conditional) $if term=vt100 "\C-H" : backward-delete-char $endif (yes, the numpad delete has its own case!) Here's another one, for Control-Backspace and Control-Delete ### Line cuts will Ctrl-Backspace and Ctrl-Delete "\C-_": backward-kill-line "\e[3;5~": kill-line # Ctrl-Delete variants for tmux and urxvt "\e[M": kill-line "\e[3^": kill-line And last time I checked, Windows terminal needed proper remaps cf https://github.com/microsoft/Terminal/issues/755 https://github.com/microsoft/Terminal/issues/755 like { "keys": "ctrl+backspace", "command": { "action": "sendInput", "input": "\u0017" }, This would piggyback on "\C-h" backward-kill-word - which might be incompatible as it's got a different meaning for VT-100 as noted above. Quoting you again: > I’ve searched several times for such standards before but never had any luck… You shouldn't bother too much about that: terminals are just tools to help you do your work, and while sometimes you can use a lot of pre-existing configurations or documentation to have as much compatibility among the various standards as possible, there are other times when you need to break the standards that stand in your way. For example, I'm a Windows fan, so I believe Ctrl-C should be copy, Ctrl-V paste, and I don't really care about the traditional unixisms that would cause me try to learn to use Shift-Control-C for copy and Shift-Control-V for paste (just... no!!!) You may disagree with that, so let's take a more staightfoward example: I care even less of the more obscure unixisms like Ctrl-S/Ctrl-Q that I rarely need. Who needs to "freeze" the tty output in 2022? So in that case, I've remapped Ctrl-S to "kill word forward", something usually done with Esc-d by default. To achieve that, in my .bashrc I first clear the defaults with stty: ## Remap ctrl-c to ctrl-x to copy/paste with ctrl-c and ctrl-v, and disable ctrl-s/ctrl-q stty intr ^X stop undef start undef rprnt undef discard undef swtch undef -ixoff -ixon # The above doesn't show ^S,^Q,^R and ^O anymore in stty -a Then I can do the remappings in my .inputrc: ### Backward-kill-word is ctrl-w, while kill-word is alt|esc-d, # so instead, map ctrl-s which makes ctrl-k|u and ctrl-w|s very close "\C-s": kill-word All that to say, standards can be helpful, but there's nothing set in stone: with Control-H and Control-? already causing such headaches (but following all the standards) I don't feel so bad for abusing the standards with my use of Control-S for forward kill word, as it complements nicely the existing Control-K, Control-U and Control-W (all the 3 of which are standard BTW!)
- psim1 4y agoIf this piques your interest and you use Python, check out the blessed library: https://github.com/jquast/blessed https://github.com/jquast/blessed
- voidhorse 4y agoI can tell you why people still use ncurses: if you’re actually interested in accounting for all the nuanced eldritch madness that is terminal emulation implementation and history it’s a monumental effort, at least imo. Sure, if all you care about is coloring text on recent terminals, I do think just using ansi codes is fine. However, I completely disagree with the assertion that hardcoding ansi codes is somehow “more readable” than using a well-named API call that abstracts such detail away from the user. Maybe I’m alone in this, but I really don’t want to waste brain space memorizing ansi codes. Yeah I can write my own library or little macros to do this but…why? If I’m doing anything more involved than coloring text why wouldn’t I just pull in the lib I need? There’s no way in hell I want to maintain a custom implementation of terminal cursor movement for kicks. I’d much rather reach for a battle tested library that scores of other devs have already used and improved upon, whether it’s ncurses or one of the more modern TUI libs. Also, it’s become cool recently to hate ncurses for some reason. Are there things ncurses should do differently from today’s perspective? Sure. Is it’s api awkward to use in the face of modern programming features and paradigms that we’re now used to? Sure. But on the whole it’s design is really solid and it has plentiful documentation. Whenever I see rants like this I get the impression the author is a person that lacks an appreciation for history and the way technical development proceeds in general and imagines they are our technical savior, come down from the heavens to enlighten all us blindered fools about how terrible X is. If you want to educate people about ansi codes, great. A really inefficient way to do that is to wrap your advice in an obnoxious rant.
- msla 4y agoBut, you see, ncurses works, so it can't be allowed to stand. We have to disdain it, and pretend that it's bad for some undefined reason, so we can make half-functional software that ignores any solutions older than My August Personage. It's the Wheel Of Progress or something. /s
- jart 4y agoncurses delenda est (ncurses must be destroyed)
- randomswede 4y ago
- nnoitra 4y agomy eyes....
- _rmcx 4y agoOne thing that the author doesn't seem to know about is /dev/tty. In the article the escape codes are just sent to stdout. Though an awful lot of applications (including the greatest ones) do this, IMHO this is wrong. The terminal control codes are used to control a terminal, and they are often not meant to be part of the output stream, for example when the output is piped or redirected to a text file. When what you intend to do is to make your output fancy only when the output is a terminal, surely you should just send everything to stdout and use isatty to decide whether to also send those terminal control codes. But if what you want to build is a whole TUI like vim or the author's example app, you should send all the control to /dev/tty. This way if needed you can extend your app to be able to be a useful part of a pipe, as bytes sent to /dev/tty will not be redirected but will always be handled by the terminal. To prove that this can be useful, fzf, a fuzzy matcher, uses a TUI to let users input the pattern and pick among the matches, and prints the result to stdout. Sadly, however, it uses stderr to control the terminal instead of /dev/tty; this makes its ability to print error messages somewhat limited and its behavior unexpected when stderr is redirected. Also imagine that you can use vim in a pipe, instead of sed or awk, to see the effect of your edits live. Also, try `vi > /dev/null`. I'd say the behavior is a bug. IIRC ncurses makes use of /dev/tty and by default makes the app made with it redirectable, and this is a reason we should use it in the 21st century, among others. What's sad to me is that so far all the Rust terminal libs I've seen ignore /dev/tty, so it's impossible to use them to build something that both have a good TUI and can be used in pipes.
- knorker 4y agoSo what happens when you do "./foo | less"? You want "foo" to start injecting formatting to the terminal, while "less" is too?
- rcfox 4y agoThis is my first time hearing of this functionality. How does it work with buffered stdout? For example, if you wanted to colour a single word?
- _rmcx 4y ago> This is my first time hearing of this functionality. I was also surprised when I discovered this. IMO this should be used everywhere but I've rarely seen it. > How does it work with buffered stdout? For example, if you wanted to colour a single word? This is not affected by buffering. What matters is what the output device/file/stream gets eventually. How coloring a single word works depends on how you use it. You can do write_and_flush_to_dev_tty(BEGIN_RED_TEXT); write_and_flush_to_dev_tty("word"); write_and_flush_to_dev_tty(END_RED_TEXT); The write_and_flush_... pseudo functions are written in this way just to make it clear that I'm describing the behavior when the output gets the bytes immediately. I don't mean that you should use /dev/tty like this. Redirection won't have any effect on these lines of code. You always get a red "word" on the terminal. The redirection target doesn't get anything. write_and_flush_to_dev_tty(BEGIN_RED_TEXT); write_and_flush_to_stdout("word"); write_and_flush_to_dev_tty(END_RED_TEXT); When directly used on a terminal, you get a red "word" on your terminal, but when you do redirection, the target only gets plaintext "word". write_and_flush_to_dev_tty(BEGIN_RED_TEXT); write_and_flush_to_stdout("word"); write_and_flush_to_stdout(END_RED_TEXT); When redirected, your terminal stays red after the red "word" is printed, and your redirection target gets an extra escape code. When stdout is a tty, /dev/tty is the same as stdout, so a write that goes to one goes to the other. In this case, even if you don't flush after write immediately it's likely not a problem. Still it's something that the developer should pay attention to. ------------- Edit: Please ignore all the pseudocode examples. They don't convey what I wanted to express. Just use /dev/tty in the same way as how you would use stdin/stdout/stderr that is connected to a terminal. Only difference is that it is a rw device that can be used for input and output at the same time.
- somat 4y agoEvery time I read this I disagree pretty hard. curses is not that pretty, but it exists to save us from the insanity that is direct terminal codes. I had an employer once who early on had invested heavily in wyse terminals, and here we were wanting to access these programs with terminal emulators, do you know how many good open source wyse terminal emulators there are? well it is pretty close to zero. Almost every day the mandatory prayer "I wish they had used curses"
- dfee 4y agoFor anyone else on iOS Safari: turn the font size up to 300% on the left hand side of the URL bar. I’m not even geriatric.
- dfee 4y agoRead it through. Enjoyed it. Lexi: font size!
- account42 4y agoThis site would actually has a decent font size and a responsive layout (within reason, code snippes will have additional line breaks) but your browser (like all mobile browser) is intentionally pretending to have a larger desktop viewport and scaling down the result. The way for the website to disable this unhelpful behavior is include the following tag in their <head>: <meta name="viewport" content="width=device-width, initial-scale=1"> It is unfortunate that mobile browser developers have decided to break usability of perfectly fine websites just to provide a workaround for the rare site that has a rigid table-based layout. It is sad that this workaround is still the default now that mobile browsers have a dedicated desktop mode that can be used for such sites.
- teddyh 4y ago> being compatible only with ANSI-capable terminals is a feature, not a bug, go the fuck away. terminfo is a fucking joke. nobody needs to target obscure dumb terminals (or smart terminals, for that matter) from 1983 anymore. No, terminal emulators differ all over the place, especially for new features. Do you want to lock yourself in and only use the ancient ANSI codes? In, like you say, “THE TWENTY FIRST FUCKING CENTURY”? Great, you do that. What’s that you say? You want to use modern features on terminals which support it? Do you then write “if getenv("TERM") == "spiffy-terminal"”? Congratulations, you’ve just begun implementing your very own ad hoc, informally-specified and bug-ridden terminal UI library. > my hope is that this tutorial will curtail some of the more egregiously trivial uses of ncurses and provide others with the knowledge needed to implement a 21st-century terminal UI library If you don’t like curses specifically, then don’t use it, but there are now myriads of alternatives.
- deleted 4y ago[deleted]
- sixie6e 4y agothe author hates ncurses so much he can't escape them lol
- bluenose69 4y agoI'm probably interested in reading the material, but the colours and font make it difficult to do so. Of course, I could switch my browser to reader mode. It would only take a moment. And perhaps this attention-seeking author has some great insights. Maybe my life would be changed, if I just took the time to decode the message. Maybe.
- cab11150904 4y agoNo capitals and useless cussing. Didn't make it past the first 2 sentences.
- 1ark 4y agoI really appreciate posts like this. Learned so much from reading it. Engaging writing style too!