84 lines
3.2 KiB
EmacsLisp
84 lines
3.2 KiB
EmacsLisp
|
|
;;; bjolang-lsp.el --- Commands for the parts of BjolangLsp that LSP has no request for -*- lexical-binding: t; -*-
|
||
|
|
|
||
|
|
;;; Commentary:
|
||
|
|
|
||
|
|
;; Macro expansion: `bjo-expand-macro' shows the expansion of the macro call
|
||
|
|
;; at point all the way down, and `bjo-expand-macro-1' one step of it, in a
|
||
|
|
;; buffer of their own. With a prefix argument they keep the names hygiene
|
||
|
|
;; made, such as `tmp__37', which is what tells a template's name from the
|
||
|
|
;; caller's of the same spelling.
|
||
|
|
;;
|
||
|
|
;; The expansion is the compiler's, from its last check of the buffer; a
|
||
|
|
;; change not yet checked is checked first. `loop', `seql', `->' and the
|
||
|
|
;; other forms the parser turns into code itself are not macros, and have
|
||
|
|
;; no expansion to show.
|
||
|
|
|
||
|
|
;;; Code:
|
||
|
|
|
||
|
|
(require 'lsp-mode)
|
||
|
|
|
||
|
|
(defvar bjo-mode-map)
|
||
|
|
(defvar bjo-mode-hook)
|
||
|
|
(declare-function bjo-mode "bjomode")
|
||
|
|
|
||
|
|
(defun bjo--field (result key)
|
||
|
|
"The field KEY, a string, of RESULT as `lsp-mode' decoded it.
|
||
|
|
A hash table or a plist, as `lsp-use-plists' says, which can differ from
|
||
|
|
how this file was compiled."
|
||
|
|
(if (hash-table-p result)
|
||
|
|
(gethash key result)
|
||
|
|
(plist-get result (intern (concat ":" key)))))
|
||
|
|
|
||
|
|
(defun bjo--expand-macro (full hygienic)
|
||
|
|
"Show the expansion of the macro call at point.
|
||
|
|
FULL expands the macro calls in the expansion too; HYGIENIC keeps the
|
||
|
|
names hygiene made."
|
||
|
|
(let* ((params (append (lsp--text-document-position-params)
|
||
|
|
(list :full (if full t :json-false)
|
||
|
|
:hygienic (if hygienic t :json-false))))
|
||
|
|
(result (lsp-request "bjolang/expandMacro" params)))
|
||
|
|
(if (null result)
|
||
|
|
(message "No macro call at point.")
|
||
|
|
(let ((macro (bjo--field result "macro"))
|
||
|
|
(text (bjo--field result "text"))
|
||
|
|
(buffer (get-buffer-create "*bjo expansion*")))
|
||
|
|
(with-current-buffer buffer
|
||
|
|
(let ((inhibit-read-only t)
|
||
|
|
;; The expansion is not a file, and must not start a server.
|
||
|
|
(bjo-mode-hook nil))
|
||
|
|
(erase-buffer)
|
||
|
|
(bjo-mode)
|
||
|
|
(insert (format ";; (%s ...), %s%s\n\n"
|
||
|
|
macro
|
||
|
|
(if full "expanded all the way" "one step")
|
||
|
|
(if hygienic ", with hygiene's names" ""))
|
||
|
|
text
|
||
|
|
"\n")
|
||
|
|
(font-lock-ensure)
|
||
|
|
(goto-char (point-min)))
|
||
|
|
;; Read only, and `q' to leave, without binding `q' in the mode's
|
||
|
|
;; own map, which every Bjolang buffer shares.
|
||
|
|
(view-mode 1))
|
||
|
|
(display-buffer buffer)))))
|
||
|
|
|
||
|
|
(defun bjo-expand-macro (&optional hygienic)
|
||
|
|
"Show the macro call at point expanded all the way down.
|
||
|
|
With a prefix argument HYGIENIC, keep the names hygiene made."
|
||
|
|
(interactive "P")
|
||
|
|
(bjo--expand-macro t hygienic))
|
||
|
|
|
||
|
|
(defun bjo-expand-macro-1 (&optional hygienic)
|
||
|
|
"Show one step of the expansion of the macro call at point.
|
||
|
|
With a prefix argument HYGIENIC, keep the names hygiene made."
|
||
|
|
(interactive "P")
|
||
|
|
(bjo--expand-macro nil hygienic))
|
||
|
|
|
||
|
|
;; As SLIME binds its macroexpanders.
|
||
|
|
(with-eval-after-load 'bjo-mode
|
||
|
|
(define-key bjo-mode-map (kbd "C-c C-m") #'bjo-expand-macro-1)
|
||
|
|
(define-key bjo-mode-map (kbd "C-c M-m") #'bjo-expand-macro))
|
||
|
|
|
||
|
|
(provide 'bjolang-lsp)
|
||
|
|
|
||
|
|
;;; bjolang-lsp.el ends here
|