Emacs: 封装 webjump 搜索 symbol-at-point

webjump 是 Emacs 里内置的一个包,你可以配置想要搜索的网站,然后通过 webjump 选择搜索。

例如这是我设置的网站:

(setq webjump-sites '(("Kagi" . [simple-query "kagi.com" "kagi.com/search?q=" ""])
                      ("Kagi Translate" . [simple-query "translate.kagi.com" "translate.kagi.com/?from=auto&to=zh_cn&text=" ""])
                      ("Wikipedia" . [simple-query "wikipedia.org" "wikipedia.org/wiki/" ""])
                      ("Kagi(site:github.com)" . [simple-query "kagi.com" "kagi.com/search?q=site:github.com+" ""])
                      ("Album" . [simple-query "kagi.com" "kagi.com/images?q=" "&size=large"])
                      ("MDN" . [simple-query "developer.mozilla.org" "developer.mozilla.org/en-US/search?q=" ""])
                      ("Haici" . [simple-query "dict.cn" "dict.cn/search?q=" ""])))

当我调用 webjump 时,它会让我从上面的选项里选一个,然后输入搜索关键字,之后就会跳转到对应的网站搜索。

可以将一些比较高频的搜索条件内置在搜索链接里。如果经常搜索 GitHub 上的内容,可以加上 site:github.com ,使得总是搜索 github.com 的内容;或者也可以直接用 GitHub 本身的搜索 https://github.com/search?q=%s

symbol-at-point 也是 Emacs 里内置的一个函数,可以获取当前指针下的内容。

结合两者,我写了一个函数,获取指针下的内容,然后调用 webjump 去搜索,这样在 Emacs 里碰到什么我想要查询的,就可以快速调用常用的网站进行搜索。例如写页面的时候快速去 MDN 查询一些 API 的使用。

代码
(use-package webjump
  :bind (("C-M-?" . spike-leung/webjump-symbol-at-point))
  :config
  (setq webjump-sites '(("Kagi" . [simple-query "kagi.com" "kagi.com/search?q=" ""])
                        ("Kagi Translate" . [simple-query "translate.kagi.com" "translate.kagi.com/?from=auto&to=zh_cn&text=" ""])
                        ("Wikipedia" . [simple-query "wikipedia.org" "wikipedia.org/wiki/" ""])
                        ("Kagi(site:github.com)" . [simple-query "kagi.com" "kagi.com/search?q=site:github.com+" ""])
                        ("Album" . [simple-query "kagi.com" "kagi.com/images?q=" "&size=large"])
                        ("MDN" . [simple-query "developer.mozilla.org" "developer.mozilla.org/en-US/search?q=" ""])
                        ("Haici" . [simple-query "dict.cn" "dict.cn/search?q=" ""])))
  (defun spike-leung/webjump-symbol-at-point ()
    "获取光标下的 symbol 并通过 webjump 搜索。"
    (interactive)
    (let* ((completion-ignore-case t)
           (query (if (use-region-p)
                      (buffer-substring-no-properties (region-beginning) (region-end))
                    (thing-at-point 'symbol t)))
           ;; (query (read-string (format "Webjump search (%s): " (or content ""))
           ;;                     nil nil content))
           (item (assoc-string
                  (completing-read "WebJump to site: " webjump-sites nil t)
                  webjump-sites t))
           (name (car item))
           (expr (cdr item))
           (query-prefix (aref expr 2))
           (query-suffix (aref expr 3))
           (fun (if webjump-use-internal-browser
                    (apply-partially #'browse-url-with-browser-kind 'internal)
                  #'browse-url)))
      (funcall fun (webjump-url-fix
                    (cond ((concat query-prefix (webjump-url-encode query) query-suffix))
                          (t (error "WebJump URL expression for \"%s\" invalid"
                                    name))))))))

Emacs China 上的相关讨论


更新:

因为是针对 point 下的内容操作,所以很适合用 embark,可以不用记忆额外的快捷键,更容易想起来用。

embark 可以理解成 Emacs 里的右键菜单,在任何位置都可以调用 embark-act 唤起这个菜单,菜单中的内容是可以自己定制的,这样就可以快速进行一些操作。

最近还经常用 Kagi Assistant,所以把 Kagi Assistant 的链接也加入到了 webjump,这样我就可以随时从 Emacs 中获取上下文,然后去 Kagi Assistant 进行对话。

现在我的操作流程是:

具体代码:

webjump 部分
(use-package webjump
  :after embark
  :defer nil
  :config
  (setq webjump-sites '(("Kagi" . [simple-query "kagi.com" "kagi.com/search?q=" ""])
                        ("Kagi Translate Text" . [simple-query "translate.kagi.com" "translate.kagi.com/?from=auto&to=zh_cn&text=" ""])
                        ("Kagi Translate Page" . [simple-query "translate.kagi.com" "translate.kagi.com/zh_cn/" "?kt_view=both_vertical?kt_view=both_vertical"])
                        ("Kagi LLM" . [simple-query "kagi.com" "kagi.com/assistant?q=" "&profile=kimi-k2.5-reasoning&internet=on"])
                        ("Kagi Summary" . [simple-query "kagi.com" "kagi.com/summarizer?url=" "&target_language=ZH&summary=takeaway"])
                        ("Wikipedia" . [simple-query "wikipedia.org" "wikipedia.org/wiki/" ""])
                        ("Kagi(site:github.com)" . [simple-query "kagi.com" "kagi.com/search?q=site:github.com+" ""])
                        ("Album" . [simple-query "kagi.com" "kagi.com/images?q=" "&size=large"])
                        ("MDN" . [simple-query "developer.mozilla.org" "developer.mozilla.org/en-US/search?q=" ""])
                        ("Haici" . [simple-query "dict.cn" "dict.cn/search?q=" ""])))

  (defun spike-leung/webjump-symbol-at-point (target)
    "获取光标下的 symbol 并通过 webjump 搜索。TARGET 是 `embark-act' 的对象。"
    (let* ((completion-ignore-case t)
           ;; 从 WebJump 列表选项
           (item (assoc-string
                  (completing-read "WebJump to site: " webjump-sites nil t)
                  webjump-sites t))
           ;; 选项名称
           (name (car item))
           ;; 选项配置
           (expr (cdr item))
           ;; 选项的第 3 个参数,获取查询前缀
           (query-prefix (aref expr 2))
           ;; 选项的第 4 个参数,获取查询后缀
           (query-suffix (aref expr 3))
           (fun (if webjump-use-internal-browser
                    (apply-partially #'browse-url-with-browser-kind 'internal)
                  #'browse-url))
           ;; 如果选择的是 LLM 相关的 URL,则需要输入 Prompt
           (prompt (and (string-match-p "LLM" name) (read-string "Prompt: " "解释" t)))
           ;; 如果存在 prompt 则拼接 prompt
           (query (or (and prompt (concat target "\n" prompt)) target)))
      (funcall fun (webjump-url-fix
                    (cond ((concat query-prefix (webjump-url-encode query) query-suffix))
                          (t (error "WebJump URL expression for \"%s\" invalid"
                                    name))))))))
embark 部分
(use-package embark
  :bind
  (("C-." . embark-act)
   ("M-." . embark-dwim)
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
  :init
  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)
  :config
  (keymap-set embark-general-map "W" #'spike-leung/webjump-symbol-at-point)
  (keymap-set embark-region-map "W" #'spike-leung/webjump-symbol-at-point))

webjump 和浏览器或者搜索引擎中的 Search Shortcuts 差不多, 可以保存常用的搜索条件便于快速搜索。

例如我经常需要从 Kagi 找专辑封面的图片,而且希望图片尺寸尽可能大。

我平常的操作是:

  1. 触发搜索栏
  2. 输入关键字搜索
  3. 切换到图片搜索
  4. 设置尺寸为 large 进行过滤

通过 Search Shortcuts,我设置了 https://kagi.com/images?q=%s&size=large ,并绑定 @a

我的操作就变成:

  1. 触发搜索栏
  2. 输入 @a 快捷键触发 Search Shortcuts,输入关键字搜索,结束

可以了解一下搜索引擎的搜索操作符,例如这是 Kagi Search Operators

然后将平时频繁使用的一些搜索条件保存到 Search Shortcuts,这样下次使用就会方便一些。

Webmentions (加载中...)

如果你想回应这篇文章,你可以在你的文章中链接这篇文章,然后在下面输入你的文章的 URL 并提交。你的回应随后会显示在此页面上(如果是垃圾信息我会屏蔽)。如果要更新或删除你的回应,请更新或删除你的文章,然后再次输入该文章的 URL 并提交。(了解有关 Webmention 的更多信息。)


作 者: Spike Leung

创建于: 2026-01-26 Mon 11:54

修改于: 2026-02-01 Sun 18:58

许可证: 署名—非商业性使用—相同方式共享 4.0

支持我: 用你喜欢的方式