unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
blob e2585fe2a51cc63cac9c8592223c7fff0b47d651 4370 bytes (raw)
name: lisp/eshell/em-elecslash.el 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 
;;; em-elecslash.el --- electric forward slashes  -*- lexical-binding:t -*-

;; Copyright (C) 2022 Free Software Foundation, Inc.

;; Author: Sean Whitton <spwhitton@spwhitton.name>

;; This file is part of GNU Emacs.

;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; Electric forward slash in remote Eshells.

;;; Code:

(require 'tramp)
(require 'thingatpt)
(require 'esh-cmd)
(require 'esh-ext)
(require 'esh-mode)

;; This makes us an option when customizing `eshell-modules-list'.
;;;###autoload
(progn
(defgroup eshell-elecslash nil
  "When `default-directory' is remote thanks to Eshell's TRAMP
integration, and you are supplying absolute paths to commands, it
is easy to accidentally refer to a local path when you meant a
remote path.  This happens because absolute paths passed to Lisp
functions must be prefixed with /method:host: but absolute paths
passed to external commands must not have this prefix; it is easy
to invoke a built-in command without the prefix by mistake.  This
module tries to resolve this difficulty by filling in the
/method:host: electrically just when it's needed."
  :tag "Electric forward slash"
  :group 'eshell-module))

;;; Functions:

(defun eshell-elecslash-initialize () ;Called from `eshell-mode' via intern-soft!
  "Initialize electric forward slash support."
  (add-hook 'post-self-insert-hook
            #'eshell-electric-forward-slash nil t))

(defun eshell-electric-forward-slash ()
  "Electric insertion of TRAMP part of `default-directory' in
remote Eshells.  Added to `post-self-insert-hook' when the
Eshell elecslash module is initialized.

Typing a forward slash in a remote Eshell performs the
completion.  Typing a second forward slash undoes it."
  (when (eq ?/ (char-before))
    (delete-char -1)
    (let ((tilde-before (eq ?~ (char-before)))
          (command (save-excursion
                     (eshell-bol)
                     (skip-syntax-forward " ")
                     (thing-at-point 'sexp))))
      (if (and (file-remote-p default-directory)
               ;; We can't formally parse the input.  But if there is
               ;; one of these operators behind us, then looking at
               ;; the first command would not be sensible.  So be
               ;; conservative: don't insert the Tramp prefix if there
               ;; are any of these operators behind us.
               (not (looking-back (regexp-opt '("&&" "|" ";"))
                                  eshell-last-output-end))
	       (or (= (point) eshell-last-output-end)
		   (and tilde-before
                        (= (1- (point)) eshell-last-output-end))
		   (and (or tilde-before
                            (eq ?\s (char-syntax (char-before))))
		        (or (eshell-find-alias-function command)
			    (and (fboundp (intern-soft command))
			         (or eshell-prefer-lisp-functions
				     (not (eshell-search-path command))))))))
	  (let ((map (make-sparse-keymap))
	        (start (if tilde-before (1- (point)) (point)))
                (localname
                 (tramp-file-name-localname
                  (tramp-dissect-file-name default-directory))))
	    (when tilde-before (delete-char -1))
	    (insert
             (substring default-directory 0
                        (string-search localname default-directory)))
	    (unless tilde-before (insert "/"))
	    ;; Typing a second slash undoes the insertion, for when
	    ;; you really do want to type a local absolute path.
	    (define-key map "/" (lambda ()
				  (interactive)
				  (delete-region start (point))
				  (insert (if tilde-before "~/" "/"))))
	    (set-transient-map map))
        (insert "/")))))

(provide 'em-elecslash)

;; Local Variables:
;; generated-autoload-file: "esh-groups.el"
;; End:

;;; esh-elecslash.el ends here

debug log:

solving e2585fe2a5 ...
found e2585fe2a5 in https://yhetil.org/emacs-devel/87k0bokg98.fsf@melete.silentflame.com/

applying [1/1] https://yhetil.org/emacs-devel/87k0bokg98.fsf@melete.silentflame.com/
diff --git a/lisp/eshell/em-elecslash.el b/lisp/eshell/em-elecslash.el
new file mode 100644
index 0000000000..e2585fe2a5

Checking patch lisp/eshell/em-elecslash.el...
Applied patch lisp/eshell/em-elecslash.el cleanly.

index at:
100644 e2585fe2a51cc63cac9c8592223c7fff0b47d651	lisp/eshell/em-elecslash.el

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).