3

When I copy line three below in evil-mode

function foo() {
}
var bar; #copy

and paste it at line two, I get

function foo() {
var bar; #paste
}

instead of the correctly indented

function foo() {
  var bar; #paste
}

I'd like to automatically indent my newly-pasted lines of code, and in vim, the fix for this is to remap the p key to "nnoremap gp p`[v`]=".

I figured that I could use the following in my init.el file to replicate the behaviour:

(fset 'paste-and-indent
  "p`[v`]=")
(define-key evil-normal-state-map (kbd "p") 'paste-and-indent)

But when I try to use the code, upon pressing p I get "After 0 kbd macro iterations: Lisp nesting exceeds 'max-lisp-eval-depth'." I'm confused by this, as max-lisp-eval-depth is set to 800!

Can anyone offer advice on how to implement this behaviour in evil-mode emacs?

1

This is possible using evil-indent and evil-get-marker.

This uses the with-undo-collapse macro so the operation doesn't create multiple undo entries.

(defun paste-and-indent-after ()
  (interactive)
  (with-undo-collapse
    (evil-paste-after 1)
    (evil-indent (evil-get-marker ?\[) (evil-get-marker ?\]))))
(defun paste-and-indent-before ()
  (interactive)
  (with-undo-collapse
    (evil-paste-before 1)
    (evil-indent (evil-get-marker ?\[) (evil-get-marker ?\]))))

;; Bindings for evil leader
(evil-leader/set-key "p" 'paste-and-indent-after)
(evil-leader/set-key "P" 'paste-and-indent-before)

Note that I couldn't get other answers here working.

0

This isn't a perfect solution, but it's the best I've found so far:

(fset 'indent-pasted-text
  "`[v`]=")
... 
(evil-leader/set-key
  "p" 'indent-pasted-text

This setup means that after pasting, I can hit <leader>p to correctly indent the text. I'm sure there's a better solution, and if you have one feel free to share it—I'll accept your answer instead.

-1

Your solution failed because it has unbounded recursion; the first thing it does is call whatever is bound to the "p" key, which is itself. Try something like this instead:

(defun paste-and-indent ()
  (interactive)
  (evil-paste-after 0)
  (indent-region))
  • So if I unbind the p key first, it should work? – tcelferact Mar 14 '17 at 0:21
  • If you unbind the 'p' key then it won't call anything at all; that won't help you. – db48x Mar 14 '17 at 0:23
  • I see. I've tried the above function, but it gives me Wrong type argument: commandp, paste-and-indent – tcelferact Mar 14 '17 at 0:28
  • Sorry, that's what I get for typing this into a textbox instead of into Emacs iteself. – db48x Mar 14 '17 at 0:30
  • 1
    Ok, now it says Wrong number of arguments: (2 . 3), 0. – tcelferact Mar 14 '17 at 0:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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