GNU Emacs 24 上的 redo+.el

5

我正在尝试在OSX上的GNU Emacs 24中使用redo+.el。当我尝试加载文件(使用M-x load-file或在我的.emacs文件中使用(require 'redo+))时,我会遇到以下错误:

Attempt to modify read-only object

调试器的完整输出如下(也可以在这里查看)。

Debugger entered--Lisp error: (error "Attempt to modify read-only object")
  setcar(((and (not buffer-read-only) (not (eq t buffer-undo-list)) (if (eq last-command (quote undo)) (listp pending-undo-list) (consp buffer-undo-list))) :help "Undo last operation") (and (not buffer-read-only) (consp buffer-undo-list) (or (not (or (eq last-buffer-undo-list buffer-undo-list) (eq last-buffer-undo-list (cdr buffer-undo-list)))) (listp pending-undo-list))))
  (lambda (map) (setcar (cdr (memq :enable (assq (quote undo) (cdr map)))) (quote (and (not buffer-read-only) (consp buffer-undo-list) (or (not (or (eq last-buffer-undo-list buffer-undo-list) (eq last-buffer-undo-list ...))) (listp pending-undo-list))))))((keymap (undo menu-item "Undo" undo :enable (and (not buffer-read-only) (not (eq t buffer-undo-list)) (if (eq last-command (quote undo)) (listp pending-undo-list) (consp buffer-undo-list))) :help "Undo last operation") (separator-undo "--") (cut menu-item "Cut" kill-region :enable (and mark-active (not buffer-read-only)) :help "Cut (kill) text in region between mark and current position") (copy menu-item "Copy" ns-copy-including-secondary :enable mark-active :help "Copy text in region between mark and current position" :keys "\\[ns-copy-including-secondary]") (paste menu-item "Paste" yank :enable (and (or (and (fboundp (quote x-selection-exists-p)) (x-selection-exists-p (quote CLIPBOARD))) (if (featurep (quote ns)) (cdr yank-menu) kill-ring)) (not buffer-read-only)) :help "Paste (yank) text most recently cut/copied") (select-paste menu-item "Select and Paste" yank-menu :enable (and (cdr yank-menu) (not buffer-read-only)) :help "Choose a string from the kill ring and paste it") (clear menu-item "Clear" delete-region :enable (and mark-active (not buffer-read-only)) :help "Delete the text in region between mark and current position") (mark-whole-buffer menu-item "Select All" mark-whole-buffer :help "Mark the whole buffer for a subsequent cut/copy") (separator-search "--") (search menu-item "Search" (keymap (search-forward menu-item "String Forward..." nonincremental-search-forward :help "Search forward for a string") (search-backward menu-item "String Backwards..." nonincremental-search-backward :help "Search backwards for a string") (re-search-forward menu-item "Regexp Forward..." nonincremental-re-search-forward :help "Search forward for a regular expression") (re-search-backward menu-item "Regexp Backwards..." nonincremental-re-search-backward :help "Search backwards for a regular expression") (separator-repeat-search "--") (repeat-search-fwd menu-item "Repeat Forward" nonincremental-repeat-search-forward :enable (or (and (eq menu-bar-last-search-type (quote string)) search-ring) (and (eq menu-bar-last-search-type (quote regexp)) regexp-search-ring)) :help "Repeat last search forward") (repeat-search-back menu-item "Repeat Backwards" nonincremental-repeat-search-backward :enable (or (and (eq menu-bar-last-search-type (quote string)) search-ring) (and (eq menu-bar-last-search-type (quote regexp)) regexp-search-ring)) :help "Repeat last search backwards") (separator-tag-search "--") (tags-srch menu-item "Search Tagged Files..." tags-search :help "Search for a regexp in all tagged files") (tags-continue menu-item "Continue Tags Search" tags-loop-continue :help "Continue last tags search operation") (separator-tag-isearch "--") (i-search menu-item "Incremental Search" (keymap (isearch-forward menu-item "Forward String..." isearch-forward :help "Search forward for a string as you type it") (isearch-backward menu-item "Backward String..." isearch-backward :help "Search backwards for a string as you type it") (isearch-forward-regexp menu-item "Forward Regexp..." isearch-forward-regexp :help "Search forward for a regular expression as you type it") (isearch-backward-regexp menu-item "Backward Regexp..." isearch-backward-regexp :help "Search backwards for a regular expression as you type it") "Incremental Search")) "Search")) (replace menu-item "Replace" (keymap (query-replace menu-item "Replace String..." query-replace :enable (not buffer-read-only) :help "Replace string interactively, ask about each occurrence") (query-replace-regexp menu-item "Replace Regexp..." query-replace-regexp :enable (not buffer-read-only) :help "Replace regular expression interactively, ask about each occurrence") (separator-replace-tags "--") (tags-repl menu-item "Replace in Tagged Files..." tags-query-replace :help "Interactively replace a regexp in all tagged files") (tags-repl-continue menu-item "Continue Replace" tags-loop-continue :help "Continue last tags replace operation") "Replace")) (goto menu-item "Go To" (keymap (go-to-line menu-item "Goto Line..." goto-line :help "Read a line number and go to that line") (go-to-pos menu-item "Goto Buffer Position..." goto-char :help "Read a number N and go to buffer position N") (beg-of-buf menu-item "Goto Beginning of Buffer" beginning-of-buffer) (end-of-buf menu-item "Goto End of Buffer" end-of-buffer) (separator-tags "--") (find-tag menu-item "Find Tag..." find-tag :help "Find definition of function or variable") (find-tag-otherw menu-item "Find Tag in Other Window..." find-tag-other-window :help "Find function/variable definition in another window") (next-tag menu-item "Find Next Tag" menu-bar-next-tag :enable (and (boundp (quote tags-location-ring)) (not (ring-empty-p tags-location-ring))) :help "Find next function/variable matching last tag name") (next-tag-otherw menu-item "Next Tag in Other Window" menu-bar-next-tag-other-window :enable (and (boundp (quote tags-location-ring)) (not (ring-empty-p tags-location-ring))) :help "Find next function/variable matching last tag name in another window") (apropos-tags menu-item "Tags Apropos..." tags-apropos :help "Find function/variables whose names match regexp") (separator-tag-file "--") (set-tags-name menu-item "Set Tags File Name..." visit-tags-table :help "Tell Tags commands which tag table file to use") "Go To")) (bookmark menu-item "Bookmarks" menu-bar-bookmark-map) (separator-bookmark "--") (fill menu-item "Fill" fill-region :enable (and mark-active (not buffer-read-only)) :help "Fill text in region to fit between left and right margin") (spell menu-item "Spell" ispell-menu-map) (props menu-item "Text Properties" facemenu-menu) "Edit"))
  mapc((lambda (map) (setcar (cdr (memq :enable (assq (quote undo) (cdr map)))) (quote (and (not buffer-read-only) (consp buffer-undo-list) (or (not (or (eq last-buffer-undo-list buffer-undo-list) (eq last-buffer-undo-list ...))) (listp pending-undo-list)))))) ((keymap (undo menu-item "Undo" undo :enable (and (not buffer-read-only) (not (eq t buffer-undo-list)) (if (eq last-command (quote undo)) (listp pending-undo-list) (consp buffer-undo-list))) :help "Undo last operation") (separator-undo "--") (cut menu-item "Cut" kill-region :enable (and mark-active (not buffer-read-only)) :help "Cut (kill) text in region between mark and current position") (copy menu-item "Copy" ns-copy-including-secondary :enable mark-active :help "Copy text in region between mark and current position" :keys "\\[ns-copy-including-secondary]") (paste menu-item "Paste" yank :enable (and (or (and (fboundp (quote x-selection-exists-p)) (x-selection-exists-p (quote CLIPBOARD))) (if (featurep (quote ns)) (cdr yank-menu) kill-ring)) (not buffer-read-only)) :help "Paste (yank) text most recently cut/copied") (select-paste menu-item "Select and Paste" yank-menu :enable (and (cdr yank-menu) (not buffer-read-only)) :help "Choose a string from the kill ring and paste it") (clear menu-item "Clear" delete-region :enable (and mark-active (not buffer-read-only)) :help "Delete the text in region between mark and current position") (mark-whole-buffer menu-item "Select All" mark-whole-buffer :help "Mark the whole buffer for a subsequent cut/copy") (separator-search "--") (search menu-item "Search" (keymap (search-forward menu-item "String Forward..." nonincremental-search-forward :help "Search forward for a string") (search-backward menu-item "String Backwards..." nonincremental-search-backward :help "Search backwards for a string") (re-search-forward menu-item "Regexp Forward..." nonincremental-re-search-forward :help "Search forward for a regular expression") (re-search-backward menu-item "Regexp Backwards..." nonincremental-re-search-backward :help "Search backwards for a regular expression") (separator-repeat-search "--") (repeat-search-fwd menu-item "Repeat Forward" nonincremental-repeat-search-forward :enable (or (and (eq menu-bar-last-search-type ...) search-ring) (and (eq menu-bar-last-search-type ...) regexp-search-ring)) :help "Repeat last search forward") (repeat-search-back menu-item "Repeat Backwards" nonincremental-repeat-search-backward :enable (or (and (eq menu-bar-last-search-type ...) search-ring) (and (eq menu-bar-last-search-type ...) regexp-search-ring)) :help "Repeat last search backwards") (separator-tag-search "--") (tags-srch menu-item "Search Tagged Files..." tags-search :help "Search for a regexp in all tagged files") (tags-continue menu-item "Continue Tags Search" tags-loop-continue :help "Continue last tags search operation") (separator-tag-isearch "--") (i-search menu-item "Incremental Search" (keymap (isearch-forward menu-item "Forward String..." isearch-forward :help "Search forward for a string as you type it") (isearch-backward menu-item "Backward String..." isearch-backward :help "Search backwards for a string as you type it") (isearch-forward-regexp menu-item "Forward Regexp..." isearch-forward-regexp :help "Search forward for a regular expression as you type it") (isearch-backward-regexp menu-item "Backward Regexp..." isearch-backward-regexp :help "Search backwards for a regular expression as you type it") "Incremental Search")) "Search")) (replace menu-item "Replace" (keymap (query-replace menu-item "Replace String..." query-replace :enable (not buffer-read-only) :help "Replace string interactively, ask about each occurrence") (query-replace-regexp menu-item "Replace Regexp..." query-replace-regexp :enable (not buffer-read-only) :help "Replace regular expression interactively, ask about each occurrence") (separator-replace-tags "--") (tags-repl menu-item "Replace in Tagged Files..." tags-query-replace :help "Interactively replace a regexp in all tagged files") (tags-repl-continue menu-item "Continue Replace" tags-loop-continue :help "Continue last tags replace operation") "Replace")) (goto menu-item "Go To" (keymap (go-to-line menu-item "Goto Line..." goto-line :help "Read a line number and go to that line") (go-to-pos menu-item "Goto Buffer Position..." goto-char :help "Read a number N and go to buffer position N") (beg-of-buf menu-item "Goto Beginning of Buffer" beginning-of-buffer) (end-of-buf menu-item "Goto End of Buffer" end-of-buffer) (separator-tags "--") (find-tag menu-item "Find Tag..." find-tag :help "Find definition of function or variable") (find-tag-otherw menu-item "Find Tag in Other Window..." find-tag-other-window :help "Find function/variable definition in another window") (next-tag menu-item "Find Next Tag" menu-bar-next-tag :enable (and (boundp (quote tags-location-ring)) (not (ring-empty-p tags-location-ring))) :help "Find next function/variable matching last tag name") (next-tag-otherw menu-item "Next Tag in Other Window" menu-bar-next-tag-other-window :enable (and (boundp (quote tags-location-ring)) (not (ring-empty-p tags-location-ring))) :help "Find next function/variable matching last tag name in another window") (apropos-tags menu-item "Tags Apropos..." tags-apropos :help "Find function/variables whose names match regexp") (separator-tag-file "--") (set-tags-name menu-item "Set Tags File Name..." visit-tags-table :help "Tell Tags commands which tag table file to use") "Go To")) (bookmark menu-item "Bookmarks" menu-bar-bookmark-map) (separator-bookmark "--") (fill menu-item "Fill" fill-region :enable (and mark-active (not buffer-read-only)) :help "Fill text in region to fit between left and right margin") (spell menu-item "Spell" ispell-menu-map) (props menu-item "Text Properties" facemenu-menu) "Edit") (keymap (new-file menu-item "Visit New File..." find-file :enable (menu-bar-non-minibuffer-window-p) :help "Specify a new file's name, to edit the file" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :label "New File" :vert-only t) (open-file menu-item "Open File..." menu-find-file-existing :enable (menu-bar-non-minibuffer-window-p) :help "Read an existing file into an Emacs buffer" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :label "Open" :vert-only t) (dired menu-item "Open Directory..." dired :enable (menu-bar-non-minibuffer-window-p) :help "Read a directory, to operate on its files" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :vert-only t) (kill-buffer menu-item "Close" kill-this-buffer :enable (kill-this-buffer-enabled-p) :help "Discard (kill) current buffer" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :vert-only t) (save-buffer menu-item "Save" save-buffer :enable (and (buffer-modified-p) (buffer-file-name) (menu-bar-non-minibuffer-window-p)) :help "Save current buffer to its file" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :label "Save") (separator-1 "--") (undo menu-item "Undo" undo :enable (and (not buffer-read-only) (not (eq t buffer-undo-list)) (if (eq last-command (quote undo)) (listp pending-undo-list) (consp buffer-undo-list))) :help "Undo last operation" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...)))))) (separator-2 "--") (cut menu-item "Cut" kill-region :enable (and mark-active (not buffer-read-only)) :help "Cut (kill) text in region between mark and current position" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :vert-only t) (copy menu-item "Copy" ns-copy-including-secondary :enable mark-active :help "Copy text in region between mark and current position" :keys "\\[ns-copy-including-secondary]" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :vert-only t) (paste menu-item "Paste" yank :enable (and (or (and (fboundp (quote x-selection-exists-p)) (x-selection-exists-p (quote CLIPBOARD))) (if (featurep (quote ns)) (cdr yank-menu) kill-ring)) (not buffer-read-only)) :help "Paste (yank) text most recently cut/copied" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :vert-only t) (separator-3 "--") (isearch-forward menu-item "Forward String..." isearch-forward :help "Search forward for a string as you type it" :image (find-image (cond ((not (display-color-p)) (quote (... ... ... ...))) ((< (display-color-cells) 256) (quote (... ... ... ...))) (t (quote (... ... ...))))) :label "Search" :vert-only t))))
  (if nil nil (mapc (function (lambda (map) (setcar (cdr (memq :enable (assq ... ...))) (quote (and (not buffer-read-only) (consp buffer-undo-list) (or ... ...)))))) (append (list menu-bar-edit-menu) (if window-system (list tool-bar-map)))) (define-key-after menu-bar-edit-menu [redo] (quote (menu-item "Redo" redo :enable (and (not buffer-read-only) (not (eq buffer-undo-list t)) (not (eq last-buffer-undo-list nil)) (or (eq last-buffer-undo-list buffer-undo-list) (let (...) (and ... ...) (while ... ...) (eq last-buffer-undo-list p))) (not (eq (cdr buffer-undo-list) pending-undo-list))) :help "Redo the most recent undo")) (quote undo)) (if window-system (progn (tool-bar-add-item-from-menu (quote redo) "redo" nil :visible (quote (not (eq (quote special) (get major-mode ...))))) (define-key-after tool-bar-map [redo] (cdr (assq (quote redo) tool-bar-map)) (quote undo)) (if (boundp (quote x-gtk-stock-map)) (setq x-gtk-stock-map (cons (quote ("etc/images/redo" . "gtk-redo")) x-gtk-stock-map))) (defalias (quote redo-toolbar-update) (function (lambda (&optional bgn end lng) (interactive) (set-buffer-modified-p (buffer-modified-p))))) (add-hook (quote after-change-functions) (quote redo-toolbar-update)))))
  eval-buffer(#<buffer  *load*> nil "/Users/john/Documents/scripts/emacs/redo+.el" nil t)  ; Reading at buffer position 11262
  load-with-code-conversion("/Users/john/Documents/scripts/emacs/redo+.el" "/Users/john/Documents/scripts/emacs/redo+.el" nil t)
  require(redo+)
  eval((require (quote redo+)) nil)
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp nil nil)

我之前在 Ubuntu 系统上成功使用过完全相同的 .el 文件。有任何解决此问题的想法吗?

更新

根据这个网址中的信息(感谢 Daniel Martin),我可以通过注释掉以下代码块来加载模块:

  (mapc (lambda (map)
          (setcar (cdr (memq :enable (assq 'undo (cdr map))))
              '(and (not buffer-read-only)
                (consp buffer-undo-list)
                (or (not (or (eq last-buffer-undo-list
                         buffer-undo-list)
                         (eq last-buffer-undo-list
                         (cdr buffer-undo-list))))
                    (listp pending-undo-list)))))
        (append (list menu-bar-edit-menu)
            (if window-system (list tool-bar-map))))

我并不太在意这个问题,因为我只会通过键盘快捷键使用撤销/重做功能,而不是通过菜单项。 不过链接提到可以使用以下代码来解决此问题,但老实说我不知道如何做到(我对Lisp很差)...

 (let ((elem (copy-sequence (cdr (assq 'undo menu-bar-edit-menu)))))
   (setcar (cdr (memq :enable elem)) <your-exp-here>)
   elem))

1
使用 --debug-init 参数启动 Emacs,以获取完整的堆栈跟踪。 - Daniel Martín
在执行 M-x load-file 前,可以输入 M-x toggle-debug-on-error 来开启调试模式。 - legoscia
当然,我已经在这里粘贴了调试器的输出。 - John J. Camilleri
我在Debian上的Emacs 24上遇到了相同的错误。我怀疑问题是redo+.el和Emacs 24之间的冲突。你的Ubuntu系统是否使用Emacs 23? - Tyler
2
你有读过这个吗?:http://lists.gnu.org/archive/html/emacs-bug-tracker/2012-10/msg00051.html - Daniel Martín
显示剩余5条评论
1个回答

5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接