Live data from Hacker News

Terminals Are Weird

catern.com

21–30 of 48 posts

Re: Terminals Are Weird

#21

This, like many things, is a case where many different problems get complected, because no one is able to step back and tweak every level of the stack to cleanly separate out the relevant models/abstractions. Ideally, a computer keyboard would be able to directly send both an arbitrary number of named control functions, and arbitrary unicode text (either as full strings or as code units one by one). Instead though, k…

> Ideally, a computer keyboard would be able to directly send both an arbitrary number of named control functions, and arbitrary unicode text (either as full strings or as code units one by one)

You're right about how the input stack is tangled up, but wrong about the ideal state. The keyboard is absolutely not the right place for this sort of intelligence.

No keyboard has 100k+ keys, so Unicode input is fundamentally a UI problem. Look at the enormous number of Chinese input methods, all of which need to cooperate closely with the GUI to work. Or heck, how do you type é? On OS X, you can either press option-e followed by e, or press and hold e, and select from a popup menu. These both require integration with the OS and GUI, and cannot be handled by the keyboard itself.

Even setting aside Unicode input, we still often need to know which keys were pressed. I'm programming a FPS game - what happens when the user presses the 2 key? If it's on the number row, it should select weapon #2; but if it's on the numpad, it should move the character backwards. So it's not enough to know the key's character; I need to know which physical key was pressed!

The layered approach you describe is confusing and error-prone, but it's necessary, because software needs to act at different levels. Some software wants very high-level Unicode text input, while others need to know very fine-grained keyboard layout details. All of the data must be bubbled up through all layers.

Re: Terminals Are Weird

#22

This, like many things, is a case where many different problems get complected, because no one is able to step back and tweak every level of the stack to cleanly separate out the relevant models/abstractions. Ideally, a computer keyboard would be able to directly send both an arbitrary number of named control functions, and arbitrary unicode text (either as full strings or as code units one by one). Instead though, k…

> Ideally, a computer keyboard would be able to directly send both an arbitrary number of named control functions, and arbitrary unicode text (either as full strings or as code units one by one) You're right about how the input stack is tangled up, but wrong about the ideal state. The keyboard is absolutely not the right place for this sort of intelligence. No keyboard has 100k+ keys, so Unicode input is fundamentall…

I said this was my ideal, not that it was a practical way forward for our current software stack.

In my ideal world, your app registers that it needs a “pick weapon #2” button, and a “walk backward” button. Then I can configure my keyboard firmware and/or the low levels of my operating system keyboard handling code to map whatever button I want to those semantic actions.

The problem with the scheme where the application is programmed to directly look for the “2” key and then pick which semantic meaning to assign based on context, is that there is at that point no way to intercept and disambiguate “put a 2 character in the text box” from “pick weapon #2”.

This isn’t the biggest problem for games, but it’s a huge pain in the ass when, for example, all kinds of desktop applications intercept my standard text-editing shortcuts (either system defaults or ones I have defined myself) and clobbers them with its own new commands (for example many applications overwrite command+arrows or option+arrows or similar to mean “switch tab”, but in a text box context I am instead trying to say “move to the beginning of the line” or “move left by one word”), often leaving me no way to separate the semantic intentions into separate keystrokes.

The problem is that there is no level at which I can direct a particular button on my keyboard to always mean “move left by one word”... the way things are set up now, I have literally no way to firmly bind a key to that precise semantic meaning, but instead I need to bind the key to some ambiguous keystroke which only sometimes has that meaning, but sometimes might mean something else instead.

Re: Terminals Are Weird

#23

Terminals aren't weird. It's just that they work by sending and receiving strictly characters. If you look into ASCII or Unicode, there is no Ctrl+Shift+I character, so such a thing cannot be transmitted. That's not quite the end of the story because terminals can certainly generate special escape sequences for certain keys, depending on the terminal type. For example, although there is also no ASCII character corres…

> In principle, your terminal could also turn Ctrl-Shift-I into some special escape sequence which an application could parse. Such a sequence just doesn't exist in the terminal protocol you are using, that is all.

A specification that allows all key combinations to be recognized by terminal applications does indeed exist: http://www.leonerd.org.uk/hacks/fixterms/

Sadly, very few apps use it. Vim for example doesn't, but maybe there is hope that NeoVim will: https://github.com/neovim/neovim/issues/176

Re: Terminals Are Weird

#24

I totally don't buy the recommendation. If you're going to do something new, you better stop worrying about backward compatibility. ssh and tmux won't work? big effin deal. Those projects would need to grow up in order to keep up with the times. You can't be conservative like that if the goal is to right the wrongs and learn from past mistakes. The road is going to be bumpy but the light at the tunnel would be worth…

> ssh and tmux won't work? big effin deal

So when I want to ssh into a remote machine, I don't use your new program, unless you've also written an ssh replacement. If I want virtual screens, I don't use your new program, unless you've also written a tmux (or screen) replacement. Et cetera.

Your new terminal program is useless till you've replaced or updated "all" the programs that depend on traditional terminal behavior. And "all", in this case, is reasonably close to being literal. If you get 80% of what I need, it's not enough. And the last 20% will likely differ from person to person.

And I'll need to replace my keyboard, too?

I totally don't buy that you're not being tongue-in-cheek.

Re: Terminals Are Weird

#25

Terminals aren't weird. It's just that they work by sending and receiving strictly characters. If you look into ASCII or Unicode, there is no Ctrl+Shift+I character, so such a thing cannot be transmitted. That's not quite the end of the story because terminals can certainly generate special escape sequences for certain keys, depending on the terminal type. For example, although there is also no ASCII character corres…

Terminals are weird, but it's not because of the data stream.

The real mind-bending weirdness is in the kernel tty layer, for historical performance reasons. Userspace apps weren't able to keep up with typing in the early days, so the kernel is expected to handle stuff like simple editting (^H) and line buffering. And it has to handle baud rate and uart settings, of course. And it has to trap "special" keys like ^C so that hung applications can be reliably terminated via a signal. And it has to detect dropped lines to free up the terminal for other users.

And it still does all this nonsense even in a world where those use cases are all forgotten.

Terminals are weird.

(But no, there aren't any other good alternatives, so we just deal with it.)

Re: Terminals Are Weird

#26
post #25

Terminals aren't weird. It's just that they work by sending and receiving strictly characters. If you look into ASCII or Unicode, there is no Ctrl+Shift+I character, so such a thing cannot be transmitted. That's not quite the end of the story because terminals can certainly generate special escape sequences for certain keys, depending on the terminal type. For example, although there is also no ASCII character corres…

Terminals are weird, but it's not because of the data stream. The real mind-bending weirdness is in the kernel tty layer, for historical performance reasons. Userspace apps weren't able to keep up with typing in the early days, so the kernel is expected to handle stuff like simple editting (^H) and line buffering. And it has to handle baud rate and uart settings, of course. And it has to trap "special" keys like ^C s…

The tty layer handles line editing so that programmers do not have to replicate this functionality.

If you write a simple program that obtains commands using "fgets", you automatically get simple editing, and that functionality goes away when the input is redirected from some other device or file.

The simple editing is consistent from program to program and maintains the user's preferences.

The tty input editing could be done in user space, like in the C library (and in POSIX implementations on non-Unix kernels like Cygwin and whatnot, that seems to be where it is).

The mind-boggling complexity is in sessions, controlling terminals, POSIX job control, foreground and background process groups and such.

Plus the quirks: like Ctrl-D just means "return now from the system call", so it only signals EOF when typed on an empty line due to read returning zero. And on TTY's it's a recoverable condition:

   cat /dev/tty /dev/tty
   a
   b
   c
   [Ctrl-D] # first "EOF"
   d
   e
   f
   [Ctrl-D] # second "EOF

Re: Terminals Are Weird

#27

Earlier quoted context omitted.

> Ideally, a computer keyboard would be able to directly send both an arbitrary number of named control functions, and arbitrary unicode text (either as full strings or as code units one by one) You're right about how the input stack is tangled up, but wrong about the ideal state. The keyboard is absolutely not the right place for this sort of intelligence. No keyboard has 100k+ keys, so Unicode input is fundamentall…

I said this was my ideal, not that it was a practical way forward for our current software stack. In my ideal world, your app registers that it needs a “pick weapon #2” button, and a “walk backward” button. Then I can configure my keyboard firmware and/or the low levels of my operating system keyboard handling code to map whatever button I want to those semantic actions. The problem with the scheme where the applicat…

> In my ideal world, your app registers that it needs a “pick weapon #2” button, and a “walk backward” button. Then I can configure my keyboard firmware and/or the low levels of my operating system keyboard handling code to map whatever button I want to those semantic actions.

Then the OS / Firmware is dealing with questions like, "What button fires the secondary dorsal thrusters". Does it make sense to handle that kind of question so far from the site where the semantic knowledge is present? No.

Likewise, a web server doesn't provide application-level semantic information in its replies, only protocol-level semantic information. One application might think 301 means "update the bookmark" and 502 means "try again later", but another application might think 502 means "try another server" or that 404 might mean "delete a local file" or "display an error message to the user".

Likewise, a game is prepared to deal with buttons, not semantics. The number and layout of buttons is closely tied with design decisions. A FPS gives you WASD, plus QERF for common actions, ZXC for less common actions, 1234 for menus / weapon selections. The design of the game from top to bottom is affected by this. You swap in a controller for a keyboard, and you'll decide to change how weapon selection is presented: maybe spokes around a center so you can use a joystick instead of items in a row corresponding to numeric buttons. You add auto-aim to compensate for the inaccuracy inherent in gamepad joysticks, but the vehicle sections become easier. You might even redesign minigames (Mass Effect has a completely different hacking minigame for console and PC versions).

Or look at web browsers. As soon as you hook a touch interface to the web browser you might want to pop up an on-screen keyboard in response to touch events, but you need to move the viewpoint so that you can see what you're typing.

Input is inherently messy, and you can't pull semantics out of applications because you'll just make the user experience worse.

ON THE OTHER HAND...

> The problem is that there is no level at which I can direct a particular button on my keyboard to always mean “move left by one word”...

This is available through use of common UI toolkits. I believe on OS X, you can bind a button to mean "move left by one word" in all applications which use the Cocoa toolkit (which is the vast majority of all applications on OS X). The way this works is there are some global preferences which specifies a key binding for "moveWordLeft:". The key event, when it is not handled by other handlers, then gets translated to a "moveWordLeft:" method call by NSResponder. The method for configuring these key bindings is relatively obscure, suffice it to say that you can press option+left arrow in almost any application to move left one word, and you can configure the key binding (i.e., choose a different key) across applications on a per-user basis.

https://developer.apple.com/library/mac/documentation/Cocoa/...:

Re: Terminals Are Weird

#28
post #25

Earlier quoted context omitted.

Terminals are weird, but it's not because of the data stream. The real mind-bending weirdness is in the kernel tty layer, for historical performance reasons. Userspace apps weren't able to keep up with typing in the early days, so the kernel is expected to handle stuff like simple editting (^H) and line buffering. And it has to handle baud rate and uart settings, of course. And it has to trap "special" keys like ^C s…

The tty layer handles line editing so that programmers do not have to replicate this functionality. If you write a simple program that obtains commands using "fgets", you automatically get simple editing, and that functionality goes away when the input is redirected from some other device or file. The simple editing is consistent from program to program and maintains the user's preferences. The tty input editing coul…

Well, sure. But in a sane modern architecture that simple editor would be implemented in a userspace app (the terminal emulator would be an obvious candidate) and speak a sane protocol instead of the ioctl madness we have with termios.

But it doesn't and it won't, so we all deal with it. But it remains crazy.

Re: Terminals Are Weird

#29

Earlier quoted context omitted.

I said this was my ideal, not that it was a practical way forward for our current software stack. In my ideal world, your app registers that it needs a “pick weapon #2” button, and a “walk backward” button. Then I can configure my keyboard firmware and/or the low levels of my operating system keyboard handling code to map whatever button I want to those semantic actions. The problem with the scheme where the applicat…

> In my ideal world, your app registers that it needs a “pick weapon #2” button, and a “walk backward” button. Then I can configure my keyboard firmware and/or the low levels of my operating system keyboard handling code to map whatever button I want to those semantic actions. Then the OS / Firmware is dealing with questions like, "What button fires the secondary dorsal thrusters". Does it make sense to handle that k…

"Likewise, a game is prepared to deal with buttons, not semantics. The number and layout of buttons is closely tied with design decisions. A FPS gives you WASD, plus QERF for common actions, ZXC for less common actions, 1234 for menus / weapon selections."

Except on my keyboard layout an FPS should be giving me QSDZ, for the same pattern of movement keys, because I'm French and use AZERTY. Or AOE, because I use Dvorak; ARSW because Colemak...

Not really, but you take my point...

And of course, most games let you redefine your keys anyway, probably largely for this reason. I'm not sure how much this undermines your other points.

Re: Terminals Are Weird

#30

Earlier quoted context omitted.

> Ideally, a computer keyboard would be able to directly send both an arbitrary number of named control functions, and arbitrary unicode text (either as full strings or as code units one by one) You're right about how the input stack is tangled up, but wrong about the ideal state. The keyboard is absolutely not the right place for this sort of intelligence. No keyboard has 100k+ keys, so Unicode input is fundamentall…

I said this was my ideal, not that it was a practical way forward for our current software stack. In my ideal world, your app registers that it needs a “pick weapon #2” button, and a “walk backward” button. Then I can configure my keyboard firmware and/or the low levels of my operating system keyboard handling code to map whatever button I want to those semantic actions. The problem with the scheme where the applicat…

I can touch-type on a QWERTY keyboard. For the Latin alphabet, I want a QWERTY layout even when I'm typing French or German; even when the keyboard is physically labelled AZERTY or QWERTZ. I type Korean on a 2-Set Hangul layout, but have never used a keyboard that was labelled with that layout. (Aside: typing in this layout does not generate a Unicode codepoint per keypress, but combines two or three letters into a single codepoint).

If the keyboard was responsible for deciding all this, I'd need three keyboards and I'd need to carry them around with me whenever I wanted to use somebody else's computer.

Post reply on HN