1

When I typed C-y to call yank, I got this.

apply: Symbol's value as variable is void: n

Debugger entered--Lisp error: (void-variable n)
ad-Advice-current-kill( ... [interprogram-paste-function interprogram-cut-function kill-ring kill-ring-yank-pointer yank-pop-change-selection 0 nil mapc kill-new error "Kill ring is empty" mod] 6 2016971] 0)
apply(ad-Advice-current-kill ... [interprogram-paste-function interprogram-cut-function kill-ring kill-ring-yank-pointer yank-pop-change-selection 0 nil mapc kill-new error "Kill ring is empty" mod] 6 2016971] 0)
current-kill(0)
yank(nil)
call-interactively(yank nil nil)
command-execute(yank)

The '...' in the traceback is messy code.

I have found it's this sentence that caused this error.

(require 'multiple-cursors)

The contents after querying function current-kill.

current-kill is a compiled Lisp function in `simple.el'.

(current-kill ARG1 &optional ARG2)

:around advice: `ad-Advice-current-kill'

And the contents after pressing ad-Advice-current-kill.

ad-Advice-current-kill is a compiled Lisp function.

(ad-Advice-current-kill AD--ADDOIT-FUNCTION ARG1 &optional ARG2)

Before-advice `interprogram-paste-for-all-cursors'.

It's really inconvenient that yank can't work. Hoping to solve it quickly, I post the source code for interprogram-paste-for-all-cursors

(defadvice current-kill (before interprogram-paste-for-all-cursors activate)
  (let ((interprogram-paste (and (= n 0)
                                 interprogram-paste-function
                                 (funcall interprogram-paste-function))))
    (when interprogram-paste
      ;; Add interprogram-paste to normal kill ring, just
      ;; like current-kill usually does for itself.
      ;; We have to do the work for it tho, since the funcall only returns
      ;; something once. It is not a pure function.
      (let ((interprogram-cut-function nil))
        (if (listp interprogram-paste)
            (mapc 'kill-new (nreverse interprogram-paste))
          (kill-new interprogram-paste))
        ;; And then add interprogram-paste to the kill-rings
        ;; of all the other cursors too.
        (mc/for-each-fake-cursor
         (let ((kill-ring (overlay-get cursor 'kill-ring))
               (kill-ring-yank-pointer (overlay-get cursor 'kill-ring-yank-pointer)))
           (if (listp interprogram-paste)
               (mapc 'kill-new (nreverse interprogram-paste))
             (kill-new interprogram-paste))
           (overlay-put cursor 'kill-ring kill-ring)
           (overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer)))))))
moyotar
  • 76
  • 7
  • 1
    This is extremely weird, but the first way to understand the error would be to M-x toggle-debug-on-error to get the backtrace of the error. – wvxvw Nov 28 '16 at 15:02
  • Do you see the same thing when you start Emacs using emacs -Q (no init file)? If yes then M-x report-emacs-bug, providing a step-by-step recipe. If no, recursively bisect your init file to find the culprit. – Drew Nov 28 '16 at 15:24
  • @Drew With no init file to restart emacs, yank works normally. – moyotar Nov 28 '16 at 15:28
  • @wvxvw Thanks! By your help, I learned how to get traceback when encountering errors. And I have added traceback. – moyotar Nov 28 '16 at 15:30
  • 1
    Then bisect your init file to find out what causes the problem. You can use comment-region to comment out 1/2, then 3/4, 7/8, 15/16,... until you isolate the problem. It's very quick to do. With C-u, comment-region uncomments the region. – Drew Nov 28 '16 at 15:37
  • I think that if you do C-h f current-kill it will show you a help page describing where the advice was added. If you then move the point to the link to the advice and press RET, it should open the file where this advice was defined. It should be easy to figure out how this code ended up in your init file once you are there. – wvxvw Nov 28 '16 at 16:33
  • For info on bisecting your init file: http://emacs.stackexchange.com/questions/28429/how-do-i-troubleshoot-emacs-problems/28430#28430 – Tyler Nov 28 '16 at 16:36
  • @wvxvw I updated the question. – moyotar Nov 28 '16 at 17:53
  • @Tyler I updated the question. – moyotar Nov 28 '16 at 17:53
  • @Drew I updated the question – moyotar Nov 28 '16 at 17:54
  • Look in the source code of library multiple-cursors for interprogram-paste-for-all-cursors. That seems to be where there is a reference to an unbound variable n. A wild guess is that it is a free variable in a lambda form, and for some reason the file is not using lexical scope. If you cannot find or figure out what to do, consider sending a bug report to the maintainer of that library. – Drew Nov 28 '16 at 19:09
  • @Drew Thanks a lot! I have reported it to the maintainer. – moyotar Nov 29 '16 at 02:40
  • @Drew I posted the source code for interprogram-paste-for-all-cursors – moyotar Nov 29 '16 at 08:41
  • Here the report to maintainer. – moyotar Nov 29 '16 at 08:43
  • This may be a problem with parsing the defadvice form that probably changed recently. Since this advise specifies activate flag (no idea what it's for), it might have been interpreted as arguments. Hence, try making it all explicit: copy the arguments from current-kill plus first (for position) before activate and see if it works. – wvxvw Nov 29 '16 at 13:56
  • @wvxvw Sorry. I don't really know how to do. – moyotar Nov 29 '16 at 16:34
  • Change the first line to be (defadvice current-kill (before interprogram-paste-for-all-cursors (n &optional do-not-move) first activate). – wvxvw Nov 30 '16 at 08:32
  • @wvxvw Great! It works! Thank you very much! – moyotar Nov 30 '16 at 09:24
  • @wvxvw Will it influence something else? – moyotar Nov 30 '16 at 10:08
  • 1
    Oh, good to hear it worked. Will it influence anything else? - rather unlikely, but, I believe the maintainer would give you a better answer. – wvxvw Nov 30 '16 at 15:40
  • @wvxvw Yes. The maintainer has payed more attention to this problem. – moyotar Dec 01 '16 at 02:37

1 Answers1

1

The answer I believe is that the argument list for current-kill as defined in your session is (ARG1 &optional ARG2), whereas the argument list in at least the current release version of emacs is (N &optional DO-NOT-MOVE). The important difference is the replacement of N with ARG1 in your version.

If you look at the very beginning of the defadvice that you posted, it expects N to be defined. In the release version of emacs, N is bound when current-kill is called, but in your case the value that would be bound to N is bound to ARG1 instead.

Looking through the git history for emacs quickly, I couldn't find a point at which current-kill had the same argument list as the definition you provided, so my guess is that in one of your packages (or some code you are loading) current-kill is being redefined with a different argument list. That's just a guess though.

justbur
  • 1,510
  • 9
  • 8