PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/prelude/elpa/helm-20131105.847/helm-net.el

https://bitbucket.org/hoangtu/emacs
Emacs Lisp | 386 lines | 289 code | 46 blank | 51 comment | 28 complexity | 156286b026658e37f1bbc970624021d9 MD5 | raw file
  1. ;;; helm-net.el --- helm browse url and search web.
  2. ;; Copyright (C) 2012 ~ 2013 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. (eval-when-compile (require 'cl))
  15. (require 'helm)
  16. (require 'url)
  17. (require 'xml)
  18. (require 'browse-url)
  19. (defgroup helm-net nil
  20. "Net related applications and libraries for Helm."
  21. :group 'helm)
  22. (defcustom helm-google-suggest-default-browser-function nil
  23. "The browse url function you prefer to use with google suggest.
  24. When nil, use the first browser function available
  25. See `helm-browse-url-default-browser-alist'."
  26. :group 'helm-net
  27. :type 'symbol)
  28. (defcustom helm-home-url "http://www.google.fr"
  29. "Default url to use as home url."
  30. :group 'helm-net
  31. :type 'string)
  32. (defcustom helm-surfraw-default-browser-function nil
  33. "The browse url function you prefer to use with surfraw.
  34. When nil, fallback to `browse-url-browser-function'."
  35. :group 'helm-net
  36. :type 'symbol)
  37. (defcustom helm-google-suggest-url
  38. "http://google.com/complete/search?output=toolbar&q="
  39. "URL used for looking up Google suggestions."
  40. :type 'string
  41. :group 'helm-net)
  42. (defcustom helm-google-suggest-search-url
  43. "http://www.google.com/search?ie=utf-8&oe=utf-8&q="
  44. "URL used for Google searching."
  45. :type 'string
  46. :group 'helm-net)
  47. (defcustom helm-google-suggest-use-curl-p nil
  48. "When non--nil use CURL to get info from `helm-google-suggest-url'.
  49. Otherwise `url-retrieve-synchronously' is used."
  50. :type 'boolean
  51. :group 'helm-net)
  52. (defcustom helm-yahoo-suggest-url
  53. "http://search.yahooapis.com/WebSearchService/V1/relatedSuggestion?appid=Generic&query="
  54. "Url used for looking up Yahoo suggestions."
  55. :type 'string
  56. :group 'helm-net)
  57. (defcustom helm-yahoo-suggest-search-url
  58. "http://search.yahoo.com/search?&ei=UTF-8&fr&h=c&p="
  59. "Url used for Yahoo searching."
  60. :type 'string
  61. :group 'helm-net)
  62. (defcustom helm-surfraw-duckduckgo-url
  63. "https://duckduckgo.com/lite/?q=%s&kp=1"
  64. "The duckduckgo url.
  65. This is a format string, don't forget the `%s'.
  66. If you have personal settings saved on duckduckgo you should have
  67. a personal url, see your settings on duckduckgo."
  68. :type 'string
  69. :group 'helm-net)
  70. ;;; Google Suggestions
  71. ;;
  72. ;;
  73. ;; Internal
  74. (defvar helm-ggs-max-length-real-flag 0)
  75. (defvar helm-ggs-max-length-num-flag 0)
  76. (defun helm-google-suggest-fetch (input)
  77. "Fetch suggestions for INPUT from XML buffer.
  78. Return an alist with elements like (data . number_results)."
  79. (setq helm-ggs-max-length-real-flag 0
  80. helm-ggs-max-length-num-flag 0)
  81. (let ((request (concat helm-google-suggest-url
  82. (url-hexify-string input)))
  83. (fetch #'(lambda ()
  84. (loop
  85. with result-alist = (xml-get-children
  86. (car (xml-parse-region
  87. (point-min) (point-max)))
  88. 'CompleteSuggestion)
  89. for i in result-alist
  90. for data = (cdr (caadr (assoc 'suggestion i)))
  91. for nqueries = (cdr (caadr (assoc 'num_queries i)))
  92. for lqueries = (length (helm-ggs-set-number-result
  93. nqueries))
  94. for ldata = (length data)
  95. do
  96. (progn
  97. (when (> ldata helm-ggs-max-length-real-flag)
  98. (setq helm-ggs-max-length-real-flag ldata))
  99. (when (> lqueries helm-ggs-max-length-num-flag)
  100. (setq helm-ggs-max-length-num-flag lqueries)))
  101. collect (cons data nqueries) into cont
  102. finally return cont))))
  103. (if helm-google-suggest-use-curl-p
  104. (with-temp-buffer
  105. (call-process "curl" nil t nil request)
  106. (funcall fetch))
  107. (with-current-buffer
  108. (url-retrieve-synchronously request)
  109. (funcall fetch)))))
  110. (defun helm-google-suggest-set-candidates (&optional request-prefix)
  111. "Set candidates with result and number of google results found."
  112. (let ((suggestions
  113. (loop with suggested-results = (helm-google-suggest-fetch
  114. (or (and request-prefix
  115. (concat request-prefix
  116. " " helm-pattern))
  117. helm-pattern))
  118. for (real . numresult) in suggested-results
  119. ;; Prepare number of results with ","
  120. for fnumresult = (helm-ggs-set-number-result numresult)
  121. ;; Calculate number of spaces to add before fnumresult
  122. ;; if it is smaller than longest result
  123. ;; `helm-ggs-max-length-num-flag'.
  124. ;; e.g 1,234,567
  125. ;; 345,678
  126. ;; To be sure it is aligned properly.
  127. for nspaces = (if (< (length fnumresult)
  128. helm-ggs-max-length-num-flag)
  129. (- helm-ggs-max-length-num-flag
  130. (length fnumresult))
  131. 0)
  132. ;; Add now the spaces before fnumresult.
  133. for align-fnumresult = (concat (make-string nspaces ? )
  134. fnumresult)
  135. for interval = (- helm-ggs-max-length-real-flag
  136. (length real))
  137. for spaces = (make-string (+ 2 interval) ? )
  138. for display = (format "%s%s(%s results)"
  139. real spaces align-fnumresult)
  140. collect (cons display real))))
  141. (if (loop for (disp . dat) in suggestions
  142. thereis (equal dat helm-pattern))
  143. suggestions
  144. ;; if there is no suggestion exactly matching the input then
  145. ;; prepend a Search on Google item to the list
  146. (append
  147. suggestions
  148. (list (cons (concat "Search for " "'" helm-input "'" " on Google")
  149. helm-input))))))
  150. (defun helm-ggs-set-number-result (num)
  151. (if num
  152. (progn
  153. (and (numberp num) (setq num (number-to-string num)))
  154. (loop for i in (reverse (split-string num "" t))
  155. for count from 1
  156. append (list i) into C
  157. when (= count 3)
  158. append (list ",") into C
  159. and do (setq count 0)
  160. finally return
  161. (replace-regexp-in-string
  162. "^," "" (mapconcat 'identity (reverse C) ""))))
  163. "?"))
  164. (defun helm-google-suggest-action (candidate)
  165. "Default action to jump to a google suggested candidate."
  166. (let ((arg (concat helm-google-suggest-search-url
  167. (url-hexify-string candidate))))
  168. (helm-aif helm-google-suggest-default-browser-function
  169. (funcall it arg)
  170. (helm-browse-url arg))))
  171. (defvar helm-google-suggest-default-function
  172. 'helm-google-suggest-set-candidates
  173. "Default function to use in helm google suggest.")
  174. (defvar helm-source-google-suggest
  175. '((name . "Google Suggest")
  176. (candidates . (lambda ()
  177. (funcall helm-google-suggest-default-function)))
  178. (action . (("Google Search" . helm-google-suggest-action)))
  179. (volatile)
  180. (requires-pattern . 3)
  181. (delayed)))
  182. (defun helm-google-suggest-emacs-lisp ()
  183. "Try to emacs lisp complete with google suggestions."
  184. (helm-google-suggest-set-candidates "emacs lisp"))
  185. ;;; Yahoo suggestions
  186. ;;
  187. ;;
  188. (defun helm-yahoo-suggest-fetch (input)
  189. "Fetch Yahoo suggestions for INPUT from XML buffer.
  190. Return an alist with elements like (data . number_results)."
  191. (let ((request (concat helm-yahoo-suggest-url
  192. (url-hexify-string input))))
  193. (with-current-buffer
  194. (url-retrieve-synchronously request)
  195. (loop with result-alist =
  196. (xml-get-children
  197. (car (xml-parse-region
  198. (point-min) (point-max)))
  199. 'Result)
  200. for i in result-alist
  201. collect (caddr i)))))
  202. (defun helm-yahoo-suggest-set-candidates ()
  203. "Set candidates with Yahoo results found."
  204. (let ((suggestions (helm-yahoo-suggest-fetch helm-input)))
  205. (or suggestions
  206. (append
  207. suggestions
  208. (list (cons (concat "Search for " "'" helm-input "'" " on Yahoo")
  209. helm-input))))))
  210. (defun helm-yahoo-suggest-action (candidate)
  211. "Default action to jump to a Yahoo suggested candidate."
  212. (helm-browse-url (concat helm-yahoo-suggest-search-url
  213. (url-hexify-string candidate))))
  214. (defvar helm-source-yahoo-suggest
  215. '((name . "Yahoo Suggest")
  216. (candidates . helm-yahoo-suggest-set-candidates)
  217. (action . (("Yahoo Search" . helm-yahoo-suggest-action)))
  218. (volatile)
  219. (requires-pattern . 3)
  220. (delayed)))
  221. ;;; Web browser functions.
  222. ;;
  223. ;;
  224. ;; If default setting of `w3m-command' is not
  225. ;; what you want and you modify it, you will have to reeval
  226. ;; also `helm-browse-url-default-browser-alist'.
  227. (defvar helm-browse-url-chromium-program "chromium-browser")
  228. (defvar helm-browse-url-uzbl-program "uzbl-browser")
  229. (defvar helm-browse-url-default-browser-alist
  230. `((,(or (and (boundp 'w3m-command) w3m-command)
  231. "/usr/bin/w3m") . w3m-browse-url)
  232. (,browse-url-firefox-program . browse-url-firefox)
  233. (,helm-browse-url-chromium-program . helm-browse-url-chromium)
  234. (,helm-browse-url-uzbl-program . helm-browse-url-uzbl)
  235. (,browse-url-kde-program . browse-url-kde)
  236. (,browse-url-gnome-moz-program . browse-url-gnome-moz)
  237. (,browse-url-mozilla-program . browse-url-mozilla)
  238. (,browse-url-galeon-program . browse-url-galeon)
  239. (,browse-url-netscape-program . browse-url-netscape)
  240. (,browse-url-mosaic-program . browse-url-mosaic)
  241. (,browse-url-xterm-program . browse-url-text-xterm))
  242. "*Alist of \(executable . function\) to try to find a suitable url browser.")
  243. (defun* helm-generic-browser (url name &rest args)
  244. "Browse URL with NAME browser."
  245. (let ((proc (concat name " " url)))
  246. (message "Starting %s..." name)
  247. (apply 'start-process proc nil name
  248. (append args (list url)))
  249. (set-process-sentinel
  250. (get-process proc)
  251. #'(lambda (process event)
  252. (when (string= event "finished\n")
  253. (message "%s process %s" process event))))))
  254. (defun helm-browse-url-chromium (url)
  255. "Browse URL with google chrome browser."
  256. (interactive "sURL: ")
  257. (helm-generic-browser
  258. url helm-browse-url-chromium-program))
  259. (defun helm-browse-url-uzbl (url &optional ignore)
  260. "Browse URL with uzbl browser."
  261. (interactive "sURL: ")
  262. (helm-generic-browser url helm-browse-url-uzbl-program "-u"))
  263. (defun helm-browse-url-default-browser (url &rest args)
  264. "Find the first available browser and ask it to load URL."
  265. (let ((default-browser-fn
  266. (loop for (exe . fn) in helm-browse-url-default-browser-alist
  267. thereis (and exe (executable-find exe)
  268. (and (fboundp fn) fn)))))
  269. (if default-browser-fn
  270. (apply default-browser-fn url args)
  271. (error "No usable browser found"))))
  272. (defun helm-browse-url (url &rest args)
  273. "Default command to browse URL."
  274. (if browse-url-browser-function
  275. (browse-url url args)
  276. (helm-browse-url-default-browser url args)))
  277. ;;; Surfraw
  278. ;;
  279. ;; Need external program surfraw.
  280. ;; <http://surfraw.alioth.debian.org/>
  281. ;; Internal
  282. (defvar helm-surfraw-engines-history nil)
  283. (defvar helm-surfraw-input-history nil)
  284. (defvar helm-surfraw--elvi-cache nil)
  285. (defun helm-build-elvi-list ()
  286. "Return list of all engines and descriptions handled by surfraw."
  287. (or helm-surfraw--elvi-cache
  288. (setq helm-surfraw--elvi-cache
  289. (cdr (with-temp-buffer
  290. (call-process "surfraw" nil t nil "-elvi")
  291. (split-string (buffer-string) "\n"))))))
  292. ;;;###autoload
  293. (defun helm-surfraw (pattern engine)
  294. "Preconfigured `helm' to search PATTERN with search ENGINE."
  295. (interactive (list (read-string "SearchFor: "
  296. nil 'helm-surfraw-input-history
  297. (thing-at-point 'symbol))
  298. (helm-comp-read
  299. "Engine: "
  300. (helm-build-elvi-list)
  301. :must-match t
  302. :name "Surfraw Search Engines"
  303. :del-input nil
  304. :history helm-surfraw-engines-history)))
  305. (let* ((engine-nodesc (car (split-string engine)))
  306. (url (if (string= engine-nodesc "duckduckgo")
  307. ;; "sr duckduckgo -p foo" is broken, workaround.
  308. (format helm-surfraw-duckduckgo-url pattern)
  309. (with-temp-buffer
  310. (apply 'call-process "surfraw" nil t nil
  311. (append (list engine-nodesc "-p") (split-string pattern)))
  312. (replace-regexp-in-string
  313. "\n" "" (buffer-string)))))
  314. (browse-url-browser-function (or helm-surfraw-default-browser-function
  315. browse-url-browser-function)))
  316. (if (string= engine-nodesc "W")
  317. (helm-browse-url helm-home-url)
  318. (helm-browse-url url)
  319. (setq helm-surfraw-engines-history
  320. (cons engine (delete engine helm-surfraw-engines-history))))))
  321. ;;;###autoload
  322. (defun helm-google-suggest ()
  323. "Preconfigured `helm' for google search with google suggest."
  324. (interactive)
  325. (helm-other-buffer 'helm-source-google-suggest "*helm google*"))
  326. ;;;###autoload
  327. (defun helm-yahoo-suggest ()
  328. "Preconfigured `helm' for Yahoo searching with Yahoo suggest."
  329. (interactive)
  330. (helm-other-buffer 'helm-source-yahoo-suggest "*helm yahoo*"))
  331. (provide 'helm-net)
  332. ;; Local Variables:
  333. ;; byte-compile-warnings: (not cl-functions obsolete)
  334. ;; coding: utf-8
  335. ;; indent-tabs-mode: nil
  336. ;; End:
  337. ;;; helm-net.el ends here