1. 38
  1.  

  2. 6

    Having terminal text be editable is really nice. Instead of having to fiddle with history, you can just scroll up and modify the command you sent yourself. Plan9’s shell lets you do this and it’s great.

    1. 4

      Although I’ve never used the Plan9 shell myself, I’m a fan of eshell’s smart display, which seems to come from Plan9 https://masteringemacs.org/article/complete-guide-mastering-eshell#plan-9-smart-shell

      1. 1

        I don’t get why it can possibly be great.

        • Plan 9 terminal makes it easy to mess up commands and output history which I’m used to being immutable and append-only.
        • When you want to repeat a command, you have to scroll up through multiple screens of text (using the mouse) and then copy the command with a mouse chord, and then scroll back to the end of the output and paste it. I find pressing Ctrl-P or the up arrow in any modern shell much more ergonomic.
        • When I need to copy text output from the shell, I can use either the terminal emulator selection or tmux selection mode.
        1. 1

          I can speak about the eshell behavior that I like that seems to come from Plan9 (I may be mistaken on origin here)…

          It’s hard to explain, eshell’s smart display leaves the cursor over executed command and allows editing to refine the command after seeing its output… unless you write a different command and you’re dropped to an empty prompt. That prolly didn’t make much sense… Here’s a gif https://imgur.com/a/0JIMrmS

          1. 1

            Yes, that looks much saner than the Plan9 terminal, with its minimalism laudable in theory, but painful in practice.

          2. 1

            Plan 9 terminal makes it easy to mess up commands and output history which I’m used to being immutable and append-only.

            this is a change in expectations. I don’t expect my output history to be immutable and append only. it’s a bit like a printout, that I might want to write some temporary notes in.

            When you want to repeat a command, you have to scroll up through multiple screens of text (using the mouse) and then copy the command with a mouse chord, and then scroll back to the end of the output and paste it. I find pressing Ctrl-P or the up arrow in any modern shell much more ergonomic.

            I think the use shines in not repeating a command, but repeating a command with some modifications. I often find myself having to hit up arrow a bunch of times, left arrow to the spot I want to change, make the change. I don’t see how this is more ergonomic than “scroll up, click on spot I want to change, change, copy line and paste line.” Combining this with output modifications is great too: I can ls a directory and then write out the operations I want to do to each file in the output.

            When I need to copy text output from the shell, I can use either the terminal emulator selection or tmux selection mode.

            Right, and if you want to make any nontrivial edits to that output you then have to open it in an editor.

        2. 3

          If you’re interested in blending shell and editor, some prior art:

          • Acme, which got it from…
          • Oberon, which I believe got it from Cedar
          • MPW, which got it from…
          • Domain/OS pad

          All of this have an emphasis on editing text buffers, but executing commands in the same context as them.

          1. 1

            Though it’s not a shell, I think Xcode Playgrounds is another interesting interactive environment.

            1. 1

              Agreed; another good example of line-blurring in interactivity is Mathematica.

              1. 1

                Big fan of playgrounds. On a similar wavelength, Emacs org babel brings similar interactivity to all sorts of languages and tools (albeit not a polished out of the box). Been experimenting recently with adding SwiftUI support https://xenodium.com/previewing-swiftui-layouts-in-emacs-revisited.

            2. 3

              For snippets in the shell, Fish Shell supports them out of the box with abbreviations and Zsh supports them with a plugin.

              1. 2

                I’m just a simple vim user, but doing all-keyboard interaction in a single tabbed iTerm window for editing and running commands is why I haven’t been able to master VS Code or other GUI editors yet. I’ve tried to learn keyboard shortcuts, but that always falls flat at some point, and not touching the mouse is how I fixed my RSI-like symptoms. (Vim emulator plug-ins fall flat at simple things, from my experience.)

                (Edit: Brought this up because I think it’s super important to have shell and editor close to eachother as well.)

                Emacs looks wild. Sometimes I wonder if the grass really is greener there. I’m definitely not doing OP’s magic in vim. (But I’ve also never felt slow.)

                1. 7

                  I’m a vim user who has been using Emacs for about a year. It can feel slow with too many modules or really big files, but usually (with daemon mode) plenty snappy. Evil mode + a few hacks and I often can’t tell i’ve left. Still type vim to open files (using an alias).

                  However there is no reason to use emacs as a code editor if you just want to try other apps like shells or org etc. It’s a lisp machine that happens to include a text editor. evil-org or evil mode on eshell work quite well in their own right.

                  1. 1

                    (Vim emulator plug-ins fall flat at simple things, from my experience.)

                    FWIW if you do want to try to use VS Code with vi keybindings, I recommend https://marketplace.visualstudio.com/items?itemName=asvetliakov.vscode-neovim because it’s quite accurate. It runs commands through an actual running copy of neovim. It is a large improvement over its main competitor, vscodevim. There are some infelicities but oh well, Macros work.

                    Emacs looks wild. Sometimes I wonder if the grass really is greener there. I’m definitely not doing OP’s magic in vim. (But I’ve also never felt slow.)

                    A warning since you mentioned RSI, if you do try switching, stick to a vi emulation mode like evil-mode or whatever. (There are at least 2 vi keybindings plugins for Emacs, I can’t remember what they’re called, they’re relatively accurate.) Do not try Emacs default keybindings. The sheer amount of chording they make you do all the time is hell on wrists.

                  2. 2

                    You can do this with ansi-term and not have to use the elisp shell

                    1. 1

                      You can also do this with M-x shell and not have to use eshell. The problem with ansi-term is it’s a terminal emulator and as such captures a lot of keybindings. History is delegated to the shell and so on, rather than letting emacs do the work as it does in comint modes. I’m pretty much saying I guess you lose the interface consistency by using ansi-term.

                      1. 1

                        With ansi-term I use C-c C-j to switch to emacs mode if I need to, best of both worlds

                        1. 1

                          @noa @judson, good shoutout on other shells. Hopefully more explicit now in https://xenodium.com/yasnippet-in-emacs-eshell/#bash-zsh-and-others-welcome

                      2. 2

                        Take Emacs eshell looping, for example. I use it so infrequently, I could never remember eshell’s syntax. I would refer back to EmacsWiki’s Eshell For Loop or Mastering Emacs’s Mastering Eshell comments for a reminder. It finally dawned on me. I don’t need to internalize this eshell syntax. I have YASnippet available like any other buffer. I could just type “for” and let YASnippet do the rest for me.

                        Hm I’m not an Emacs (or eshell) user, so I don’t quite get what he’s saying here. From what I understand eshell is kind of a Lisp-ish DSL for shell? I mentioned it here:

                        https://github.com/oilshell/oil/wiki/Internal-DSLs-for-Shell

                        So how does YASnippet differ? Doesn’t it also introduce a new syntax that’s not shell? It looks like it’s

                        for f in *.png { file "$f"; }
                        

                        which is oddly Oil syntax but it’s not Bourne shell syntax! (with curly braces, and the trailing ; is optional in Oil)


                        Anyway, if you want to avoid remembering new syntaxes, for the shell case specifically, Emacs could be turned into a client of Oil’s headless mode:

                        I haven’t written about it properly yet, but basically you can communicate with Oil over a Unix domain socket, and pass FDs for terminals to get “real” output. It’s a lot better than the scraping of bash -i or some such, which I know some Emacs packages do.

                        For example, you don’t have the “where does the command’s output end?” problem, and isatty() will work so ls --color works, etc.

                        Preliminary docs here: http://www.oilshell.org/blog/2021/06/hotos-shell-panel.html#oils-headless-mode-should-be-useful-for-ui-research

                        1. 2

                          The yasnippet example is an expansion, they don’t need to remember the syntax because they type “for”, press tab or whatever, and are moved through the changeable variables. The synax is still that of eshell, which OP says they use “for” in rarely enough that they forget.

                          Your headless mode sounds quite cool. I’ve not had a problem with shells in emacs but i know that some people with more complex promts or uses have had trouble.

                          1. 2

                            Hi @andyc. yeah, what @noa says. Expansion and argument hopping are the important bits.

                            I happen to expand “for” to eshell syntax as eshell is my shell, but can really expand to any other shell syntax. No need to remember Bash (or any) syntax either.

                            Patched post and added a bash example, highlighting argument hopping a little more https://xenodium.com/yasnippet-in-emacs-eshell/#bash-zsh-and-others-welcome

                            1. 1

                              Ah OK thanks, that clarifies things!

                          2. 2

                            If it can be chained onto an ssh session that sounds like it could be a great tramp backend.

                            1. 1

                              eshell isn’t very lisp-ish. more bash-ish but written by lispers.

                              1. 1

                                I’ve been trying out elvish and that actually feels a little lisp-y when you do anything involving equality or comparison; since they have the same syntax as other functions, you write (== (+ $a $b) $c).

                            2. 1

                              If you get tired of scrolling up to find your old commands, there are shell mode key bindings for that. I don’t recall them off hand, but get in shell mode and do C-h m to get help on the mode specific bindings.

                              1. 1

                                If you get tired of scrolling up to find your old commands

                                I do :) To jump back to previous invocations, imenu can be pretty handy https://xenodium.com/imenu-on-emacs-eshell. Should work with shell mode.

                              2. 1

                                I used to use M-x shell a bunch with $TERM set to “dumb” so that most programs wouldn’t try to emit vt100 escape sequences (which wouldn’t work anyway) and that was, like, the second nice thing about Emacs for me. (The first was magit.) The experience was… quirky, but it was neat being able to just cut and paste right out of the shell buffers.

                                1. 1

                                  For me the path to something similar was to start using a terminal multiplexer - I am using screen, because this is what is preinstalled on most servers, but there is tmux might be at least as good - with a scroll back buffer of 1000. Like this I have as many terminals open as I want, in one single window and I can copy and paste by using the screen short-cuts (Ctrl-A + VI navigation to navigate inside the window, Ctrl-A + [ to select a range that is copied and Ctrl-A ] to paste, most of the time after you have switched to another terminal window inside screen).

                                  The reason that I started to use screen, was work on console on client’s servers limited to a single SSH console. But once I learned this I started to use it even on my Desktop - which resolved a huge issue that I had before - quite often my work requires to spin up a Windows VM to do conf calls and such, and from this Windows VM I can SSH to the Host (which is the Desktop machine) and have all the sessions open. Once I am done using Windows, I just detach the screen session in Windows, close the VM and go back working inside the Gnome Terminal.

                                  I am a VI person, using VI wherever it is possible - (1) in VIM itself, (2) on the Bash with set -o vi to edit the command lines, that sometimes tend to get so long, that pressing ‘v’ will spin up the VIM to have more comfort, (3) in Emacs for Org-Mode via Evil-Mode, in GHCi (can be configured in $HOME/.haskeline) and all the Terminal programs with readline support where you can switch to vi mode with Ctrl-Alt-j.

                                  Maybe someone will find this method useful.

                                  The only problem that popped up, is that emacs in terminal doesn’t show the nice unicode symbols (status line and org-mode decorations) when I am connecting to the machine via SSH and attaching the screen. Tried different settings with LC_* and LANG variables, but so far was not able to find a solution. If someone has suggestions I would be very grateful.

                                  1. 2

                                    Personally I connect via (multiple) terminals to the remote server and edit the files in Emacs via tramp. This works well enough in my use case and I have configured ssh to reuse the connection, i. e. this is at the end of my ~/.ssh/config:

                                    Host *
                                      ControlMaster auto
                                      ControlPath ~/.ssh/ssh_mux_%h_%p_%r
                                    

                                    In general, with Emacs you’d try to set it up so you don’t need the shell, so if you for example want to compile something on the remote server you could use compile-mode for that, which will even give you output linked to the file and line. This is basically how emacs sucks you in as you can do more and more of your workflow within it and it reduces the need for a shell.

                                    However, I’ve found that for large swathes of text the shell modes - pick any - do not work too well and slow down. Hence I’m still using the dual approach with emacs + shell to run interactive sessions, which works reasonably well.