unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
blob 091acb9a8618b0b546f7a0441c165a028697a686 4658 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
114
115
116
117
118
119
120
 
;;; 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
  "Electric forward slash in remote Eshells.

This module helps with supplying absolute file name arguments to
remote commands.  After enabling it, typing a forward slash as
the first character of a command line argument will automatically
insert the Tramp prefix, /method:host:.  The automatic insertion
applies only when `default-directory' is remote and the command
is a Lisp function.

The result is that in most cases of supplying absolute file name
arguments to commands you should see the Tramp prefix inserted
automatically only when that's what you'd reasonably expect.
This frees you from having to keep track of whether commands are
Lisp functions or external when typing command line arguments."
  :tag "Electric forward slash"
  :group 'eshell-module))

;;; Functions:

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

(defun eshell-electric-forward-slash ()
  "Implementation of electric forward slash in remote Eshells.

Initializing the `eshell-elecslash' module adds this function to
`post-self-insert-hook'.  Typing / or ~/ as the first character
of a command line argument automatically inserts the Tramp prefix
in the case that `default-directory' is remote and the command is
a Lisp function.  Typing a second forward slash undoes the
insertion."
  (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 file name.
	    (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 091acb9a86 ...
found 091acb9a86 in https://git.savannah.gnu.org/cgit/emacs.git

(*) 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).