From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Sean Whitton Newsgroups: gmane.emacs.devel Subject: New optional Eshell module: em-elecslash Date: Sat, 16 Apr 2022 11:57:55 -0700 Message-ID: <87k0bokg98.fsf@melete.silentflame.com> References: <87r18qu5e1.fsf@posteo.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="18573"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Emacs/29.0.50 (x86_64-pc-linux-gnu) To: emacs-devel@gnu.org, Philip Kaludercic Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Apr 16 20:59:03 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nfndN-0004eb-28 for ged-emacs-devel@m.gmane-mx.org; Sat, 16 Apr 2022 20:59:03 +0200 Original-Received: from localhost ([::1]:55094 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nfndL-0007fJ-JK for ged-emacs-devel@m.gmane-mx.org; Sat, 16 Apr 2022 14:58:59 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:34586) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nfncR-0006DE-SB for emacs-devel@gnu.org; Sat, 16 Apr 2022 14:58:04 -0400 Original-Received: from wout5-smtp.messagingengine.com ([64.147.123.21]:46305) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nfncO-0008TZ-UG for emacs-devel@gnu.org; Sat, 16 Apr 2022 14:58:03 -0400 Original-Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id DD8BE3201FEA; Sat, 16 Apr 2022 14:57:57 -0400 (EDT) Original-Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Sat, 16 Apr 2022 14:57:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=spwhitton.name; h=cc:content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:reply-to:sender:subject:subject:to:to; s=fm3; t=1650135477; x=1650221877; bh=QhFtOCYEV3xuoZ7fpWIpoxKBD kRn1BjmRzgxoJ8OHrI=; b=Cr4uHrNBIpD2GANKYUcQSMtd4I3ZhuuGqoVJBgP8V 0q6CCmyenuRxv/rhns9ElHWImiR6E7BxxF1aUYSdaKBYgD7uFbbTrl7aX5OVOs6r 0UW//pUtomfCcKoeiIyKpQP1kiEE+K1FZqWWOC6CeOV8Th2t+TzNtRdawjEaqes3 Hko35Rwc7krc/Vr5n6clv58orlQLHiZhIgCcSAAmFO+alsLNl13MUQMqIzDY5egX 1qQ/tL1s8UtaoG9EWdycjsnnGq8cyfyoOEW6i/Mka4aeJe8WuuKzAJERKAc+EvPs NYYh2rxb8gIgYdE1CSpFToRP+3g67KV3kFVnl1VGrpzLA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:reply-to:sender :subject:subject:to:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1650135477; x=1650221877; bh=Q hFtOCYEV3xuoZ7fpWIpoxKBDkRn1BjmRzgxoJ8OHrI=; b=gyL5Y9luXbYRJOwzU Wa7lEhybmVEYxdAytCD1pmaFZqPUxDWBQraiP+OZ5XZi1VwiCrki/LRRaCDNUX0P AXdb3cxov+yN3WnoDMIXothjKA9z5WFVWq0XknctCm/c0AR9w+F+8Sdiv94vge1O YDQU19mFkdDlqsg/fb6hJs+8XwBsPkaCv8dKNZ7xvmliKyawvtoVrFeDkx8JHOTu x/tpusp35ZTp1LP50ILCBkMgcAVoutjLpOGecLHakN3ZIJcfrkoN/HGAZsJE7QVn Uxk7QqTWAOPLlf+ALft0bgJ18hsFh2teC8/qKRqr/tfAI4jY8SXAlN5QV/ttfJ/j 6rcqA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvvddrudeljedgudefvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefhvffujggffffkgggtsehmtddtredtredtnecuhfhrohhmpefuvggrnhcu hghhihhtthhonhcuoehsphifhhhithhtohhnsehsphifhhhithhtohhnrdhnrghmvgeqne cuggftrfgrthhtvghrnhepkedtheegieehledutdeggfeghfeujeffvdefudevteeiheei leetveeufeeigeejnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilh hfrhhomhepshhpfihhihhtthhonhesshhpfihhihhtthhonhdrnhgrmhgv X-ME-Proxy: Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat, 16 Apr 2022 14:57:57 -0400 (EDT) Original-Received: by melete.silentflame.com (Postfix, from userid 1000) id 022B77E4C94; Sat, 16 Apr 2022 11:57:55 -0700 (MST) In-Reply-To: <87r18qu5e1.fsf@posteo.net> Received-SPF: pass client-ip=64.147.123.21; envelope-from=spwhitton@spwhitton.name; helo=wout5-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:288498 Archived-At: --=-=-= Content-Type: text/plain Hello, On Sat 29 Jan 2022 at 11:51AM GMT, Philip Kaludercic wrote: > Sean Whitton writes: > >> Hello, >> >> I have a useful Eshell thing that I would like to make more broadly >> available but which should definitely not be turned on by default. The >> final implementation will be as an Eshell module which makes an addition >> to post-self-insert-hook. > > Could you give any details on what the feature is? Here is my new module, which I'd like to install on master. -- Sean Whitton --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-New-electric-forward-slash-Eshell-module.patch >From c915c51cd32b6354b951f10fb4d2d3666b3480d2 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Sat, 16 Apr 2022 08:23:14 -0700 Subject: [PATCH] New electric forward slash Eshell module * lisp/eshell/em-elecslash.el: New module. * etc/NEWS: * doc/misc/eshell.texi (Electric forward slash): Document the module. --- doc/misc/eshell.texi | 59 +++++++++++++++++++ etc/NEWS | 8 +++ lisp/eshell/em-elecslash.el | 113 ++++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 lisp/eshell/em-elecslash.el diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index 372e4c3ffb..61db05c4e3 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -1241,6 +1241,7 @@ Extension modules * Key rebinding:: * Smart scrolling:: * Terminal emulation:: +* Electric forward slash:: @end menu @node Writing a module @@ -1273,6 +1274,64 @@ Terminal emulation This section is not yet written. +@node Electric forward slash +@section Electric forward slash + +This optional module tries to help with passing absolute paths to +commands when @code{default-directory} is remote. When using Eshell's +Tramp support, it is easy to accidentally refer to a local path when +you meant a remote path. The problem arises because absolute paths +passed to Lisp functions must have Tramp's @code{/method:host:} +prefix, but absolute paths passed to external commands must not have +this prefix. Typically, one does not think about whether a command is +a Lisp function or an external command while inputting command line +arguments. For example, suppose you execute + +@example + cd /ssh:root@@example.com: + find /etc -name "*gnu*" +@end example + +@noindent and in reviewing the output of the command, you identify a +file @code{/etc/gnugnu} that should be moved somewhere else. So you +type + +@example + mv /etc/gnugnu /tmp +@end example + +@noindent But since @code{mv} refers to the local Lisp function +@code{eshell/mv}, not a remote shell command, to say this is to +request that the local file @code{/etc/gnugnu} be moved into the local +@code{/tmp} directory. What you should have typed is + +@example + mv /ssh:root@@example.com:/etc/gnugnu /ssh:root@@example.com:/tmp +@end example + +@noindent but it is easy to forget to do that, and it takes much +longer to type. + +If the @code{eshell-elecslash} module has been added to +@code{eshell-modules-list}, and @code{default-directory} is remote, +then when you type the first forward slash of an argument to a Lisp +function, the Tramp prefix will be filled in for you. A second +forward slash can be used to undo the insertion, for when you really +do want to pass a local absolute path, such as when you want to copy a +remote file to the local machine. And when typing arguments to +external commands, the Tramp prefix is not filled in. The result is +that you don't have to think about inserting the Tramp prefix and can +just type absolute paths in the same way for both types of command. +The Tramp prefix is additionally filled in when you type @code{~/}. + +The code that determines whether or not the Tramp prefix should be +inserted uses simple heuristics. A limitation of the current +implementation is that only the status as Lisp function or external +program of the command at the very beginning of input can be +considered. Thus when chaining commands with the operators @code{&&}, +@code{||}, @code{|} and @code{;}, the electric forward slash is active +only within the first command. + @node Bugs and ideas @chapter Bugs and ideas @cindex reporting bugs and ideas diff --git a/etc/NEWS b/etc/NEWS index 79c27da549..696c3ff844 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1165,6 +1165,14 @@ support for pipelines which will move a lot of data. See section "Running Shell Pipelines Natively" in the Eshell manual, node "(eshell) Input/Output". ++++ +*** New optional Eshell module to help avoid mistakes when supplying +absolute paths to commands in remote Eshells. 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 instead of a remote path. See +"Electric forward slash" in the Eshell manual. + ** Miscellaneous +++ diff --git a/lisp/eshell/em-elecslash.el b/lisp/eshell/em-elecslash.el new file mode 100644 index 0000000000..e2585fe2a5 --- /dev/null +++ b/lisp/eshell/em-elecslash.el @@ -0,0 +1,113 @@ +;;; em-elecslash.el --- electric forward slashes -*- lexical-binding:t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; Author: Sean Whitton + +;; 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 . + +;;; 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 -- 2.30.2 --=-=-=--