From 5b67f1b58382c8cd89f4b9f2d07368b0c65b24e8 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 14:47:40 -0600 Subject: [PATCH 01/24] fc --- extensions/template/lem-template.asd | 6 +++ extensions/template/src/core.lisp | 55 ++++++++++++++++++++++++++++ lem.asd | 1 + 3 files changed, 62 insertions(+) create mode 100644 extensions/template/lem-template.asd create mode 100644 extensions/template/src/core.lisp diff --git a/extensions/template/lem-template.asd b/extensions/template/lem-template.asd new file mode 100644 index 000000000..b20c1675c --- /dev/null +++ b/extensions/template/lem-template.asd @@ -0,0 +1,6 @@ +(asdf:defsystem "lem-template" + :author "garlic0x1" + :license "MIT" + :depends-on (:cl-template) + :components ((:module "src" + :components ((:file "core"))))) diff --git a/extensions/template/src/core.lisp b/extensions/template/src/core.lisp new file mode 100644 index 000000000..2b4b8faba --- /dev/null +++ b/extensions/template/src/core.lisp @@ -0,0 +1,55 @@ +(defpackage #:lem-template/core + (:nicknames :lem-template) + (:use :cl :lem) + (:import-from #:alexandria-2 #:line-up-first #:when-let #:rcurry)) +(in-package :lem-template/core) + +(defvar *templates* nil + "List of registered file templates.") + +(defparameter *auto-template* t) + +(defstruct template + pattern + file) + +(defun empty-buffer-p (buffer) + (point= (buffer-start-point buffer) + (buffer-end-point buffer))) + +(defun register-template (&key pattern file) + (setf *templates* + (cons (make-template :pattern pattern :file file) + *templates*))) + +(defmacro register-templates (&body templates) + `(progn + ,@(mapcar + (lambda (it) `(register-template ,@it)) + templates))) + +(defun render-file (template-file &optional args) + (line-up-first + (uiop:read-file-string template-file) + (cl-template:compile-template) + (funcall args))) + +(defun template-match-p (template filename) + (cl-ppcre:scan (template-pattern template) filename)) + +(defun find-match (buffer-filename) + (when-let ((tmpl (find-if (rcurry #'template-match-p buffer-filename) *templates*))) + (template-file tmpl))) + +(defun insert-template (buffer) + (when-let (file (find-match (buffer-filename buffer))) + (insert-string + (buffer-start-point buffer) + (render-file file `(:buffer ,buffer))))) + +(add-hook *find-file-hook* + (lambda (buffer) + (when (and *auto-template* + (empty-buffer-p buffer) + (not (uiop:file-exists-p (buffer-filename buffer)))) + (insert-template buffer)))) diff --git a/lem.asd b/lem.asd index 6e3fc53bd..cac836b0a 100644 --- a/lem.asd +++ b/lem.asd @@ -205,6 +205,7 @@ (defsystem "lem/extensions" :depends-on (#+sbcl + "lem-template" "lem-welcome" "lem-lsp-mode" "lem-vi-mode" From c78b3e978818644ef76f3af32beb018a9aeac854 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 14:56:00 -0600 Subject: [PATCH 02/24] exports and docstrings --- extensions/template/src/core.lisp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/extensions/template/src/core.lisp b/extensions/template/src/core.lisp index 2b4b8faba..ca8151adc 100644 --- a/extensions/template/src/core.lisp +++ b/extensions/template/src/core.lisp @@ -1,13 +1,18 @@ (defpackage #:lem-template/core (:nicknames :lem-template) (:use :cl :lem) - (:import-from #:alexandria-2 #:line-up-first #:when-let #:rcurry)) + (:import-from #:alexandria-2 #:line-up-first #:when-let #:rcurry) + (:export #:*templates* + #:*auto-template* + #:register-template + #:register-templates)) (in-package :lem-template/core) (defvar *templates* nil "List of registered file templates.") -(defparameter *auto-template* t) +(defparameter *auto-template* t + "Enable automatically populating new files with templates.") (defstruct template pattern @@ -18,38 +23,46 @@ (buffer-end-point buffer))) (defun register-template (&key pattern file) + "Register a template used for filenames matching pattern." (setf *templates* (cons (make-template :pattern pattern :file file) *templates*))) (defmacro register-templates (&body templates) + "Register multiple templates with `register-template`." `(progn ,@(mapcar (lambda (it) `(register-template ,@it)) templates))) (defun render-file (template-file &optional args) + "Render a cl-template file to a string." (line-up-first (uiop:read-file-string template-file) (cl-template:compile-template) (funcall args))) (defun template-match-p (template filename) + "Template pattern matches filename." (cl-ppcre:scan (template-pattern template) filename)) (defun find-match (buffer-filename) + "Find template where pattern matches filename." (when-let ((tmpl (find-if (rcurry #'template-match-p buffer-filename) *templates*))) (template-file tmpl))) (defun insert-template (buffer) + "Insert registered template into buffer." (when-let (file (find-match (buffer-filename buffer))) (insert-string (buffer-start-point buffer) (render-file file `(:buffer ,buffer))))) +(defun new-file-p (buffer) + "Buffer is a new file, and does not already exist on disk." + (not (uiop:file-exists-p (buffer-filename buffer)))) + (add-hook *find-file-hook* (lambda (buffer) - (when (and *auto-template* - (empty-buffer-p buffer) - (not (uiop:file-exists-p (buffer-filename buffer)))) + (when (and *auto-template* (new-file-p buffer)) (insert-template buffer)))) From 24bcb82b86abf04a4d4597b2a404c7651071c728 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 15:11:59 -0600 Subject: [PATCH 03/24] handle render error --- extensions/template/src/core.lisp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/extensions/template/src/core.lisp b/extensions/template/src/core.lisp index ca8151adc..e72e38276 100644 --- a/extensions/template/src/core.lisp +++ b/extensions/template/src/core.lisp @@ -54,9 +54,13 @@ (defun insert-template (buffer) "Insert registered template into buffer." (when-let (file (find-match (buffer-filename buffer))) - (insert-string - (buffer-start-point buffer) - (render-file file `(:buffer ,buffer))))) + (handler-case + (insert-string + (buffer-start-point buffer) + (render-file file `(:buffer ,buffer))) + (error (c) + (declare (ignore c)) + (message "Failed to render template: ~a" file))))) (defun new-file-p (buffer) "Buffer is a new file, and does not already exist on disk." From 8338167a9ba6a16385e2ff0fe6ce945ee442f675 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 15:25:44 -0600 Subject: [PATCH 04/24] remove-old-template and delete empty-buffer-p --- extensions/template/src/core.lisp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/extensions/template/src/core.lisp b/extensions/template/src/core.lisp index e72e38276..4e6a87ffe 100644 --- a/extensions/template/src/core.lisp +++ b/extensions/template/src/core.lisp @@ -18,12 +18,17 @@ pattern file) -(defun empty-buffer-p (buffer) - (point= (buffer-start-point buffer) - (buffer-end-point buffer))) +(defun remove-old-template (pattern) + "Get rid of old template for pattern when a new one is registered." + (setf *templates* + (remove-if + (lambda (tmpl) + (equal pattern (template-pattern tmpl))) + *templates*))) (defun register-template (&key pattern file) "Register a template used for filenames matching pattern." + (remove-old-template pattern) (setf *templates* (cons (make-template :pattern pattern :file file) *templates*))) From 26bebf67eb208e282bb323aa54298ee89be3820f Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 15:35:29 -0600 Subject: [PATCH 05/24] cleanup --- extensions/template/src/core.lisp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/extensions/template/src/core.lisp b/extensions/template/src/core.lisp index 4e6a87ffe..18ae18bd1 100644 --- a/extensions/template/src/core.lisp +++ b/extensions/template/src/core.lisp @@ -22,16 +22,13 @@ "Get rid of old template for pattern when a new one is registered." (setf *templates* (remove-if - (lambda (tmpl) - (equal pattern (template-pattern tmpl))) + (lambda (tmpl) (equal pattern (template-pattern tmpl))) *templates*))) (defun register-template (&key pattern file) "Register a template used for filenames matching pattern." (remove-old-template pattern) - (setf *templates* - (cons (make-template :pattern pattern :file file) - *templates*))) + (push (make-template :pattern pattern :file file) *templates*)) (defmacro register-templates (&body templates) "Register multiple templates with `register-template`." @@ -56,6 +53,10 @@ (when-let ((tmpl (find-if (rcurry #'template-match-p buffer-filename) *templates*))) (template-file tmpl))) +(defun new-file-p (buffer) + "Buffer is a new file, and does not already exist on disk." + (not (uiop:file-exists-p (buffer-filename buffer)))) + (defun insert-template (buffer) "Insert registered template into buffer." (when-let (file (find-match (buffer-filename buffer))) @@ -67,10 +68,6 @@ (declare (ignore c)) (message "Failed to render template: ~a" file))))) -(defun new-file-p (buffer) - "Buffer is a new file, and does not already exist on disk." - (not (uiop:file-exists-p (buffer-filename buffer)))) - (add-hook *find-file-hook* (lambda (buffer) (when (and *auto-template* (new-file-p buffer)) From f1f5d80966b49de5dfa36027a0ba09d6128a09b8 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 15:38:34 -0600 Subject: [PATCH 06/24] expose insert-template command --- extensions/template/src/core.lisp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/template/src/core.lisp b/extensions/template/src/core.lisp index 18ae18bd1..ff39a58ee 100644 --- a/extensions/template/src/core.lisp +++ b/extensions/template/src/core.lisp @@ -5,7 +5,8 @@ (:export #:*templates* #:*auto-template* #:register-template - #:register-templates)) + #:register-templates + #:insert-template)) (in-package :lem-template/core) (defvar *templates* nil @@ -57,7 +58,7 @@ "Buffer is a new file, and does not already exist on disk." (not (uiop:file-exists-p (buffer-filename buffer)))) -(defun insert-template (buffer) +(define-command insert-template (&optional (buffer (current-buffer))) () "Insert registered template into buffer." (when-let (file (find-match (buffer-filename buffer))) (handler-case From 6c692d37cd14a7e60948c5ab7076550fa0e712e0 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 15:49:53 -0600 Subject: [PATCH 07/24] move files --- extensions/template/lem-template.asd | 3 +-- extensions/template/{src/core.lisp => template.lisp} | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) rename extensions/template/{src/core.lisp => template.lisp} (97%) diff --git a/extensions/template/lem-template.asd b/extensions/template/lem-template.asd index b20c1675c..a4314cc2f 100644 --- a/extensions/template/lem-template.asd +++ b/extensions/template/lem-template.asd @@ -2,5 +2,4 @@ :author "garlic0x1" :license "MIT" :depends-on (:cl-template) - :components ((:module "src" - :components ((:file "core"))))) + :components ((:file "template"))) diff --git a/extensions/template/src/core.lisp b/extensions/template/template.lisp similarity index 97% rename from extensions/template/src/core.lisp rename to extensions/template/template.lisp index ff39a58ee..c8ea99ea4 100644 --- a/extensions/template/src/core.lisp +++ b/extensions/template/template.lisp @@ -1,5 +1,4 @@ -(defpackage #:lem-template/core - (:nicknames :lem-template) +(defpackage #:lem-template (:use :cl :lem) (:import-from #:alexandria-2 #:line-up-first #:when-let #:rcurry) (:export #:*templates* From 9d555e65bf6b51b950ab17b8e9272f99e2e645d6 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 15:59:07 -0600 Subject: [PATCH 08/24] readme --- extensions/template/README.md | 24 ++++++++++++++++++++++++ extensions/template/template.lisp | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 extensions/template/README.md diff --git a/extensions/template/README.md b/extensions/template/README.md new file mode 100644 index 000000000..4267f7523 --- /dev/null +++ b/extensions/template/README.md @@ -0,0 +1,24 @@ +# lem-template + +A templating extension to generate boilerplate in new files. + +# Usage + +Here is an example template file that generates a simple `.asd` to help get you started. + +``` +(asdf:defsystem "<%= (pathname-name (lem:buffer-filename (@ buffer))) %>" + :author "" + :license "MIT" + :depends-on () + :components ((:module "src" + :components ((:file "core"))))) +``` + +Assuming this file exists in `~/.config/lem/templates/asd.clt`, you can register it like this: + +```lisp +(lem-template:register-template + :pattern ".*\.asd" + :template (merge-pathname "templates/asd.clt" (lem-home))) +``` diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index c8ea99ea4..8f6a1eb24 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -6,7 +6,7 @@ #:register-template #:register-templates #:insert-template)) -(in-package :lem-template/core) +(in-package :lem-template) (defvar *templates* nil "List of registered file templates.") From 7a69fecac187f1dfd5d7b8c99209fb0e06931c82 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 16:09:43 -0600 Subject: [PATCH 09/24] more readme --- extensions/template/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/template/README.md b/extensions/template/README.md index 4267f7523..279b46e79 100644 --- a/extensions/template/README.md +++ b/extensions/template/README.md @@ -20,5 +20,7 @@ Assuming this file exists in `~/.config/lem/templates/asd.clt`, you can register ```lisp (lem-template:register-template :pattern ".*\.asd" - :template (merge-pathname "templates/asd.clt" (lem-home))) + :file (merge-pathnames "templates/asd.clt" (lem-home))) ``` + +You can create any kind of template you want in the [cl-template](https://github.com/alpha123/cl-template) format, `buffer` is passed to the template and you can read it with `(@ buffer)` From 175217b57b41cbd0949ecd015eea233a6b1f7c98 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 16:24:16 -0600 Subject: [PATCH 10/24] link to examples --- extensions/template/README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/extensions/template/README.md b/extensions/template/README.md index 279b46e79..92a866988 100644 --- a/extensions/template/README.md +++ b/extensions/template/README.md @@ -19,8 +19,20 @@ Assuming this file exists in `~/.config/lem/templates/asd.clt`, you can register ```lisp (lem-template:register-template - :pattern ".*\.asd" - :file (merge-pathnames "templates/asd.clt" (lem-home))) + :pattern ".*\.asd" + :file (merge-pathnames "templates/asd.clt" (lem-home))) ``` You can create any kind of template you want in the [cl-template](https://github.com/alpha123/cl-template) format, `buffer` is passed to the template and you can read it with `(@ buffer)` + +# Examples + +See [my templates](https://github.com/garlic0x1/.lem/templates/) for more examples, I used the plural `register-templates` to register them like this: + +```lisp +(register-templates + (:pattern ".*\.asd" :file (merge-pathnames "templates/asd.clt" (lem-home))) + (:pattern ".*\.lisp" :file (merge-pathnames "templates/lisp.clt" (lem-home))) + (:pattern ".*\.go" :file (merge-pathnames "templates/go.clt" (lem-home))) + (:pattern "Makefile" :file (merge-pathnames "templates/Makefile.clt" (lem-home)))) +``` From 3865d2757f7b859dc3de711fbbb95cfb1630238f Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 16:30:54 -0600 Subject: [PATCH 11/24] pass path to template --- extensions/template/README.md | 6 +++--- extensions/template/template.lisp | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/extensions/template/README.md b/extensions/template/README.md index 92a866988..8fd2276e0 100644 --- a/extensions/template/README.md +++ b/extensions/template/README.md @@ -7,7 +7,7 @@ A templating extension to generate boilerplate in new files. Here is an example template file that generates a simple `.asd` to help get you started. ``` -(asdf:defsystem "<%= (pathname-name (lem:buffer-filename (@ buffer))) %>" +(asdf:defsystem "<%= (pathname-name (@ path)) %>" :author "" :license "MIT" :depends-on () @@ -23,11 +23,11 @@ Assuming this file exists in `~/.config/lem/templates/asd.clt`, you can register :file (merge-pathnames "templates/asd.clt" (lem-home))) ``` -You can create any kind of template you want in the [cl-template](https://github.com/alpha123/cl-template) format, `buffer` is passed to the template and you can read it with `(@ buffer)` +You can create any kind of template you want in the [cl-template](https://github.com/alpha123/cl-template) format, `buffer` and `path` are passed to the template and you can read it with `(@ buffer)` etc. # Examples -See [my templates](https://github.com/garlic0x1/.lem/templates/) for more examples, I used the plural `register-templates` to register them like this: +See [my templates](https://github.com/garlic0x1/.lem/tree/master/templates) for more examples, I used the plural `register-templates` to register them like this: ```lisp (register-templates diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index 8f6a1eb24..d9d7bde81 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -63,7 +63,8 @@ (handler-case (insert-string (buffer-start-point buffer) - (render-file file `(:buffer ,buffer))) + (render-file file `(:buffer ,buffer + :path ,(buffer-filename buffer)))) (error (c) (declare (ignore c)) (message "Failed to render template: ~a" file))))) From 10b439a18534d125b410d1c436f0c35d16c3af33 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Sun, 28 Jan 2024 19:23:29 -0600 Subject: [PATCH 12/24] remove command --- extensions/template/template.lisp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index d9d7bde81..8055d3407 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -57,7 +57,7 @@ "Buffer is a new file, and does not already exist on disk." (not (uiop:file-exists-p (buffer-filename buffer)))) -(define-command insert-template (&optional (buffer (current-buffer))) () +(defun insert-template (buffer) "Insert registered template into buffer." (when-let (file (find-match (buffer-filename buffer))) (handler-case From d1bbbae1e20b8fceb14ed935b56aae44e2f46165 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 29 Jan 2024 18:32:41 -0600 Subject: [PATCH 13/24] refactor with named templates --- extensions/template/lem-template.asd | 4 ++- extensions/template/prompt.lisp | 19 ++++++++++ extensions/template/template.lisp | 52 ++++++++++++++++------------ extensions/template/utils.lisp | 18 ++++++++++ 4 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 extensions/template/prompt.lisp create mode 100644 extensions/template/utils.lisp diff --git a/extensions/template/lem-template.asd b/extensions/template/lem-template.asd index a4314cc2f..841aa6ce9 100644 --- a/extensions/template/lem-template.asd +++ b/extensions/template/lem-template.asd @@ -2,4 +2,6 @@ :author "garlic0x1" :license "MIT" :depends-on (:cl-template) - :components ((:file "template"))) + :components ((:file "utils") + (:file "prompt") + (:file "template"))) diff --git a/extensions/template/prompt.lisp b/extensions/template/prompt.lisp new file mode 100644 index 000000000..bebe2d82d --- /dev/null +++ b/extensions/template/prompt.lisp @@ -0,0 +1,19 @@ +(defpackage #:lem-template/prompt + (:use :cl :lem) + (:import-from #:alexandria-2 + #:curry + #:hash-table-keys) + (:export #:prompt-hash-table)) +(in-package :lem-template/prompt) + +(defun table-completion (table string) + (remove-if-not + (lambda (it) (str:prefix? (list it) string)) + (hash-table-keys table))) + +(defun prompt-hash-table (prompt table) + (gethash + (prompt-for-string + prompt + :completion-function (curry #'table-completion table)) + table)) diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index 8055d3407..5339e4d18 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -1,34 +1,41 @@ (defpackage #:lem-template (:use :cl :lem) - (:import-from #:alexandria-2 #:line-up-first #:when-let #:rcurry) - (:export #:*templates* + (:import-from #:lem-template/prompt + #:prompt-hash-table) + (:import-from #:lem-template/utils + #:buffer-empty-p + #:new-file-p + #:hash-table-first) + (:import-from #:alexandria-2 + #:line-up-first + #:when-let + #:rcurry + #:if-let) + (:export #:*patterns* #:*auto-template* #:register-template #:register-templates #:insert-template)) (in-package :lem-template) -(defvar *templates* nil - "List of registered file templates.") +(defvar *patterns* nil + "List of registered file patterns.") (defparameter *auto-template* t "Enable automatically populating new files with templates.") -(defstruct template +(defstruct pattern pattern - file) + templates) -(defun remove-old-template (pattern) - "Get rid of old template for pattern when a new one is registered." - (setf *templates* - (remove-if - (lambda (tmpl) (equal pattern (template-pattern tmpl))) - *templates*))) - -(defun register-template (&key pattern file) +(defun register-template (&key pattern file (name "default")) "Register a template used for filenames matching pattern." - (remove-old-template pattern) - (push (make-template :pattern pattern :file file) *templates*)) + (if-let ((p (find-if (lambda (it) (equal pattern (pattern-pattern it))) *patterns*))) + (setf (gethash name (pattern-templates p)) file) + (progn (push (make-pattern :pattern pattern + :templates (make-hash-table :test #'equal)) + *patterns*) + (register-template :pattern pattern :file file :name name)))) (defmacro register-templates (&body templates) "Register multiple templates with `register-template`." @@ -46,16 +53,15 @@ (defun template-match-p (template filename) "Template pattern matches filename." - (cl-ppcre:scan (template-pattern template) filename)) + (cl-ppcre:scan (pattern-pattern template) filename)) (defun find-match (buffer-filename) "Find template where pattern matches filename." - (when-let ((tmpl (find-if (rcurry #'template-match-p buffer-filename) *templates*))) - (template-file tmpl))) - -(defun new-file-p (buffer) - "Buffer is a new file, and does not already exist on disk." - (not (uiop:file-exists-p (buffer-filename buffer)))) + (when-let ((p (find-if (rcurry #'template-match-p buffer-filename) *patterns*))) + (let ((tmpls (pattern-templates p))) + (if (= 1 (hash-table-count tmpls)) + (hash-table-first tmpls) + (prompt-hash-table "Template: " tmpls))))) (defun insert-template (buffer) "Insert registered template into buffer." diff --git a/extensions/template/utils.lisp b/extensions/template/utils.lisp new file mode 100644 index 000000000..adfd6b82d --- /dev/null +++ b/extensions/template/utils.lisp @@ -0,0 +1,18 @@ +(defpackage #:lem-template/utils + (:use :cl :lem) + (:import-from #:alexandria-2 #:hash-table-keys) + (:export #:buffer-empty-p #:new-file-p #:hash-table-first)) +(in-package :lem-template/utils) + +(defun buffer-empty-p (buffer) + "If start and end are equal, buffer is empty." + (point= (buffer-start-point buffer) + (buffer-end-point buffer))) + +(defun new-file-p (buffer) + "Buffer is a new file, and does not already exist on disk." + (not (uiop:file-exists-p (buffer-filename buffer)))) + +(defun hash-table-first (table) + "Get one item out of a hash-table." + (gethash (car (hash-table-keys table)) table)) From f72989d227267e39ba0a2ad52a11676c8cdbfd30 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 29 Jan 2024 19:55:35 -0600 Subject: [PATCH 14/24] docstrings and stuff --- extensions/template/lem-template.asd | 1 + extensions/template/prompt.lisp | 6 +++--- extensions/template/render.lisp | 10 ++++++++++ extensions/template/template.lisp | 18 ++++-------------- 4 files changed, 18 insertions(+), 17 deletions(-) create mode 100644 extensions/template/render.lisp diff --git a/extensions/template/lem-template.asd b/extensions/template/lem-template.asd index 841aa6ce9..47e6bd823 100644 --- a/extensions/template/lem-template.asd +++ b/extensions/template/lem-template.asd @@ -3,5 +3,6 @@ :license "MIT" :depends-on (:cl-template) :components ((:file "utils") + (:file "render") (:file "prompt") (:file "template"))) diff --git a/extensions/template/prompt.lisp b/extensions/template/prompt.lisp index bebe2d82d..9ab7c2d81 100644 --- a/extensions/template/prompt.lisp +++ b/extensions/template/prompt.lisp @@ -1,17 +1,17 @@ (defpackage #:lem-template/prompt (:use :cl :lem) - (:import-from #:alexandria-2 - #:curry - #:hash-table-keys) + (:import-from #:alexandria-2 #:curry #:hash-table-keys) (:export #:prompt-hash-table)) (in-package :lem-template/prompt) (defun table-completion (table string) + "Completion function for #'prompt-hash-table." (remove-if-not (lambda (it) (str:prefix? (list it) string)) (hash-table-keys table))) (defun prompt-hash-table (prompt table) + "Prompt the keys of a hash-table, return the corresponding value." (gethash (prompt-for-string prompt diff --git a/extensions/template/render.lisp b/extensions/template/render.lisp new file mode 100644 index 000000000..2ac26bef4 --- /dev/null +++ b/extensions/template/render.lisp @@ -0,0 +1,10 @@ +(defpackage #:lem-template/render + (:use :cl :lem) + (:export #:render-file)) +(in-package :lem-template/render) + +(defun render-file (template-file &optional args) + "Render a cl-template file to a string." + (funcall args + (cl-template:compile-template + (uiop:read-file-string template-file)))) diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index 5339e4d18..4b18979cb 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -1,5 +1,7 @@ (defpackage #:lem-template (:use :cl :lem) + (:import-from #:lem-template/render + #:render-file) (:import-from #:lem-template/prompt #:prompt-hash-table) (:import-from #:lem-template/utils @@ -7,12 +9,10 @@ #:new-file-p #:hash-table-first) (:import-from #:alexandria-2 - #:line-up-first #:when-let #:rcurry #:if-let) - (:export #:*patterns* - #:*auto-template* + (:export #:*auto-template* #:register-template #:register-templates #:insert-template)) @@ -39,17 +39,7 @@ (defmacro register-templates (&body templates) "Register multiple templates with `register-template`." - `(progn - ,@(mapcar - (lambda (it) `(register-template ,@it)) - templates))) - -(defun render-file (template-file &optional args) - "Render a cl-template file to a string." - (line-up-first - (uiop:read-file-string template-file) - (cl-template:compile-template) - (funcall args))) + `(progn ,@(mapcar (lambda (it) `(register-template ,@it)) templates))) (defun template-match-p (template filename) "Template pattern matches filename." From 6038fe4ad892f307808567c9d8f1213ebae0e20b Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 29 Jan 2024 20:00:58 -0600 Subject: [PATCH 15/24] bug fix and add none option --- extensions/template/prompt.lisp | 7 ++++--- extensions/template/render.lisp | 7 ++++--- extensions/template/template.lisp | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/template/prompt.lisp b/extensions/template/prompt.lisp index 9ab7c2d81..fe15d0cdb 100644 --- a/extensions/template/prompt.lisp +++ b/extensions/template/prompt.lisp @@ -6,9 +6,10 @@ (defun table-completion (table string) "Completion function for #'prompt-hash-table." - (remove-if-not - (lambda (it) (str:prefix? (list it) string)) - (hash-table-keys table))) + (cons "none" + (remove-if-not + (lambda (it) (str:prefix? (list it) string)) + (hash-table-keys table)))) (defun prompt-hash-table (prompt table) "Prompt the keys of a hash-table, return the corresponding value." diff --git a/extensions/template/render.lisp b/extensions/template/render.lisp index 2ac26bef4..36cf9bc9d 100644 --- a/extensions/template/render.lisp +++ b/extensions/template/render.lisp @@ -5,6 +5,7 @@ (defun render-file (template-file &optional args) "Render a cl-template file to a string." - (funcall args - (cl-template:compile-template - (uiop:read-file-string template-file)))) + (funcall + (cl-template:compile-template + (uiop:read-file-string template-file)) + args)) diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index 4b18979cb..1f31bde2f 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -62,7 +62,7 @@ (render-file file `(:buffer ,buffer :path ,(buffer-filename buffer)))) (error (c) - (declare (ignore c)) + (message "Error: ~a" c) (message "Failed to render template: ~a" file))))) (add-hook *find-file-hook* From 5a0cc3ba25b30e67e18d4a940e35e57727a3518a Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 29 Jan 2024 21:00:00 -0600 Subject: [PATCH 16/24] readme --- extensions/template/README.md | 26 ++++++++++++++++++++------ extensions/template/template.lisp | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/extensions/template/README.md b/extensions/template/README.md index 8fd2276e0..294a73698 100644 --- a/extensions/template/README.md +++ b/extensions/template/README.md @@ -23,16 +23,30 @@ Assuming this file exists in `~/.config/lem/templates/asd.clt`, you can register :file (merge-pathnames "templates/asd.clt" (lem-home))) ``` -You can create any kind of template you want in the [cl-template](https://github.com/alpha123/cl-template) format, `buffer` and `path` are passed to the template and you can read it with `(@ buffer)` etc. +If you provide multiple templates for the same pattern, with the `:name` option (examples below), you will be prompted to choose a template. + +You can create any kind of template you want in the [cl-template](https://github.com/alpha123/cl-template) format, `buffer` and `path` are passed to the template and you can read it with `(@ buffer)`, `(@ path)` etc. + +Templating can be disabled if you put this in your config: + +```lisp +(setf lem-template:*auto-template* nil) +``` # Examples See [my templates](https://github.com/garlic0x1/.lem/tree/master/templates) for more examples, I used the plural `register-templates` to register them like this: ```lisp -(register-templates - (:pattern ".*\.asd" :file (merge-pathnames "templates/asd.clt" (lem-home))) - (:pattern ".*\.lisp" :file (merge-pathnames "templates/lisp.clt" (lem-home))) - (:pattern ".*\.go" :file (merge-pathnames "templates/go.clt" (lem-home))) - (:pattern "Makefile" :file (merge-pathnames "templates/Makefile.clt" (lem-home)))) +(lem-template:register-templates + (:pattern ".*\.asd" + :name "Basic ASD" + :file (merge-pathnames "templates/asd.clt" (lem-home))) + (:pattern ".*\.asd" + :name "Test ASD" + :file (merge-pathnames "templates/test.asd.clt" (lem-home))) + (:pattern ".*\.lisp" + :file (merge-pathnames "templates/lisp.clt" (lem-home)))) ``` + +When you create a new `.asd` file, you will be prompted to choose `Test ASD` or `Basic ASD`. When you create a new `.lisp` file, it will automatically insert the single template. diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index 1f31bde2f..bd2199c4d 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -62,7 +62,7 @@ (render-file file `(:buffer ,buffer :path ,(buffer-filename buffer)))) (error (c) - (message "Error: ~a" c) + (message "Render error: ~a" c) (message "Failed to render template: ~a" file))))) (add-hook *find-file-hook* From a391c08cea5e48f4e45fcd14c137262ea62c662f Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 29 Jan 2024 22:18:19 -0600 Subject: [PATCH 17/24] asdf --- extensions/template/lem-template.asd | 2 +- extensions/template/prompt.lisp | 7 +++---- extensions/template/render.lisp | 6 +++++- extensions/template/template.lisp | 6 ++++-- qlfile | 1 + qlfile.lock | 4 ++++ 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/extensions/template/lem-template.asd b/extensions/template/lem-template.asd index 47e6bd823..05aef08d9 100644 --- a/extensions/template/lem-template.asd +++ b/extensions/template/lem-template.asd @@ -3,6 +3,6 @@ :license "MIT" :depends-on (:cl-template) :components ((:file "utils") - (:file "render") + (:file "render") (:file "prompt") (:file "template"))) diff --git a/extensions/template/prompt.lisp b/extensions/template/prompt.lisp index fe15d0cdb..c58f9b22a 100644 --- a/extensions/template/prompt.lisp +++ b/extensions/template/prompt.lisp @@ -6,10 +6,9 @@ (defun table-completion (table string) "Completion function for #'prompt-hash-table." - (cons "none" - (remove-if-not - (lambda (it) (str:prefix? (list it) string)) - (hash-table-keys table)))) + (remove-if-not + (lambda (it) (str:prefix? (list it) string)) + (cons "none" (hash-table-keys table)))) (defun prompt-hash-table (prompt table) "Prompt the keys of a hash-table, return the corresponding value." diff --git a/extensions/template/render.lisp b/extensions/template/render.lisp index 36cf9bc9d..68d0e69cc 100644 --- a/extensions/template/render.lisp +++ b/extensions/template/render.lisp @@ -1,8 +1,12 @@ (defpackage #:lem-template/render (:use :cl :lem) - (:export #:render-file)) + (:export #:render-file #:render-string)) (in-package :lem-template/render) +(defun render-string (string &optional args) + "Render a cl-template string to a string." + (funcall (cl-template:compile-template string) args)) + (defun render-file (template-file &optional args) "Render a cl-template file to a string." (funcall diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index bd2199c4d..ad2719e5c 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -15,7 +15,9 @@ (:export #:*auto-template* #:register-template #:register-templates - #:insert-template)) + #:insert-template + #:render-file + #:render-string)) (in-package :lem-template) (defvar *patterns* nil @@ -67,5 +69,5 @@ (add-hook *find-file-hook* (lambda (buffer) - (when (and *auto-template* (new-file-p buffer)) + (when (and *auto-template* (new-file-p buffer) (buffer-empty-p buffer)) (insert-template buffer)))) diff --git a/qlfile b/qlfile index a74b85f5d..9dde73372 100644 --- a/qlfile +++ b/qlfile @@ -8,3 +8,4 @@ git cl-sdl2 https://github.com/lem-project/cl-sdl2.git git cl-sdl2-ttf https://github.com/lem-project/cl-sdl2-ttf.git git cl-sdl2-image https://github.com/lem-project/cl-sdl2-image.git git jsonrpc https://github.com/cxxxr/jsonrpc.git +git cl-template https://github.com/alpha123/cl-template diff --git a/qlfile.lock b/qlfile.lock index 0583b04f6..e7307a3a2 100644 --- a/qlfile.lock +++ b/qlfile.lock @@ -42,3 +42,7 @@ (:class qlot/source/git:source-git :initargs (:remote-url "https://github.com/cxxxr/jsonrpc.git") :version "git-28c4c962cfe936c7cd00dcab3bcae47b6f9de071")) +("cl-template" . + (:class qlot/source/git:source-git + :initargs (:remote-url "https://github.com/alpha123/cl-template") + :version "git-46193a9a389bb950530e579eae7e6e5a18184832")) From ae49ae4ae6d8b333a1c1bb2e5ffc2bd8b37f78ed Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 29 Jan 2024 23:11:09 -0600 Subject: [PATCH 18/24] renaming stuff --- extensions/template/template.lisp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index ad2719e5c..a28d99c03 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -20,23 +20,23 @@ #:render-string)) (in-package :lem-template) -(defvar *patterns* nil +(defvar *tmpl-patterns* nil "List of registered file patterns.") (defparameter *auto-template* t "Enable automatically populating new files with templates.") -(defstruct pattern +(defstruct tmpl-pattern pattern templates) (defun register-template (&key pattern file (name "default")) "Register a template used for filenames matching pattern." - (if-let ((p (find-if (lambda (it) (equal pattern (pattern-pattern it))) *patterns*))) - (setf (gethash name (pattern-templates p)) file) - (progn (push (make-pattern :pattern pattern - :templates (make-hash-table :test #'equal)) - *patterns*) + (if-let ((p (find-if (lambda (it) (equal pattern (tmpl-pattern-pattern it))) *tmpl-patterns*))) + (setf (gethash name (tmpl-pattern-templates p)) file) + (progn (push (make-tmpl-pattern :pattern pattern + :templates (make-hash-table :test #'equal)) + *tmpl-patterns*) (register-template :pattern pattern :file file :name name)))) (defmacro register-templates (&body templates) @@ -45,12 +45,12 @@ (defun template-match-p (template filename) "Template pattern matches filename." - (cl-ppcre:scan (pattern-pattern template) filename)) + (cl-ppcre:scan (tmpl-pattern-pattern template) filename)) (defun find-match (buffer-filename) "Find template where pattern matches filename." - (when-let ((p (find-if (rcurry #'template-match-p buffer-filename) *patterns*))) - (let ((tmpls (pattern-templates p))) + (when-let ((p (find-if (rcurry #'template-match-p buffer-filename) *tmpl-patterns*))) + (let ((tmpls (tmpl-pattern-templates p))) (if (= 1 (hash-table-count tmpls)) (hash-table-first tmpls) (prompt-hash-table "Template: " tmpls))))) From a3753f288122f3e7d468f9d328106b21d5527cc6 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Tue, 30 Jan 2024 00:33:04 -0600 Subject: [PATCH 19/24] refactor and add snippets --- extensions/template/lem-template.asd | 4 ++- extensions/template/package.lisp | 5 ++++ extensions/template/prompt.lisp | 15 ++++++---- extensions/template/snippet.lisp | 42 ++++++++++++++++++++++++++++ extensions/template/template.lisp | 10 +++---- 5 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 extensions/template/package.lisp create mode 100644 extensions/template/snippet.lisp diff --git a/extensions/template/lem-template.asd b/extensions/template/lem-template.asd index 05aef08d9..1e81b7c6b 100644 --- a/extensions/template/lem-template.asd +++ b/extensions/template/lem-template.asd @@ -5,4 +5,6 @@ :components ((:file "utils") (:file "render") (:file "prompt") - (:file "template"))) + (:file "template") + (:file "snippet") + (:file "package"))) diff --git a/extensions/template/package.lisp b/extensions/template/package.lisp new file mode 100644 index 000000000..1748c6904 --- /dev/null +++ b/extensions/template/package.lisp @@ -0,0 +1,5 @@ +(uiop:define-package #:lem-template + (:use :cl :lem) + (:use-reexport #:lem-template/render) + (:use-reexport #:lem-template/template) + (:use-reexport #:lem-template/snippet)) diff --git a/extensions/template/prompt.lisp b/extensions/template/prompt.lisp index c58f9b22a..99bcd02cf 100644 --- a/extensions/template/prompt.lisp +++ b/extensions/template/prompt.lisp @@ -4,16 +4,19 @@ (:export #:prompt-hash-table)) (in-package :lem-template/prompt) -(defun table-completion (table string) +(defun table-completion (table &key with-none-option) "Completion function for #'prompt-hash-table." - (remove-if-not - (lambda (it) (str:prefix? (list it) string)) - (cons "none" (hash-table-keys table)))) + (lambda (string) + (remove-if-not + (lambda (it) (str:prefix? (list it) string)) + (if with-none-option + (cons "none" (hash-table-keys table)) + (hash-table-keys table))))) -(defun prompt-hash-table (prompt table) +(defun prompt-hash-table (prompt table &key with-none-option) "Prompt the keys of a hash-table, return the corresponding value." (gethash (prompt-for-string prompt - :completion-function (curry #'table-completion table)) + :completion-function (table-completion table :with-none-option with-none-option)) table)) diff --git a/extensions/template/snippet.lisp b/extensions/template/snippet.lisp new file mode 100644 index 000000000..80bbdfdd5 --- /dev/null +++ b/extensions/template/snippet.lisp @@ -0,0 +1,42 @@ +(defpackage #:lem-template/snippet + (:use :cl :lem) + (:import-from #:lem-template/render + #:render-string) + (:import-from #:lem-template/prompt + #:prompt-hash-table) + (:import-from #:alexandria-2 + #:if-let) + (:export #:register-snippet + #:register-snippets + #:insert-snippet)) +(in-package :lem-template/snippet) + +(defvar *mode-snippets* (make-hash-table) + "Table mapping mode to another table of named snippets.") + +(defun register-snippet (&key mode name file string) + "Register a snippet used in mode." + (if-let ((snips (gethash mode *mode-snippets*))) + (if file + (setf (gethash name snips) (uiop:read-file-string file)) + (setf (gethash name snips) string)) + (progn (setf (gethash mode *mode-snippets*) (make-hash-table :test #'equal)) + (register-snippet :mode mode :name name :file file :string string)))) + +(defmacro register-snippets (&body snippets) + "Register multiple templates with `register-template`." + `(progn ,@(mapcar (lambda (it) `(register-snippet ,@it)) snippets))) + +(define-command insert-snippet () () + "Select a snippet to insert at point." + (let* ((buffer (current-buffer)) + (point (current-point)) + (mode (buffer-major-mode buffer))) + (if-let ((snips (gethash mode *mode-snippets*))) + (progn + (insert-string point (render-string + (prompt-hash-table "Snippet: " snips) + `(:buffer ,buffer + :path ,(buffer-filename buffer)))) + (ignore-errors (lem:format-buffer :buffer buffer))) + (message "No snippets for mode ~a" mode)))) diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index a28d99c03..a2d5be6c7 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -1,4 +1,4 @@ -(defpackage #:lem-template +(defpackage #:lem-template/template (:use :cl :lem) (:import-from #:lem-template/render #:render-file) @@ -15,10 +15,8 @@ (:export #:*auto-template* #:register-template #:register-templates - #:insert-template - #:render-file - #:render-string)) -(in-package :lem-template) + #:insert-template)) +(in-package :lem-template/template) (defvar *tmpl-patterns* nil "List of registered file patterns.") @@ -53,7 +51,7 @@ (let ((tmpls (tmpl-pattern-templates p))) (if (= 1 (hash-table-count tmpls)) (hash-table-first tmpls) - (prompt-hash-table "Template: " tmpls))))) + (prompt-hash-table "Template: " tmpls :with-none-option t))))) (defun insert-template (buffer) "Insert registered template into buffer." From 188fcde5b26177c58bbb54c94f46ff7f89c3d14c Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Tue, 30 Jan 2024 02:28:52 -0600 Subject: [PATCH 20/24] cleanup --- extensions/template/lem-template.asd | 1 + extensions/template/prompt.lisp | 2 +- extensions/template/snippet.lisp | 12 ++++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/extensions/template/lem-template.asd b/extensions/template/lem-template.asd index 1e81b7c6b..ca441be9c 100644 --- a/extensions/template/lem-template.asd +++ b/extensions/template/lem-template.asd @@ -1,6 +1,7 @@ (asdf:defsystem "lem-template" :author "garlic0x1" :license "MIT" + :description "A system for snippets and new file templates." :depends-on (:cl-template) :components ((:file "utils") (:file "render") diff --git a/extensions/template/prompt.lisp b/extensions/template/prompt.lisp index 99bcd02cf..89b885c07 100644 --- a/extensions/template/prompt.lisp +++ b/extensions/template/prompt.lisp @@ -1,6 +1,6 @@ (defpackage #:lem-template/prompt (:use :cl :lem) - (:import-from #:alexandria-2 #:curry #:hash-table-keys) + (:import-from #:alexandria-2 #:hash-table-keys) (:export #:prompt-hash-table)) (in-package :lem-template/prompt) diff --git a/extensions/template/snippet.lisp b/extensions/template/snippet.lisp index 80bbdfdd5..fd5a66879 100644 --- a/extensions/template/snippet.lisp +++ b/extensions/template/snippet.lisp @@ -6,11 +6,15 @@ #:prompt-hash-table) (:import-from #:alexandria-2 #:if-let) - (:export #:register-snippet + (:export #:*format-after-snippet* + #:register-snippet #:register-snippets #:insert-snippet)) (in-package :lem-template/snippet) +(defvar *format-after-snippet* t + "When enabled, formats buffer after inserting snippet.") + (defvar *mode-snippets* (make-hash-table) "Table mapping mode to another table of named snippets.") @@ -34,9 +38,13 @@ (mode (buffer-major-mode buffer))) (if-let ((snips (gethash mode *mode-snippets*))) (progn + ;; insert the snippet (insert-string point (render-string (prompt-hash-table "Snippet: " snips) `(:buffer ,buffer :path ,(buffer-filename buffer)))) - (ignore-errors (lem:format-buffer :buffer buffer))) + ;; format the new snippet + (when *format-after-snippet* + (write-to-file-without-write-hook buffer (buffer-filename buffer)) + (lem:format-buffer :buffer buffer :auto t))) (message "No snippets for mode ~a" mode)))) From d1344ee3c0932c7b3e42022c3866b3eb9c015517 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Tue, 30 Jan 2024 17:46:57 -0600 Subject: [PATCH 21/24] use built-in completion mechanism --- extensions/template/prompt.lisp | 18 +++++++----------- src/config.lisp | 6 +++--- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/extensions/template/prompt.lisp b/extensions/template/prompt.lisp index 89b885c07..ce65b34a1 100644 --- a/extensions/template/prompt.lisp +++ b/extensions/template/prompt.lisp @@ -1,22 +1,18 @@ (defpackage #:lem-template/prompt (:use :cl :lem) - (:import-from #:alexandria-2 #:hash-table-keys) + (:import-from #:alexandria-2 #:hash-table-keys #:rcurry) (:export #:prompt-hash-table)) (in-package :lem-template/prompt) -(defun table-completion (table &key with-none-option) - "Completion function for #'prompt-hash-table." - (lambda (string) - (remove-if-not - (lambda (it) (str:prefix? (list it) string)) - (if with-none-option - (cons "none" (hash-table-keys table)) - (hash-table-keys table))))) - (defun prompt-hash-table (prompt table &key with-none-option) "Prompt the keys of a hash-table, return the corresponding value." (gethash (prompt-for-string prompt - :completion-function (table-completion table :with-none-option with-none-option)) + :completion-function + (rcurry #'completion + (if with-none-option + (cons "none" (hash-table-keys table)) + (hash-table-keys table)) + :test #'lem-core::fuzzy-match-p)) table)) diff --git a/src/config.lisp b/src/config.lisp index e7a6353a7..5418e713b 100644 --- a/src/config.lisp +++ b/src/config.lisp @@ -2,10 +2,10 @@ (defun lem-home () (let ((xdg-lem (uiop:xdg-config-home "lem/")) - (dot-lem (merge-pathnames ".lem/" (user-homedir-pathname)))) + (dot-lem (merge-pathnames ".lem/" (user-homedir-pathname)))) (or (uiop:getenv "LEM_HOME") - (and (probe-file dot-lem) dot-lem) - xdg-lem))) + (and (probe-file dot-lem) dot-lem) + xdg-lem))) (defun lem-logdir-pathname () (merge-pathnames "logs/" (lem-home))) From b7ca1ac2791f94b8c834e96280a9b147632941ef Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Wed, 31 Jan 2024 01:22:06 -0600 Subject: [PATCH 22/24] add buffer-empty-p to src/buffer/package.lisp --- extensions/template/snippet.lisp | 4 +++- extensions/template/template.lisp | 1 - extensions/template/utils.lisp | 7 +------ src/buffer/internal/buffer.lisp | 11 ++++++++--- src/buffer/package.lisp | 5 +++-- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/extensions/template/snippet.lisp b/extensions/template/snippet.lisp index fd5a66879..3528f7114 100644 --- a/extensions/template/snippet.lisp +++ b/extensions/template/snippet.lisp @@ -46,5 +46,7 @@ ;; format the new snippet (when *format-after-snippet* (write-to-file-without-write-hook buffer (buffer-filename buffer)) - (lem:format-buffer :buffer buffer :auto t))) + (lem:format-buffer :buffer buffer :auto t)) + ;; alert the user + (message "Snippet inserted.")) (message "No snippets for mode ~a" mode)))) diff --git a/extensions/template/template.lisp b/extensions/template/template.lisp index a2d5be6c7..99c22ddd7 100644 --- a/extensions/template/template.lisp +++ b/extensions/template/template.lisp @@ -5,7 +5,6 @@ (:import-from #:lem-template/prompt #:prompt-hash-table) (:import-from #:lem-template/utils - #:buffer-empty-p #:new-file-p #:hash-table-first) (:import-from #:alexandria-2 diff --git a/extensions/template/utils.lisp b/extensions/template/utils.lisp index adfd6b82d..dbefad33d 100644 --- a/extensions/template/utils.lisp +++ b/extensions/template/utils.lisp @@ -1,14 +1,9 @@ (defpackage #:lem-template/utils (:use :cl :lem) (:import-from #:alexandria-2 #:hash-table-keys) - (:export #:buffer-empty-p #:new-file-p #:hash-table-first)) + (:export #:new-file-p #:hash-table-first)) (in-package :lem-template/utils) -(defun buffer-empty-p (buffer) - "If start and end are equal, buffer is empty." - (point= (buffer-start-point buffer) - (buffer-end-point buffer))) - (defun new-file-p (buffer) "Buffer is a new file, and does not already exist on disk." (not (uiop:file-exists-p (buffer-filename buffer)))) diff --git a/src/buffer/internal/buffer.lisp b/src/buffer/internal/buffer.lisp index 135577860..7dc254a5e 100644 --- a/src/buffer/internal/buffer.lisp +++ b/src/buffer/internal/buffer.lisp @@ -330,9 +330,9 @@ Options that can be specified by arguments are ignored if `temporary` is NIL and (defun modified-buffers () (remove-if (lambda (buffer) - (not (and (buffer-filename buffer) - (buffer-modified-p buffer)))) - (buffer-list))) + (not (and (buffer-filename buffer) + (buffer-modified-p buffer)))) + (buffer-list))) (defun get-buffer (buffer-or-name) "`buffer-or-name`がバッファならそのまま返し、 @@ -405,3 +405,8 @@ Options that can be specified by arguments are ignored if `temporary` is NIL and (defun clear-buffer-edit-history (buffer) (setf (buffer-edit-history buffer) (make-array 0 :adjustable t :fill-pointer 0))) + +(defun buffer-empty-p (buffer) + "If start and end points are equal, buffer is empty." + (point= (buffer-start-point buffer) + (buffer-end-point buffer))) diff --git a/src/buffer/package.lisp b/src/buffer/package.lisp index 8b727af05..953233dcc 100644 --- a/src/buffer/package.lisp +++ b/src/buffer/package.lisp @@ -80,7 +80,8 @@ :clear-buffer-edit-history ;; TODO: delete ugly exports :%buffer-clear-keep-binfo - :%buffer-keep-binfo) + :%buffer-keep-binfo + :buffer-empty-p) (:export :buffer-list :any-modified-buffer-p @@ -301,7 +302,7 @@ (:use :cl :lem/buffer/internal :lem/buffer/encodings - :lem/common/hooks + :lem/common/hooks :lem/common/var) (:export :*find-file-hook* From 6c7a52bbd1b516bc2293227b8027097095388c15 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 12 Feb 2024 01:05:34 -0600 Subject: [PATCH 23/24] fix some indentation --- .elixir-tools/next-ls.log | 87 +++++++++++++++++++++++++++++++++ src/buffer/internal/buffer.lisp | 6 +-- 2 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 .elixir-tools/next-ls.log diff --git a/.elixir-tools/next-ls.log b/.elixir-tools/next-ls.log new file mode 100644 index 000000000..6a6ce4f60 --- /dev/null +++ b/.elixir-tools/next-ls.log @@ -0,0 +1,87 @@ + +04:28:52.733 [info] Loading 146 CA(s) from :otp store + +04:28:52.936 [debug] sent notification server -> client window/logMessage + +04:28:52.941 [error] LSP Exited. + +Last message received: handle_request %{"id" => "dvbuB2x32I2j", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54052, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} + +** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} + (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 + (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 + (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 + + + + +04:30:46.839 [info] Loading 146 CA(s) from :otp store + +04:30:47.426 [debug] sent notification server -> client window/logMessage + +04:30:47.428 [error] LSP Exited. + +Last message received: handle_request %{"id" => "dvbuB2x32I2j", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54132, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} + +** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} + (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 + (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 + (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 + + + + +04:31:12.517 [info] Loading 146 CA(s) from :otp store + +04:31:13.068 [debug] sent notification server -> client window/logMessage + +04:31:13.072 [error] LSP Exited. + +Last message received: handle_request %{"id" => "EasiKt8u7reH", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54132, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} + +** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} + (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 + (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 + (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 + + + + +04:35:11.521 [notice] SIGTERM received - shutting down + + +04:35:11.522 [notice] SIGTERM received - shutting down + + +04:36:41.331 [info] Loading 146 CA(s) from :otp store + +04:36:41.898 [debug] sent notification server -> client window/logMessage + +04:36:41.901 [error] LSP Exited. + +Last message received: handle_request %{"id" => "OdvbuB2x32I2", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54388, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} + +** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} + (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 + (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 + (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 + + + + +04:39:50.523 [info] Loading 146 CA(s) from :otp store + +04:39:51.020 [debug] sent notification server -> client window/logMessage + +04:39:51.023 [error] LSP Exited. + +Last message received: handle_request %{"id" => "jeasiKt8u7re", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54388, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} + +** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} + (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 + (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 + (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 + + + + \ No newline at end of file diff --git a/src/buffer/internal/buffer.lisp b/src/buffer/internal/buffer.lisp index 7dc254a5e..8da3d9d1f 100644 --- a/src/buffer/internal/buffer.lisp +++ b/src/buffer/internal/buffer.lisp @@ -330,9 +330,9 @@ Options that can be specified by arguments are ignored if `temporary` is NIL and (defun modified-buffers () (remove-if (lambda (buffer) - (not (and (buffer-filename buffer) - (buffer-modified-p buffer)))) - (buffer-list))) + (not (and (buffer-filename buffer) + (buffer-modified-p buffer)))) + (buffer-list))) (defun get-buffer (buffer-or-name) "`buffer-or-name`がバッファならそのまま返し、 From 5bec3d8c42b82ccc37433b14c41f785e36328e90 Mon Sep 17 00:00:00 2001 From: garlic0x1 Date: Mon, 12 Feb 2024 01:06:07 -0600 Subject: [PATCH 24/24] fix some indentation --- .elixir-tools/next-ls.log | 87 --------------------------------------- 1 file changed, 87 deletions(-) delete mode 100644 .elixir-tools/next-ls.log diff --git a/.elixir-tools/next-ls.log b/.elixir-tools/next-ls.log deleted file mode 100644 index 6a6ce4f60..000000000 --- a/.elixir-tools/next-ls.log +++ /dev/null @@ -1,87 +0,0 @@ - -04:28:52.733 [info] Loading 146 CA(s) from :otp store - -04:28:52.936 [debug] sent notification server -> client window/logMessage - -04:28:52.941 [error] LSP Exited. - -Last message received: handle_request %{"id" => "dvbuB2x32I2j", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54052, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} - -** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} - (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 - (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 - (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 - - - - -04:30:46.839 [info] Loading 146 CA(s) from :otp store - -04:30:47.426 [debug] sent notification server -> client window/logMessage - -04:30:47.428 [error] LSP Exited. - -Last message received: handle_request %{"id" => "dvbuB2x32I2j", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54132, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} - -** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} - (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 - (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 - (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 - - - - -04:31:12.517 [info] Loading 146 CA(s) from :otp store - -04:31:13.068 [debug] sent notification server -> client window/logMessage - -04:31:13.072 [error] LSP Exited. - -Last message received: handle_request %{"id" => "EasiKt8u7reH", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54132, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} - -** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} - (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 - (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 - (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 - - - - -04:35:11.521 [notice] SIGTERM received - shutting down - - -04:35:11.522 [notice] SIGTERM received - shutting down - - -04:36:41.331 [info] Loading 146 CA(s) from :otp store - -04:36:41.898 [debug] sent notification server -> client window/logMessage - -04:36:41.901 [error] LSP Exited. - -Last message received: handle_request %{"id" => "OdvbuB2x32I2", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54388, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} - -** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} - (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 - (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 - (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 - - - - -04:39:50.523 [info] Loading 146 CA(s) from :otp store - -04:39:51.020 [debug] sent notification server -> client window/logMessage - -04:39:51.023 [error] LSP Exited. - -Last message received: handle_request %{"id" => "jeasiKt8u7re", "jsonrpc" => "2.0", "method" => "initialize", "params" => %{"capabilities" => %{"textDocument" => %{"codeAction" => %{}, "completion" => %{"completionItem" => %{"snippetSupport" => nil}, "contextSupport" => true}, "definition" => %{"linkSupport" => nil}, "documentSymbol" => %{"hierarchicalDocumentSymbolSupport" => true}, "formatting" => %{}, "hover" => %{}, "implementation" => %{"linkSupport" => nil}, "onTypeFormatting" => %{}, "publishDiagnostics" => %{"relatedInformation" => true}, "rangeFormatting" => %{}, "references" => %{}, "rename" => %{}, "signatureHelp" => %{"contextSupport" => true, "signatureInformation" => %{"activeParameterSupport" => true, "documentationFormat" => ["plaintext", "markdown"], "parameterInformation" => %{"labelOffsetSupport" => true}}}, "synchronization" => %{"didSave" => true}, "typeDefinition" => %{"linkSupport" => nil}}, "workspace" => %{}}, "clientInfo" => %{"name" => "lem"}, "processId" => 54388, "rootUri" => "file:///home/garlic/elixir/hack/", "trace" => "off", "workspaceFolders" => nil}} - -** (MatchError) no match of right hand side value: {:error, %{"id" => "expected an integer"}} - (gen_lsp 0.7.1) lib/gen_lsp.ex:267: anonymous fn/6 in GenLSP.loop/3 - (gen_lsp 0.7.1) lib/gen_lsp.ex:391: GenLSP.attempt/4 - (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3 - - - - \ No newline at end of file