diff options
| author | Yuchen Pei <hi@ypei.me> | 2022-09-09 12:40:29 +1000 | 
|---|---|---|
| committer | Yuchen Pei <hi@ypei.me> | 2022-09-09 12:40:29 +1000 | 
| commit | 4acf751ddeca449847aa866a56308949ba756955 (patch) | |
| tree | 1b4031d06f7e809f85c54bfb4444048f5159d6a0 /lisp | |
| parent | 0566547e07065581e2f45288eed63e4fb5874cf4 (diff) | |
initial elisp binding
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/servall-client.el | 50 | ||||
| -rw-r--r-- | lisp/servall-wikipedia.el | 102 | 
2 files changed, 152 insertions, 0 deletions
| diff --git a/lisp/servall-client.el b/lisp/servall-client.el new file mode 100644 index 0000000..2c6dd17 --- /dev/null +++ b/lisp/servall-client.el @@ -0,0 +1,50 @@ +;; -*- lexical-binding: t; -*- + +(defvar servall-endpoint "localhost:5555") +(defvar servall-client-buffer-name "*servall-client*") + +(defun servall-api-wikipedia-search (query) +  (servall-url-fetch-json +   (concat servall-endpoint "/wikipedia/search/" query))) + +(defun servall-api-wikipedia-org (name) +  (servall-url-fetch-json +   (concat servall-endpoint "/wikipedia/org/" name))) + +(defun servall-parse-http-header (text) +  (let ((status) (fields)) +    (with-temp-buffer +      (insert text) +      (goto-char (point-min)) +      (re-search-forward "^HTTP.*\\([0-9]\\{3\\}\\).*$") +      (setq status (match-string 1)) +      (while (re-search-forward "^\\(.*?\\): \\(.*\\)$" nil t) +        (push (cons (intern (match-string 1)) (match-string 2)) fields))) +    (list (cons 'status status) (cons 'fields fields)))) + +(defun servall-url-fetch-json (url &optional decompression with-header) +  (with-current-buffer (get-buffer-create servall-client-buffer-name) +    (goto-char (point-max)) +    (insert "[" (current-time-string) "] Request: " url "\n")) +  (with-current-buffer (url-retrieve-synchronously url t) +    (let ((header) (status) (fields) (json)) +      (delete-http-header) +      (setq header (servall-parse-http-header (car kill-ring)) +            status (alist-get 'status header) +            fields (alist-get 'fields header)) +      (with-current-buffer servall-client-buffer-name +        (insert "[" (current-time-string) "] Response: " status "\n")) +      (when decompression +        (call-process-region (point) (point-max) "gunzip" t t t) +        (goto-char (point-min))) +      (call-interactively 'delete-trailing-whitespace) +      (if (string= status "200") +          (unless (= (point) (point-max)) +            (if with-header +                (list +                 (cons 'header fields) +                 (cons 'json (json-read))) +              (json-read))) +        (error "HTTP error: %s" (buffer-substring (point) (point-max))))))) + +(provide 'servall-client) diff --git a/lisp/servall-wikipedia.el b/lisp/servall-wikipedia.el new file mode 100644 index 0000000..978e902 --- /dev/null +++ b/lisp/servall-wikipedia.el @@ -0,0 +1,102 @@ +;; -*- lexical-binding: t; -*- + +(defvar servall-results-mode-map special-mode-map) +(defvar servall-results-buffer "*servall-results*") + +(define-derived-mode servall-results-mode org-mode "servall-results" +  "Mode for showing and selecting results" +  (setq-local buffer-read-only t +              servall-results-update-function nil +              servall-results-re-search-function nil +              servall-results-open-function nil)) + +(defun servall-results-update () +  (interactive) +  (funcall servall-results-update-function)) + +(defun servall-results-re-search () +  (interactive) +  (call-interactively servall-results-re-search-function)) + +(defun servall-results-open () +  (interactive) +  (funcall servall-results-open-function)) + +(define-key servall-results-mode-map "n" 'org-next-visible-heading) +(define-key servall-results-mode-map "g" 'servall-results-update) +(define-key servall-results-mode-map "\r" 'servall-results-open) +(define-key servall-results-mode-map "p" 'org-previous-visible-heading) +(define-key servall-results-mode-map "s" 'servall-results-re-search) + +(define-derived-mode servall-wikipedia-results-mode servall-results-mode +  "servall-wikipedia-results" +  "Mode for showing and selecting wikipedia results" +  (setq-local servall-wikipedia-results-query nil)) + +(defun servall-wikipedia-results-highlight () +  (save-excursion +    (goto-char (point-min)) +    (while (re-search-forward "<span class=\"searchmatch\">\\(.*?\\)</span>" nil t) +      (replace-match +       (propertize (match-string 1) 'font-lock-face 'match))))) + +(defun servall-wikipedia-results-update () +  (let* ((resp (servall-api-wikipedia-search servall-wikipedia-results-query)) +         (results (alist-get 'search +                             (alist-get 'query resp))) +         (inhibit-read-only t)) +    (erase-buffer) +    (mapc +     (lambda (result) +       (let ((title (alist-get 'title result))) +         (insert +          (propertize +           (concat "* " title "\n") +           'title title)) +         (insert (alist-get 'snippet result) "\n\n"))) +     results) +    (servall-wikipedia-results-highlight) +    (goto-char (point-min)))) + +(defun servall-wikipedia-search (query) +  (interactive "sWikipedia Query: ") +  (with-current-buffer (get-buffer-create servall-results-buffer) +    (servall-wikipedia-results-mode) +    (setq servall-wikipedia-results-query query +          servall-results-update-function 'servall-wikipedia-results-update +          servall-results-re-search-function 'servall-wikipedia-search +          servall-results-open-function 'servall-wikipedia-results-open) +    (servall-results-update)) +  (switch-to-buffer servall-results-buffer)) + +(defun servall-wikipedia-results-open () +  (when-let ((title (get-text-property (point) 'title))) +    (switch-to-buffer-other-window (servall-wikipedia-load title)))) + +(defun servall-wikipedia-to-name (title) +  (replace-regexp-in-string " " "_" title)) + +(defvar servall-wikipedia-view-mode-map special-mode-map) +(defun servall-wikipedia-view-buffer (title) +  (format "*wikipedia %s*" title)) + +(defvar servall-wikipedia-view-mode-map special-mode-map) + +(define-derived-mode servall-wikipedia-view-mode org-mode +  "servall-wikipedia-view" +  "Mode for viewing wikipedia entries." +  (setq-local buffer-read-only t +              servall-wikipedia-title nil)) + +(defun servall-wikipedia-load (title) +  (let ((buffer (get-buffer-create (servall-wikipedia-view-buffer title)))) +    (with-current-buffer buffer +      (servall-wikipedia-view-mode) +      (setq servall-wikipedia-title title) +      (let ((inhibit-read-only t)) +        (erase-buffer) +        (insert (servall-api-wikipedia-org title))) +      (goto-char (point-min))) +    buffer)) + +(provide 'servall-wikipedia) | 
