emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 74f377b 1/2: comint-insert-previous-argument counts


From: Dima Kogan
Subject: [Emacs-diffs] master 74f377b 1/2: comint-insert-previous-argument counts args from start or from end
Date: Mon, 18 Jun 2018 02:02:08 -0400 (EDT)

branch: master
commit 74f377b3955198d6f66afa34bbbf6d004aad134a
Author: Dima Kogan <address@hidden>
Commit: Dima Kogan <address@hidden>

    comint-insert-previous-argument counts args from start or from end
    
    This function is invoked in shell-mode by the user, and is meant to
    emulate what M-. does in zsh and bash: it inserts an argument from a
    previous command.  Without a prefix argument, it inserts the last arg
    from the previous command; with an argument INDEX, it inserts the
    INDEX-th argument.  bash counts from the start, while zsh counts from
    the end.  This patch adds a variable
    `comint-insert-previous-argument-from-end' that emulates the zsh
    behavior if non-nil.
    
    * lisp/comint.el (comint-arguments): can take in negative arguments to count
      from the end, same as indexing in python.
      (comint-insert-previous-argument): if
      comint-insert-previous-argument-from-end is non-nil, INDEX counts
      arguments from the end; if nil, from the beginning
      (Bug#25271)
    * etc/NEWS: Document this.
---
 etc/NEWS       | 10 ++++++++++
 lisp/comint.el | 44 +++++++++++++++++++++++++++++++-------------
 2 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 5a3a27e..8bf1da4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -190,6 +190,16 @@ navigation and editing of large files.
 It now treats the optional 2nd argument to mean that the URL should be
 shown in the currently selected window.
 
+** Comint
+*** 'comint-insert-previous-argument' knows how to count args
+from the beginning or from the end.  This is useful because
+'comint-insert-previous-argument' exists to emulate M-. in bash and zsh; and
+bash counts from the start while zsh counts from the end.
+
+*** New variable 'comint-insert-previous-argument-from-end' controls whether
+args passed to 'comint-insert-previous-argument' count from the beginning or
+from the end
+
 ** Flymake
 
 +++
diff --git a/lisp/comint.el b/lisp/comint.el
index f334a4c..f66e40b 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -1682,12 +1682,13 @@ characters), and are not considered to be delimiters."
 
 (defun comint-arguments (string nth mth)
   "Return from STRING the NTH to MTH arguments.
-NTH and/or MTH can be nil, which means the last argument.
-Returned arguments are separated by single spaces.
-We assume whitespace separates arguments, except within quotes
-and except for a space or tab that immediately follows a backslash.
-Also, a run of one or more of a single character
-in `comint-delimiter-argument-list' is a separate argument.
+NTH and/or MTH can be nil, which means the last argument.  NTH
+and MTH can be <0 to count from the end; -1 means last argument.
+Returned arguments are separated by single spaces.  We assume
+whitespace separates arguments, except within quotes and except
+for a space or tab that immediately follows a backslash.  Also, a
+run of one or more of a single character in
+`comint-delimiter-argument-list' is a separate argument.
 Argument 0 is the command name."
   ;; The first line handles ordinary characters and backslash-sequences
   ;; (except with w32 msdos-like shells, where backslashes are valid).
@@ -1709,7 +1710,7 @@ Argument 0 is the command name."
         (count 0)
         beg str quotes)
     ;; Build a list of all the args until we have as many as we want.
-    (while (and (or (null mth) (<= count mth))
+    (while (and (or (null mth) (< mth 0) (<= count mth))
                (string-match argpart string pos))
       ;; Apply the `literal' text property to backslash-escaped
       ;; characters, so that `comint-delim-arg' won't break them up.
@@ -1736,8 +1737,14 @@ Argument 0 is the command name."
              args (if quotes (cons str args)
                     (nconc (comint-delim-arg str) args))))
     (setq count (length args))
-    (let ((n (or nth (1- count)))
-         (m (if mth (1- (- count mth)) 0)))
+    (let ((n (cond
+              ((null nth) (1- count))
+              ((>= nth 0) nth)
+              (t          (+ count nth))))
+          (m (cond
+              ((null mth) 0)
+              ((>= mth 0) (1- (- count mth)))
+              (t          (1- (- mth))))))
       (mapconcat
        (function (lambda (a) a)) (nthcdr n (nreverse (nthcdr m args))) " "))))
 
@@ -2652,8 +2659,16 @@ text matching `comint-prompt-regexp'."
 (defvar-local comint-insert-previous-argument-last-start-pos nil)
 (defvar-local comint-insert-previous-argument-last-index nil)
 
-;; Needs fixing:
-;;  make comint-arguments understand negative indices as bash does
+(defcustom comint-insert-previous-argument-from-end nil
+  "If nil, the INDEX argument to
+`comint-insert-previous-argument' refers to the INDEX-th
+argument, counting from the beginning; if non-nil, counting from
+the end.  This exists to emulate the bahavior of `M-number M-.'
+in bash and zsh: in bash, `number' counts from the
+beginning (variable in nil), while in zsh it counts from the end."
+  :type 'boolean
+  :group 'comint)
+
 (defun comint-insert-previous-argument (index)
   "Insert the INDEXth argument from the previous Comint command-line at point.
 Spaces are added at beginning and/or end of the inserted string if
@@ -2661,8 +2676,8 @@ necessary to ensure that it's separated from adjacent 
arguments.
 Interactively, if no prefix argument is given, the last argument is inserted.
 Repeated interactive invocations will cycle through the same argument
 from progressively earlier commands (using the value of INDEX specified
-with the first command).
-This command is like `M-.' in bash."
+with the first command).  Values of INDEX<0 count from the end, so INDEX=-1
+is the last argument.  This command is like `M-.' in bash and zsh."
   (interactive "P")
   (unless (null index)
     (setq index (prefix-numeric-value index)))
@@ -2672,6 +2687,9 @@ This command is like `M-.' in bash."
         (setq index comint-insert-previous-argument-last-index))
        (t
         ;; This is a non-repeat invocation, so initialize state.
+         (when (and index
+                    comint-insert-previous-argument-from-end)
+           (setq index (- index)))
         (setq comint-input-ring-index nil)
         (setq comint-insert-previous-argument-last-index index)
         (when (null comint-insert-previous-argument-last-start-pos)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]