From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Jay Kamat Newsgroups: gmane.emacs.bugs Subject: bug#29821: Ensure quick substitution only occurs at start of line Date: Wed, 03 Jan 2018 17:17:27 -0800 Message-ID: <87po6q5sns.fsf@gmail.com> References: <87fu8272h6.fsf@gmail.com> <87shbqto33.fsf@users.sourceforge.net> <87wp11rqtr.fsf@users.sourceforge.net> <871sj96lgu.fsf@gmail.com> <87tvw4syi9.fsf@users.sourceforge.net> <87wp105ezz.fsf@gmail.com> <87o9mbso9j.fsf@users.sourceforge.net> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1515028576 16892 195.159.176.226 (4 Jan 2018 01:16:16 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 4 Jan 2018 01:16:16 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.90 (gnu/linux) Cc: 29821@debbugs.gnu.org, Andreas Schwab To: Noam Postavsky Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Jan 04 02:16:12 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eWu8g-00041l-Ac for geb-bug-gnu-emacs@m.gmane.org; Thu, 04 Jan 2018 02:16:10 +0100 Original-Received: from localhost ([::1]:44386 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWuAf-0002hn-Dz for geb-bug-gnu-emacs@m.gmane.org; Wed, 03 Jan 2018 20:18:13 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:51158) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWuAY-0002hF-It for bug-gnu-emacs@gnu.org; Wed, 03 Jan 2018 20:18:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eWuAU-0003mI-Jk for bug-gnu-emacs@gnu.org; Wed, 03 Jan 2018 20:18:06 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:54395) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eWuAU-0003lx-Dy for bug-gnu-emacs@gnu.org; Wed, 03 Jan 2018 20:18:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1eWuAT-0003iw-Vn for bug-gnu-emacs@gnu.org; Wed, 03 Jan 2018 20:18:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Jay Kamat Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 04 Jan 2018 01:18:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 29821 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 29821-submit@debbugs.gnu.org id=B29821.151502865714277 (code B ref 29821); Thu, 04 Jan 2018 01:18:01 +0000 Original-Received: (at 29821) by debbugs.gnu.org; 4 Jan 2018 01:17:37 +0000 Original-Received: from localhost ([127.0.0.1]:34843 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eWuA5-0003iC-89 for submit@debbugs.gnu.org; Wed, 03 Jan 2018 20:17:37 -0500 Original-Received: from mail-pl0-f42.google.com ([209.85.160.42]:43985) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eWuA3-0003hw-FH for 29821@debbugs.gnu.org; Wed, 03 Jan 2018 20:17:35 -0500 Original-Received: by mail-pl0-f42.google.com with SMTP id z5so131753plo.10 for <29821@debbugs.gnu.org>; Wed, 03 Jan 2018 17:17:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=xxy40rcFKJSBQBc0bIH2L2UmO3Xd4+LePPtP7BnfP3g=; b=lGqh4ODOMQBt7TyUUbSaj4dfuCVEmH1NPmYybuwIG/l7oZZOaa+Sqtbbek/PdT+J61 Nf8c4YC0iOy8kxJmXZrJUWxSi7BwzUuKuLP4ALIp+Q2Lk0sI1tYYMNstMYSTzOFPvfVl r985/UOOY7OVMeWGfjkx8L8iv330eQjl+HiEivSHvsXFWXbrVAW6n9+31+TPZpwlVuIe vcfgc33ClE3uk1Q4dPQiUpTi46qjcabBTHDrsk0QcDWzEGKzoGxjpvmCa0TRDzfDIo0C w2cgj1XZ3/8esonBFFlVd8LDIq/QJdPb5m79NY7y5/m2rvnQQ4v9Y32YGd3yb5C+cMJt qBqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=xxy40rcFKJSBQBc0bIH2L2UmO3Xd4+LePPtP7BnfP3g=; b=pd6bwh4mr/Zv71Hm5xFqTiMg1fQWAkKbXjgwN0gN5k13dZfltHGlnayjUPiHjQXot+ cJoVsVYcVvY2RYhdmweTgZkf3aDFQhvdeLZEYoK+GfWPBnCGwu6HY82Lz4lNeMVvNxAp pqUU/c5IChGmXBUIv+YW8uHHRQAYp55nGWQCNXzME0CLjt8i+VlGoLXgEGh2+93qerzH VJjC7quouebQ/yloGq6xkbuJKrlFQjC2ac3WMtlaP9QY9HqQIU4ldnhDZ7FtcSvdQah0 YaCzCoVx3MpfPeUHwzPmhwPVUG8iU7+QiZHqtyt8iAe5WAiyG7BiQg1aKS2GgnSYOazk QoaQ== X-Gm-Message-State: AKGB3mI4vaquCIrHgTlE1fV4lWPKSCm4C6I5aSD0BBNHVT58BClcHzYH 22Q3yeHTEoFhpItgLnia658= X-Google-Smtp-Source: ACJfBouYfanCXKLrSKEP/10F31HaKzF3H9Hl7RWzIi7a3uMRujibcdPoxFA2cyOYZ3usCQyvxsN4wg== X-Received: by 10.84.246.20 with SMTP id k20mr3073975pll.209.1515028649474; Wed, 03 Jan 2018 17:17:29 -0800 (PST) Original-Received: from laythe (c-67-161-9-47.hsd1.ca.comcast.net. [67.161.9.47]) by smtp.gmail.com with ESMTPSA id b9sm5124433pfl.108.2018.01.03.17.17.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 03 Jan 2018 17:17:28 -0800 (PST) In-Reply-To: <87o9mbso9j.fsf@users.sourceforge.net> (Noam Postavsky's message of "Tue, 02 Jan 2018 20:51:36 -0500") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:141761 Archived-At: --=-=-= Content-Type: text/plain Noam Postavsky writes: > Oh, yes, I was confused by your docstring. By "if no match found" you > meant when the line doesn't match ^foo^bar^ at all; I had somehow got > the impression you meant that there was no match for "foo". Ah, yes, I'll try to make the docstring a bit more clear! > This eq test will always be nil, right? Because the only time it's t > is when you pass something that's not a history reference, but the thing > we passed is a history reference by construction. So this could be > simplified to Yup, that's true, I'll simplify that down. Here's a patch which tries to fix those issues. Thanks again, -Jay --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Prevent-expansion-of-quick-substitutions-when-not-at.patch >From e7632214858e9f12eed5d9c3cba1fb3c37529db5 Mon Sep 17 00:00:00 2001 From: Jay Kamat Date: Fri, 22 Dec 2017 15:34:44 -0800 Subject: [PATCH] Prevent expansion of quick substitutions when not at start of line See bug #29157 for an initial report Also, allow spaces inside substitutions, so ^foo bar^baz works. * lisp/eshell/em-hist.el (eshell-expand-history-references): Expand history substitution before other types of expansions, and expand them with the whole line. (eshell-history-substitution): New function to expand only substitutions, taking in the entire typed line rather than individual arguments. --- lisp/eshell/em-hist.el | 55 ++++++++++++++++++++++++++++++++------------------ lisp/eshell/em-pred.el | 3 ++- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el index df462a7058..b75d218110 100644 --- a/lisp/eshell/em-hist.el +++ b/lisp/eshell/em-hist.el @@ -581,21 +581,30 @@ eshell-hist-parse-arguments (defun eshell-expand-history-references (beg end) "Parse and expand any history references in current input." - (let ((result (eshell-hist-parse-arguments beg end))) + (let ((result (eshell-hist-parse-arguments beg end)) + (full-line (buffer-substring-no-properties beg end))) (when result (let ((textargs (nreverse (nth 0 result))) (posb (nreverse (nth 1 result))) - (pose (nreverse (nth 2 result)))) + (pose (nreverse (nth 2 result))) + (full-line-subst (eshell-history-substitution full-line))) (save-excursion - (while textargs - (let ((str (eshell-history-reference (car textargs)))) - (unless (eq str (car textargs)) - (goto-char (car posb)) - (insert-and-inherit str) - (delete-char (- (car pose) (car posb))))) - (setq textargs (cdr textargs) - posb (cdr posb) - pose (cdr pose)))))))) + (if full-line-subst + ;; Found a ^foo^bar substitution + (progn + (goto-char beg) + (insert-and-inherit full-line-subst) + (delete-char (- end beg))) + ;; Try to expand other substitutions + (while textargs + (let ((str (eshell-history-reference (car textargs)))) + (unless (eq str (car textargs)) + (goto-char (car posb)) + (insert-and-inherit str) + (delete-char (- (car pose) (car posb))))) + (setq textargs (cdr textargs) + posb (cdr posb) + pose (cdr pose))))))))) (defvar pcomplete-stub) (defvar pcomplete-last-completion-raw) @@ -630,20 +639,26 @@ eshell-complete-history-reference (setq history (cdr history))) (cdr fhist))))))) +(defun eshell-history-substitution (line) + "Expand quick hist substitutions formatted as ^foo^bar^. +Returns nil if string does not match quick substitution format, +and acts like !!:s/foo/bar/ otherwise." + ;; `^string1^string2^' + ;; Quick Substitution. Repeat the last command, replacing + ;; STRING1 with STRING2. Equivalent to `!!:s/string1/string2/' + (when (and (eshell-using-module 'eshell-pred) + (string-match "^\\^\\([^^]+\\)\\^\\([^^]+\\)\\^?\\s-*$" + line)) + (eshell-history-reference + (format "!!:s/%s/%s/" + (match-string 1 line) + (match-string 2 line))))) + (defun eshell-history-reference (reference) "Expand directory stack REFERENCE. The syntax used here was taken from the Bash info manual. Returns the resultant reference, or the same string REFERENCE if none matched." - ;; `^string1^string2^' - ;; Quick Substitution. Repeat the last command, replacing - ;; STRING1 with STRING2. Equivalent to `!!:s/string1/string2/' - (if (and (eshell-using-module 'eshell-pred) - (string-match "\\^\\([^^]+\\)\\^\\([^^]+\\)\\^?\\s-*$" - reference)) - (setq reference (format "!!:s/%s/%s/" - (match-string 1 reference) - (match-string 2 reference)))) ;; `!' ;; Start a history substitution, except when followed by a ;; space, tab, the end of the line, = or (. diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el index 72a7bc4afc..86a9d4262a 100644 --- a/lisp/eshell/em-pred.el +++ b/lisp/eshell/em-pred.el @@ -545,7 +545,8 @@ eshell-pred-substitute (function (lambda (str) (if (string-match ,match str) - (setq str (replace-match ,replace t nil str))) + (setq str (replace-match ,replace t nil str)) + (error (concat str ": substitution failed"))) str)) lst))))) (defun eshell-include-members (&optional invert-p) -- 2.11.0 --=-=-=--