Skip to content

Commit

Permalink
Merge 4909a63 into 414e2a1
Browse files Browse the repository at this point in the history
  • Loading branch information
areina committed Nov 29, 2016
2 parents 414e2a1 + 4909a63 commit 4eae497
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 50 deletions.
100 changes: 50 additions & 50 deletions helm-dash.el
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ Available formats are
:group 'helm-dash)

(defcustom helm-dash-enable-debugging t
"When non-nil capture stderr from sql commands and display in a
buffer. Setting this to nil may speed up querys."
"When non-nil capture stderr from sql commands and display it in a buffer.
Setting this to nil may speed up queries."
:group 'helm-dash)


Expand Down Expand Up @@ -125,7 +125,8 @@ Suggested values are:
(expand-file-name helm-dash-docsets-path))

(defun helm-dash-sql (db-path sql)
"Run the sql command, parse the results and display errors"
"Run in the db located at DB-PATH the SQL command and parse the results.
If there are errors, print them in `helm-dash-debugging-buffer'"
(helm-dash-parse-sql-results
(with-output-to-string
(let ((error-file (when helm-dash-enable-debugging
Expand Down Expand Up @@ -200,23 +201,16 @@ The Argument DB-PATH should be a string with the sqlite db path."
"DASH"
"ZDASH")))

(defun helm-dash-read-json-from-url (url)
"Read and return a JSON object from URL."
(with-current-buffer
(url-retrieve-synchronously url)
(goto-char url-http-end-of-headers)
(json-read)))

(defun helm-dash-read-json-from-url (addr)
(let ((url addr))
(with-current-buffer
(url-retrieve-synchronously url)
(goto-char url-http-end-of-headers)
(json-read))))

(defun helm-dash-search-all-docsets ()
"Fetch docsets from the original Kapeli's feed."
(let ((url "https://api.github.com/repos/Kapeli/feeds/contents/"))
(with-current-buffer
(url-retrieve-synchronously url)
(goto-char url-http-end-of-headers)
(json-read))))

(defun helm-dash-search-all-user-docsets ()
(defun helm-dash-unofficial-docsets ()
"Return a list of lists with docsets contributed by users.
The first element is the docset's name second the docset's archive url."
(let ((user-docs (helm-dash-read-json-from-url
"https://dashes-to-dashes.herokuapp.com/docsets/contrib")))
(mapcar (lambda (docset)
Expand All @@ -231,16 +225,17 @@ The Argument DB-PATH should be a string with the sqlite db path."
These docsets are not available to install.
See here the reason: https://github.com/areina/helm-dash/issues/17.")

(defun helm-dash-available-docsets ()
(defun helm-dash-official-docsets ()
"Return a list of official docsets (http://kapeli.com/docset_links)."
(delq nil (mapcar (lambda (docset)
(let ((name (assoc-default 'name docset)))
(if (and (equal (file-name-extension name) "xml")
(not
(member (file-name-sans-extension name) helm-dash-ignored-docsets)))
(file-name-sans-extension name))))
(helm-dash-search-all-docsets))))

(let ((docsets (helm-dash-read-json-from-url
"https://api.github.com/repos/Kapeli/feeds/contents/")))
(delq nil (mapcar (lambda (docset)
(let ((name (assoc-default 'name docset)))
(if (and (equal (file-name-extension name) "xml")
(not
(member (file-name-sans-extension name) helm-dash-ignored-docsets)))
(file-name-sans-extension name))))
docsets))))

(defun helm-dash-installed-docsets ()
"Return a list of installed docsets."
Expand Down Expand Up @@ -271,7 +266,7 @@ Report an error unless a valid docset is selected."

;;;###autoload
(defun helm-dash-deactivate-docset(docset)
"Deactivate DOCSET. If called interactively prompts for the docset name."
"Deactivate DOCSET. If called interactively prompts for the docset name."
(interactive (list (helm-dash-read-docset
"Deactivate docset"
helm-dash-common-docsets)))
Expand All @@ -283,6 +278,8 @@ Report an error unless a valid docset is selected."
(helm-dash-install-docset-from-file docset-tmp-path)))

(defun helm-dash--ensure-created-docsets-path (docset-path)
"Check if DOCSET-PATH directory exists.
If doesn't exist, it asks to create it."
(or (file-directory-p docset-path)
(and (y-or-n-p (format "Directory %s does not exist. Want to create it? "
docset-path))
Expand All @@ -293,9 +290,9 @@ Report an error unless a valid docset is selected."
(defun helm-dash-install-user-docset (docset-name)
(interactive (list (helm-dash-read-docset
"Install docset"
(mapcar 'car (helm-dash-search-all-user-docsets)))))
(mapcar 'car (helm-dash-unofficial-docsets)))))
(when (helm-dash--ensure-created-docsets-path (helm-dash-docsets-path))
(helm-dash--install-docset (car (assoc-default docset-name (helm-dash-search-all-user-docsets))) docset-name)))
(helm-dash--install-docset (car (assoc-default docset-name (helm-dash-unofficial-docsets))) docset-name)))


;;;###autoload
Expand All @@ -318,22 +315,22 @@ Report an error unless a valid docset is selected."
"Download docset with specified DOCSET-NAME and move its stuff to docsets-path."
(interactive (list (helm-dash-read-docset
"Install docset"
(helm-dash-available-docsets))))
(helm-dash-official-docsets))))

(when (helm-dash--ensure-created-docsets-path (helm-dash-docsets-path))
(let ((feed-url (format "%s/%s.xml" helm-dash-docsets-url docset-name))
(docset-tmp-path (format "%s%s-docset.tgz" temporary-file-directory docset-name))
(feed-tmp-path (format "%s%s-feed.xml" temporary-file-directory docset-name)))

(url-copy-file feed-url feed-tmp-path t)
(url-copy-file (helm-dash-get-docset-url feed-tmp-path) docset-tmp-path t)
(url-copy-file feed-url feed-tmp-path t)
(url-copy-file (helm-dash-get-docset-url feed-tmp-path) docset-tmp-path t)

(helm-dash-install-docset-from-file docset-tmp-path))))
(helm-dash-install-docset-from-file docset-tmp-path))))

;;;###autoload
(defun helm-dash-async-install-docset (docset-name)
"Asynchronously download docset with specified DOCSET-NAME and move its stuff to docsets-path."
(interactive (list (helm-dash-read-docset "Install docset" (helm-dash-available-docsets))))
(interactive (list (helm-dash-read-docset "Install docset" (helm-dash-official-docsets))))
(when (helm-dash--ensure-created-docsets-path (helm-dash-docsets-path))
(let ((feed-url (format "%s/%s.xml" helm-dash-docsets-url docset-name)))

Expand Down Expand Up @@ -389,24 +386,28 @@ The Argument FEED-PATH should be a string with the path of the xml file."
(cl-caddr (cl-first url))))

(defvar helm-dash-sql-queries
'((DASH . ((select . (lambda (pattern)
(let ((like (helm-dash-sql-compose-like "t.name" pattern))
(query "SELECT t.type, t.name, t.path FROM searchIndex t WHERE %s ORDER BY LENGTH(t.name), LOWER(t.name) LIMIT 1000"))
(format query like))))))
(ZDASH . ((select . (lambda (pattern)
(let ((like (helm-dash-sql-compose-like "t.ZTOKENNAME" pattern))
(query "SELECT ty.ZTYPENAME, t.ZTOKENNAME, f.ZPATH, m.ZANCHOR FROM ZTOKEN t, ZTOKENTYPE ty, ZFILEPATH f, ZTOKENMETAINFORMATION m WHERE ty.Z_PK = t.ZTOKENTYPE AND f.Z_PK = m.ZFILE AND m.ZTOKEN = t.Z_PK AND %s ORDER BY LENGTH(t.ZTOKENNAME), LOWER(t.ZTOKENNAME) LIMIT 1000"))
(format query like))))))))
'((DASH . (lambda (pattern)
(let ((like (helm-dash-sql-compose-like "t.name" pattern))
(query "SELECT t.type, t.name, t.path FROM searchIndex t WHERE %s ORDER BY LENGTH(t.name), LOWER(t.name) LIMIT 1000"))
(format query like))))
(ZDASH . (lambda (pattern)
(let ((like (helm-dash-sql-compose-like "t.ZTOKENNAME" pattern))
(query "SELECT ty.ZTYPENAME, t.ZTOKENNAME, f.ZPATH, m.ZANCHOR FROM ZTOKEN t, ZTOKENTYPE ty, ZFILEPATH f, ZTOKENMETAINFORMATION m WHERE ty.Z_PK = t.ZTOKENTYPE AND f.Z_PK = m.ZFILE AND m.ZTOKEN = t.Z_PK AND %s ORDER BY LENGTH(t.ZTOKENNAME), LOWER(t.ZTOKENNAME) LIMIT 1000"))
(format query like))))))

(defun helm-dash-sql-compose-like (column pattern)
""
(let ((conditions (mapcar (lambda (word) (format "%s like '%%%s%%'" column word))
(split-string pattern " "))))
(format "%s" (mapconcat 'identity conditions " AND "))))

(defun helm-dash-sql-execute (query-type docset-type pattern)
""
(funcall (cdr (assoc query-type (assoc (intern docset-type) helm-dash-sql-queries))) pattern))
(defun helm-dash-sql-query (docset-type pattern)
"Return a SQL query to search documentation in dash docsets.
A different query is returned depending on DOCSET-TYPE. PATTERN
is used to compose the SQL WHERE clause."
(when-let ((compose-select-query-func
(cdr (assoc (intern docset-type) helm-dash-sql-queries))))
(funcall compose-select-query-func pattern)))

(defun helm-dash-maybe-narrow-docsets (pattern)
"Return a list of helm-dash-connections.
Expand Down Expand Up @@ -443,9 +444,8 @@ Ex: This avoids searching for redis in redis unless you type 'redis redis'"
(let ((docset-type (cl-caddr docset)))
(helm-dash-sql
(cadr docset)
(helm-dash-sql-execute 'select
docset-type
(helm-dash-sub-docset-name-in-pattern helm-pattern (car docset))))))
(helm-dash-sql-query docset-type
(helm-dash-sub-docset-name-in-pattern helm-pattern (car docset))))))

(defun helm-dash--candidate (docset row)
"Return a list extracting info from DOCSET and ROW to build a helm candidate.
Expand Down
13 changes: 13 additions & 0 deletions test/helm-dash-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,19 @@
'(("C" "/tmp/.docsets/C.docset/Contents/Resources/docSet.dsidx" "DASH"))))
)))))

;; helm-dash-sql-query

(ert-deftest helm-dash-sql-query/DASH-docset-type ()
(should (equal "SELECT t.type, t.name, t.path FROM searchIndex t WHERE t.name like '%blpop%' ORDER BY LENGTH(t.name), LOWER(t.name) LIMIT 1000"
(helm-dash-sql-query "DASH" "blpop"))))

(ert-deftest helm-dash-sql-query/ZDASH-docset-type ()
(should (equal "SELECT ty.ZTYPENAME, t.ZTOKENNAME, f.ZPATH, m.ZANCHOR FROM ZTOKEN t, ZTOKENTYPE ty, ZFILEPATH f, ZTOKENMETAINFORMATION m WHERE ty.Z_PK = t.ZTOKENTYPE AND f.Z_PK = m.ZFILE AND m.ZTOKEN = t.Z_PK AND t.ZTOKENNAME like '%blpop%' ORDER BY LENGTH(t.ZTOKENNAME), LOWER(t.ZTOKENNAME) LIMIT 1000"
(helm-dash-sql-query "ZDASH" "blpop"))))

(ert-deftest helm-dash-sql-query/UNKNOWN-docset-type ()
(should (equal nil (helm-dash-sql-query "FOO" "blpop"))))

(provide 'helm-dash-test)

;;; helm-dash-test ends here

0 comments on commit 4eae497

Please sign in to comment.