Klimi's new dotfiles with stow.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

431 行
15 KiB

  1. ;;; helm-net.el --- helm browse url and search web. -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2012 ~ 2019 Thierry Volpiatto <thierry.volpiatto@gmail.com>
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;; This program is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; You should have received a copy of the GNU General Public License
  12. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ;;; Code:
  14. (require 'cl-lib)
  15. (require 'helm)
  16. (require 'helm-help)
  17. (require 'url)
  18. (require 'xml)
  19. (require 'browse-url)
  20. (defgroup helm-net nil
  21. "Net related applications and libraries for Helm."
  22. :group 'helm)
  23. (defcustom helm-google-suggest-default-browser-function nil
  24. "The browse url function you prefer to use with google suggest.
  25. When nil, use the first browser function available
  26. See `helm-browse-url-default-browser-alist'."
  27. :group 'helm-net
  28. :type 'symbol)
  29. (defcustom helm-home-url "https://www.google.com"
  30. "Default url to use as home url."
  31. :group 'helm-net
  32. :type 'string)
  33. (defcustom helm-surfraw-default-browser-function nil
  34. "The browse url function you prefer to use with surfraw.
  35. When nil, fallback to `browse-url-browser-function'."
  36. :group 'helm-net
  37. :type 'symbol)
  38. (defcustom helm-google-suggest-url
  39. "https://encrypted.google.com/complete/search?output=toolbar&q=%s"
  40. "URL used for looking up Google suggestions.
  41. This is a format string, don't forget the `%s'."
  42. :type 'string
  43. :group 'helm-net)
  44. (defcustom helm-google-suggest-search-url
  45. "https://encrypted.google.com/search?ie=utf-8&oe=utf-8&q=%s"
  46. "URL used for Google searching.
  47. This is a format string, don't forget the `%s'."
  48. :type 'string
  49. :group 'helm-net)
  50. (defvaralias 'helm-google-suggest-use-curl-p 'helm-net-prefer-curl)
  51. (make-obsolete-variable 'helm-google-suggest-use-curl-p 'helm-net-prefer-curl "1.7.7")
  52. (defcustom helm-net-prefer-curl nil
  53. "When non--nil use CURL external program to fetch data.
  54. Otherwise `url-retrieve-synchronously' is used."
  55. :type 'boolean
  56. :group 'helm-net)
  57. (defcustom helm-surfraw-duckduckgo-url
  58. "https://duckduckgo.com/lite/?q=%s&kp=1"
  59. "The duckduckgo url.
  60. This is a format string, don't forget the `%s'.
  61. If you have personal settings saved on duckduckgo you should have
  62. a personal url, see your settings on duckduckgo."
  63. :type 'string
  64. :group 'helm-net)
  65. (defcustom helm-search-suggest-action-wikipedia-url
  66. "https://en.wikipedia.org/wiki/Special:Search?search=%s"
  67. "The Wikipedia search url.
  68. This is a format string, don't forget the `%s'."
  69. :type 'string
  70. :group 'helm-net)
  71. (defcustom helm-search-suggest-action-youtube-url
  72. "https://www.youtube.com/results?aq=f&search_query=%s"
  73. "The Youtube search url.
  74. This is a format string, don't forget the `%s'."
  75. :type 'string
  76. :group 'helm-net)
  77. (defcustom helm-search-suggest-action-imdb-url
  78. "http://www.imdb.com/find?s=all&q=%s"
  79. "The IMDb search url.
  80. This is a format string, don't forget the `%s'."
  81. :type 'string
  82. :group 'helm-net)
  83. (defcustom helm-search-suggest-action-google-maps-url
  84. "https://maps.google.com/maps?f=q&source=s_q&q=%s"
  85. "The Google Maps search url.
  86. This is a format string, don't forget the `%s'."
  87. :type 'string
  88. :group 'helm-net)
  89. (defcustom helm-search-suggest-action-google-news-url
  90. "https://www.google.com/search?safe=off&prmd=nvlifd&source=lnms&tbs=nws:1&q=%s"
  91. "The Google News search url.
  92. This is a format string, don't forget the `%s'."
  93. :type 'string
  94. :group 'helm-net)
  95. (defcustom helm-google-suggest-actions
  96. '(("Google Search" . helm-google-suggest-action)
  97. ("Wikipedia" . (lambda (candidate)
  98. (helm-search-suggest-perform-additional-action
  99. helm-search-suggest-action-wikipedia-url
  100. candidate)))
  101. ("Youtube" . (lambda (candidate)
  102. (helm-search-suggest-perform-additional-action
  103. helm-search-suggest-action-youtube-url
  104. candidate)))
  105. ("IMDb" . (lambda (candidate)
  106. (helm-search-suggest-perform-additional-action
  107. helm-search-suggest-action-imdb-url
  108. candidate)))
  109. ("Google Maps" . (lambda (candidate)
  110. (helm-search-suggest-perform-additional-action
  111. helm-search-suggest-action-google-maps-url
  112. candidate)))
  113. ("Google News" . (lambda (candidate)
  114. (helm-search-suggest-perform-additional-action
  115. helm-search-suggest-action-google-news-url
  116. candidate))))
  117. "List of actions for google suggest sources."
  118. :group 'helm-net
  119. :type '(alist :key-type string :value-type function))
  120. (defcustom helm-browse-url-firefox-new-window "-new-tab"
  121. "Allow choosing to browse url in new window or new tab.
  122. Can be \"-new-tab\" (default) or \"-new-window\"."
  123. :group 'helm-net
  124. :type '(radio
  125. (const :tag "New tab" "-new-tab")
  126. (const :tag "New window" "-new-window")))
  127. (defcustom helm-net-curl-switches '("-s" "-L")
  128. "Arguments list passed to curl when using `helm-net-prefer-curl'."
  129. :group 'helm-net
  130. :type '(repeat string))
  131. ;;; Additional actions for search suggestions
  132. ;;
  133. ;;
  134. ;; Internal
  135. (defun helm-search-suggest-perform-additional-action (url query)
  136. "Perform the search via URL using QUERY as input."
  137. (browse-url (format url (url-hexify-string query))))
  138. (defun helm-net--url-retrieve-sync (request parser)
  139. (if helm-net-prefer-curl
  140. (with-temp-buffer
  141. (apply #'call-process "curl"
  142. nil t nil request helm-net-curl-switches)
  143. (funcall parser))
  144. (with-current-buffer (url-retrieve-synchronously request)
  145. (funcall parser))))
  146. ;;; Google Suggestions
  147. ;;
  148. ;;
  149. (defun helm-google-suggest-parser ()
  150. (cl-loop
  151. with result-alist = (xml-get-children
  152. (car (xml-parse-region
  153. (point-min) (point-max)))
  154. 'CompleteSuggestion)
  155. for i in result-alist collect
  156. (cdr (cl-caadr (assq 'suggestion i)))))
  157. (defun helm-google-suggest-fetch (input)
  158. "Fetch suggestions for INPUT from XML buffer."
  159. (let ((request (format helm-google-suggest-url
  160. (url-hexify-string input))))
  161. (helm-net--url-retrieve-sync
  162. request #'helm-google-suggest-parser)))
  163. (defun helm-google-suggest-set-candidates (&optional request-prefix)
  164. "Set candidates with result and number of google results found."
  165. (let ((suggestions (helm-google-suggest-fetch
  166. (or (and request-prefix
  167. (concat request-prefix
  168. " " helm-pattern))
  169. helm-pattern))))
  170. (if (member helm-pattern suggestions)
  171. suggestions
  172. ;; if there is no suggestion exactly matching the input then
  173. ;; prepend a Search on Google item to the list
  174. (append
  175. suggestions
  176. (list (cons (format "Search for '%s' on Google" helm-input)
  177. helm-input))))))
  178. (defun helm-ggs-set-number-result (num)
  179. (if num
  180. (progn
  181. (and (numberp num) (setq num (number-to-string num)))
  182. (cl-loop for i in (reverse (split-string num "" t))
  183. for count from 1
  184. append (list i) into C
  185. when (= count 3)
  186. append (list ",") into C
  187. and do (setq count 0)
  188. finally return
  189. (replace-regexp-in-string
  190. "^," "" (mapconcat 'identity (reverse C) ""))))
  191. "?"))
  192. (defun helm-google-suggest-action (candidate)
  193. "Default action to jump to a google suggested candidate."
  194. (let ((arg (format helm-google-suggest-search-url
  195. (url-hexify-string candidate))))
  196. (helm-aif helm-google-suggest-default-browser-function
  197. (funcall it arg)
  198. (helm-browse-url arg))))
  199. (defvar helm-google-suggest-default-function
  200. 'helm-google-suggest-set-candidates
  201. "Default function to use in helm google suggest.")
  202. (defvar helm-source-google-suggest
  203. (helm-build-sync-source "Google Suggest"
  204. :candidates (lambda ()
  205. (funcall helm-google-suggest-default-function))
  206. :action 'helm-google-suggest-actions
  207. :volatile t
  208. :keymap helm-map
  209. :requires-pattern 3))
  210. (defun helm-google-suggest-emacs-lisp ()
  211. "Try to emacs lisp complete with google suggestions."
  212. (helm-google-suggest-set-candidates "emacs lisp"))
  213. ;;; Web browser functions.
  214. ;;
  215. ;;
  216. ;; If default setting of `w3m-command' is not
  217. ;; what you want and you modify it, you will have to reeval
  218. ;; also `helm-browse-url-default-browser-alist'.
  219. (defvar helm-browse-url-chromium-program "chromium-browser")
  220. (defvar helm-browse-url-uzbl-program "uzbl-browser")
  221. (defvar helm-browse-url-conkeror-program "conkeror")
  222. (defvar helm-browse-url-opera-program "opera")
  223. (defvar helm-browse-url-default-browser-alist
  224. `((,(or (and (boundp 'w3m-command) w3m-command)
  225. "/usr/bin/w3m") . w3m-browse-url)
  226. (,browse-url-firefox-program . browse-url-firefox)
  227. (,helm-browse-url-chromium-program . helm-browse-url-chromium)
  228. (,helm-browse-url-conkeror-program . helm-browse-url-conkeror)
  229. (,helm-browse-url-opera-program . helm-browse-url-opera)
  230. (,helm-browse-url-uzbl-program . helm-browse-url-uzbl)
  231. (,browse-url-kde-program . browse-url-kde)
  232. (,browse-url-gnome-moz-program . browse-url-gnome-moz)
  233. (,browse-url-mozilla-program . browse-url-mozilla)
  234. (,browse-url-galeon-program . browse-url-galeon)
  235. (,browse-url-netscape-program . browse-url-netscape)
  236. (,browse-url-mosaic-program . browse-url-mosaic)
  237. (,browse-url-xterm-program . browse-url-text-xterm)
  238. ("emacs" . eww-browse-url))
  239. "*Alist of \(executable . function\) to try to find a suitable url browser.")
  240. (cl-defun helm-generic-browser (url cmd-name &rest args)
  241. "Browse URL with NAME browser."
  242. (let ((proc (concat cmd-name " " url)))
  243. (message "Starting %s..." cmd-name)
  244. (apply 'start-process proc nil cmd-name
  245. (append args (list url)))
  246. (set-process-sentinel
  247. (get-process proc)
  248. (lambda (process event)
  249. (when (string= event "finished\n")
  250. (message "%s process %s" process event))))))
  251. ;;;###autoload
  252. (defun helm-browse-url-firefox (url &optional _ignore)
  253. "Same as `browse-url-firefox' but detach from emacs.
  254. So when you quit emacs you can keep your firefox session open
  255. and not be prompted to kill firefox process.
  256. NOTE: Probably not supported on some systems (e.g Windows)."
  257. (interactive (list (read-string "URL: " (browse-url-url-at-point))
  258. nil))
  259. (setq url (browse-url-encode-url url))
  260. (let ((process-environment (browse-url-process-environment)))
  261. (call-process-shell-command
  262. (format "(%s %s %s &)"
  263. browse-url-firefox-program
  264. helm-browse-url-firefox-new-window
  265. (shell-quote-argument url)))))
  266. ;;;###autoload
  267. (defun helm-browse-url-opera (url &optional _ignore)
  268. "Browse URL with opera browser and detach from emacs.
  269. So when you quit emacs you can keep your opera session open
  270. and not be prompted to kill opera process.
  271. NOTE: Probably not supported on some systems (e.g Windows)."
  272. (interactive (list (read-string "URL: " (browse-url-url-at-point))
  273. nil))
  274. (setq url (browse-url-encode-url url))
  275. (let ((process-environment (browse-url-process-environment)))
  276. (call-process-shell-command
  277. (format "(%s %s &)"
  278. helm-browse-url-opera-program (shell-quote-argument url)))))
  279. ;;;###autoload
  280. (defun helm-browse-url-chromium (url &optional _ignore)
  281. "Browse URL with google chrome browser."
  282. (interactive "sURL: ")
  283. (helm-generic-browser
  284. url helm-browse-url-chromium-program))
  285. ;;;###autoload
  286. (defun helm-browse-url-uzbl (url &optional _ignore)
  287. "Browse URL with uzbl browser."
  288. (interactive "sURL: ")
  289. (helm-generic-browser url helm-browse-url-uzbl-program "-u"))
  290. ;;;###autoload
  291. (defun helm-browse-url-conkeror (url &optional _ignore)
  292. "Browse URL with conkeror browser."
  293. (interactive "sURL: ")
  294. (helm-generic-browser url helm-browse-url-conkeror-program))
  295. (defun helm-browse-url-default-browser (url &rest args)
  296. "Find the first available browser and ask it to load URL."
  297. (let ((default-browser-fn
  298. (cl-loop for (exe . fn) in helm-browse-url-default-browser-alist
  299. thereis (and exe (executable-find exe) (fboundp fn) fn))))
  300. (if default-browser-fn
  301. (apply default-browser-fn url args)
  302. (error "No usable browser found"))))
  303. (defun helm-browse-url (url &rest args)
  304. "Default command to browse URL."
  305. (if browse-url-browser-function
  306. (browse-url url args)
  307. (helm-browse-url-default-browser url args)))
  308. ;;; Surfraw
  309. ;;
  310. ;; Need external program surfraw.
  311. ;; <http://surfraw.alioth.debian.org/>
  312. ;; Internal
  313. (defvar helm-surfraw-engines-history nil)
  314. (defvar helm-surfraw-input-history nil)
  315. (defvar helm-surfraw--elvi-cache nil)
  316. (defun helm-build-elvi-list ()
  317. "Return list of all engines and descriptions handled by surfraw."
  318. (or helm-surfraw--elvi-cache
  319. (setq helm-surfraw--elvi-cache
  320. (cdr (with-temp-buffer
  321. (call-process "surfraw" nil t nil "-elvi")
  322. (split-string (buffer-string) "\n"))))))
  323. ;;;###autoload
  324. (defun helm-surfraw (pattern engine)
  325. "Preconfigured `helm' to search PATTERN with search ENGINE."
  326. (interactive
  327. (list
  328. (let* ((default (if (use-region-p)
  329. (buffer-substring-no-properties
  330. (region-beginning) (region-end))
  331. (thing-at-point 'symbol)))
  332. (prompt (if default
  333. (format "SearchFor (default %s): " default)
  334. "SearchFor: ")))
  335. (read-string prompt nil 'helm-surfraw-input-history default))
  336. (helm-comp-read
  337. "Engine: "
  338. (helm-build-elvi-list)
  339. :must-match t
  340. :name "Surfraw Search Engines"
  341. :del-input nil
  342. :history helm-surfraw-engines-history)))
  343. (let* ((engine-nodesc (car (split-string engine)))
  344. (url (if (string= engine-nodesc "duckduckgo")
  345. ;; "sr duckduckgo -p foo" is broken, workaround.
  346. (format helm-surfraw-duckduckgo-url
  347. (url-hexify-string pattern))
  348. (with-temp-buffer
  349. (apply 'call-process "surfraw" nil t nil
  350. (append (list engine-nodesc "-p") (split-string pattern)))
  351. (replace-regexp-in-string
  352. "\n" "" (buffer-string)))))
  353. (browse-url-browser-function (or helm-surfraw-default-browser-function
  354. browse-url-browser-function)))
  355. (if (string= engine-nodesc "W")
  356. (helm-browse-url helm-home-url)
  357. (helm-browse-url url)
  358. (setq helm-surfraw-engines-history
  359. (cons engine (delete engine helm-surfraw-engines-history))))))
  360. ;;;###autoload
  361. (defun helm-google-suggest ()
  362. "Preconfigured `helm' for google search with google suggest."
  363. (interactive)
  364. (helm-other-buffer 'helm-source-google-suggest "*helm google*"))
  365. (provide 'helm-net)
  366. ;; Local Variables:
  367. ;; byte-compile-warnings: (not obsolete)
  368. ;; coding: utf-8
  369. ;; indent-tabs-mode: nil
  370. ;; End:
  371. ;;; helm-net.el ends here