Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/hrs/engine-mode
Minor mode for defining and querying search engines through Emacs.
https://github.com/hrs/engine-mode
emacs search
Last synced: 9 days ago
JSON representation
Minor mode for defining and querying search engines through Emacs.
- Host: GitHub
- URL: https://github.com/hrs/engine-mode
- Owner: hrs
- License: gpl-3.0
- Created: 2014-05-06T17:35:00.000Z (over 10 years ago)
- Default Branch: main
- Last Pushed: 2023-10-23T06:55:49.000Z (about 1 year ago)
- Last Synced: 2024-08-02T02:09:11.782Z (3 months ago)
- Topics: emacs, search
- Language: Emacs Lisp
- Size: 623 KB
- Stars: 271
- Watchers: 7
- Forks: 23
- Open Issues: 3
-
Metadata Files:
- Readme: README.org
- License: LICENSE.md
Awesome Lists containing this project
- awesome-starred - engine-mode - Minor mode for defining and querying search engines through Emacs. (Emacs Lisp)
README
#+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_srcThis 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_srcYou 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_srcAs 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_srcIf 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_srcOr, 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_srcYou 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_srcTyping =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