3

I switched to Emacs from Vim and because of Vims functionality of giving keys a prefix, (for example to jump up several lines etc.) i installed relative-linum-mode right away.

Now i found out about Emacs native functionality of jumping to a specific line with M-g M-g (and passing the line number in the minibuffer; the function is called goto-line) and find that much more useful than giving a prefix to C-n or C-p, which is of course not a functionality exclusive to Vim, but i found that to be too tedious in Emacs after all... Maybe i just didn't get used to it.

Now my idea is to have line numbers deactivated most of the time because i find that to look a lot cleaner, but when i press M-g M-g to activate linum-mode, passing the desired line number and after pressing enter and jumping to that line to deactivate linum-mode

Can i bind that to M-g M-g somehow? I know how to rebind keys but i can't figure out how (and if) my desired behavior is possible!

2 Answers 2

3

Here you go:

(global-set-key [remap goto-line] #'my-goto-line)

(defvar my-temp-linum-mode-sym
  (if (fboundp 'display-line-numbers-mode)
      'display-line-numbers-mode
    'linum-mode)
  "Use `display-line-numbers-mode' if it's available; `linum-mode' otherwise.")

(defun my-goto-line (line &optional buffer)
  "`goto-line' with temporary line-numbering."
  (interactive
   (let ((my-temp-linum-buffer
          ;; Use the same prefix-arg behaviour as `goto-line'.
          (if current-prefix-arg
              (other-buffer (current-buffer) t)
            (current-buffer))))
     ;; If line numbering is currently enabled in that buffer, then we
     ;; want to leave it alone.
     (when (with-current-buffer my-temp-linum-buffer
             (and (boundp my-temp-linum-mode-sym)
                  (symbol-value my-temp-linum-mode-sym)))
       (setq my-temp-linum-buffer nil))
     ;; Prompt the user for the line number, using the interactive
     ;; form from `goto-line'.  Line numbering will be enabled and
     ;; then disabled again during this procedure.
     (eval (cadr (interactive-form 'goto-line)))))
  ;; Pass the line and buffer arguments to `goto-line'.
  (goto-line line buffer))

(defun my-temp-linum-set-state (arg)
  "Enable or disable line numbering."
  (and (bound-and-true-p my-temp-linum-buffer)
       (buffer-live-p my-temp-linum-buffer)
       (with-current-buffer my-temp-linum-buffer
         ;; Call the specified mode function.
         (funcall my-temp-linum-mode-sym arg))))

(defun my-temp-linum-enable-maybe ()
  (my-temp-linum-set-state 1))

(defun my-temp-linum-disable-maybe ()
  (my-temp-linum-set-state -1))

(add-hook 'minibuffer-setup-hook #'my-temp-linum-enable-maybe)
(add-hook 'minibuffer-exit-hook #'my-temp-linum-disable-maybe)
2
  • Wow that was quick! I didn't expect such an answer in this small amount of time and honestly, i wouldn't have gotten something similar on my own. Thank you!
    – Tim Hilt
    Sep 26, 2018 at 9:20
  • You're welcome. It seemed like a fun problem to solve. I've added some more comments to the code to explain what it's doing.
    – phils
    Sep 26, 2018 at 9:21
0

Here a function that I have been using for a long time and recently modified to work without linum-mode since emacs 26.1 came with its own display-line-numbers-mode. You can bind it to any keys you want.

  ;; emacs-version 26.1
  (defun goto-line-with-feedback ()
    "Show line numbers temporarily when prompting for the line number to go to."
    (interactive)
    (unwind-protect
        (progn
          (display-line-numbers-mode)
          (goto-line (read-number "Goto line: ")))
      (display-line-numbers-mode 0)))
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.