Mle is a small, flexible, terminal-based text editor written in C
github.com
github.com
Ctrl-X to exit is not intuitive. That's used to cut text almost everywhere. Instead, use Ctrl-Q (quit).
It's been 35 years since CUA[1]. Another terminal editor, micro[2], already adopted these conventions—Ctrl-C to copy, Ctrl-X to cut, Ctrl-V to paste—other terminal editors should as well.
Plus it's even used in that one famous Matrix scene[1] where he is trying to close out of whatever he sees open on his computer. ;)
[1]: https://youtu.be/sjoad6gcRzs?t=31 (31 ~ 50s)
It’s no IDE, but it never claimed it was either. It doesn’t require a manual, as even the shortcuts are shown at the bottom of the screen for reference. And it includes syntax highlighting, tab handling, and basic cut/copy/paste handling.
What is it you’re missing from a standard text editor?
Blasphemy. Especially in a terminal environment.
Ctrl-C has meant "Interrupt" since the 1960s.
IBM and MSFT decided to bastardize the Macintosh's Cmd-C into Ctrl-C for "Copy", but this is a historical tragedy that should not be propagated.
Ctrl-S means "XOFF ~(Pause output)", and Ctrl-Q means "XON ~(Resume output)".
Only in context.
I don't really care what Windows people do with their Ctrl keys.
But using Ctrl-C for copy in a terminal environment (from TOPS-20 to Linux and macOS, and whatever MSFT calls its captive Linux env) is wrong.
It is wrong because Ctrl-C already performs another critical (more important) system function. It can't do both, and forking (knifing?) up the UI to have it do different things is a mistake.
Ctrl-C for copy is not a standard in the UNIX/POSIX terminal environment, and it cannot become so, due to the preexisting meaning. Any other usage in that context is wrong and will fail.
Your bias is in your experience too. There may be more of you than there are of me, globally, but your language (UX expectations) is not universal, and will fail in other places.
This is a non-sequitur. Standards change all the time, even things with a preexisting meaning.
I also seriously doubt you believe it yourself. You brought up the example of Ctrl-Q earlier. Is it truly your position that it's not possible for the standard meaning of Ctrl-Q to be something other than XON?
Ctrl-Q does not even reach the application in a standard terminal configuration. It is possible to configure the terminal to allow it, of course, and some existing applications do so.
However, it will not become "standard" because it cannot be ubiquitous, or even common except in certain classes of application.
And what would you do with Ctrl-Q? Quit? Ctrl-C has you covered there (retroactive mnemonic: "Cancel").
So don't bother trying to redefine Ctrl-C either, you will only cause unnecessary pain for your users, and adoption hassles for your software.
Windows users are not your target market for terminal-based software. So instead of inventing your own creole Esperanto patois, just speak the local language!
Between bogarting the Control key and flipping the directory separator, Windows should use the motto "We're different just because we can be."
Let's ask users of the unix style terminal what ctrl-c means there.
And when was the last time you tried pressing Ctrl-C in vim?
It's evidently been many years.
Here, I'll save you a few keystrokes:
vim /tmp/sigh
^C
Type :qa! and press <Enter> to abandon all changes and exit VimVim added Ctrl-C messaging because people complained about remembering :q.
Anyone complaining about that today is just drafting off the historic humor and making a show of their ongoing ignorance.
Line oriented interactions ^C as break maybe makes sense. In a screen oriented termcap application I don’t think you are right.
(Note that "Break" is another key sequence entirely. If someone asks you to send a Break, you would not send Ctrl-C.)
I am arguing that setting Ctrl-C to any other action (esp a very common action like Copy) in a terminal environment application of any kind, e.g. a screen-oriented editor, is a bad idea.
After loaded, some executables install their own handlers for Ctrl-C. None of them are copy/paste.
Emacs does nothing on a single Ctrl-C, and a double Ctrl-C evokes a "this does nothing" message. Vim prints a "how to quit" message.
I'm sure you can find an example of a terminal based program that does something less reasonable with Ctrl-C. I'm not sure you can find an example that treats Ctrl-C as copy. But you could certainly write one. You should expect people to complain if you do!
By the way, Ctrl-D does not close the terminal either. It tells the shell that you're finished sending input, which means it has no more work to do and should exit. If you have jobs running in the background, it will warn you first (default config). If the shell exits, and it was the only thing running in the terminal, the terminal may then decide to close itself. Some do, some do not.
Back to Ctrl-C though, using your example of top as a screen-oriented program: when you press Ctrl-C in top, it interprets the input as Interrupt, and ... exits! Just like a user in a terminal environment would expect. :)
You are right, it does exit on ^C. I picked it as an example of something that seems compliant but doesn’t actually behave like a line oriented program as a screen oriented program.
stdin is a different thing in a screen-oriented program than a line-oriented one, yes. Screen-oriented typically operates on characters not strings, roughly.
Closing stdin in a screen-oriented program doesn't really have a meaningful interpretation.
But if you'd like an example of a screen-oriented program that exits on Ctrl-D, I can offer musikcube. Not very well-known perhaps (though it's a great music player), and to be fair I consider the Ctrl-D behavior to be a UX oddity, however harmless.
Because that's the intuitive behavior in the terminal. The other programs you listed launch their own window and are obviously a different context.
Even things like vim and emacs (the foundational terminal editors) will give you a message that ctrl+c doesn't work the way you expect (admittedly in emacs you have to hit it repeatedly), because it's so expected that it's assumed that's what you're going to try.
You can have different behavior with ctrl + c, but it's going to be confusing enough that you're also going to have to print a message for everyone else.
Ctrl-C means interrupt to everyone in Unix, since the dawn of Unix.
Terminal != Terminal application
Would you really want your SSH connection or editor session with unsaved changes just exit after pressing one key combination? Interactive applications have different requirements than a commandline with much more limited inputs. There's no reason to be against Ctrl-C for copy in a text editor.
xterm should also not respond to an application command.
An editor is an application, and it should respond. You can choose to handle interrupts instead of immediately exiting of course. But the meaning is intact.
A well-behaved application in a POSIX environment will not fight the well-established conventions. There are many reasons for this, but the two most obvious are:
- The implementation of the expected behavior might be outside of your control. Try pressing Ctrl-S in some terminals, and you will find that it does not reach the application because flow control is handled at a lower layer. By convention.
- Just don't abuse your users! If they get accustomed to using the non-standard Ctrl-C for copy, and then use that same action in another application, they might lose data and it will be your fault.
That ship has sailed. Today, most people are accustomed to using Ctrl-C to copy.
That is not true, in the relevant context: that within which this software is released.
Microsoft didn't make their own keyboards (at the time), so was at a bit of a disadvantage when they copied the functionality from Apple. They didn't have to choose Ctrl, but they apparently decided that multitasking and job control were the domain of non-personal computers and not their problem.
Trying to remember where some option in a cluttered dropdown menu you used 20 minutes ago is working memory, something I'm personally terrible with. It's either whiplash out of a flow state, or risks sidetracking me.
It takes practice to build muscle memory, but it's something that generally stays with you for a long time, so it's an investment.
The point is that you don't think about keyboard shortcuts. You just think about the thing you need to do, and let your hands do it.
This is why old cashier systems are so super fast.
If something can open a shell remotely, it can show a GUI remotely.
Secure servers do not include GUI packages. They are enormous, require elevated privileges, and have a poor security history.
No reasonably quasi-secure server in the last 25 years has included GUI packages, but has allowed and often depended on shell access.
Modern deployment regimes which include ephemeral instances sometimes do not permit shell access.
These are not the same things!
By having my editor (and the LSP servers, etc.) running on a different machine I can afford to have it be a big, high core count Linux machine maybe with GPUs in it that is arbitrarily hot or loud or heavy. For many languages (C/C++, Haskell, Rust, there are others) either the build or the go-to-definition or some other frequently-done thing are slow on even the best laptop / quiet PC.
By having the client machine be an appliance running a terminal emulator, my colleagues and I can be indifferent to one another’s choices in desktop environment: there can be Mac people and Windows people and desktop Linux people etc. In my case I can have a slim little MacBook Air that can drive a big display, play sound properly out of the box, wake/sleep properly out of the box, and otherwise get out of the way while I work on the “real” computer, which can be anywhere with a manageable ping from here.
There are disadvantages too: mostly that networks go down, GUIs are nice for some things, and others. It’s not a free lunch.
It’s a tradeoff (and I’m aware that it’s surprising to many that regular computers still aren’t fast enough for many hackers), buts it’s not just Luddism.
If all your boxes are reasonably local those can be great options, but they still don’t obsolete tmux and stuff. Nothing obsoletes tmux and stuff.
Whether it’s vi or emacs or tmux or whatever: this field is too competitive to let shitty stuff stick around for decades. People who go all terminal know the alternatives, they’ve tried them, they try the new ones, and they know what the fuck they’re doing.
And if the speed is lower, then typically it also implies a high latency. Then I have found that running a GUI remotely via xpra gives a better experience than running an editor with IDE features under ssh and tmux. I suspect XPRA protocol simply has less round trips than a terminal IO as the latter was never designed for high-latency links.
Because unlike web apps, terminal apps are often fast (and even faster when the terminal has HW acceleration, see for example https://alacritty.org). Unlike native GUIs, they can easily go through a low-bandwidth network connection (e.g. ssh). They are often portable and can be easily made stable without a huge stack of dependencies.
I spend a lot of time ssh’ed into other computers where there is no gui.
I often tell new devs that there are different formats for computer programs, just like with media.
1. One dimensional, text only
2. Two dimensional desktop
3. Three dimensional VR / AR, etc
Just like audio, video and physical immersive art, having one that exists doesn’t make the others invalid, bad, or useless. You need to pick the right format for the job.
If you’re doing “low level” things one dimensional is often the most useful - which, I think, is why the hacker community prefers terminal based.
(not to mention you can often view lower dimensional things in higher dimensions, but not the other way around (something like running a terminal in VR vs VR in a terminal))
* You get a video in a standard container and modern compression format you can host anywhere, and edit with video editing tools.
* Screen recorders can capture the microphone too, so you can explain what you're doing.
* Importantly, they can also capture the mouse cursor, which is useful even in a demo of a TTY app that has no built-in mouse support, because you can point to things in the terminal and highlight them as you speak. Mouse-based copy and paste actions are easier for the viewer to follow when there is a cursor.
* Everything you see is captured, pixel for pixel (other than very very fast, fleeting actions that are quicker than the frame rate, obviously).
* If in the demo you need to scroll up through the TTY history with the scrollbar or Shift-PgUp, that is all nicely captured. Your scrollbar is included in the video.
I can't recommend asciinema becuase while the tools to record TTY sessions are free, the animated rendering is done by uploading to the website. There are ways to self-host asciicast, but that looks like a huge PITA compared to a video file you can send to someone as a mail mail attachment, drop into a Slack channel, or put into a shared file directory. I don't want to become a host to give someone a file.
I tried alternatives to asciicast like ttystudio; they are all a hassle compared to even the most basic screen recording app like kazaa on Ubuntu, and lose on all the above points. But at least some of the alternatives give you a GIF file you can put anywhere.
Some work by simulating an ANSI terminal internally, rendering it to pixels and taking snapshots of that state --- which is just a form of screen recording!
I would say it's fair to TTY specific recording an anti-pattern. It seems cool and everyone is doing it, until they slap themselves on the forehead one day.
* Asciinema text uses the user’s preferred font instead of whatever monstrosity of a Comic Code font the developer happens to like
* Asciinema text can be selected and copied
* You can zoom in on it and it’ll still be high quality
etc. Arguing against Asciinema is like saying you prefer when people take screenshots of their Gnome Terminal windows instead of inserting code blocks into their blog posts :p
Does this mean I can have a vi-like experience, but I have to configure it myself? A quick look into the help page of mle was not very helpful.
The power of Vi is in the grammar. It’s fairly intuitive to combine motions with verbs, and you can string together chains of commands without much thought.
For example, “04wd$VU” would uppercase the first four words in a line and delete the rest of the line.
I don’t think something like that would be achievable with the basic key mapping that Mle has.
Vim colleagues insist I could just write macros, yeah no.
"Here you go"
"Yeah no"
Not sure if I'd go with that one.
For an interactive program, favor simplicity over portability to more than a handful popular platforms that people are actually using.
Do not favor simplicity over portability to more than one platform. (Feel free to ignore this if you work for Microsoft, as the maintainer of calculator.exe, and similar work.)
Definitely favor simplicity over portability to systems that use sign-magnitude integer representations, or have 36 bit words and 9 bit bytes, or binary files that add extra zeros to pad your file to a full sector, or have no POSIX or Windows API whatsoever, or whose null pointer is not an all-zero bit pattern, ... even if your program runs on some computer they have in the basement of the Smithsonian, they are not going to to risk installing it there, and if they do, nobody will use it.
vim is also super extensible with plugins - one of the biggest reason to use it.
Modal editing is definitely a must for terminal editors, and generally good for all editors.
I'm personally not the crowd who'd use this kind of software. My preference is emacs which has a different philosophy when it comes to "hacking" the editor.
This project might be something for the suckless crowd.