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](https://github.com/magnars/multiple-cursors.el/issues/271) 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,500
  • 8
  • 8