X-Git-Url: https://code.delx.au/gnu-emacs-elpa/blobdiff_plain/7e7d7bbea8bbe625bb38e29502c47b42245fcbd7..4d1fad67524431f7c8f20bc62e503d49e8177fb8:/packages/multishell/multishell.el diff --git a/packages/multishell/multishell.el b/packages/multishell/multishell.el index e23813d25..7295aa1ea 100644 --- a/packages/multishell/multishell.el +++ b/packages/multishell/multishell.el @@ -15,39 +15,47 @@ ;; a la `pop-to-buffer' - plus a keybinding. Together, they enable you 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 elsewhere inside emacs. +;; ;; * Use universal arguments to launch and choose among alternate shell buffers, -;; * ... and select which is default. -;; * 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 change which is the current default. ;; -;; For example: +;; * 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 - +;; for example: ;; -;; * `/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 - there's a sporadic problem when opening a shell pointed at a -;; remote homedir, eg `/ssh:example.net:` or `/ssh:example.net:~`. It -;; sometimes fails, particularly for remotes with empty fs path syntax. Until -;; fixed, you may need to start remote shells with an explicit path, then -;; cd ~. If you set up `multishell`s persistent dir-tracking history, -;; you'll be able to use completion to start that shell in the right place, -;; in your subsequent sessions.) +;; * '\#intrn/ssh:corp.com|ssh:intern.corp.com|sudo:root@intern.corp.com:/etc' +;; to go via corp.com to intern.corp.com, sudood to root, in /etc. Whee! (-: +;; The buffer will be named "*#intrn*". ;; +;; * File visits will all be under the auspices of the account, and relative to +;; the current directory, on the remote host. +;; ;; See the `multishell-pop-to-shell` docstring for details. ;; ;; 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. -;; -;; Please use [the repository](https://github.com/kenmanheimer/EmacsMultishell) +;; Please use +;; [the multishell repository](https://github.com/kenmanheimer/EmacsMultishell) ;; issue tracker to report problems, suggestions, etc. ;; +;; (NOTE - tramp sometimes has a problem opening a remote shell pointed at +;; a homedir, eg `/ssh:example.net:` or `/ssh:example.net:~`. When it +;; fails, it won't work for the rest of the session. Non-homedir remote +;; access isn't disrupted. Until this is fixed, you may need to start +;; remote shells with an explicit path, then cd ~.) +;; ;; Change Log: ;; ;; * 2016-01-16 1.0.5 Ken Manheimer: @@ -85,6 +93,8 @@ (require 'comint) (require 'shell) +(defvar multishell-version "1.0.5") + (defgroup multishell nil "Allout extension that highlights outline structure graphically. @@ -171,24 +181,23 @@ emacs sessions." (defvar multishell-primary-name "*shell*" "Shell name to use for un-modified multishell-pop-to-shell buffer target.") -;; There is usually only one entry per name, but disruptions happen. +;; Multiple entries happen because completion also adds name to history. (defun multishell-register-name-to-path (name path) "Add or replace entry associating NAME with PATH in `multishell-history'. -If NAME already had a PATH and new PATH is empty, retain old one. +If NAME already had a PATH and new PATH is empty, retain the prior one. Promote added/changed entry to the front of the list." ;; Add or promote to the front, tracking path changes in the process. (let* ((entries (multishell-history-entries name)) - (becomes (concat name path)) - oldpath) + (path (or path ""))) (dolist (entry entries) - (when (or (not path) (string= path "")) + (when (string= path "") ;; Retain explicit established path. - (setq path (cadr (multishell-split-entry-name-and-tramp entry)) - becomes (concat name path))) + (setq path (cadr (multishell-split-entry-name-and-tramp entry)))) (setq multishell-history (delete entry multishell-history))) - (setq multishell-history (push becomes multishell-history)))) + (setq multishell-history (push (concat name path) + multishell-history)))) (defun multishell-history-entries (name) "Return `multishell-history' entry that starts with NAME, or nil if none." @@ -268,6 +277,9 @@ For example: \"*example.net*\". * '\#ex/ssh:example.net|sudo:root@example.net:/etc' for a root shell in /etc on example.net named \"*#ex*\". +* '\#in/ssh:corp.com|ssh:internal.corp.com|sudo:root@internal.corp.com:/etc' + for a root shell name \"*in*\" in /etc on internal.corp.com, via host + corp.com. \(NOTE that there is a problem with specifying a remote homedir using tramp syntax, eg '/ssh:example.net:'. That sometimes fails on an obscure @@ -281,9 +293,9 @@ history but will not take effect for an already-running shell. To remove a shell buffer's history entry, kill the buffer and affirm removal of the entry when prompted. -===== Activate savehist to persisting your shell buffer names and paths: +===== Activate savehist to retain shell buffer names and paths across Emacs sessions: -To have emacs maintain your history of shell buffer names and paths, +To have emacs maintain your history of shell buffer names and paths, customize the savehist group to activate savehist." (interactive "P") @@ -307,14 +319,15 @@ customize the savehist group to activate savehist." (curr-buff-proc (get-buffer-process from-buffer)) (target-buffer (if from-buffer-is-shell from-buffer - (let ((got (get-buffer target-shell-buffer-name))) - (if (buffer-live-p got) - got - (kill-buffer got) - (get-buffer target-shell-buffer-name))))) + (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) + (when doublearg (setq multishell-primary-name target-shell-buffer-name)) @@ -359,9 +372,7 @@ customize the savehist group to activate savehist." (let ((process (get-buffer-process (current-buffer)))) (if (and process (equal 'stop (process-status process))) (continue-process process))) - (multishell-register-name-to-path (multishell-unbracket-asterisks - target-shell-buffer-name) - use-default-dir) + (when (or already-there (equal (current-buffer) from-buffer)) (goto-char (point-max)) @@ -524,15 +535,16 @@ Return them as a list (name dir), with dir nil if none given." (cd default-directory) (error ;; Aargh. Need to isolate this tramp bug. - (when (and (stringp (cadr err)) - (string-equal (cadr err) - "Selecting deleted buffer")) - (signal (car err) - (list - (format "%s, %s (\"%s\")" - "Tramp shell can fail on empty (homedir) path" - "please try again with an explicit path" - (cadr err))))))) + (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 empty (homedir) path" + "please try again with an explicit path" + (cadr err)))) + (signal (car err)(cdr err))))) (setq buffer (set-buffer (apply 'make-comint (multishell-unbracket-asterisks buffer-name) prog