1. 11

    This article is much more than its title. It ties together a lot of interesting threads about project values, what emacs/vim/neovim/vscode all stand for, discusses software freedom and the evolution of mature projects, and more. Long, but highly recommended.

    1. 3

      I think the title is intended as being very tongue-in-cheek! But yeah, great article.

      1. 6

        I think the title is intended as being very tongue-in-cheek!

        You got it.

        But yeah, great article.

        Thanks Phil. You’re one of my inspirations for starting to use Emacs by the way :)

        1. 5

          I think the title is intended as being very tongue-in-cheek!

          You got it.

          No doubt. I just wanted to make sure it wasn’t being overlooked because of that.

          1. 1

            nods

            Props for going through the whole thing!

          2. 4

            “Now, back to work. What was I doing again? Oh yeah, let’s open that file.”

            That was a really great payoff for those of us who made it to the end :)

            1. 6

              Heh. Funny thing, when I started writing the essay I had the first and the last sentence ready. From there, I only had to fill in the middle… which took a few months.

          3. 1

            I hadn’t actually finished the article when I posted this yesterday. =)

            It is very easy to either freeze Emacs or cause it to run very slowly. Multiple times a day I have to hit C-g incessantly to bring it back from being frozen. When that fails, I am sometimes able to get it back with pkill -SIGUSR2 Emacs. At least once per week I have to pkill -9 Emacs because it turned completely unresponsive.

            This is wild for me to hear! I run Emacs as my entire window manager, and the situation of having to cancel a long-running operation with C-g happens … maybe a couple times a month for me. I wonder if the situation for the author is worse because he’s running it on a proprietary platform, or is there some other confounding factor?

            1. 2

              Off the top of my head, my main culprits for freezes and slowdowns are (1) Tramp, (2) Flycheck+Tramp interactions, (3) accidentally opening files with long lines (the many mitigations don’t seem to work consistently), (4) magit with large git repositories (especially via Tramp) and (5) eshell output with long lines.

              1. 1

                In that case this is a nice validation of my choice to run Emacs over SSH. =)

                I have a similar situation where all my work stays on my work computer (which is fast and has a lot of ram, but has a terrible display) so I use my personal laptop most of the time. Using Emacs inside mosh+tmux allows me to maintain the illusion that it’s all local; when I wake my laptop up the connection is re-established in a second or two.

                The only downside is that pressing enter on URLs can’t open them in my local browser, so I have to handle that part using my terminal emulator. So far urxvt is the only one I’ve found that allows me to open URLs without using the mouse, so I’ve stuck with it all these years.

                1. 2

                  I’ve recently switched to Emacs over SSH for work too. It works surprisingly well, but I do miss the graphical interface, especially for posframe and Org. Also, I still have to configure my terminal app so that I can use the command key for the Emacs meta and have yanked text be put into the system clipboard.

                  I’m curious if you have any ideas or reactions to “The values of Emacs” or “From catching up to getting ahead”. Were the arguments and characterizations fair? Does the “Emacs wishlist” intersect with what you envision for the future?

                  1. 2

                    but I do miss the graphical interface, especially for posframe and Org

                    I’m not a big Org user but I’ve noticed that Org has some curious key bindings; is the main problem that these can’t be represented within the limitations of terminals?

                    I’m curious if you have any ideas or reactions to “The values of Emacs” or “From catching up to getting ahead”.

                    I agree with your characterization of the values, except I might frame it differently. To me the most important thing about Emacs is a combination of extensibility and introspectability, but those two words on their own don’t really capture it fully; it’s the “live-ness” of the extensibility and introspectability. If I had to sum it up in one word, the only word I can think of is “smalltalkness”. The seamless reprogram-as-you-go-ness.

                    When it comes to the specifics of competing with VS Code, I’ve long ago made my peace with the idea that I lost the ability to put my head in the place of the “typical new user” and so it’s difficult for me to look at VS Code and see what it is about it that has caused it to become so successful; all I can see is a program that isn’t built around the quality of smalltalkness. That one factor has become so dominant in my view that it obscures everything else. (Similarly my view of LSP is colored by the fact that it’s emphatically not repl-driven and that the implementations I’ve seen for things like Clojure do a poor job of a lot of core functionality that we have long had great repl-based tooling for, so I never bothered to set it up.)

                    I realized while reading that section that Doom and Spacemacs functionally acts as Emacs forks in some less-severe ways; like XEmacs their popularity places pressure on the mainline Emacs to modernize and change with the needs of newer users. I had never really thought about it in those terms before.

                    As for the wishlist, I think I am less concerned with single-core efficiency; the main thing I would like to see is a kind of actor-based system. Multi-core support in Emacs that uses threads with shared memory is just a fundamentally doomed idea, but splitting off threads that use message passing to communicate seems promising, especially if you could send a buffer to another thread (and lose access to it from your current thread). The compatibility problems this brings are serious and severe, so I can understand why not a lot of progress has been made.

                    The rendering engine is something I abstractly see as needing a lot of improvement, but it’s not a pain point I run into personally. Same with stability; I can’t remember the last crash I witnessed; it’s probably been around two years.

                    From a language level I would love to see a good module system. That could be done in an incremental way and allow for much cleaner patterns around hiding implementation details. I would also like to see a good associative data structure; hash tables have always been an absolute disaster when I’ve tried to use them. But admittedly I haven’t kept up with the new core functions so maybe it’s gotten better.

        1. 2

          This seems to imply that you can plug both in at the same time, but there is cable juggling to switch, right?

          1. 1

            It looks like you can connect two computers to the TS3 at the same time, but only one of them can see the the connected dock peripherals at a time.

            I have a Caldigit TS3 dock and two Thunderbolt 3 capable machines (a Z390 based Hackintosh and my work MBP) and the way I share the all my TS3 connected devices between the two machines is by using three Thunderbolt 3 -> Thunderbolt 2 adapters in conjunction with a Thunderbolt-2 KVM switch.

            This is a pretty ugly and expensive hack that I’d hesitate to recommend to anyone, but it works for me, in that it enables me to explicitly control which computer has access to the TS3 dock (with no cable juggling) at the cost of a 50% reduction in bandwidth.

            1. 1

              You also lose charging, right?

              1. 1

                Yeah, no charging with Thunderbolt 2.

          1. 5

            I recently bought a Logitech Streamcam (1080p60) with a good 1/2.0 aperture and very good image and sound quality. While browsing the market, it seemed to be the only sensible choice (who needs 4k when no service transmits at that resolution?). Much more important than image quality to me is high framerate (i.e. 60 FPS). The image quality of the Streamcam is really good and it works natively with the basic UVC-drivers in Linux, even though there still seems to exists a race-condition in its firmware that will probably be fixed soon.

            Anyway, I’d pick that if anyone asked me for a recommendation. The next step basically seems to be to use a DSLR and a USB-HDMI-streamer, but this is just overkill for meetings. I’d think about it if I was a high-ranking executive in a company being in meetings all day or something.

            1. 3

              Anyway, I’d pick that if anyone asked me for a recommendation. The next step basically seems to be to use a DSLR and a USB-HDMI-streamer, but this is just overkill for meetings. I’d think about it if I was a high-ranking executive in a company being in meetings all day or something.

              Some Canon cameras have a webcam driver, and i’ve been using it on and off (with a Rebel T6) since it came out earlier this year. The trade-off is you get great optics (I love how I look in a wide-angle lens, and a big lens makes the lighting vs. sensitivity & shutter speed trade-off less pronounced), but the weight of those optics (450g body + 385g lens) makes it less flexible to position than a normal webcam (Logitech C920 is 162g) on an articulated arm. I have done a few calls that really benefit from a big studio-type setup where I can spend time setting it up, but the daily or weekly meetings don’t really need that.

              1. 2

                I use a 2012 vintage Canon EOS M (which I picked up off Ebay for ~$150) and a cheap 1080p USB HDMI capture card. I was drawn to the EOS M because of its great support for Magic Lantern (an Open Source camera firmware) which allows for clean HDMI output.

                1. 1

                  Oh wow, that’s a very cute camera :3

                  Mine sadly doesn’t have Magic Lantern yet, and no clean HDMI either.

                2. 1

                  Is that by using the EOS Webcam Utility or does the newer models come with webcam support built in?

                  I’ve previously tried the webcam utility beta version with a camera when it came out (can’t remember if it was the 6D or 550D/Rebel T2i I used) and it wasn’t really usable since there was a very noticeable delay in the video input which wasn’t the case for the audio (it came directly into the laptop).

                  I didn’t look into ways of delaying the audio to sync it up with the video, but I guess it could have been usable if I got that worked out.

                  1. 1

                    It’s the webcam utility, yeah. I didn’t notice any difference in latency between the camera and a USB mic or Bluetooth headphones.

              1. 5

                Recently also acquired the TS3 and I am a bit awed by the power of Thunderbolt 3. One cable carries 87W of power, 4K@60Hz, and a huge number of USB 3 at 10 and 5Gbps. My monitor also has a few USB-A ports which themselves get carried through its Thunderbolt 3 to the dock and then to the laptop. It’s clean as heck.

                1. 2

                  I love mine too — only problem is my 2020 MacBook Pro technically requires 96W of power, though I never drive it hard enough for long enough to have trouble. But I think Apple just solved that problem permanently with the M1…

                  1. 1

                    It’s also been reported that the M1 has Thunderbolt 4 ports, which support hubs that can multiplex one Thunderbolt-4 port into three – handy for devices that only have one port on them and don’t support chaining.

                1. 3

                  For someone who’s never used buckling spring, how is the feel different from, let’s say, cherry mx browns or blues?

                  Always been curious about the Model M. It seems to have a dedicated loyal following.

                  1. 9

                    They’re a lot heavier.

                    1. 9

                      Also you spouse, cat, neighbours, and your neighbour’s neighbours will know when you’re coding at night.

                    2. 6

                      I love the sound and feel of buckling spring switches. They have a satisfying ‘snap’ to them when pressed – I can’t think of a switch I’ve typed on that had better feedback. That said, the Model M itself is not a very ergonomic keyboard, which is why I don’t use one. I’ve become quite dependent on having 12 thumb keys, nice hand separation, concave key wells, and an ortholinear layout..

                      1. 1

                        What keyboards do you recommend that meet your criteria for being ergonomic?

                        1. 1

                          Based on the description, I think spudlyo is thinking of the Kinesis Advantage.

                          1. 1

                            Yup, as avh-on1 guessed, I’m a Kinesis Advantage user, and have been for the past 10 years or so. Nowadays there are a few other keyboards that have some of these features, like the ErgoDox EZ which are gaining in popularity. Since switching to the Kinesis, I’ve not had any issues with pain in my hands or wrists, and now that Control and Meta are on my thumbs no reoccurrence of “Emacs pinkie” either.

                          2. 1

                            I’ve always wanted to try a nice ergonomic spring-buckling keyboard. Sadly, no one seems to make them (and the physical layout seems different enough that adapting an existing one would be too much effort), so I’ve stuck with my trusty kinesis.

                          3. 4

                            Cherry MX blues feel linear but with a high-pitched bump in the middle (which makes sense because they use a metal click leaf). The Model M’s buckling springs feel heavier and “springier” (the force curve isn’t linear), and make a lower-pitched sound.

                            1. 3

                              MX switches are essentially friction based, using plastic on metal to create fric…feedback. Buckling springs operate in a entirely different manner and are hard to compare. You press down on a spring, which eventually buckles and creates the sound, the tactile feedback and triggers the key press.

                              I kinda liked my Model M (which I found in an electronics dumpster at work), but decided to throw 400 USD at a new Model F keyboard when drunk for the lulz.

                              The Model F is such a nice keyboard. It’s hard to go back to anything else! But it’s also loud and ping-y so I can barely use it at home or at work (which these days is the same thing haha).

                              1. 2

                                It’s like the difference between hitting a wiffle ball versus a baseball. Buckling springs are heavier and more gratifying.

                                Full disclosure, I prefer cherry reds. to extend the metaphor, they feel like swinging a wiffle ball bat and missing, which sounds bad, but I like the effortlessness. I have been through both unicomp and IBM model Ms and loved them but at some point I joined the light (actuation force) side. I think the reason the unicomp ones are lighter is because they have an aluminum backplate (rather than steel)

                                1. 1

                                  You have to press harder. Laying your hands across the keyboard will not type a key by accident. The spring has a bit of a ringing sound after the keypress. “Ka-chunggg”

                                1. 1

                                  neat idea, but it doesn’t work for me (tmux 3.1_c):

                                  ❯ tmux popup -R "ping meain.io"
                                  unknown command: popup
                                  
                                  1. 1

                                    This is a new feature in 3.2, which is currently at rc2.

                                    1. 1

                                      Oh. Thanks, the author could have mentioned this wasn’t a released feature yet :P

                                  1. 2

                                    Holiday projects! I’ve been meaning to write a blog post about the mechanics of how gpg-agent chooses to use Emacs for pinentry, and what you need to do on the Emacs side to make that work. I’m also wanting to patch Polybar so customi/ipc hooks can take arguments. Finally, I’d like to spend more time learning Guix preferably by writing Guile code.

                                    1. 0

                                      It actually ships a manpage.

                                      1. 20

                                        … which clocks in at ~19,000 words, and after a short description which introduces terms like sessions, pseudo terminals, windows, and panes, begins with an alpha sorted list of options followed by the default key bindings.

                                        I take no issue with well written easy-on-the-eyes blog posts about how to get started with tmux. Having said that though, I’d really like to read meatier articles about tmux that cover more advanced topics.

                                        I’m reminded of a remark from last year by nicm, maintainer of tmux:

                                        I’d like to see a few tmux 102 or 201 or whatever articles that cover some of the more advanced features such as hooks, targets and IDs, monitoring and alerts, formats and #(), command sequences, if-shell and run-shell, new/neww/splitw -P and shell scripting with tmux, buffers, capture-pane and pipe-pane, find-window and filters etc in the choose modes, pane titles, terminal-overrides, linking windows and session groups, detach -P, remain-on-exit and exit-unattached and detach-on-destroy, the mouse and advanced key bindings, the new status-format stuff in 2.9, and even menus coming in 3.0.

                                        Personally, I’m really psyched about the new popup windows that are coming in 3.2, and would love to read more about that feature. Of course I know I could write one myself I suppose :-).

                                      1. 3

                                        This is a good presentation, but I find it funny how terminals want to shoehorn in what has been available in GUIs for a while.

                                        1. 9

                                          The terminal is still my most productive environment. Typing commands and little loops and globs and pipelines and whatever is inherently faster for me than any sort of GUI manipulation.

                                          This is especially true if you work across machines (again, for me). X and Plan 9 almost got remote graphical applications right, but it never quite worked seamlessly and it got to the point where it seems like people only ever use remote command lines and now most of the major OS’s have done away with seamless remote GUIs if they ever had them to begin with.

                                          Something that also would’ve improved my GUI experience, and which I hacked in to dwm years ago, is window swallowing. When I’m working in the terminal, writing my little loops and pipelines and availing myself of the power of the command line, when I launch a graphical text editor my attention is popped to another window.

                                          I realize this is what a lot of people want, but for me, the concept of the editor taking over the window I’m in makes so much more sense to me intuitively and makes context switching so much easier. Plan 9 did it and a few other GUIs did it but no mainstream ones do, and certainly not when dealing with remote graphical applications.

                                          1. 2

                                            I think it’s interesting to debate if this is right or not. I’m not a fan of using technologies in a way that it wasn’t indented, because I feel like it might always come back and bite you. People do crazy things with terminals, and even though it’s usually mostly aestethic, it breaks stuff for specifc users. I like to use the Emacs terminal, and therefore stick to non-interactive tools that avoid taking over the whole terminal or jumping around. It’s a minority, but good design shouldn’t be at anyone’s disadvantage. The concept of graceful degradation, as sometimes seen applied to websites, might be relevant here too. Not everything should have to work everywhere (most modern terminal emulators can’t plot graphics either), but assuming everything is a vt100 shouldn’t be the default either.

                                            1. 1

                                              As a GNU Emacs user, I find it funny that I have way better control over my preferred OpenType font (JetBrains Mono) in my terminal than I do using the GUI version of the editor. I hate wide spacing between letters in monospace fonts, so I like to adjust the kerning to scrunch the letters together. Try this in Emacs, you’ll find you can’t, regardless if you set the :width to condensed, semi-condensed, or ultra-super-mega-condensed. Also try configuring ligatures, sylistic sets, or the fallback behavior – those kind of detailed font tweaks aren’t exposed by Emacs, yet they are in certain terminal emulators.

                                              1. 3

                                                There is something to be said for having a minimal protocol between the “GUI Server” (frontend) and the backend ;) But doesn’t seem like Display PostScript is coming back, so we’re stuck with the terminal.

                                                1. 2

                                                  Not with that attitude. I’ve been seriously considering using a DPS derivative to solve the problem of the hideous and useless terminal (but don’t hold your breath).

                                                  I still don’t understand why there’s been so little (re)invention in this area, save for game engines. Once you gain some basic understanding of how GUI libraries are put together, it is fairly straight-forward to reimplement them given a text shaping/rendering engine and a rasterizer, such as Pango with Cairo (the latter itself a derivative of Postscript, just like HTML canvas’ 2D context).

                                                  Misusing a Unix terminal as a GUI server doesn’t make it easy to create user interfaces, despite expectations.

                                                  1. 1

                                                    Years ago I wrote an experiment where the terminal could be flipped into a special mode via escape sequence that would then accept a Lua script, and would flip the window to a Cairo-based canvas that was manipulable via Lua.

                                                    The experiment “worked” but it turns out I’m really bad at GUI programming, especially at such a low level. But it was a neat experiment.

                                                    I’m curious what your DPS derivative would look like? DPS is neat.

                                                    1. 1

                                                      It’s a shame that no such experiment has really “seen the light of day”, except for one web-based prototype.

                                                      There are quite a few choices in this area, so me saying “derivative” mostly hints at there being a possible need for divergence. I haven’t really had a close look at DPS, so I take it mostly as a concept, as I have intimate knowledge of Cairo and the two are nearly the same thing.

                                                      If you have some sort of canvas, you can start with a Widget:

                                                      • abstract get_size()
                                                      • abstract render(context)
                                                      • abstract on_key(key, state)
                                                      • abstract on_mouse*(x, y, state)

                                                      Define a container such as VerticalBox:

                                                      • children[]
                                                      • heights[]
                                                      • private recalc(): ask each children for how high they want to be etc.
                                                      • render(): iterate through children, translate origin, possibly clip, save state, call their render method, restore state
                                                      • on_key(): find which child has keyboard focus and forward the event, possibly bubble up
                                                      • on_mouse*(): see what child could contain the given point

                                                      Perhaps a Button:

                                                      • text
                                                      • private depressed
                                                      • abstract on_click()
                                                      • get_size(): measure the text, add padding
                                                      • render(): clear with background colour, draw ridge, measure the text, render it in the center, adjust if depressed
                                                      • on_key(): call on_click() if the key is Enter/Space
                                                      • on_mouse(): toy with depressed, maybe call on_click(), invalidate the widget’s region

                                                      It’s all rather simple like this. It will take some time but it doesn’t require deep thought to get it working.

                                                      The context passed to the render method just queues/forwards DPS commands. Fonts can either be rendered on the client and glyphs cached on the server (XRender method, undesirable here), or you need to have a backwards channel to query font properties–if you ban scaling or rotation transformations and stick to translations only, it won’t depend on DPS state, and if you disregard ligatures and other nice-to-haves, you can shape it yourself trivially.

                                                      What’s hard is how to make this work in a non-hierarchical way, which I don’t think I need–a vector graphics alternate screen is fine for me, and it is possible to make a graphical shell with this–you can have parts of the screen emulating a vt100 and parts of it either retaining some DPS output or running an application–a graphical tmux is quite possible. It should also be possible to do things like embed text editors–this is extremely desirable. In general, most issues are about conceptual design.

                                                      What’s nice is that if these GUIs run in a mode, you can throw terminfo and other terrible legacy burden over the wall.

                                                      1. 1

                                                        What do you think about having the terminal be a Wayland compositor, that will place windows below where you started them? Then you won’t have the problem of having to integrate with every graphics API.

                                                        1. 1

                                                          Wayland adds ridiculous levels of complexity and the subwindows become completely opaque.

                                                          With DPS you can impose arbitrary high-detail scaling and even have a universal text selection mechanism.

                                                          It could be added as an optional feature, though.

                                            1. 2

                                              How about /proc/pid/syscall?

                                              This is great, because it exposes the process’ currently executed system call, argument registers, and stack pointer in a lightweight way without having to resort to PTRACE attach. At work we use this trick to monitor Ruby EventMachine workers to determine how much time they’re spending blocked on select(2) versus doing actual I/O. Pretty cool.