Last active
July 23, 2022 15:39
-
-
Save twlz0ne/a6334bf0bc4ff6fc07be2a6e9b1f52a1 to your computer and use it in GitHub Desktop.
Custom Firefox Search Engine #Emacs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(cl-defun custom-firefox-search-engine (&key | |
name | |
description | |
iconurl | |
searchurl | |
&allow-other-keys) | |
"Custom Firefox Search Engin. | |
NAME Short name of search engine | |
DESCRIPTION Description of search engine | |
ICONURL URL of icon file | |
SEARCHURL Search URL with {searchTerms} in place of query | |
Usage: | |
M-x custom-firefox-search-engine | |
Or: | |
(custom-firefox-search-engine :name \"汉典\" | |
:description \"zdic.net\" | |
:iconurl \"https://www.zdic.net/favicon.ico\" | |
:searchurl \"https://www.zdic.net/hans/{searchTerms}\") | |
(custom-firefox-search-engine :name \"京东\" | |
:description \"jd.com\" | |
:iconurl \"https://www.jd.com/favicon.ico\" | |
:searchurl \"https://search.jd.com/Search?enc=utf-8&keyword={searchTerms}\") | |
Alternate tools: | |
- https://mycroftproject.com/dlstats.html | |
A webside provides a collection of Search Engines. | |
- https://addons.mozilla.org/en-US/firefox/addon/search-engines-helper/ | |
An add-on for exporting, importing and customizing Search Engines. | |
Inspired by @wsug's works in https://emacs-china.org/t/firefox/18244" | |
(interactive | |
(let* ((searchurl | |
(read-string (concat "Search url (e.g. " | |
(propertize | |
"https://example.com/search?keyword={searchTerms}" | |
'face 'font-lock-keyword-face) | |
"): "))) | |
(urlobj (url-generic-parse-url searchurl))) | |
(list :name (read-string "Name (as short as possible): " (url-host urlobj)) | |
:description (read-string "Description: " (url-host urlobj)) | |
:iconurl (read-string "Icon url: " (concat (url-type urlobj) "://" (url-host urlobj) "/favicon.ico")) | |
:searchurl searchurl))) | |
(require 'web-server) | |
(require 'sgml-mode) | |
(let (server) | |
(setq server | |
(ws-start | |
`(((lambda (_) t) . | |
(lambda (request) | |
(with-slots (process headers) request | |
(pcase (alist-get :GET headers) | |
("/" | |
(message "==> [CUSTOM-ENGINE] /") | |
(ws-response-header process 200 '("Content-type" . "text/html")) | |
(process-send-string process | |
(format-spec | |
"\ | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset=\"utf-8\"/><title>%n</title> | |
<link | |
rel=\"search\" | |
type=\"application/opensearchdescription+xml\" | |
title=\"%n\" | |
href=\"/opensearch.xml\"> | |
</head> | |
<body> | |
<h2>Finish following steps:</h2> | |
<ol> | |
<li> Right-click in the address bar, choose【Add \"%n\"】. </li> | |
<li> Right-click to open <a href=\"about:preferences#search\" target=\"_blank\"> about:preferences#search </a> in new tab to set keyword. </li> | |
<li> <a href=\"/close\">Close</a> the web server and this page. </li> | |
</ol> | |
</body> | |
</html>" | |
(list (cons ?n ,name))))) | |
("/opensearch.xml" | |
(message "==> [CUSTOM-ENGINE] /opensearch.xml") | |
(ws-response-header process 200 '("Content-type" . "text/html")) | |
(process-send-string process | |
(format-spec | |
"\ | |
<?xml version=\"1.0\" encoding=\"UTF-8\"?> | |
<OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\"> | |
<ShortName>%n</ShortName> | |
<Description>%d</Description> | |
<InputEncoding>UTF-8</InputEncoding> | |
<Image width=\"32\" height=\"32\" type=\"image/x-icon\">%i</Image> | |
<Url type=\"text/html\" template=\"%s\"></Url> | |
</OpenSearchDescription>" | |
(list (cons ?n ,name) | |
(cons ?d ,description) | |
(cons ?i ,iconurl) | |
(cons ?s ,(with-temp-buffer | |
(insert searchurl) | |
(sgml-quote (point-min) (point-max)) | |
(buffer-string))))))) | |
("/close" | |
(message "==> [CUSTOM-ENGINE] /close") | |
(ws-response-header process 200 '("Content-type" . "text/html")) | |
(process-send-string process | |
"\ | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<script type=\"text/javascript\"> | |
window.close(); | |
</script> | |
</head> | |
</html>") | |
(run-with-timer | |
0.1 nil | |
(lambda (server) | |
(message "==> [CUSTOM-ENGINE] stop server: %s" (process-contact (ws-process server))) | |
(ws-stop server)) | |
(plist-get (process-plist process) :server))) | |
(_ (ws-send-404))))))) | |
t)) | |
(browse-url | |
(format "http://localhost:%s" (cadr (process-contact (ws-process server))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment