【已入门勿看】我的 emacs 离线查词(英文单词查字典之目前)方案

把过年这半个月时间研究的查词方案分享出来,感谢论坛的

SPQR 创造了一个不依赖sdcv程序的纯lisp办法,解决了windows下sdcv难以编译运行的问题

redguardtoo 帮我确认了纯lisp可以查stardict,并且是我查词方案的基础

unique_nospace_brief 直接指出并给了调用goldendict和Silverdict的代码(后者我还没读完)

也要感谢ai,大部分时间我是在以对话来修改。llm的作用可能就是收集了大量的解决办法提优。 所以我想我把自己的改的配置放到网上,它也能搜索到,间接也算是贡献了吧

下面是代码,不会折叠,就直接贴出来吧

;; -*- coding: utf-8; lexical-binding: t; -*-

(require 'cl-lib)
(require 'subr+)

(defvar my-dict-buffer-name "*MYDICT*"
  "The buffer buffer of my dictionary lookup.")

(defvar my-dict-complete
  '("~/.stardict/dic/stardict-ecdict-2.4.2" "stardict-ecdict-2.4.2"))

(defvar my-dict-complete-cache nil "Internal variable.")

(defvar my-dict-buffer "*Dictionary Definition*"
  "Buffer name for displaying dictionary definitions.")

(cl-defun my-dict-get-word-at-point ()
  "Get the word at the current point, handling punctuation and special characters."
  (when-let ((bounds (bounds-of-thing-at-point 'word)))  ;; 使用 'word 而不是 'symbol
    (let* ((word (buffer-substring-no-properties (car bounds) (cdr bounds)))
           (trimmed-word (string-trim word))
           (lowercase-word (downcase trimmed-word)))
      lowercase-word)))  ;; 返回整个单词

(cl-defun my-dict-quit-window ()
  "Quit window."
  (interactive)
  (quit-window t))

(cl-defmacro my-dict-search-detail (word dict cache)
  "Return WORD's definition with DICT, CACHE."
  `(when-let ((cache (or ,cache (stardict-open (nth 0 ,dict) (nth 1 ,dict) t))))
     (stardict-lookup cache ,word)))

(cl-defun my-dict-show-definition (dict cache buffer-name)
  "Show dictionary lookup in buffer."
  (interactive)
  (when-let* ((word (my-dict-get-word-at-point))
              (def (my-dict-search-detail word dict cache)))
    (with-current-buffer (get-buffer-create buffer-name)
      (setq buffer-read-only nil)
      (erase-buffer)
      (insert def)
      (goto-char (point-min))
      (with-local-quit
        (local-set-key (kbd "q") 'my-dict-quit-window)
        (when (and (boundp 'evil-mode) evil-mode)
          (evil-local-set-key 'normal "q" 'my-dict-quit-window))
        (display-buffer (current-buffer) '((display-buffer-in-side-window)
                                           (side . right)
                                           (slot . 0)
                                           (window-width . 50)))))))


(cl-defun my-dict-complete-definition ()
  "Show dictionary lookup in buffer."
  (interactive)
  (my-dict-show-definition my-dict-complete my-dict-complete-cache my-dict-buffer-name))

(defun goldendict-popup ()
  "Query GoldenDict popup thing."
  (interactive)
  (let (content-str)
    (setq content-str (my-dict-get-word-at-point))  ;; 使用 my-dict-get-word-at-point 函数获取单词
    (if content-str
        (let ((exe-path
               (cond
                ((eq system-type 'windows-nt) "goldendict.exe ")
                ((eq system-type 'darwin) "/Applications/GoldenDict.app/Contents/MacOS/GoldenDict ")
                (t "goldendict "))))
          (start-process-shell-command
           "goldendict-popup" nil
           (concat exe-path content-str)))
      (message "No Word at that point"))))

(global-set-key (kbd "C-c d") 'my-dict-simple-definition)
(global-set-key (kbd "C-c g") 'goldendict-popup)

(provide 'init-dictionary)

当日更新:删除了朗道,查询时总是有一个信息 You can’t save this buffer because compression program is not defined,我解决不了,直接删了,只用 ecdict 了

计划待学习后如能弄明白就更新:

补充Siverdict的查词部分

如能学会,加上popweb查韦氏在线词典的方案(届时就可以去掉标题里的离线二字)

1 个赞

或许我之前写过的一个中英文翻译方案也可以作为参考,离线方式同样使用了开源的 stardict.el,如果本地安装了sdcv则会使用sdcv命令查询,速度会更快一些

1 个赞

感谢,我去学习下

目前感觉纯lisp的 sdcv 延迟大些, 我去作者贴子留言了,不知有没有加速的办法 目前主用 unique_nospace_brief 指点的 goldendict,词典资源不是 sdcv 能比的

我是这么干的,直接去msys2下载sdcv编译好的二进制文件,再把它依赖的一些库文件也下载下来放在一起,在windows上就可以用了,在emacs里面配合了quick-sdcv使用 :sunglasses:

mysys2我也试了,我在另一个贴子 如何令 sdcv 在 windows 下用上 ecdict 里描述了下用ecdict的问题(这个词库大是个人必用的)

请问你可以正常查询ecdict吗,是我哪里设置得不对吗谢谢

词典我用的牛津高阶英汉双解是正常的,ecdict没试过咧