1

I'm often making typing mistakes which will kick me out of the current function block (hitting M-n when I meant C-n). In such cases it would be nice to be able to return immediately to the previous cursor position. My understanding (correct me if I'm wrong) is that the mark ring is not ideally suited to this purpose because it requires setting the mark at positions ahead of time.

I guess I'm asking for a 'trailing mark ring' that stores all cursor positions, say, 2 or 3 moves back...or something like that.

MathManM
  • 171
  • 3
  • It's hard to say if the mark ring will be helpful to you. Some navigation commands automatically set a mark in order to make it easier to return to your former position. Since you're hitting these commands accidentally, the easiest way to find out is just to try popping the mark ring to see where it takes you. – Tyler Feb 19 '17 at 04:20
  • @phils Thanks. Can you elaborate? – MathManM Feb 19 '17 at 22:42
  • Commands like interactive search (C-s) automatically set the mark. After using `C-s` to navigate to a new place in the file, you can return to your original spot by popping the mark with `C-u C-`. This is fairly common for functions that involve moving point around. I don't know what `M-n` is bound to in your example, but it's possible it does this too. – Tyler Feb 20 '17 at 02:56
  • 2
    Maybe [point-undo.el](http://www.emacswiki.org/emacs/point-undo.el) is what your're looking for. See also [this question](http://emacs.stackexchange.com/questions/27988/navigate-cursor-position-history-with-line-based-jumps). – Timm Feb 20 '17 at 20:03
  • @Timm Thanks; that's exactly what I needed! – MathManM Mar 25 '17 at 18:38

1 Answers1

1

This is doubtless a little simplistic, but I expect it would deal with most cases.

(defvar-local my-track-prev-pos-marker nil
  "Buffer-local marker to remember the previous editing position.")

(add-hook 'pre-command-hook 'my-track-prev-pos-pre-command)

(defun my-track-prev-pos-pre-command ()
  "Track the previous editing position in `my-track-prev-pos-marker'."
  (unless (eq this-command 'my-track-prev-pos-jump)
    (if (markerp my-track-prev-pos-marker)
        (set-marker my-track-prev-pos-marker (point))
      (setq my-track-prev-pos-marker (point-marker)))))

(add-hook 'kill-buffer-hook 'my-track-prev-pos-kill-buffer-hook)

(defun my-track-prev-pos-kill-buffer-hook ()
  "Reclaim the buffer-local marker."
  (setq my-track-prev-pos-marker nil))

(defun my-track-prev-pos-jump ()
  "Jump to the previous editing position."
  (interactive)
  (when (markerp my-track-prev-pos-marker)
    (let ((prev (marker-position my-track-prev-pos-marker)))
      (set-marker my-track-prev-pos-marker (point))
      (goto-char prev))))

(global-set-key (kbd "C-c b") 'my-track-prev-pos-jump)
phils
  • 48,657
  • 3
  • 76
  • 115