Project Icon

engine-mode

Emacs定制搜索引擎工具

engine-mode是Emacs的全局小模式,用于定义和管理自定义搜索引擎。它允许用户绑定快捷键,直接从编辑器中进行搜索查询。该模式支持为每个搜索引擎设置特定浏览器、修改搜索词和自定义文档字符串。相比内置的webjump,engine-mode提供了更多功能和灵活性,适合经常进行网络搜索的Emacs用户。

#+title: =engine-mode= #+options: toc:nil num:nil

[[https://melpa.org/#/engine-mode][https://melpa.org/packages/engine-mode-badge.svg]] [[https://stable.melpa.org/#/engine-mode][https://stable.melpa.org/packages/engine-mode-badge.svg]] [[https://www.gnu.org/licenses/gpl-3.0][https://img.shields.io/badge/License-GPL%20v3-blue.svg]] [[https://github.com/hrs/engine-mode/actions/workflows/test.yml][https://github.com/hrs/engine-mode/actions/workflows/test.yml/badge.svg?branch=main]]

engine-mode is a global minor mode for Emacs. It enables you to easily define search engines, bind them to keybindings, and query them from the comfort of your editor.

#+ATTR_HTML: :alt Demo searching for a term, with the results opening in a browser window. #+ATTR_HTML: :width 100% [[file:./doc/demo.gif]]

For example, suppose we want to be able to easily search GitHub:

#+begin_src emacs-lisp (defengine github "https://github.com/search?ref=simplesearch&q=%s") #+end_src

This defines an interactive function engine/search-github. When executed it will take the selected region (or prompt for input, if no region is selected) and search GitHub for it, displaying the results in your default browser.

The defengine macro can also take an optional key combination, prefixed with engine/keymap-prefix (which defaults to =C-x /=). That keybinding will be wrapped in a call to kbd.

#+begin_src emacs-lisp (defengine duckduckgo "https://duckduckgo.com/?q=%s" :keybinding "d") #+end_src

=C-x / d= is now bound to the new function engine/search-duckduckgo! Nifty.

If you'd like to see a video on the whys and wherefores of this mode, check out [[https://www.youtube.com/watch?v=MBhJBMYfWUo][the talk @hrs gave at EmacsNYC]].

** Installation

engine-mode is available on MELPA.

Using use-package:

#+begin_src emacs-lisp (use-package engine-mode :ensure t

:config
(engine-mode t))

#+end_src

You can also install it like any other elisp file by adding it to your load path and globally enabling it:

#+begin_src emacs-lisp (require 'engine-mode) (engine-mode t) #+end_src

** Changing your default browser

engine-mode uses the engine/browser-function variable to determine which browser it should use to open the URL it constructs. To change the default browser, redefine engine/browser-function. For example, to always use Emacs' built-in eww browser:

#+begin_src emacs-lisp (setq engine/browser-function 'eww-browse-url) #+end_src

engine/browser-function defaults to browse-url-browser-function, which Emacs uses globally to open links.

The implementation of the browse-url-browser-function variable contains a comprehensive list of possible browser functions. You can get to that by hitting =C-h v browse-url-browser-function = and following the link to =browse-url.el=.

** Changing your browser on a per-engine basis

To only change the browser for a single engine, use the :browser keyword argument when you define the engine. For example, to use eww only for your GitHub search results, try:

#+begin_src emacs-lisp (defengine github "https://github.com/search?ref=simplesearch&q=%s" :browser 'eww-browse-url) #+end_src

As mentioned about, see the implementation of the browse-url-browser-function for a definitive list of browsers.

** Changing the keymap prefix

The default keymap prefix for engine-mode is =C-x /=. If you'd like to bind the keymap to an additional prefix (say, =C-c s=), you totally can:

#+begin_src emacs-lisp (engine/set-keymap-prefix (kbd "C-c s")) #+end_src

If you use use-package, you can achieve the same thing with:

#+begin_src emacs-lisp :bind-keymap ("C-c s" . engine-mode-prefixed-map) #+end_src

** Custom docstrings

defengine assigns each engine a reasonable default docstring, but you can override that on a case-by-case basis with the :docstring keyword argument:

#+begin_src emacs-lisp (defengine ctan "https://www.ctan.org/search/?x=1&PORTAL=on&phrase=%s" :docstring "Search the Comprehensive TeX Archive Network (ctan.org)") #+end_src

** Modifying the search term before sending it

An engine might want to transform a search term in some way before it interpolates the term into the URL. Maybe the term should have a different encoding, or be capitalized differently, or, uh, be passed through [[https://en.wikipedia.org/wiki/ROT13][ROT13]]. Whatever the reason, you can apply a custom transformation to a search term by passing a function to defengine through the :term-transformation-hook keyword argument.

For example, to UPCASE all of your DuckDuckGo searches:

#+begin_src emacs-lisp (defengine duckduckgo "https://duckduckgo.com/?q=%s" :term-transformation-hook upcase) #+end_src

Or, to ensure that all your queries are encoded as latin-1:

#+begin_src emacs-lisp (defengine diec2 "dlc.iec.cat/results.asp?txtEntrada=%s" :term-transformation-hook (lambda (term) (encode-coding-string term latin-1)) :keybinding "c") #+end_src

You could also use a :term-transformation-hook to make an engine behave differently when given a [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Prefix-Command-Arguments.html][prefix argument]] (i.e. typing =C-u= before invoking the engine).

Some search engines support querying for exact phrases by enclosing the search string with double quotes. Transformations could be useful in this case to perform a literal search instead if the universal argument is present:

#+begin_src emacs-lisp (defengine duckduckgo "https://duckduckgo.com/?q=%s" :term-transformation-hook (lambda (term) (if current-prefix-arg (concat """ term """) term)) :keybinding "d") #+end_src

Typing =C-x / d= will perform a regular search, but typing =C-u C-x / d= will wrap your query in quotes before searching for it. That's especially useful when searching for the contents of the region.

** Importing keyword searches from other browsers

Since many browsers save keyword searches using the same format as engine-mode (that is, by using %s in a url to indicate a search term), it's not too hard to import them into Emacs.

[[https://github.com/sshaw][@sshaw]] has written a script to [[https://gist.github.com/sshaw/9b635eabde582ebec442][import from Chrome on OS X]]. Thanks for that!

** Comparison with =webjump=

Emacs has a perfectly lovely built-in =webjump= package which allows the user to define a set of URLs, interpolate search terms into them, and visit them in the browser.

Why might you use =engine-mode= instead of =webjump=?

  • You want to bind specific searches to keybindings. Because =engine-mode= defines a function for each engine, keybindings in =engine-mode= can be associated directly with specific searches.
  • You'd like to associate browser functions with engines on a case-by-case basis. For example, if you want to perform some searches in Firefox, and other searches in =eww=, that's trivial in =engine-mode=.
  • You like some of =engine-mode='s minor UI conveniences. If you've got a region selected, for example, =engine-mode= will use that as the search query, while =webjump= will ignore it and offer an empty prompt.

If you're not interested in these features, =webjump= is a great choice! Honestly, the author of =engine-mode= probably wouldn't have bothered writing it if they'd known =webjump= existed at the time. :sweat_smile:

** Engine examples

#+begin_src emacs-lisp (defengine amazon "https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=%s")

(defengine duckduckgo "https://duckduckgo.com/?q=%s" :keybinding "d")

(defengine github "https://github.com/search?ref=simplesearch&q=%s")

(defengine google "https://www.google.com/search?ie=utf-8&oe=utf-8&q=%s" :keybinding "g")

(defengine google-images "https://www.google.com/images?hl=en&source=hp&biw=1440&bih=795&gbv=2&aq=f&aqi=&aql=&oq=&q=%s")

(defengine google-maps "https://maps.google.com/maps?q=%s" :docstring "Mappin' it up.")

(defengine project-gutenberg "https://www.gutenberg.org/ebooks/search/?query=%s")

(defengine qwant "https://www.qwant.com/?q=%s")

(defengine stack-overflow "https://stackoverflow.com/search?q=%s")

(defengine twitter "https://twitter.com/search?q=%s")

(defengine wikipedia "https://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s" :keybinding "w" :docstring "Searchin' the wikis.")

(defengine wiktionary "https://www.wikipedia.org/search-redirect.php?family=wiktionary&language=en&go=Go&search=%s")

(defengine wolfram-alpha "https://www.wolframalpha.com/input/?i=%s")

(defengine youtube "https://www.youtube.com/results?aq=f&oq=&search_query=%s") #+end_src

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

白日梦AI

白日梦AI提供专注于AI视频生成的多样化功能,包括文生视频、动态画面和形象生成等,帮助用户快速上手,创造专业级内容。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

讯飞绘镜

讯飞绘镜是一个支持从创意到完整视频创作的智能平台,用户可以快速生成视频素材并创作独特的音乐视频和故事。平台提供多样化的主题和精选作品,帮助用户探索创意灵感。

Project Cover

讯飞文书

讯飞文书依托讯飞星火大模型,为文书写作者提供从素材筹备到稿件撰写及审稿的全程支持。通过录音智记和以稿写稿等功能,满足事务性工作的高频需求,帮助撰稿人节省精力,提高效率,优化工作与生活。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号