Emacs 键盘宏无法调用组织模式捕获模板

Emacs keyboard macro fails to invoke org-mode capture template

我正在尝试使用以下键盘测试宏

(fset 'jj   [?\C-c ?c ?t ?j ?j  return ?\C-c ?\C-c]) 

调用此捕获模板定义

(setq org-capture-templates '(("t" "Todo" entry (file "~/org/j.org"))))

请注意 C-c c 调用 M-x org-capture.

不幸的是,它会产生以下错误消息:

After 0 kbd macro
iterations: byte-code: Capture abort: (wrong-type-argument stringp
(file:~/org/todo.org::*Tasks Tasks))

我制作了下面的回溯显示。组织模式配置是 追加在回溯之后。

Debugger entered--Lisp error: 
(error "Capture abort: (wrong-type-argument stringp
(file:~/org/todo.org::*Tasks Tasks))")

signal(error ("Capture abort: (wrong-type-argument stringp
(file:~/org/todo.org::*Tasks Tasks))"))

error("Capture abort: %s" (wrong-type-argument stringp
("file:~/org/todo.org::*Tasks" "Tasks")))

(condition-case error (org-capture-put :template
(org-capture-fill-template)) ((error quit) (if (get-buffer "*Capture*")
(kill-buffer "*Capture*")) (error "Capture abort: %s" error)))

 (cond ((equal entry "C") (customize-variable (quote org-capture-templates))) 
  ((equal entry "q") (error "Abort")) 
  (t (org-capture-set-plist entry) (org-capture-get-template) 
     (org-capture-put :original-buffer orig-buf 
                      :original-file (or (buffer-file-name orig-buf) 
                                         (and (featurep (quote dired)) 
                                              (car (rassq orig-buf
                                                         dired-buffers))))
                      :original-file-nondirectory (and (buffer-file-name
                                                      orig-buf) (file-name-nondirectory

        (buffer-file-name orig-buf)))
                      :annotation annotation :initial initial
:return-to-wconf (current-window-configuration)
                      :default-time (or org-overriding-default-time
 (org-current-time))$) 
     (org-capture-set-target-location) 
     (condition-case error
         (org-capture-put :template (org-capture-fill-template))
       ((error quit) 
        (if (get-buffer "*Capture*") (kill-buffer "*Capture*")) 
        (error "Capture abort: %s" error))) 
     (setq org-capture-clock-keep (org-capture-get :clock-keep)) 
     (if (equal goto 0) 
         (org-capture-insert-template-here) 
       (condition-case error 
           (org-capture-place-template 
            (equal (car (org-capture-get :target)) (quote function))) 
         ((error quit) (if (and (buffer-base-buffer ...) 
                                (string-match "\`CAPTURE-" ...)) 
                           (kill-buffer (current-buffer))) 
          (set-window-configuration (org-capture-get :return-to-wconf)) 
          (error "Capture template `%s': %s" (org-capture-get :key) (nth
                                                           1 error)))) 
       (if (and (derived-mode-p (quote org-mode))
                (org-capture-get :clock-in)) 
           (condition-case nil (progn (if (org-clock-is-active) 
                                          (org-capture-put 
                                           :interrupted-clock...)) 
                                      (org-clock-in) (org-set-local
(quote org-capture-clock-was-started) t)) 
             (error "Could not start the clock in this capture buffer"))) 
       (if (org-capture-get :immediate-finish) (org-capture-finalize)))))

(let* ((orig-buf (current-buffer)) 
   (annotation 
    (if (and (boundp (quote org-capture-link-is-already-stored))
             org-capture-link-is-already-stored) 
        (plist-get org-store-link-plist :annotation) 
      (condition-case nil (progn (org-store-link nil)) 
        (error nil)))) 
   (entry (or org-capture-entry (org-capture-select-template keys)))
         initial) 
 (setq initial (or org-capture-initial (and (org-region-active-p)
 (buffer-substring (point) (mark))))) 
 (if (stringp initial) (progn (remove-text-properties 0 (length initial)
 (quote (read-only t)) initial))) 
 (if (stringp annotation) (progn (remove-text-properties 0 (length annotation) 
   (quote (read-only  t)) annotation))) 
 (cond ((equal entry "C")
     (customize-variable (quote org-capture-templates))) 
    ((equal entry "q") 
     (error "Abort")) (t (org-capture-set-plist entry)
                         (org-capture-get-template) 
                         (org-capture-put 
                          :original-buffer orig-buf
                          :original-file (or (buffer-file-name orig-buf)
                                             (and (featurep (quote dired)) 
                                                  (car (rassq orig-buf
                                          dired-buffers)))) 
                          :original-file-nondirectory (and
                              (buffer-file-name orig-buf)

  (file-name-nondirectory

            (buffer-file-name orig-buf))) 
                          :annotation annotation :initial initial
                       :return-to-wconf
                          (current-window-configuration) 
                          :default-time (or org-overriding-default-time
        (org-current-time)))
                         (org-capture-set-target-location) 
                         (condition-case error 
                             (org-capture-put :template
          (org-capture-fill-template))
                           ((error quit) 
                            (if (get-buffer "*Capture*") 
                                (kill-buffer "*Capture*")) 
                            (error "Capture abort: %s" error))) 
                         (setq org-capture-clock-keep (org-capture-get
              :clock-keep)) 
                         (if (equal goto 0) 
 (org-capture-insert-template-here) 
                           (condition-case error
 (org-capture-place-template (equal (car ...) (quote function))) 
                             ((error quit) (if (and ... ...)
                                               (kill-buffer ...)) 
                              (set-window-configuration (org-capture-get
    :return-to-wconf)) 
                              (error "Capture template `%s': %s"
(org-capture-get :key) (nth 1 error)))) 
                           (if (and (derived-mode-p (quote org-mode))
(org-capture-get :clock-in))
                               (condition-case nil (progn (if ... ...)
(org-clock-in) (org-set-local ... t)) 
                                 (error "Could not start the clock in
               this capture buffer"))) 
                           (if (org-capture-get :immediate-finish)
(org-capture-finalize))))))                    
(cond ((equal goto (quote (4))) (org-capture-goto-target)) 
  ((equal goto (quote (16))) (org-capture-goto-last-stored))
  (t (let* ((orig-buf (current-buffer)) 
            (annotation (if (and (boundp ...)
org-capture-link-is-already-stored) 
                            (plist-get org-store-link-plist :annotation) 
                          (condition-case nil (progn ...) (error nil)))) 
            (entry (or org-capture-entry
                       (org-capture-select-template keys))) initial) 
       (setq initial (or org-capture-initial 
                         (and (org-region-active-p)
                              (buffer-substring (point) (mark))))) 
       (if (stringp initial) 
           (progn
             (remove-text-properties 0 (length initial) 
                                     (quote (read-only t)) initial))) 
       (if (stringp annotation)
           (progn (remove-text-properties 0 (length annotation) 
                                          (quote (read-only t))
annotation))) 
       (cond ((equal entry "C") (customize-variable (quote
 org-capture-templates))) 
             ((equal entry "q") 
              (error "Abort")) 
             (t (org-capture-set-plist entry) (org-capture-get-template) 
                (org-capture-put 
                 :original-buffer orig-buf 
                 :original-file (or (buffer-file-name orig-buf) (and ...
...)) 
                 :original-file-nondirectory (and (buffer-file-name
orig-buf) (file-name-nondirectory ...)) 
                 :annotation annotation 
                 :initial initial 
                 :return-to-wconf (current-window-configuration) 
                 :default-time (or org-overriding-default-time
(org-current-time)))
                (org-capture-set-target-location) 
                (condition-case error (org-capture-put 
                                       :template
(org-capture-fill-template))
                  ((error quit) (if ... ...) 
                   (error "Capture abort: %s" error))) 
                (setq org-capture-clock-keep
                      (org-capture-get :clock-keep)) 
                (if (equal goto 0)
                    (org-capture-insert-template-here) 
                  (condition-case error (org-capture-place-template ...)
                    (... ... ... ...)) 
                  (if (and ... ...) (condition-case nil ... ...)) 
                  (if (org-capture-get :immediate-finish)
                      (org-capture-finalize))))))))                
org-capture(nil)
call-interactively(org-capture nil nil)
command-execute(jj record)
execute-extended-command(nil "jj")
call-interactively(execute-extended-command nil nil)
----------------------------------------------------
ORG-MODE CONFIGURATION
Emacs  : GNU Emacs 24.3.1 (i686-pc-linux-gnu, GTK+ Version 3.4.2)
      of 2014-02-22 on chindi10, modified by Debian
Package: Org-mode version 8.2.10 (8.2.10-dist  <at>  /usr/share/emacs/site-lisp/org/)

 current state:
==============
(setq
 org-ctrl-c-ctrl-c-hook '(org-babel-hash-at-point
 org-babel-execute-safely-maybe)
 org-tab-first-hook '(org-hide-block-toggle-maybe
 org-src-native-tab-command-maybe org-babel-hide-result-toggle-maybe
 org-babel-header-arg-expand)
 org-agenda-use-time-grid nil
 org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-hide-drawers
 org-cycle-hide-inline-tasks org-cycle-show-empty-lines
 org-optimize-window-after-visibility-change)
 org-agenda-custom-commands '(("pa" "A-priority" tags-todo
 "+SCHEDULED<=\"<today>\"+PRIORITY=\"A\"") ("pb" "B-priority"

                      tags-todo

                      "+SCHEDULED<=\"<today>\"+PRIORITY=\"B\"")
                          ("pc" "C-priority" tags-todo
 "+SCHEDULED<=\"<today>\"+PRIORITY=\"C\"") ("b" "Buy" tags

                      "+CATEGORY=\"BUY\"")
                          ("w" "Web" tags "+CATEGORY=\"WEB\"") ("k"
 "Books" tags "+CATEGORY=\"BOOKS\"")
                          ("v" "Movies" tags "+CATEGORY=\"MOVIES\"")
 ("u" "Music" tags "+CATEGORY=\"MUSIC\""))
 org-agenda-before-write-hook '(org-agenda-add-entry-text)
 org-speed-command-hook '(org-speed-command-default-hook
 org-babel-speed-command-hook)
 org-babel-pre-tangle-hook '(save-buffer)
 org-occur-hook '(org-first-headline-recenter)
 org-deadline-warning-days 0
 org-metaup-hook '(org-babel-load-in-session-maybe)
 org-confirm-elisp-link-function 'yes-or-no-p
 org-capture-templates '(("t" "Todo" entry (file "~/org/j.org")))
 org-agenda-sorting-strategy '((agenda priority-down) (todo priority-down
 category-keep) (tags priority-down category-keep) (search category-keep))
 org-agenda-start-with-follow-mode t
 org-clock-out-hook '(org-clock-remove-empty-clock-drawer)
 org-agenda-prefix-format "  %-11:c% s"
 org-mode-hook '(#[nil "01234$7" [org-add-hook
 change-major-mode-hook org-show-block-all append local]
               5]
             #[nil "01234$7" [org-add-hook
 change-major-mode-hook org-babel-show-result-all append local] 5]
 org-babel-result-hide-spec org-babel-hide-all-hashes my-org-mode-hook)
 org-agenda-start-on-weekday nil
 org-agenda-mode-hook '(my-org-agenda-mode-hook)
 org-directory "~/org/"
 org-metadown-hook '(org-babel-pop-to-session-maybe)
 org-agenda-files '("~/org/todo.org" "~/org/home.org")
 org-src-mode-hook '(org-src-babel-configure-edit-buffer
 org-src-mode-configure-edit-buffer)
 org-after-todo-state-change-hook '(org-clock-out-if-current)
 org-confirm-shell-link-function 'yes-or-no-p
 )

短:executing-kbd-macro in org-store-link 是原因。我想不出一个简单的解决方案。

我试图重现这个错误并找到了函数

(defun test-inside-kbd-macro ()
  (interactive)
  (print (ignore-errors (org-store-link nil))))

根据通往 运行 的方式给出不同的结果。 1) M-x test-inside-kbd-macro 给出 "[[file:~/git/org/refile.org::*kbd%20capture][kbd capture]]" (字符串),但是 2)

(execute-kbd-macro (read-kbd-macro "M-x test-inside-kbd-macro RET"))

给出 ("file:~/git/org/refile.org::*kbd capture" "kbd capture") (列表)。所以错误 (wrong-type-argument stringp ...) 就是因此而发生的。

如果你看到函数的代码org-store-link(最后 10 行)

;; Return the link
(if (not (and (or (org-called-interactively-p 'any)
         executing-kbd-macro) link))
   (or agenda-link (and link (org-make-link-string link desc)))
 (push (list link desc) org-stored-links)
 (message "Stored: %s" (or desc link))
 (when custom-id
   (setq link (concat "file:" (abbreviate-file-name
                   (buffer-file-name)) "::#" custom-id))
   (push (list link desc) org-stored-links))
 (car org-stored-links))))))

您会发现在 1) 情况下,函数 test-inside-kbd-macro 的值是使用 (org-make-link-string link desc) 创建的,在 2) 情况下 - 使用 (car org-stored-links).

我认为这是由于 if 部分中的 executing-kbd-macro


组织捕获:

注释 -> (忽略错误 (org-store-link nil))

(org-capture-put ... :annotation 注释 ...)

org-capture-fill-template:

(v-a (or (plist-get org-store-link-plist :annotation)
      annotation
      (org-capture-get :annotation)
      ""))

(v-A (if (and v-a (string-match l-re v-a))

生成错误。