Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
231 lines (198 sloc) 7.5 KB
;;; File : company-distel-lib.el
;;; Author : Sebastian Weddmark Olsson
;;; Purpose : Library for company-distel. Can get documentation
;;; and do Distel request. :) ooooh
;;; Created : August 2012 as an internship at Klarna AB
;;; Comment : Please let me know if you find any bugs or you
;;; want some feature or something
(require 'distel)
(defvar erl-distel-get-doc-from-internet nil
"Whether or not to find the documentation on the internet.")
(defvar erl-distel-valid-syntax "a-zA-Z:_-"
"Which syntax to skip backwards to find start of word.")
;;; docs funs ;;;
(defun erl-company-get-doc-buffer (args)
"Returns a buffer with the documentation for ARGS."
(with-current-buffer (company-doc-buffer)
(insert (erl-company-get-doc-string args))
(defun erl-company-get-doc-string (args)
"Returns the documentation string for ARGS."
(let* ((isok (string-match ":" args))
(mod (substring args 0 isok))
(fun (and isok (substring args (+ isok 1))))
(doc (and fun (erl-company-local-docs mod fun)))
(edocs (when (and
(or (not doc) (string= doc "")))
(erl-company-get-docs-from-internet-p mod fun)))
(met (and fun (erl-format-arglists (erl-company-get-metadoc mod fun))))
(to-show (or (and (not (string= doc "")) doc)
(and (not (string= edocs "")) edocs)
(and met (concat mod ":" fun met))
(format "Couldn't find any help for %s." args))))
(defun erl-company-get-docs-from-internet-p (mod fun) ;; maybe version?
"Download the documentation from internet."
(let ((str
(url-retrieve-synchronously (format "" mod))
(goto-char (point-min))
;; find <p> containing <a name="`FUN'"> then
;; find <div class="REFBODY">
(let* ((m (re-search-forward (or (and fun (format "<p>.*?<a name=\"%s.*?\">" fun))
"<h3>DESCRIPTION</h3>") nil t))
(beg (and m (match-end 0)))
(end (and m (progn (re-search-forward "</p>.*?</div>" nil t)
(match-end 0)))))
(and beg end (buffer-substring beg end))))))
(and str
(erl-company-html-to-string str))))
(defun erl-company-html-to-string (string)
"Removes html-tags from `STRING'."
(let ((replaces '(("</?p>" . "\n")
("<br>" . "\n")
("<[^>]*>" . "")
("[[:space:]|\n]$" . "")
("^[[:space:]]+" . "")
("^\n[\n]+" . "")
("&gt;" . ">")
("&lt;" . "<"))))
(dolist (tagpair replaces string)
(setq string (replace-regexp-in-string (car tagpair) (cdr tagpair) string)))))
;;; Distel funs ;;;
(defun erl-company-complete (search-string buf)
"Complete `search-string' as a external module or function in current buffer."
(let* ((isok (string-match ":" search-string))
(mod (and isok (substring search-string 0 isok)))
(fun (and isok (substring search-string (+ isok 1))))
(node erl-nodename-cache))
(if isok (erl-complete-function mod fun)
(erl-complete-module search-string))
(sleep-for 0.1)
(mapcar (lambda (item) (concat mod (when mod ":") item))
(defvar try-erl-args-cache '()
"Store the functions arguments.")
(defvar try-erl-desc-cache ""
"Store of the description.")
(defvar try-erl-complete-cache '()
"Completion candidates cache.")
(defun erl-company-get-metadoc (mod fun)
"Get the arguments for a function."
(let ((node erl-nodename-cache))
(erl-company-args mod fun))
(sleep-for 0.1)
(defun erl-company-local-docs (mod fun)
"Get local documentation for a function."
(erl-company-get-metadoc mod fun)
(let ((node erl-nodename-cache))
(setq try-erl-desc-cache "")
(dolist (args try-erl-args-cache)
(erl-company-describe mod fun args)))
(sleep-for 0.1)
(defun erl-company-describe (mod fun args)
"Get the documentation of a function."
(erl-send-rpc node 'distel 'describe (list (intern mod)
(intern fun)
(length args)))
(&erl-company-receive-describe args)))
(defun &erl-company-receive-describe (args)
(erl-receive (args)
((['rex ['ok desc]]
(let ((descr (format "%s:%s/%s\n%s\n\n"
(elt (car desc) 0)
(elt (car desc) 1)
(elt (car desc) 2)
(elt (car desc) 3))))
(when desc (setq try-erl-desc-cache (concat descr try-erl-desc-cache)))))
(message "fail: %s" else)))))
(defun erl-company-args (mod fun)
"Find the arguments to a function `FUN' in a module `MOD'"
(erl-send-rpc node 'distel 'get_arglists (list mod fun))
(defun &erl-company-receive-args ()
(erl-receive ()
((['rex 'error])
(['rex docs]
(setq try-erl-args-cache docs))
(message "fail: %s" else)
(setq try-erl-args-cache '())))))
(defun erl-complete-module (module)
"Get list of modulenames starting with `MODULE'."
(erl-send-rpc node 'distel 'modules (list module))
(defun erl-complete-function (module function)
"Get list of function names starting with `FUNCTION'"
(erl-send-rpc node 'distel 'functions (list module function))
(defun &erl-complete-receive-completions ()
(erl-receive ()
((['rex ['ok completions]]
(setq try-erl-complete-cache completions))
(message "Unexpected reply: %s" other)))))
;;; Local buffer funs ;;;
(defun erl-get-dabbrevs (args &optional times limit)
"Use `dabbrev' to find last used commands beginning with ARGS in current buffer only. TIMES is how many times it will match, defaults to 5. LIMIT is how far from point it should search, defaults to the start of the previous defun."
(when (require 'dabbrev nil t)
(setq dabbrev-check-other-buffers nil
dabbrev--last-expansion-location (point))
(let ((times (or times 5))
(dabbrev-limit (or limit (- (point) (save-excursion
(backward-char (length args))
(ret-list '())
(while (and (> times 0) (dabbrev--find-expansion args 1 nil)))
(defun erl-get-functions (args)
"Get all function definitions beginning with ARGS in the current buffer."
(let ((case-fold-search nil)
(funs '())
(goto-char (point-min))
(while (setq fun-end (re-search-forward (format "^%s.*?(" args) nil t))
(add-to-list 'funs (buffer-substring (match-beginning 0) (1- fun-end)))))
(defun erl-company-grab-word ()
"Grab the current Erlang mod/fun/word."
(buffer-substring (point) (save-excursion
(skip-chars-backward erl-distel-valid-syntax)
(defun erl-company-is-comment-or-cite-p (&optional poin)
"Returns t if point is inside a comment or a cite."
(let ((po (or poin (point))))
(goto-char po)
(re-search-forward "[%\|\"|\']" po t)
(or (eql (char-before) ?%)
(and (or (eql (char-before) ?\")
(eql (char-before) ?\'))
(not (re-search-forward "[\"\|\']" po t)))))))
(provide 'distel-completion-lib)
Something went wrong with that request. Please try again.