From 0d113bbf4138bd8e24556bff62d19ce02a27650d Mon Sep 17 00:00:00 2001 From: Daniel Nicolai Date: Mon, 1 Feb 2021 09:34:28 +0100 Subject: [PATCH 1/3] Add option global `mark-goto-buffer-not-line` Because of multiple requests to have some quick way to mark buffers for quickly switching between multiple buffers, and also inspired by @yyoncho his [evil-marker-plus](https://github.com/yyoncho/evil-markers-plus), I figured that it is often preferred to just jump to the last buffer position instead of a specific line number when jumping to a global mark (if one wants to jump to the specific line then one could jump with backtick, optionally follow by a zero, instead of jumping with quote. A following commit implements listing the marks with some delay in *evil-marks* buffer (similar to which-key package behavior) --- evil-commands.el | 14 ++++++++++---- evil-vars.el | 7 +++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index 073ffc53..e6da59bd 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -765,6 +765,9 @@ Columns are counted from zero." :type exclusive (move-to-column (or count 0))) +(defun evil--goto-mark-globalp (marker) + (not (equal (current-buffer) (marker-buffer marker)))) + (evil-define-command evil-goto-mark (char &optional noerror) "Go to the marker specified by CHAR." :keep-visual t @@ -775,8 +778,11 @@ Columns are counted from zero." (let ((marker (evil-get-marker char))) (cond ((markerp marker) - (switch-to-buffer (marker-buffer marker)) - (goto-char (marker-position marker))) + (let ((goto-is-global (evil--goto-mark-globalp marker))) + (switch-to-buffer (marker-buffer marker)) + (unless (and evil-mark-goto-buffer-not-line + goto-is-global) + (goto-char (marker-position marker))))) ((numberp marker) (goto-char marker)) ((consp marker) @@ -797,8 +803,8 @@ Columns are counted from zero." :type line :jump t (interactive (list (read-char))) - (evil-goto-mark char noerror) - (evil-first-non-blank)) + (when (evil-goto-mark char noerror) + (evil-first-non-blank))) (evil-define-motion evil-jump-backward (count) "Go to older position in jump list. diff --git a/evil-vars.el b/evil-vars.el index 1936c79a..d9f5a70c 100644 --- a/evil-vars.el +++ b/evil-vars.el @@ -591,6 +591,13 @@ large accessible in insert state." :type 'boolean :group 'evil) +(defcustom evil-mark-goto-buffer-not-line t + "Behavior of goto mark with `''. +When `t', `'' jumps to last cursor position of the marked buffer +instead of jumping to the mark its line number." + :type 'boolean + :group 'evil) + (defcustom evil-complete-all-buffers t "\\ Whether completion looks for matches in all buffers. From 7dad900c32d1014a617b654606a3d5f376c225b8 Mon Sep 17 00:00:00 2001 From: Daniel Nicolai Date: Mon, 1 Feb 2021 10:30:42 +0100 Subject: [PATCH 2/3] On goto, show marks with delay in *evil-marks* buffer This commit adds functionality to the previous commit (i.e. mark-goto-buffer-not-line), and shows marks in the *evil-marks* window after a delay (similiar to which-key). It is especially handy to remind of which mark is associated with which buffer. --- evil-commands.el | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ evil-maps.el | 4 ++-- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index e6da59bd..3fc502b9 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -806,6 +806,61 @@ Columns are counted from zero." (when (evil-goto-mark char noerror) (evil-first-non-blank))) +(defun evil--goto-mark-list (marks &optional line-or-buffer) + (let ((initial-buffer (current-buffer))) + (evil-show-marks marks) + (let* ((char (read-char)) + (key (char-to-string char)) + (entry (tabulated-list-get-entry))) + (while (and + entry + (not (string= (aref entry 0) key))) + (next-line) + (setq entry (tabulated-list-get-entry))) + (cond ((eobp) (message "Marker '%s' is not set in this buffer" key) + (evil-list-view-quit)) + (t (evil-list-view-quit) + (switch-to-buffer (car (elt entry 3))) + (let ((same-buffer (equal initial-buffer (current-buffer)))) + (when (or same-buffer + (and (not same-buffer) (not line-or-buffer))) + (evil-goto-mark (string-to-char (elt entry 0))) + (when line-or-buffer + (evil-first-non-blank))))))))) + +(evil-define-command evil-goto-mark-list (marks &optional line-or-buffer) + :keep-visual t + :repeat nil + :type exclusive + :jump t + (interactive "") + (with-timeout (0.6 + (evil--goto-mark-list marks line-or-buffer)) + (let* ((char (read-char))) + (when (and (evil-goto-mark char) line-or-buffer) + (evil-first-non-blank))))) + +(evil-define-command evil-goto-mark-line-list (marks) + :keep-visual t + :repeat nil + :type line + :jump t + (interactive "") + (evil-goto-mark-list marks t)) + +(defun evil-goto-mark-set () + (if evil-mark-goto-buffer-not-line + 'evil-goto-mark-list + 'evil-goto-mark)) + +(defun evil-goto-mark-line-set () + (if evil-mark-goto-buffer-not-line + 'evil-goto-mark-line-list + 'evil-goto-mark-line)) + +(setq evil-goto-mark-auto (evil-goto-mark-set)) +(setq evil-goto-mark-line-auto (evil-goto-mark-line-set)) + (evil-define-motion evil-jump-backward (count) "Go to older position in jump list. To go the other way, press \ diff --git a/evil-maps.el b/evil-maps.el index 91ed47eb..8b71533e 100644 --- a/evil-maps.el +++ b/evil-maps.el @@ -220,8 +220,8 @@ (define-key evil-motion-state-map "g#" 'evil-search-unbounded-word-backward) (define-key evil-motion-state-map "$" 'evil-end-of-line) (define-key evil-motion-state-map "%" 'evil-jump-item) -(define-key evil-motion-state-map "`" 'evil-goto-mark) -(define-key evil-motion-state-map "'" 'evil-goto-mark-line) +(define-key evil-motion-state-map "`" evil-goto-mark-auto) +(define-key evil-motion-state-map "'" evil-goto-mark-line-auto) (define-key evil-motion-state-map "(" 'evil-backward-sentence-begin) (define-key evil-motion-state-map ")" 'evil-forward-sentence-begin) (define-key evil-motion-state-map "]]" 'evil-forward-section-begin) From 6c8c83b46de3cc1a1befccee5dc7057a52e52b7a Mon Sep 17 00:00:00 2001 From: Daniel Nicolai Date: Tue, 2 Feb 2021 18:14:27 +0100 Subject: [PATCH 3/3] Add option to global mark jump to buffer instead of line (refactored) --- evil-commands.el | 96 +++++++++++++++++++----------------------------- evil-maps.el | 4 +- 2 files changed, 40 insertions(+), 60 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index 3fc502b9..b3f4c3e1 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -768,12 +768,29 @@ Columns are counted from zero." (defun evil--goto-mark-globalp (marker) (not (equal (current-buffer) (marker-buffer marker)))) -(evil-define-command evil-goto-mark (char &optional noerror) - "Go to the marker specified by CHAR." - :keep-visual t - :repeat nil - :type exclusive - :jump t +(defun evil--goto-mark-list (&optional line-or-buffer) + (let ((initial-buffer (current-buffer))) + (evil-show-marks nil) + (let* ((char (read-char)) + (key (char-to-string char)) + (entry (tabulated-list-get-entry))) + (while (and + entry + (not (string= (aref entry 0) key))) + (next-line) + (setq entry (tabulated-list-get-entry))) + (cond ((eobp) (message "Marker '%s' is not set in this buffer" key) + (evil-list-view-quit)) + (t (evil-list-view-quit) + (switch-to-buffer (car (elt entry 3))) + (let ((same-buffer (equal initial-buffer (current-buffer)))) + (when (or same-buffer + (and (not same-buffer) (not line-or-buffer))) + (evil--goto-mark (string-to-char (elt entry 0))) + (when line-or-buffer + (evil-first-non-blank))))))))) + +(defun evil--goto-mark (char &optional noerror line-or-buffer) (interactive (list (read-char))) (let ((marker (evil-get-marker char))) (cond @@ -781,7 +798,8 @@ Columns are counted from zero." (let ((goto-is-global (evil--goto-mark-globalp marker))) (switch-to-buffer (marker-buffer marker)) (unless (and evil-mark-goto-buffer-not-line - goto-is-global) + goto-is-global + line-or-buffer) (goto-char (marker-position marker))))) ((numberp marker) (goto-char marker)) @@ -796,70 +814,32 @@ Columns are counted from zero." (if (evil-global-marker-p char) "" " in this buffer")))))) -(evil-define-command evil-goto-mark-line (char &optional noerror) - "Go to the line of the marker specified by CHAR." - :keep-visual t - :repeat nil - :type line - :jump t +(defun evil--goto-mark-line (char &optional noerror) (interactive (list (read-char))) - (when (evil-goto-mark char noerror) + (when (evil--goto-mark char nil t) (evil-first-non-blank))) -(defun evil--goto-mark-list (marks &optional line-or-buffer) - (let ((initial-buffer (current-buffer))) - (evil-show-marks marks) - (let* ((char (read-char)) - (key (char-to-string char)) - (entry (tabulated-list-get-entry))) - (while (and - entry - (not (string= (aref entry 0) key))) - (next-line) - (setq entry (tabulated-list-get-entry))) - (cond ((eobp) (message "Marker '%s' is not set in this buffer" key) - (evil-list-view-quit)) - (t (evil-list-view-quit) - (switch-to-buffer (car (elt entry 3))) - (let ((same-buffer (equal initial-buffer (current-buffer)))) - (when (or same-buffer - (and (not same-buffer) (not line-or-buffer))) - (evil-goto-mark (string-to-char (elt entry 0))) - (when line-or-buffer - (evil-first-non-blank))))))))) - -(evil-define-command evil-goto-mark-list (marks &optional line-or-buffer) +(evil-define-command evil-goto-mark () + "Go to the marker specified by CHAR." :keep-visual t :repeat nil :type exclusive :jump t - (interactive "") - (with-timeout (0.6 - (evil--goto-mark-list marks line-or-buffer)) - (let* ((char (read-char))) - (when (and (evil-goto-mark char) line-or-buffer) - (evil-first-non-blank))))) + (if evil-mark-goto-buffer-not-line + (with-timeout (0.6 (evil--goto-mark-list)) + (call-interactively 'evil--goto-mark)) + (call-interactively 'evil--goto-mark))) -(evil-define-command evil-goto-mark-line-list (marks) +(evil-define-command evil-goto-mark-line (&optional char noerror) + "Go to the line of the marker specified by CHAR." :keep-visual t :repeat nil :type line :jump t - (interactive "") - (evil-goto-mark-list marks t)) - -(defun evil-goto-mark-set () (if evil-mark-goto-buffer-not-line - 'evil-goto-mark-list - 'evil-goto-mark)) - -(defun evil-goto-mark-line-set () - (if evil-mark-goto-buffer-not-line - 'evil-goto-mark-line-list - 'evil-goto-mark-line)) - -(setq evil-goto-mark-auto (evil-goto-mark-set)) -(setq evil-goto-mark-line-auto (evil-goto-mark-line-set)) + (with-timeout (0.6 (evil--goto-mark-list t)) + (call-interactively 'evil--goto-mark-line)) + (call-interactively 'evil--goto-mark-line))) (evil-define-motion evil-jump-backward (count) "Go to older position in jump list. diff --git a/evil-maps.el b/evil-maps.el index 8b71533e..91ed47eb 100644 --- a/evil-maps.el +++ b/evil-maps.el @@ -220,8 +220,8 @@ (define-key evil-motion-state-map "g#" 'evil-search-unbounded-word-backward) (define-key evil-motion-state-map "$" 'evil-end-of-line) (define-key evil-motion-state-map "%" 'evil-jump-item) -(define-key evil-motion-state-map "`" evil-goto-mark-auto) -(define-key evil-motion-state-map "'" evil-goto-mark-line-auto) +(define-key evil-motion-state-map "`" 'evil-goto-mark) +(define-key evil-motion-state-map "'" 'evil-goto-mark-line) (define-key evil-motion-state-map "(" 'evil-backward-sentence-begin) (define-key evil-motion-state-map ")" 'evil-forward-sentence-begin) (define-key evil-motion-state-map "]]" 'evil-forward-section-begin)