From: Ken Manheimer Date: Sun, 24 Jan 2016 22:12:09 +0000 (-0500) Subject: multishell - merge 1.0.8. X-Git-Url: https://code.delx.au/gnu-emacs-elpa/commitdiff_plain/91905b6de42dd519770186436c6f9a6c92921677?hp=-c multishell - merge 1.0.8. --- 91905b6de42dd519770186436c6f9a6c92921677 diff --combined packages/multishell/README.md index 4f3bcda0b,08125f12f..08125f12f --- a/packages/multishell/README.md +++ b/packages/multishell/README.md @@@ -3,63 -3,55 +3,55 @@@ multishell.e Facilitate use of multiple local and remote Emacs shell buffers. - I use the emacs shell a *lot*. On top of emacs' powerful shell and tramp + Multishell is available via Emacs package manager, in ELPA. Install "multishell" from the `M-x package-list-packages` listing. + + I use the emacs shell a *lot*, including separate shells for separate + project, and more shells for access to remote systems (which I do a lot, as + a systems administrator). On top of emacs' powerful shell and tramp facilities, use a `multishell` (customization-activated) key binding to: * Get to the input point from wherever you are in a shell buffer, - * ... or to one of your shell buffers if you're not currently in one. + ... or to any of your shell buffers, from anywhere inside emacs. + * Use universal arguments to launch and choose among alternate shell buffers, - * ... and select which is default. + ... and change which is the current default. + + * Easily restart disconnected shells, or shells from prior sessions + ... the latter from Emacs builtin savehist minibuf history persistence + * Append a path to a new shell name to launch a shell in that directory, - * ... and use a path with Emacs tramp syntax to launch a remote shell. + ... and use a path with Emacs tramp syntax to launch a remote shell - + for example: - For example: + * `#root/sudo:root@localhost:/etc` for a buffer named "#root" with a + root shell starting in /etc. - * `/ssh:example.net:/` for a shell buffer in / on - example.net; the buffer will be named "*example.net*". + * `/ssh:example.net:/` for a shell buffer in / on example.net. + The buffer will be named "*example.net*". * `#ex/ssh:example.net|sudo:root@example.net:/etc` for a root shell starting in /etc on example.net named "*#ex*". - (NOTE that there is a frequent problem with specifying a remote homedir - using tramp syntax, eg `/ssh:example.net:` or `/ssh:example.net:~`. That - sometimes fails on an obscure bug - particularly for remote+sudo with - homedir syntax. Until fixed, you may need to start remote+sudo shells with - an explicit path, then cd ~. With `multishell`s dir-tracking persistent history, you'll be able to use completion to start that shell in the right place, in your subsequent sessions.) - - Customize-group `multishell` to select and activate a keybinding and set - various behaviors. Customize-group `savehist` to preserve buffer - names/paths across emacs sessions. - - See the `multishell-pop-to-shell` docstring for details. - - Change Log - ---------- - * 2016-01-16 1.0.5 Ken Manheimer: - - History now includes paths, when designated - - Actively track current directory in history entries that have a path. - Custom control: multishell-history-entry-tracks-current-directory - - Offer to remove shell's history entry when buffer is killed - (For now, the only UI way to remove history entries.) - - Fix - prevent duplicate entries for same name but different paths - - Fix - recognize and respect tramp path syntax to start in home dir - - But tramp bug, remote+sudo hops to a home dir can fail, get wedged. - - Simplify history var name, migrate existing history if any from old name - * 2016-01-04 Ken Manheimer - Released to ELPA - * 2016-01-02 Ken Manheimer - working on this in public, but not yet released. - - TODO - ---------- - * Isolate tramp sporadic failure to connect to remote+sudo+homedir syntax - (eg, /ssh:xyz.com|sudo:root@xyz.com: or /ssh:xyz.com|sudo:root@xyz.com:~) - * Find suitable, internally consistent ways to sort tidy completions, eg: - - first list completions for active shells, then present but inactive, - then historical - - some way for user to toggle between presenting just buffer names vs - full buffer/path - - without cutting user off from easy editing of path - * Find proper method for setting field boundary at beginning of tramp path - in the minibuffer, in order to see whether the field boundary magically - enables tramp completion of the path. - * Assess whether option to delete history entry on kill-buffer is - sufficient. + * 'interior/ssh:gateway.corp.com|ssh:interior.corp.com:' to go via + gateway.corp.com to your homedir on interior.corp.com. The buffer + will be named "*interior*". You could append a sudo hop, and so on. + + * Thanks to tramp, file visits from the shell will seamlessly be in + the auspices of the target account, and relative to the current + directory, on the host where the shell is running. + + See the `multishell-pop-to-shell` docstring (in + [multishell.el](multishell.el)) for details, and + [getting-to-a-shell.md](getting-to-a-shell.md) for the nitty-gritty + decision tree that determines where different hits of the keybinding go. + + Customize-group `multishell' to select and activate a keybinding and set + various behaviors. Customize-group `savehist' to preserve buffer + names/paths across emacs restarts. + + Please use + [the multishell repository](https://github.com/kenmanheimer/EmacsMultishell) + issue tracker to report problems, suggestions, etc. + + See the [multishell.el](multishell.el) file commentary for a change log and + Todo list. diff --combined packages/multishell/getting-to-a-shell.md index 000000000,a2ad6493d..a2ad6493d mode 000000,100644..100644 --- a/packages/multishell/getting-to-a-shell.md +++ b/packages/multishell/getting-to-a-shell.md @@@ -1,0 -1,41 +1,41 @@@ + Multishell enables you to get to the input prompt in the shell you want + with as few keystrokes as possible. + + * One keybinding, unmodified, gets you to the your current default shell, if + not in a shell, or to the input prompt of the current shell, if you're in + one. + + * Use the universal argument to select a specific shell buffer, wherever + point happens to be residing. Enter an empty line to the prompt to go to + your current default shell, or use completing read to go to a shell from + your multishell history, or start a new shell at the path you specify - + including remote paths, using tramp syntax. (See the + multishell-pop-to-shell docstring in [multishell.el](multishell.el) for + details.) + + * Use a doubled universal argument to set the shell you choose to be the + current default. (The prompt will indicate that mode with a "<==".) + + Here's the decision tree: + + * No universal argument - use: + + * From-buffer is shell buffer: use from-buffer current name/path + - if shell/connection is stopped, restart/reconnect + - if not at input prompt, go there + * From-buffer is not shell buffer: + - Go to multishell-primary-name current name/path, creating or + restarting and/or reconnecting if that shell is not currently running. + + * Universal argument provided - use: + + - No name is specified - use current multishell-primary-name path + * Name is specified - use named buffer (creating if not already present): + * Path is also specified: + - shell is running - ignore new path + - shell will be started or restarted - use new path + * No path is specified: + - Name has history: use path from history + - Name has no history: use path that target buffer already has or inherits + - If the universal argument is doubled, set the selected shell as the + default one, going forwards. diff --combined packages/multishell/multishell.el index 8c16f16d2,c19ba29a6..c19ba29a6 --- a/packages/multishell/multishell.el +++ b/packages/multishell/multishell.el @@@ -3,7 -3,7 +3,7 @@@ ;; Copyright (C) 1999-2016 Free Software Foundation, Inc. and Ken Manheimer ;; Author: Ken Manheimer - ;; Version: 1.0.7 + ;; Version: 1.0.8 ;; Created: 1999 -- first public availability ;; Keywords: processes ;; URL: https://github.com/kenmanheimer/EmacsMultishell @@@ -52,10 -52,22 +52,22 @@@ ;; ;; Please use ;; [the multishell repository](https://github.com/kenmanheimer/EmacsMultishell) - ;; issue tracker to report problems, suggestions, etc. + ;; issue tracker to report problems, suggestions, etc, and see that + ;; repository for a bit more documentation. ;; ;; Change Log: ;; + ;; * 2016-01-24 1.0.8 Ken Manheimer: + ;; - Work around the shell/tramp mishandling of remote+sudo+homedir problem! + ;; The work around is clean and simple, basically using high-level `cd' + ;; API and not messing with the low-level default-directory setting. + ;; (Turns out the problem was not in my local config. Good riddance to the + ;; awkward failure handler!) + ;; - Clean up code resolving the destination shell, starting to document the + ;; decision tree in the process. See getting-to-a-shell.md in the + ;; multishell repository, https://github.com/kenmanheimer/EmacsMultishell + ;; - There may be some shake-out on resolving the destination shell, but + ;; this release gets the fundamental functionality soundly in place. ;; * 2016-01-23 1.0.7 Ken Manheimer: ;; - Remove notes about tramp remote+sudo+homedir problem. Apparently it's ;; due to something in my local site configuration (happens with -q but @@@ -94,7 -106,7 +106,7 @@@ (require 'shell) (require 'savehist) - (defvar multishell-version "1.0.7") + (defvar multishell-version "1.0.8") (defun multishell-version (&optional here) "Return string describing the loaded multishell version." (interactive "P") @@@ -345,30 -357,33 +357,33 @@@ customize the savehist group to activat (let* ((from-buffer (current-buffer)) (from-buffer-is-shell (derived-mode-p 'shell-mode)) + (primary-name-unbracketed (multishell-unbracket-asterisks + multishell-primary-name)) + (fallthrough-name (if from-buffer-is-shell + (buffer-name from-buffer) + primary-name-unbracketed)) (doublearg (equal arg '(16))) - (target-name-and-path (multishell-resolve-target-name-and-path + (target-name-and-path + (multishell-resolve-target-name-and-path (if arg - (multishell-read-bare-shell-buffer-name - (format "Shell buffer name [%s]%s " - (substring-no-properties - multishell-primary-name - 1 (- (length multishell-primary-name) 1)) - (if doublearg " <==" ":")) - (multishell-unbracket-asterisks multishell-primary-name)) - (multishell-unbracket-asterisks multishell-primary-name)))) - (use-default-dir (cadr target-name-and-path)) + (or (multishell-read-bare-shell-buffer-name + (format "Shell buffer name [%s]%s " + primary-name-unbracketed + (if doublearg " <==" ":")) + primary-name-unbracketed) + primary-name-unbracketed) + fallthrough-name))) + (use-path (cadr target-name-and-path)) (target-shell-buffer-name (car target-name-and-path)) + (target-buffer (get-buffer target-shell-buffer-name)) (curr-buff-proc (get-buffer-process from-buffer)) - (target-buffer (if from-buffer-is-shell - from-buffer - (get-buffer target-shell-buffer-name))) inwin already-there) ;; Register early so the entry is pushed to the front: (multishell-register-name-to-path (multishell-unbracket-asterisks target-shell-buffer-name) - use-default-dir) + use-path) (when doublearg (setq multishell-primary-name target-shell-buffer-name)) @@@ -408,7 -423,7 +423,7 @@@ (if (not (comint-check-proc (current-buffer))) (multishell-start-shell-in-buffer (buffer-name (current-buffer)) - use-default-dir)) + use-path)) ;; If the destination buffer has a stopped process, resume it: (let ((process (get-buffer-process (current-buffer)))) @@@ -465,10 -480,9 +480,9 @@@ nil)) (defun multishell-read-bare-shell-buffer-name (prompt default) - "PROMPT for shell buffer name, sans asterisks. + "PROMPT for shell buffer name, sans asterisks. Indicate DEFAULT in prompt. - Return the supplied name not bracketed with the asterisks, or specified - DEFAULT on empty input." + Return the supplied name, if provided, else return nil." (let* ((candidates (append ;; Plain shell buffer names appended with names from name/path hist: @@@ -497,7 -511,7 +511,7 @@@ 'multishell-history))) (if (not (string= got "")) got - default))) + nil))) (defun multishell-resolve-target-name-and-path (path-ish) "Given name/tramp-path PATH-ISH, resolve buffer name and initial directory. @@@ -510,7 -524,7 +524,7 @@@ is used Return them as a list (name path), with name asterisk-bracketed and path nil if none resolved." - (let* ((splat (multishell-split-entry path-ish)) + (let* ((splat (multishell-split-entry (or path-ish ""))) (name (car splat)) (path (cadr splat))) (if path @@@ -563,9 -577,7 +577,7 @@@ (xargs-name (intern-soft (concat "explicit-" name "-args"))) is-remote) (set-buffer buffer-name) - (if (and path (not (string= path ""))) - (setq default-directory path)) - (setq is-remote (file-remote-p default-directory)) + (setq is-remote (and path (file-remote-p path))) (when (and is-remote (derived-mode-p 'shell-mode) (not (comint-check-proc (current-buffer)))) @@@ -574,23 -586,10 +586,10 @@@ (tramp-cleanup-connection (tramp-dissect-file-name default-directory 'noexpand) 'keep-debug 'keep-password)) - ;; (cd default-directory) will connect if remote: (when is-remote - (message "Connecting to %s" default-directory)) - (condition-case err - (cd default-directory) - (error - ;; Aargh. Need to isolate this tramp bug. - (if (and (stringp (cadr err)) - (string-equal (cadr err) - "Selecting deleted buffer")) - (signal (car err) - (list - (format "%s, %s (\"%s\")" - "Tramp shell can fail on remote|sudo to homedir" - "please try again with an explicit path" - (cadr err)))) - (signal (car err)(cdr err))))) + (message "Connecting to %s" path)) + (if (and path (not (string= path ""))) + (cd path)) (setq buffer (set-buffer (apply 'make-comint (multishell-unbracket-asterisks buffer-name) prog