Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

368 lines (320 sloc) 13.935 kB
;;; helm-net.el --- helm browse url and search web.
;; Copyright (C) 2012 Thierry Volpiatto <>
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <>.
;;; Code:
(eval-when-compile (require 'cl))
(require 'helm)
(require 'url)
(require 'xml)
(require 'browse-url)
(defgroup helm-net nil
"Net related applications and libraries for Helm."
:group 'helm)
(defcustom helm-c-google-suggest-default-browser-function nil
"The browse url function you prefer to use with google suggest.
When nil, use the first browser function available
See `helm-browse-url-default-browser-alist'."
:group 'helm-net
:type 'symbol)
(defcustom helm-c-home-url ""
"Default url to use as home url."
:group 'helm-net
:type 'string)
(defcustom helm-surfraw-default-browser-function nil
"The browse url function you prefer to use with surfraw.
When nil, fallback to `browse-url-browser-function'."
:group 'helm-net
:type 'symbol)
(defcustom helm-c-google-suggest-url
"URL used for looking up Google suggestions."
:type 'string
:group 'helm-net)
(defcustom helm-c-google-suggest-search-url
"URL used for Google searching."
:type 'string
:group 'helm-net)
(defcustom helm-google-suggest-use-curl-p nil
"When non--nil use CURL to get info from `helm-c-google-suggest-url'.
Otherwise `url-retrieve-synchronously' is used."
:type 'boolean
:group 'helm-net)
(defcustom helm-c-yahoo-suggest-url
"Url used for looking up Yahoo suggestions."
:type 'string
:group 'helm-net)
(defcustom helm-c-yahoo-suggest-search-url
"Url used for Yahoo searching."
:type 'string
:group 'helm-net)
;;; Google Suggestions
;; Internal
(defvar helm-ggs-max-length-real-flag 0)
(defvar helm-ggs-max-length-num-flag 0)
(defun helm-c-google-suggest-fetch (input)
"Fetch suggestions for INPUT from XML buffer.
Return an alist with elements like (data . number_results)."
(setq helm-ggs-max-length-real-flag 0
helm-ggs-max-length-num-flag 0)
(let ((request (concat helm-c-google-suggest-url
(url-hexify-string input))))
(flet ((fetch ()
with result-alist = (xml-get-children
(car (xml-parse-region
(point-min) (point-max)))
for i in result-alist
for data = (cdr (caadr (assoc 'suggestion i)))
for nqueries = (cdr (caadr (assoc 'num_queries i)))
for lqueries = (length (helm-c-ggs-set-number-result
for ldata = (length data)
(when (> ldata helm-ggs-max-length-real-flag)
(setq helm-ggs-max-length-real-flag ldata))
(when (> lqueries helm-ggs-max-length-num-flag)
(setq helm-ggs-max-length-num-flag lqueries)))
collect (cons data nqueries) into cont
finally return cont)))
(if helm-google-suggest-use-curl-p
(call-process "curl" nil t nil request)
(url-retrieve-synchronously request)
(defun helm-c-google-suggest-set-candidates (&optional request-prefix)
"Set candidates with result and number of google results found."
(let ((suggestions
(loop with suggested-results = (helm-c-google-suggest-fetch
(or (and request-prefix
(concat request-prefix
" " helm-pattern))
for (real . numresult) in suggested-results
;; Prepare number of results with ","
for fnumresult = (helm-c-ggs-set-number-result numresult)
;; Calculate number of spaces to add before fnumresult
;; if it is smaller than longest result
;; `helm-ggs-max-length-num-flag'.
;; e.g 1,234,567
;; 345,678
;; To be sure it is aligned properly.
for nspaces = (if (< (length fnumresult)
(- helm-ggs-max-length-num-flag
(length fnumresult))
;; Add now the spaces before fnumresult.
for align-fnumresult = (concat (make-string nspaces ? )
for interval = (- helm-ggs-max-length-real-flag
(length real))
for spaces = (make-string (+ 2 interval) ? )
for display = (format "%s%s(%s results)"
real spaces align-fnumresult)
collect (cons display real))))
(if (loop for (disp . dat) in suggestions
thereis (equal dat helm-pattern))
;; if there is no suggestion exactly matching the input then
;; prepend a Search on Google item to the list
(list (cons (concat "Search for " "'" helm-input "'" " on Google")
(defun helm-c-ggs-set-number-result (num)
(if num
(and (numberp num) (setq num (number-to-string num)))
(loop for i in (reverse (split-string num "" t))
for count from 1
append (list i) into C
when (= count 3)
append (list ",") into C
and do (setq count 0)
finally return
"^," "" (mapconcat 'identity (reverse C) ""))))
(defun helm-c-google-suggest-action (candidate)
"Default action to jump to a google suggested candidate."
(let ((arg (concat helm-c-google-suggest-search-url
(url-hexify-string candidate))))
(helm-aif helm-c-google-suggest-default-browser-function
(funcall it arg)
(helm-c-browse-url arg))))
(defvar helm-c-google-suggest-default-function
"Default function to use in helm google suggest.")
(defvar helm-c-source-google-suggest
'((name . "Google Suggest")
(candidates . (lambda ()
(funcall helm-c-google-suggest-default-function)))
(action . (("Google Search" . helm-c-google-suggest-action)))
(requires-pattern . 3)
(defun helm-c-google-suggest-emacs-lisp ()
"Try to emacs lisp complete with google suggestions."
(helm-c-google-suggest-set-candidates "emacs lisp"))
;;; Yahoo suggestions
(defun helm-c-yahoo-suggest-fetch (input)
"Fetch Yahoo suggestions for INPUT from XML buffer.
Return an alist with elements like (data . number_results)."
(let ((request (concat helm-c-yahoo-suggest-url
(url-hexify-string input))))
(flet ((fetch ()
with result-alist = (xml-get-children
(car (xml-parse-region
(point-min) (point-max)))
for i in result-alist
collect (caddr i))))
(url-retrieve-synchronously request)
(defun helm-c-yahoo-suggest-set-candidates ()
"Set candidates with Yahoo results found."
(let ((suggestions (helm-c-yahoo-suggest-fetch helm-input)))
(or suggestions
(list (cons (concat "Search for " "'" helm-input "'" " on Yahoo")
(defun helm-c-yahoo-suggest-action (candidate)
"Default action to jump to a Yahoo suggested candidate."
(helm-c-browse-url (concat helm-c-yahoo-suggest-search-url
(url-hexify-string candidate))))
(defvar helm-c-source-yahoo-suggest
'((name . "Yahoo Suggest")
(candidates . helm-c-yahoo-suggest-set-candidates)
(action . (("Yahoo Search" . helm-c-yahoo-suggest-action)))
(requires-pattern . 3)
;;; Web browser functions.
;; If default setting of `w3m-command' is not
;; what you want you and you modify it, you will have to reeval
;; also `helm-browse-url-default-browser-alist'.
(defvar w3m-command "/usr/bin/w3m")
(defvar helm-browse-url-chromium-program "chromium-browser")
(defvar helm-browse-url-uzbl-program "uzbl-browser")
(defvar helm-browse-url-default-browser-alist
`((,w3m-command . w3m-browse-url)
(,browse-url-firefox-program . browse-url-firefox)
(,helm-browse-url-chromium-program . helm-browse-url-chromium)
(,helm-browse-url-uzbl-program . helm-browse-url-uzbl)
(,browse-url-kde-program . browse-url-kde)
(,browse-url-gnome-moz-program . browse-url-gnome-moz)
(,browse-url-mozilla-program . browse-url-mozilla)
(,browse-url-galeon-program . browse-url-galeon)
(,browse-url-netscape-program . browse-url-netscape)
(,browse-url-mosaic-program . browse-url-mosaic)
(,browse-url-xterm-program . browse-url-text-xterm))
"*Alist of \(executable . function\) to try to find a suitable url browser.")
(defun* helm-c-generic-browser (url name &rest args)
"Browse URL with NAME browser."
(let ((proc (concat name " " url)))
(message "Starting %s..." name)
(apply 'start-process proc nil name
(append args (list url)))
(get-process proc)
#'(lambda (process event)
(when (string= event "finished\n")
(message "%s process %s" process event))))))
(defun helm-browse-url-chromium (url)
"Browse URL with google chrome browser."
(interactive "sURL: ")
url helm-browse-url-chromium-program))
(defun helm-browse-url-uzbl (url &optional ignore)
"Browse URL with uzbl browser."
(interactive "sURL: ")
(helm-c-generic-browser url helm-browse-url-uzbl-program "-u"))
(defun helm-browse-url-default-browser (url &rest args)
"Find the first available browser and ask it to load URL."
(let ((default-browser-fn
(loop for (exe . fn) in helm-browse-url-default-browser-alist
thereis (and exe (executable-find exe) fn))))
(if default-browser-fn
(apply default-browser-fn url args)
(error "No usable browser found"))))
(defun helm-c-browse-url (url &rest args)
"Default command to browse URL."
(if browse-url-browser-function
(browse-url url args)
(helm-browse-url-default-browser url args)))
;;; Surfraw
;; Need external program surfraw.
;; <>
;; Internal
(defvar helm-surfraw-engines-history nil)
(defvar helm-surfraw-input-history nil)
(defun helm-c-build-elvi-list ()
"Return list of all engines and descriptions handled by surfraw."
(call-process "surfraw" nil t nil
(split-string (buffer-string) "\n"))))
(defun helm-surfraw (pattern engine)
"Preconfigured `helm' to search PATTERN with search ENGINE."
(interactive (list (read-string "SearchFor: "
nil 'helm-surfraw-input-history)
"Engine: "
:must-match t
:name "Surfraw Search Engines"
:history helm-surfraw-engines-history)))
(let* ((engine-nodesc (car (split-string engine)))
(url (with-temp-buffer
(apply 'call-process "surfraw" nil t nil
(append (list engine-nodesc "-p") (split-string pattern)))
"\n" "" (buffer-string))))
(browse-url-browser-function (or helm-surfraw-default-browser-function
(if (string= engine-nodesc "W")
(helm-c-browse-url helm-c-home-url)
(helm-c-browse-url url)
(setq helm-surfraw-engines-history
(cons engine (delete engine helm-surfraw-engines-history))))))
(defun helm-google-suggest ()
"Preconfigured `helm' for google search with google suggest."
(helm-other-buffer 'helm-c-source-google-suggest "*helm google*"))
(defun helm-yahoo-suggest ()
"Preconfigured `helm' for Yahoo searching with Yahoo suggest."
(helm-other-buffer 'helm-c-source-yahoo-suggest "*helm yahoo*"))
(provide 'helm-net)
;;; helm-net.el ends here
Jump to Line
Something went wrong with that request. Please try again.