我用 edebug 调试(先edebug-defun 标记函数 acm-get-input-prefix-bound, 然后等 acm-get-input-prefix-bound 执行停住的时候按 d 单步执行, 进入函数内部), 得到了调用链
acm-get-input-prefix-bound()
(let ((bound (acm-get-input-prefix-bound))) (if bound (buffer-substring-no-properties (car bound) (cdr bound)) ""))
acm-get-input-prefix()
(lsp-bridge-call-file-api "change_file" lsp-bridge--before-change-begin-pos lsp-bridge--before-change-end-pos length (buffer-substring-no-properties begin end) (lsp-bridge--position) (acm-char-before) (buffer-name) (acm-get-input-prefix))
(if lsp-bridge-revert-buffer-flag nil (setq lsp-bridge-last-change-command (format "%s" this-command)) (setq lsp-bridge-last-change-position (list (current-buffer) (buffer-chars-modified-tick) (point))) (lsp-bridge-call-file-api "change_file" lsp-bridge--before-change-begin-pos lsp-bridge--before-change-end-pos length (buffer-substring-no-properties begin end) (lsp-bridge--position) (acm-char-before) (buffer-name) (acm-get-input-prefix)) (if (lsp-bridge-epc-live-p lsp-bridge-epc-process) (progn (let* ((current-word (thing-at-point 'word t)) (current-symbol (thing-at-point 'symbol t))) (if acm-enable-tabnine (progn (lsp-bridge-tabnine-complete))) (if acm-enable-search-sdcv-words (progn (if (or ... ...) nil (lsp-bridge-call-async "search_sdcv_words_search" current-word)))) (lsp-bridge-elisp-symbols-search current-symbol) (if lsp-bridge-prohibit-completion nil (if buffer-file-name (progn (let ... ...)))) (if (and (derived-mode-p 'web-mode) (acm-in-string-p) (save-excursion (search-backward-regexp "class=" ... t))) (progn (if (or ... ...) nil (lsp-bridge-call-async "search_tailwind_keywords_search" buffer-file-name current-symbol))))))))
lsp-bridge-monitor-after-change(2 8 6)
replace-match(" DONE " t t)
org-todo(nil)
funcall-interactively(org-todo nil)
call-interactively(org-todo nil nil)
command-execute(org-todo)
看样子是 acm-get-input-prefix-bound 干扰了 org-todo 内部的 replace-match 后面的代码。
修复很简单, 但是等我思考一下, 为啥这两个不相关的函数会相互干扰。