From 39927d996086b6c0cab012f0d5942d1e3d9e4aa6 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Mon, 7 Oct 2024 10:01:01 -0300 Subject: [PATCH 01/32] settings: preparing --- src/settings.lisp | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/settings.lisp diff --git a/src/settings.lisp b/src/settings.lisp new file mode 100644 index 000000000..d107bce8b --- /dev/null +++ b/src/settings.lisp @@ -0,0 +1,6 @@ +(defpackage :lem/settings + (:use :lem-core) + (:export #:customize-variable + #:customize-group)) + +(in-package :lem/settings) \ No newline at end of file From 6627f07247cb2674bb281f3ef84bbcf800cf7c48 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Mon, 7 Oct 2024 17:50:15 -0300 Subject: [PATCH 02/32] settings --- src/settings.lisp | 136 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index d107bce8b..0cd950b82 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -1,6 +1,136 @@ +;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Customization.html + (defpackage :lem/settings - (:use :lem-core) + (:use :cl) (:export #:customize-variable - #:customize-group)) + #:customize-group + #:defcustom + #:defgroup + #:set-variable + #:find-variable + #:find-group)) + +(in-package :lem/settings) + +(defvar *custom-vars* (make-hash-table) + "map of customization variables.") + +(defvar *custom-groups* (make-hash-table) + "map of customization groups.") + +(defclass custom-variable () + ((name :initarg :name + :accessor variable-name + :type symbol + :initform (error "Provide the variable name") + :documentation "The variable name") + (type :initarg :type + :accessor variable-type + :initform (error "Provide the variable type") + :documentation "The variable type") + (default :initarg :default + :accessor variable-default + :initform (error "Provide the variable default value") + :documentation "The variable default value") + (group :initarg :group + :accessor group-of + :type symbol + :initform (error "Provide the group for the variable") + :documentation "The group the variable belongs to") + (documentation :initarg :documentation + :accessor documentation-of + :type (or string null) + :initform nil + :documentation "The variable documentation"))) + +(defclass custom-group () + ((name :initarg :name + :accessor group-name + :type symbol + :initform (error "Provide the group name") + :documentation "The group name") + (group :initarg :group + :accessor group-of + :type (or null symbol) + :initform nil + :documentation "The parent group of this group. If it is NIL, then this is a top-level group.") + (documentation :initarg :documentation + :accessor documentation-of + :type (or string null) + :initform nil + :documentation "The group documentation"))) + +;; TODO: perhaps rethink this implementation: variables and groups could form a graph with +;; actual references stored in the CLOS object slots (parent, group, members, etc). +(defun group-variables (group) + (remove-if-not (lambda (var) + (eql (group-of var) (group-name group))) + (alexandria:hash-table-values *custom-vars*))) + +;; TODO: perhaps rethink this implementation: variables and groups could form a graph with +;; actual references stored in the CLOS object slots (parent, group, members, etc). +(defun subgroups (group) + (remove-if-not (lambda (g) + (eql (group-of g) (group-name group))) + (alexandria:hash-table-values *custom-groups*))) + +(defmacro defcustom (symbol default doc &rest args) + "Define customization variable." + (let ((vartype (or (getf args :type) + (error "Provide the type")))) + `(progn + (defvar ,symbol ,default ,doc) + (check-type ,symbol ,vartype) + (setf (gethash ',symbol *custom-vars*) + (make-instance 'custom-variable + :name ',symbol + :type ',vartype + :group ',(getf args :group) + :default ,default + :documentation ,doc)) + (gethash ',symbol *custom-vars*)))) + +(defmacro defgroup (symbol members doc &rest args) + `(progn + (setf (gethash ',symbol *custom-groups*) + (make-instance 'custom-group + :name ',symbol + :documentation ,doc + ,@args)) + ,@(loop for member in members + collect `(defcustom ,@member)))) + +(defun find-variable (name &optional (error-p t)) + (or (gethash name *custom-vars*) + (when error-p + (error "Customization variable not found: ~s" name)))) + +(defun find-group (name &optional (error-p t)) + (or (gethash name *custom-groups*) + (when error-p + (error "Custom group not found: ~s" name)))) + +(defun prompt-for-type-instance (type-spec prompt &rest args) + "Prompt for an instance of TYPE-SPEC using PROMPT." + (let ((type-discriminator (if (listp type-spec) + (car type-spec) + type-spec)) + (type-arguments (if (listp type-spec) + (cdr type-spec) + nil))) + (apply #'%prompt-for-type-instance + type-discriminator type-arguments prompt + args))) + +(defgeneric %prompt-for-type-instance (type-discriminator type-arguments prompt &rest args)) + +(defmethod %prompt-for-type-instance ((type (eql 'string)) type-args prompt &rest args) + (lem-core::prompt-for-string prompt :initial-value (getf args :initial-value))) + +(defmethod %prompt-for-type-instance ((type (eql 'integer)) type-args prompt &rest args) + (lem-core::prompt-for-integer prompt :initial-value (getf args :initial-value))) + +(defmethod %prompt-for-type-instance ((type (eql 'boolean)) type-args prompt &rest args) + (declare (ignore args)) + (lem-core::prompt-for-y-or-n-p prompt)) -(in-package :lem/settings) \ No newline at end of file From cae74b6bac327abfb127e808d13ae12829d7f038 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Mon, 7 Oct 2024 18:38:55 -0300 Subject: [PATCH 03/32] settings --- src/settings.lisp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 0cd950b82..b0e7e9df8 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -1,7 +1,7 @@ ;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Customization.html (defpackage :lem/settings - (:use :cl) + (:use :cl :lem-core) (:export #:customize-variable #:customize-group #:defcustom @@ -110,18 +110,6 @@ (when error-p (error "Custom group not found: ~s" name)))) -(defun prompt-for-type-instance (type-spec prompt &rest args) - "Prompt for an instance of TYPE-SPEC using PROMPT." - (let ((type-discriminator (if (listp type-spec) - (car type-spec) - type-spec)) - (type-arguments (if (listp type-spec) - (cdr type-spec) - nil))) - (apply #'%prompt-for-type-instance - type-discriminator type-arguments prompt - args))) - (defgeneric %prompt-for-type-instance (type-discriminator type-arguments prompt &rest args)) (defmethod %prompt-for-type-instance ((type (eql 'string)) type-args prompt &rest args) @@ -134,3 +122,14 @@ (declare (ignore args)) (lem-core::prompt-for-y-or-n-p prompt)) +(defun prompt-for-type-instance (type-spec prompt &rest args) + "Prompt for an instance of TYPE-SPEC using PROMPT." + (let ((type-discriminator (if (listp type-spec) + (car type-spec) + type-spec)) + (type-arguments (if (listp type-spec) + (cdr type-spec) + nil))) + (apply #'%prompt-for-type-instance + type-discriminator type-arguments prompt + args))) \ No newline at end of file From d57d5835b68005e77b9310e638bea0e59153f0ea Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Mon, 7 Oct 2024 19:05:42 -0300 Subject: [PATCH 04/32] settings: customize-variable command --- src/settings.lisp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/settings.lisp b/src/settings.lisp index b0e7e9df8..8949e7499 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -132,4 +132,17 @@ nil))) (apply #'%prompt-for-type-instance type-discriminator type-arguments prompt - args))) \ No newline at end of file + args))) + +(define-command customize-variable () () + (let* ((var-names (mapcar + (alexandria:compose #'prin1-to-string #'variable-name) + (alexandria:hash-table-values *custom-vars*))) + (variable-name + (prompt-for-string "Customize variable: " + :test-function (lambda (str) (< 0 (length str))) + :completion-function (lambda (string) + (completion string var-names)))) + (variable (find-variable (read-from-string variable-name))) + (value (prompt-for-type-instance (variable-type variable) "Value: "))) + (setf (symbol-value (variable-name variable)) value))) \ No newline at end of file From cbe024fc5b00a1732b922d553c1fbd146c59ae10 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Mon, 7 Oct 2024 20:29:15 -0300 Subject: [PATCH 05/32] settings: customize-group command --- src/settings.lisp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/settings.lisp b/src/settings.lisp index 8949e7499..3d5b063bb 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -145,4 +145,27 @@ (completion string var-names)))) (variable (find-variable (read-from-string variable-name))) (value (prompt-for-type-instance (variable-type variable) "Value: "))) - (setf (symbol-value (variable-name variable)) value))) \ No newline at end of file + (setf (symbol-value (variable-name variable)) value))) + +(define-command customize-group () () + (let* ((group-names (mapcar + (alexandria:compose #'prin1-to-string #'group-name) + (alexandria:hash-table-values *custom-groups*))) + (group-name + (prompt-for-string "Customize group: " + :test-function (lambda (str) (< 0 (length str))) + :completion-function (lambda (string) + (completion string group-names)))) + (group (find-group (read-from-string group-name))) + (var-names (mapcar + (alexandria:compose #'prin1-to-string #'variable-name) + (group-variables group))) + (variable-name + (prompt-for-string (format nil "Customize variable in ~a: " group-name) + :test-function (lambda (str) (< 0 (length str))) + :completion-function (lambda (string) + (completion string var-names)))) + (variable (find-variable (read-from-string variable-name))) + (value (prompt-for-type-instance (variable-type variable) "Value: "))) + (setf (symbol-value (variable-name variable)) value))) + \ No newline at end of file From ed66900ae45b604bcbfb5165387943c2f8ab19d1 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Mon, 7 Oct 2024 21:35:48 -0300 Subject: [PATCH 06/32] settings: refactoring and resetting --- src/settings.lisp | 61 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 3d5b063bb..b777ba9a8 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -37,6 +37,11 @@ :type symbol :initform (error "Provide the group for the variable") :documentation "The group the variable belongs to") + (setter :initarg :setter + :accessor variable-setter + :type (or symbol function null) + :initform nil + :documentation "A function designator used for setting the value of the variable") (documentation :initarg :documentation :accessor documentation-of :type (or string null) @@ -110,6 +115,17 @@ (when error-p (error "Custom group not found: ~s" name)))) +(defun get-variable-value (var) + (symbol-value (variable-name var))) + +(defun set-variable-value (var value) + (if (variable-setter var) + (funcall (variable-setter var) value var) + (setf (symbol-value (variable-name var)) value))) + +(defun reset-variable-value (var) + (set-variable-value var (variable-default var))) + (defgeneric %prompt-for-type-instance (type-discriminator type-arguments prompt &rest args)) (defmethod %prompt-for-type-instance ((type (eql 'string)) type-args prompt &rest args) @@ -134,18 +150,27 @@ type-discriminator type-arguments prompt args))) +(defun prompt-for-variable (prompt &optional var-names) + (let* + ((actual-var-names (or var-names + (mapcar + (alexandria:compose #'prin1-to-string #'variable-name) + (alexandria:hash-table-values *custom-vars*)))) + (variable-name + (prompt-for-string prompt + :test-function (lambda (str) (< 0 (length str))) + :completion-function (lambda (string) + (completion string actual-var-names))))) + (find-variable (read-from-string variable-name)))) + +(define-command reset-variable () () + (let ((variable (prompt-for-variable "Reset variable: "))) + (reset-variable-value variable))) + (define-command customize-variable () () - (let* ((var-names (mapcar - (alexandria:compose #'prin1-to-string #'variable-name) - (alexandria:hash-table-values *custom-vars*))) - (variable-name - (prompt-for-string "Customize variable: " - :test-function (lambda (str) (< 0 (length str))) - :completion-function (lambda (string) - (completion string var-names)))) - (variable (find-variable (read-from-string variable-name))) + (let* ((variable (prompt-for-variable "Customize variable: ")) (value (prompt-for-type-instance (variable-type variable) "Value: "))) - (setf (symbol-value (variable-name variable)) value))) + (set-variable-value variable value))) (define-command customize-group () () (let* ((group-names (mapcar @@ -157,15 +182,9 @@ :completion-function (lambda (string) (completion string group-names)))) (group (find-group (read-from-string group-name))) - (var-names (mapcar - (alexandria:compose #'prin1-to-string #'variable-name) - (group-variables group))) - (variable-name - (prompt-for-string (format nil "Customize variable in ~a: " group-name) - :test-function (lambda (str) (< 0 (length str))) - :completion-function (lambda (string) - (completion string var-names)))) - (variable (find-variable (read-from-string variable-name))) + (variable (prompt-for-variable (format nil "Customize variable in ~a: " group-name) + (mapcar + (alexandria:compose #'prin1-to-string #'variable-name) + (group-variables group)))) (value (prompt-for-type-instance (variable-type variable) "Value: "))) - (setf (symbol-value (variable-name variable)) value))) - \ No newline at end of file + (set-variable-value variable value))) \ No newline at end of file From 516d85703c979859cbce79e4a08b41593f894e49 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Tue, 8 Oct 2024 10:41:03 -0300 Subject: [PATCH 07/32] settings: towards customization buffers --- src/settings.lisp | 75 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index b777ba9a8..ef82c5ccc 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -115,13 +115,24 @@ (when error-p (error "Custom group not found: ~s" name)))) +(defun ensure-variable (variable-or-symbol) + (etypecase variable-or-symbol + (custom-variable variable-or-symbol) + (symbol (find-variable variable-or-symbol)))) + +(defun ensure-group (group-or-symbol) + (etypecase group-or-symbol + (custom-group group-or-symbol) + (symbol (find-group group-or-symbol)))) + (defun get-variable-value (var) - (symbol-value (variable-name var))) + (symbol-value (variable-name (ensure-variable var)))) (defun set-variable-value (var value) - (if (variable-setter var) - (funcall (variable-setter var) value var) - (setf (symbol-value (variable-name var)) value))) + (alexandria:if-let (setter (variable-setter (ensure-variable var))) + (if setter + (funcall setter value var) + (setf (symbol-value (variable-name (ensure-variable var))) value)))) (defun reset-variable-value (var) (set-variable-value var (variable-default var))) @@ -167,24 +178,60 @@ (let ((variable (prompt-for-variable "Reset variable: "))) (reset-variable-value variable))) -(define-command customize-variable () () - (let* ((variable (prompt-for-variable "Customize variable: ")) +(define-command customize-variable (var-designator) (:universal-nil) + (let* ((variable (or (and var-designator (ensure-variable var-designator)) + (prompt-for-variable "Customize variable: "))) (value (prompt-for-type-instance (variable-type variable) "Value: "))) (set-variable-value variable value))) -(define-command customize-group () () - (let* ((group-names (mapcar - (alexandria:compose #'prin1-to-string #'group-name) - (alexandria:hash-table-values *custom-groups*))) +(defun prompt-for-group (prompt &optional group-names) + (let* ((actual-group-names (or group-names + (mapcar + (alexandria:compose #'prin1-to-string #'group-name) + (alexandria:hash-table-values *custom-groups*)))) (group-name (prompt-for-string "Customize group: " :test-function (lambda (str) (< 0 (length str))) :completion-function (lambda (string) - (completion string group-names)))) - (group (find-group (read-from-string group-name))) - (variable (prompt-for-variable (format nil "Customize variable in ~a: " group-name) + (completion string actual-group-names))))) + (find-group (read-from-string group-name)))) + +(define-command customize-group (group-designator) (:universal-nil) + (let* ((group (or (and group-designator (ensure-group group-designator)) + (prompt-for-group "Customize group: "))) + (variable (prompt-for-variable (format nil "Customize variable in ~a: " (group-name group)) (mapcar (alexandria:compose #'prin1-to-string #'variable-name) (group-variables group)))) (value (prompt-for-type-instance (variable-type variable) "Value: "))) - (set-variable-value variable value))) \ No newline at end of file + (set-variable-value variable value))) + +(defun open-customize-variable-buffer (variable) + (let ((buf (make-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) + (with-current-buffer buf + (with-open-stream (stream (make-buffer-output-stream + (buffer-end-point buf))) + (write-string "Customize: " stream) + (prin1 (variable-name variable) stream) + (terpri stream) + (write-string "Value: " stream) + (prin1 (get-variable-value variable) stream) + (write-string " " stream) + (lem/button:insert-button + (current-point) "[Set]" + (lambda () + (customize-variable variable))) + (write-string " " stream) + (lem/button:insert-button + (current-point) "[Reset]" + (lambda () + (customize-variable variable))) + (terpri stream) + (terpri stream) + (write-string (documentation-of variable) stream) + + (setf (lem-core::buffer-read-only-p buf) t) + ;;(lem-core:switch-to-buffer buf) + (lem-core:pop-to-buffer buf) + ;;(lem-core:change-buffer-mode ) + )))) \ No newline at end of file From 6d4d2161162ad2abd5b186aaca24ee8b8a77ff2f Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Tue, 8 Oct 2024 11:58:16 -0300 Subject: [PATCH 08/32] settings: towards customization buffers --- src/settings.lisp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/settings.lisp b/src/settings.lisp index ef82c5ccc..e05c8e365 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -230,6 +230,28 @@ (terpri stream) (write-string (documentation-of variable) stream) + (setf (lem-core::buffer-read-only-p buf) t) + ;;(lem-core:switch-to-buffer buf) + (lem-core:pop-to-buffer buf) + ;;(lem-core:change-buffer-mode ) + )))) + +(defun open-customize-group-buffer (group) + (let ((buf (make-buffer (format nil "*Customize group: ~a*" (group-name group))))) + (with-current-buffer buf + (with-open-stream (stream (make-buffer-output-stream + (buffer-end-point buf))) + (write-string "Customize group: " stream) + (prin1 (group-name group) stream) + (terpri stream) (terpri stream) + (write-string (documentation-of group) stream) + (terpri stream) + (dolist (var (group-variables group)) + (terpri stream) + (prin1 (variable-name var) stream) + (write-string " - " stream) + (write-string (documentation-of var) stream)) + (setf (lem-core::buffer-read-only-p buf) t) ;;(lem-core:switch-to-buffer buf) (lem-core:pop-to-buffer buf) From 30ea73411f364521617bc5e3ee424d72cef134e5 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Tue, 8 Oct 2024 12:04:18 -0300 Subject: [PATCH 09/32] settings: prepare --- src/settings.lisp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/settings.lisp b/src/settings.lisp index e05c8e365..4d436ab49 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -206,6 +206,9 @@ (value (prompt-for-type-instance (variable-type variable) "Value: "))) (set-variable-value variable value))) +(define-command apropos-custom-variable (pattern) (:universal-nil) + (error "TODO")) + (defun open-customize-variable-buffer (variable) (let ((buf (make-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) (with-current-buffer buf From 28e3def55274176098785b0ba43e342b6a7d4bfb Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Tue, 8 Oct 2024 13:40:27 -0300 Subject: [PATCH 10/32] settings --- src/settings.lisp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/settings.lisp b/src/settings.lisp index 4d436ab49..bb008e632 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -254,6 +254,14 @@ (prin1 (variable-name var) stream) (write-string " - " stream) (write-string (documentation-of var) stream)) + + (when (subgroups group) + (terpri stream) (terpri stream) + (write-string "Subgroups:" stream) + (terpri stream) + (dolist (subgroup (subgroups group)) + (terpri stream) + (write-string (string (group-name subgroup)) stream))) (setf (lem-core::buffer-read-only-p buf) t) ;;(lem-core:switch-to-buffer buf) From 6c97b6e31c736a35e0d6b65362e4bb8d5823a1ad Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Tue, 8 Oct 2024 16:59:52 -0300 Subject: [PATCH 11/32] settings: attributes --- src/settings.lisp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index bb008e632..2a4838c8f 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -12,6 +12,16 @@ (in-package :lem/settings) +(define-attribute settings-label-attribute) + +(define-attribute settings-value-attribute + (t :foreground :base0D :bold t)) + +(define-attribute settings-action-attribute + (:dark :foreground :base09 :bold t)) + +(define-attribute settings-docs-attribute) + (defvar *custom-vars* (make-hash-table) "map of customization variables.") @@ -215,23 +225,26 @@ (with-open-stream (stream (make-buffer-output-stream (buffer-end-point buf))) (write-string "Customize: " stream) - (prin1 (variable-name variable) stream) + (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) (terpri stream) - (write-string "Value: " stream) - (prin1 (get-variable-value variable) stream) + (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) + (insert-string (current-point) (prin1-to-string (get-variable-value variable)) :attribute 'settings-value-attribute) (write-string " " stream) (lem/button:insert-button (current-point) "[Set]" (lambda () - (customize-variable variable))) + (customize-variable variable)) + :attribute 'settings-action-attribute) (write-string " " stream) (lem/button:insert-button (current-point) "[Reset]" (lambda () - (customize-variable variable))) + (customize-variable variable)) + :attribute 'settings-action-attribute) (terpri stream) (terpri stream) - (write-string (documentation-of variable) stream) + (insert-string (current-point) (documentation-of variable) + :attribute 'settings-docs-attribute) (setf (lem-core::buffer-read-only-p buf) t) ;;(lem-core:switch-to-buffer buf) From d0477cc23509d6ee517b4ae306d0c54f6c78fb58 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Tue, 8 Oct 2024 19:39:40 -0300 Subject: [PATCH 12/32] settings: defgroup macro --- src/settings.lisp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 2a4838c8f..91be8b341 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -105,13 +105,13 @@ :documentation ,doc)) (gethash ',symbol *custom-vars*)))) -(defmacro defgroup (symbol members doc &rest args) +(defmacro defgroup (symbol members doc &key group) `(progn (setf (gethash ',symbol *custom-groups*) (make-instance 'custom-group :name ',symbol :documentation ,doc - ,@args)) + :group ',group)) ,@(loop for member in members collect `(defcustom ,@member)))) From 49da091625e572c38e9cb3a8947c745dc085dc2c Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Tue, 8 Oct 2024 20:32:54 -0300 Subject: [PATCH 13/32] settings: pressable buttons and major-mode --- src/settings.lisp | 138 ++++++++++++++++++++++++++++------------------ 1 file changed, 85 insertions(+), 53 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 91be8b341..6fce8b8b6 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -2,6 +2,10 @@ (defpackage :lem/settings (:use :cl :lem-core) + (:import-from :lem/button + :button-at + :button-action + :forward-button) (:export #:customize-variable #:customize-group #:defcustom @@ -219,65 +223,93 @@ (define-command apropos-custom-variable (pattern) (:universal-nil) (error "TODO")) +(defun make-settings-buffer (name &rest args) + (let ((buffer (apply #'make-buffer name args))) + (change-buffer-mode buffer 'settings-mode) + buffer)) + (defun open-customize-variable-buffer (variable) - (let ((buf (make-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) + (let ((buf (make-settings-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) (with-current-buffer buf - (with-open-stream (stream (make-buffer-output-stream - (buffer-end-point buf))) - (write-string "Customize: " stream) - (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) - (terpri stream) - (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) - (insert-string (current-point) (prin1-to-string (get-variable-value variable)) :attribute 'settings-value-attribute) - (write-string " " stream) - (lem/button:insert-button - (current-point) "[Set]" - (lambda () - (customize-variable variable)) - :attribute 'settings-action-attribute) - (write-string " " stream) - (lem/button:insert-button - (current-point) "[Reset]" - (lambda () - (customize-variable variable)) - :attribute 'settings-action-attribute) - (terpri stream) - (terpri stream) - (insert-string (current-point) (documentation-of variable) - :attribute 'settings-docs-attribute) + (with-buffer-read-only buf nil + (with-open-stream (stream (make-buffer-output-stream + (buffer-end-point buf))) + (write-string "Customize: " stream) + (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) + (terpri stream) + (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) + (insert-string (current-point) (prin1-to-string (get-variable-value variable)) :attribute 'settings-value-attribute) + (write-string " " stream) + (lem/button:insert-button + (current-point) "[Set]" + (lambda () + (customize-variable variable)) + :attribute 'settings-action-attribute) + (write-string " " stream) + (lem/button:insert-button + (current-point) "[Reset]" + (lambda () + (customize-variable variable)) + :attribute 'settings-action-attribute) + (terpri stream) + (terpri stream) + (insert-string (current-point) (documentation-of variable) + :attribute 'settings-docs-attribute) - (setf (lem-core::buffer-read-only-p buf) t) - ;;(lem-core:switch-to-buffer buf) - (lem-core:pop-to-buffer buf) - ;;(lem-core:change-buffer-mode ) - )))) + (setf (lem-core::buffer-read-only-p buf) t) + ;;(lem-core:switch-to-buffer buf) + (lem-core:pop-to-buffer buf) + ;;(lem-core:change-buffer-mode ) + ))))) (defun open-customize-group-buffer (group) - (let ((buf (make-buffer (format nil "*Customize group: ~a*" (group-name group))))) + (let ((buf (make-settings-buffer (format nil "*Customize group: ~a*" (group-name group))))) (with-current-buffer buf - (with-open-stream (stream (make-buffer-output-stream - (buffer-end-point buf))) - (write-string "Customize group: " stream) - (prin1 (group-name group) stream) - (terpri stream) (terpri stream) - (write-string (documentation-of group) stream) - (terpri stream) - (dolist (var (group-variables group)) - (terpri stream) - (prin1 (variable-name var) stream) - (write-string " - " stream) - (write-string (documentation-of var) stream)) - - (when (subgroups group) + (with-buffer-read-only buf nil + (with-open-stream (stream (make-buffer-output-stream + (buffer-end-point buf))) + (write-string "Customize group: " stream) + (prin1 (group-name group) stream) (terpri stream) (terpri stream) - (write-string "Subgroups:" stream) - (terpri stream) - (dolist (subgroup (subgroups group)) + (write-string (documentation-of group) stream) + (terpri stream) + (dolist (var (group-variables group)) + (terpri stream) + (prin1 (variable-name var) stream) + (write-string " - " stream) + (write-string (documentation-of var) stream)) + + (when (subgroups group) + (terpri stream) (terpri stream) + (write-string "Subgroups:" stream) (terpri stream) - (write-string (string (group-name subgroup)) stream))) + (dolist (subgroup (subgroups group)) + (terpri stream) + (write-string (string (group-name subgroup)) stream))) - (setf (lem-core::buffer-read-only-p buf) t) - ;;(lem-core:switch-to-buffer buf) - (lem-core:pop-to-buffer buf) - ;;(lem-core:change-buffer-mode ) - )))) \ No newline at end of file + (setf (lem-core::buffer-read-only-p buf) t) + ;;(lem-core:switch-to-buffer buf) + (lem-core:pop-to-buffer buf) + ;;(lem-core:change-buffer-mode ) + ))))) + +(define-major-mode settings-mode nil + (:name "settings" + :keymap *settings-keymap*) + (setf (buffer-read-only-p (current-buffer)) t)) + +(define-key *settings-keymap* "Return" 'settings-default-action) +(define-key *settings-keymap* "Tab" 'settings-forward-button) +(define-key *settings-keymap* "q" 'quit-active-window) +(define-key *settings-keymap* "M-q" 'quit-active-window) + +(define-command settings-default-action () () + (let ((button (button-at (current-point)))) + (when button (button-action button)))) + +(define-command settings-forward-button () () + (let ((p (current-point))) + (or (forward-button p) + (progn + (buffer-start p) + (forward-button p))))) \ No newline at end of file From 3b9d16b19deb9b71868616276e04693256099556 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 08:37:24 -0300 Subject: [PATCH 14/32] settings --- src/settings.lisp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 6fce8b8b6..5f2844171 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -5,7 +5,8 @@ (:import-from :lem/button :button-at :button-action - :forward-button) + :forward-button + :insert-button) (:export #:customize-variable #:customize-group #:defcustom @@ -47,7 +48,6 @@ :initform (error "Provide the variable default value") :documentation "The variable default value") (group :initarg :group - :accessor group-of :type symbol :initform (error "Provide the group for the variable") :documentation "The group the variable belongs to") @@ -79,6 +79,9 @@ :initform nil :documentation "The group documentation"))) +(defmethod group-of ((var custom-variable)) + (find-group (slot-value var 'group))) + ;; TODO: perhaps rethink this implementation: variables and groups could form a graph with ;; actual references stored in the CLOS object slots (parent, group, members, etc). (defun group-variables (group) @@ -236,15 +239,19 @@ (buffer-end-point buf))) (write-string "Customize: " stream) (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) + (write-string " in: " stream) + (insert-button (current-point) (string (group-name (group-of variable))) + (lambda () + (customize-group (group-of variable))) + :attribute 'document-link-attribute) (terpri stream) (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) (insert-string (current-point) (prin1-to-string (get-variable-value variable)) :attribute 'settings-value-attribute) (write-string " " stream) - (lem/button:insert-button - (current-point) "[Set]" - (lambda () - (customize-variable variable)) - :attribute 'settings-action-attribute) + (insert-button (current-point) "[Set]" + (lambda () + (customize-variable variable)) + :attribute 'settings-action-attribute) (write-string " " stream) (lem/button:insert-button (current-point) "[Reset]" @@ -256,11 +263,7 @@ (insert-string (current-point) (documentation-of variable) :attribute 'settings-docs-attribute) - (setf (lem-core::buffer-read-only-p buf) t) - ;;(lem-core:switch-to-buffer buf) - (lem-core:pop-to-buffer buf) - ;;(lem-core:change-buffer-mode ) - ))))) + (lem-core:switch-to-buffer buf)))))) (defun open-customize-group-buffer (group) (let ((buf (make-settings-buffer (format nil "*Customize group: ~a*" (group-name group))))) @@ -287,10 +290,7 @@ (terpri stream) (write-string (string (group-name subgroup)) stream))) - (setf (lem-core::buffer-read-only-p buf) t) - ;;(lem-core:switch-to-buffer buf) - (lem-core:pop-to-buffer buf) - ;;(lem-core:change-buffer-mode ) + (lem-core:switch-to-buffer buf) ))))) (define-major-mode settings-mode nil From 1de7e04cc82542a5d017b1c6519be5849caf1344 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 09:04:12 -0300 Subject: [PATCH 15/32] settings --- src/settings.lisp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 5f2844171..2cba0a564 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -7,6 +7,8 @@ :button-action :forward-button :insert-button) + (:import-from :lem-core/commands/window + :quit-active-window) (:export #:customize-variable #:customize-group #:defcustom @@ -145,11 +147,11 @@ (defun get-variable-value (var) (symbol-value (variable-name (ensure-variable var)))) -(defun set-variable-value (var value) - (alexandria:if-let (setter (variable-setter (ensure-variable var))) - (if setter - (funcall setter value var) - (setf (symbol-value (variable-name (ensure-variable var))) value)))) +(defun set-variable-value (var-designator value) + (let ((var (ensure-variable var-designator))) + (alexandria:if-let (setter (variable-setter var)) + (funcall setter value var) + (setf (symbol-value (variable-name var)) value)))) (defun reset-variable-value (var) (set-variable-value var (variable-default var))) @@ -191,11 +193,12 @@ (completion string actual-var-names))))) (find-variable (read-from-string variable-name)))) -(define-command reset-variable () () - (let ((variable (prompt-for-variable "Reset variable: "))) +(define-command reset-variable (var-designator) (:universal-nil) + (let ((variable (or (and var-designator (ensure-variable var-designator)) + (prompt-for-variable "Reset variable: ")))) (reset-variable-value variable))) -(define-command customize-variable (var-designator) (:universal-nil) +(define-command set-variable (var-designator) (:universal-nil) (let* ((variable (or (and var-designator (ensure-variable var-designator)) (prompt-for-variable "Customize variable: "))) (value (prompt-for-type-instance (variable-type variable) "Value: "))) @@ -213,7 +216,7 @@ (completion string actual-group-names))))) (find-group (read-from-string group-name)))) -(define-command customize-group (group-designator) (:universal-nil) +(define-command customize-group-with-menu (group-designator) (:universal-nil) (let* ((group (or (and group-designator (ensure-group group-designator)) (prompt-for-group "Customize group: "))) (variable (prompt-for-variable (format nil "Customize variable in ~a: " (group-name group)) @@ -231,8 +234,10 @@ (change-buffer-mode buffer 'settings-mode) buffer)) -(defun open-customize-variable-buffer (variable) - (let ((buf (make-settings-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) +(define-command customize-variable (var-designator) (:universal-nil) + (let* ((variable (or (and var-designator (ensure-variable var-designator)) + (prompt-for-variable "Customize variable: "))) + (buf (make-settings-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) (with-current-buffer buf (with-buffer-read-only buf nil (with-open-stream (stream (make-buffer-output-stream @@ -250,13 +255,13 @@ (write-string " " stream) (insert-button (current-point) "[Set]" (lambda () - (customize-variable variable)) + (set-variable variable)) :attribute 'settings-action-attribute) (write-string " " stream) (lem/button:insert-button (current-point) "[Reset]" (lambda () - (customize-variable variable)) + (reset-variable variable)) :attribute 'settings-action-attribute) (terpri stream) (terpri stream) From f7474eb68f81b7aeb5a56b644c55bf039cc95923 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 09:07:33 -0300 Subject: [PATCH 16/32] settings --- src/settings.lisp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 2cba0a564..0c176df69 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -159,14 +159,14 @@ (defgeneric %prompt-for-type-instance (type-discriminator type-arguments prompt &rest args)) (defmethod %prompt-for-type-instance ((type (eql 'string)) type-args prompt &rest args) - (lem-core::prompt-for-string prompt :initial-value (getf args :initial-value))) + (prompt-for-string prompt :initial-value (getf args :initial-value))) (defmethod %prompt-for-type-instance ((type (eql 'integer)) type-args prompt &rest args) - (lem-core::prompt-for-integer prompt :initial-value (getf args :initial-value))) + (prompt-for-integer prompt :initial-value (getf args :initial-value))) (defmethod %prompt-for-type-instance ((type (eql 'boolean)) type-args prompt &rest args) (declare (ignore args)) - (lem-core::prompt-for-y-or-n-p prompt)) + (prompt-for-y-or-n-p prompt)) (defun prompt-for-type-instance (type-spec prompt &rest args) "Prompt for an instance of TYPE-SPEC using PROMPT." @@ -268,7 +268,7 @@ (insert-string (current-point) (documentation-of variable) :attribute 'settings-docs-attribute) - (lem-core:switch-to-buffer buf)))))) + (switch-to-buffer buf)))))) (defun open-customize-group-buffer (group) (let ((buf (make-settings-buffer (format nil "*Customize group: ~a*" (group-name group))))) @@ -295,7 +295,7 @@ (terpri stream) (write-string (string (group-name subgroup)) stream))) - (lem-core:switch-to-buffer buf) + (switch-to-buffer buf) ))))) (define-major-mode settings-mode nil From 8172bc21a5932ccacff4463a9f0914a4bc0a3d9b Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 09:10:06 -0300 Subject: [PATCH 17/32] settings --- src/settings.lisp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings.lisp b/src/settings.lisp index 0c176df69..d1e1d9437 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -202,7 +202,7 @@ (let* ((variable (or (and var-designator (ensure-variable var-designator)) (prompt-for-variable "Customize variable: "))) (value (prompt-for-type-instance (variable-type variable) "Value: "))) - (set-variable-value variable value))) + (set-variable-value variable value))) (defun prompt-for-group (prompt &optional group-names) (let* ((actual-group-names (or group-names From 60d2708418aa5268749310442aa4e883793a433e Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 09:57:09 -0300 Subject: [PATCH 18/32] settings: refresh buffer --- src/settings.lisp | 67 ++++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index d1e1d9437..968a8238d 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -238,37 +238,44 @@ (let* ((variable (or (and var-designator (ensure-variable var-designator)) (prompt-for-variable "Customize variable: "))) (buf (make-settings-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) - (with-current-buffer buf + (labels ((render-buffer () + (with-current-buffer buf + (with-open-stream (stream (make-buffer-output-stream + (buffer-end-point buf))) + (write-string "Customize: " stream) + (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) + (write-string " in: " stream) + (insert-button (current-point) (string (group-name (group-of variable))) + (lambda () + (customize-group (group-of variable))) + :attribute 'document-link-attribute) + (terpri stream) + (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) + (insert-string (current-point) (prin1-to-string (get-variable-value variable)) :attribute 'settings-value-attribute) + (write-string " " stream) + (insert-button (current-point) "[Set]" + (lambda () + (set-variable variable) + (with-buffer-read-only buf nil + (erase-buffer buf) + (render-buffer))) + :attribute 'settings-action-attribute) + (write-string " " stream) + (lem/button:insert-button + (current-point) "[Reset]" + (lambda () + (reset-variable variable) + (with-buffer-read-only buf nil + (erase-buffer buf) + (render-buffer))) + :attribute 'settings-action-attribute) + (terpri stream) + (terpri stream) + (insert-string (current-point) (documentation-of variable) + :attribute 'settings-docs-attribute))))) (with-buffer-read-only buf nil - (with-open-stream (stream (make-buffer-output-stream - (buffer-end-point buf))) - (write-string "Customize: " stream) - (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) - (write-string " in: " stream) - (insert-button (current-point) (string (group-name (group-of variable))) - (lambda () - (customize-group (group-of variable))) - :attribute 'document-link-attribute) - (terpri stream) - (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) - (insert-string (current-point) (prin1-to-string (get-variable-value variable)) :attribute 'settings-value-attribute) - (write-string " " stream) - (insert-button (current-point) "[Set]" - (lambda () - (set-variable variable)) - :attribute 'settings-action-attribute) - (write-string " " stream) - (lem/button:insert-button - (current-point) "[Reset]" - (lambda () - (reset-variable variable)) - :attribute 'settings-action-attribute) - (terpri stream) - (terpri stream) - (insert-string (current-point) (documentation-of variable) - :attribute 'settings-docs-attribute) - - (switch-to-buffer buf)))))) + (render-buffer)) + (switch-to-buffer buf)))) (defun open-customize-group-buffer (group) (let ((buf (make-settings-buffer (format nil "*Customize group: ~a*" (group-name group))))) From 33e8b1203d8803973afedc22947409fb3bfaf194 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 11:24:23 -0300 Subject: [PATCH 19/32] settings --- src/settings.lisp | 116 +++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 48 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 968a8238d..95276c2b6 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -71,7 +71,6 @@ :initform (error "Provide the group name") :documentation "The group name") (group :initarg :group - :accessor group-of :type (or null symbol) :initform nil :documentation "The parent group of this group. If it is NIL, then this is a top-level group.") @@ -82,20 +81,23 @@ :documentation "The group documentation"))) (defmethod group-of ((var custom-variable)) - (find-group (slot-value var 'group))) + (find-group (slot-value var 'group) nil)) + +(defmethod group-of ((group custom-group)) + (find-group (slot-value group 'group) nil)) ;; TODO: perhaps rethink this implementation: variables and groups could form a graph with ;; actual references stored in the CLOS object slots (parent, group, members, etc). (defun group-variables (group) (remove-if-not (lambda (var) - (eql (group-of var) (group-name group))) + (eq (group-of var) group)) (alexandria:hash-table-values *custom-vars*))) ;; TODO: perhaps rethink this implementation: variables and groups could form a graph with ;; actual references stored in the CLOS object slots (parent, group, members, etc). (defun subgroups (group) (remove-if-not (lambda (g) - (eql (group-of g) (group-name group))) + (eq (group-of g) group)) (alexandria:hash-table-values *custom-groups*))) (defmacro defcustom (symbol default doc &rest args) @@ -239,58 +241,73 @@ (prompt-for-variable "Customize variable: "))) (buf (make-settings-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) (labels ((render-buffer () - (with-current-buffer buf - (with-open-stream (stream (make-buffer-output-stream - (buffer-end-point buf))) - (write-string "Customize: " stream) - (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) - (write-string " in: " stream) - (insert-button (current-point) (string (group-name (group-of variable))) - (lambda () - (customize-group (group-of variable))) - :attribute 'document-link-attribute) - (terpri stream) - (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) - (insert-string (current-point) (prin1-to-string (get-variable-value variable)) :attribute 'settings-value-attribute) - (write-string " " stream) - (insert-button (current-point) "[Set]" - (lambda () - (set-variable variable) - (with-buffer-read-only buf nil - (erase-buffer buf) - (render-buffer))) - :attribute 'settings-action-attribute) - (write-string " " stream) - (lem/button:insert-button - (current-point) "[Reset]" - (lambda () - (reset-variable variable) - (with-buffer-read-only buf nil - (erase-buffer buf) - (render-buffer))) - :attribute 'settings-action-attribute) - (terpri stream) - (terpri stream) - (insert-string (current-point) (documentation-of variable) - :attribute 'settings-docs-attribute))))) - (with-buffer-read-only buf nil - (render-buffer)) + (with-buffer-read-only buf nil + (erase-buffer buf) + (with-current-buffer buf + (with-open-stream (stream (make-buffer-output-stream + (buffer-end-point buf))) + (write-string "Customize: " stream) + (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) + (write-string " in: " stream) + (insert-button (current-point) (string (group-name (group-of variable))) + (lambda () + (customize-group (group-of variable))) + :attribute 'document-link-attribute) + (terpri stream) + (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) + (insert-button (current-point) + (prin1-to-string (get-variable-value variable)) + (lambda () + (lem-lisp-mode/inspector:lisp-inspect (prin1-to-string (variable-name variable)))) + :attribute 'settings-value-attribute) + (write-string " " stream) + (insert-button (current-point) "[Set]" + (lambda () + (set-variable variable) + (render-buffer)) + :attribute 'settings-action-attribute) + (write-string " " stream) + (lem/button:insert-button + (current-point) "[Reset]" + (lambda () + (reset-variable variable) + (render-buffer)) + :attribute 'settings-action-attribute) + (terpri stream) + (terpri stream) + (insert-string (current-point) (documentation-of variable) + :attribute 'settings-docs-attribute)))))) + (render-buffer) (switch-to-buffer buf)))) -(defun open-customize-group-buffer (group) - (let ((buf (make-settings-buffer (format nil "*Customize group: ~a*" (group-name group))))) +(define-command customize-group (group-designator) (:universal-nil) + (let* ((group (or (and group-designator (ensure-group group-designator)) + (prompt-for-group "Customize group: "))) + (buf (make-settings-buffer (format nil "*Customize group: ~a*" (group-name group))))) (with-current-buffer buf - (with-buffer-read-only buf nil + (with-buffer-read-only buf nil + (erase-buffer buf) (with-open-stream (stream (make-buffer-output-stream (buffer-end-point buf))) (write-string "Customize group: " stream) - (prin1 (group-name group) stream) + (insert-string (current-point) (string (group-name group)) + :attribute 'document-bold-attribute) + (when (group-of group) + (write-string " in: " stream) + (insert-button (current-point) (string (group-name (group-of group))) + (lambda () + (customize-group (group-of group))) + :attribute 'document-link-attribute)) (terpri stream) (terpri stream) (write-string (documentation-of group) stream) (terpri stream) (dolist (var (group-variables group)) (terpri stream) - (prin1 (variable-name var) stream) + (insert-button (current-point) + (string (variable-name var)) + (lambda () + (customize-variable var)) + :attribute 'document-link-attribute) (write-string " - " stream) (write-string (documentation-of var) stream)) @@ -300,10 +317,13 @@ (terpri stream) (dolist (subgroup (subgroups group)) (terpri stream) - (write-string (string (group-name subgroup)) stream))) + (insert-button (current-point) + (string (group-name subgroup)) + (lambda () + (customize-group subgroup)) + :attribute 'document-link-attribute)))))) - (switch-to-buffer buf) - ))))) + (switch-to-buffer buf))) (define-major-mode settings-mode nil (:name "settings" From 9f3aa4cb76e3d1a3ee238e4c53486c0538e23f17 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 11:33:25 -0300 Subject: [PATCH 20/32] settings: customize top-level group --- src/settings.lisp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/settings.lisp b/src/settings.lisp index 95276c2b6..14ef9c5f0 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -325,6 +325,14 @@ (switch-to-buffer buf))) +(lem/settings:defgroup lem + () + "Top-level Lem settings." + ) + +(define-command customize () () + (customize-group 'lem)) + (define-major-mode settings-mode nil (:name "settings" :keymap *settings-keymap*) From 8635ff5122330a54b8d840121c8e7431d75e2f59 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 12:24:55 -0300 Subject: [PATCH 21/32] settings: save variable --- src/settings.lisp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/settings.lisp b/src/settings.lisp index 14ef9c5f0..f712be1ae 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -236,6 +236,13 @@ (change-buffer-mode buffer 'settings-mode) buffer)) +(define-command save-variable (var-designator) (:universal-nil) + (let ((variable (or (and var-designator (ensure-variable var-designator)) + (prompt-for-variable "Save variable: ")))) + (setf (config (variable-name variable)) + (get-variable-value variable)) + (message "~s saved" (variable-name variable)))) + (define-command customize-variable (var-designator) (:universal-nil) (let* ((variable (or (and var-designator (ensure-variable var-designator)) (prompt-for-variable "Customize variable: "))) @@ -273,6 +280,12 @@ (reset-variable variable) (render-buffer)) :attribute 'settings-action-attribute) + (write-string " " stream) + (lem/button:insert-button + (current-point) "[Save]" + (lambda () + (save-variable variable)) + :attribute 'settings-action-attribute) (terpri stream) (terpri stream) (insert-string (current-point) (documentation-of variable) From 7888eebf1324e19c8567d2588e02b0a130b67bf7 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 12:31:34 -0300 Subject: [PATCH 22/32] settings: save and load variables --- src/settings.lisp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/settings.lisp b/src/settings.lisp index f712be1ae..cf3f6a18d 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -243,6 +243,14 @@ (get-variable-value variable)) (message "~s saved" (variable-name variable)))) +(define-command load-variable (var-designator) (:universal-nil) + (let* ((variable (or (and var-designator (ensure-variable var-designator)) + (prompt-for-variable "Load variable: "))) + (not-saved (gensym)) + (value (config (variable-name variable) not-saved))) + (unless (eq value not-saved) + (set-variable-value variable value)))) + (define-command customize-variable (var-designator) (:universal-nil) (let* ((variable (or (and var-designator (ensure-variable var-designator)) (prompt-for-variable "Customize variable: "))) @@ -260,7 +268,7 @@ (lambda () (customize-group (group-of variable))) :attribute 'document-link-attribute) - (terpri stream) + (terpri stream) (terpri stream) (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) (insert-button (current-point) (prin1-to-string (get-variable-value variable)) From 6291802c5f35caad10297ea9c7241dd4d8c80511 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 13:30:56 -0300 Subject: [PATCH 23/32] settings: hook for loading variables --- src/settings.lisp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/settings.lisp b/src/settings.lisp index cf3f6a18d..0da209568 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -158,6 +158,12 @@ (defun reset-variable-value (var) (set-variable-value var (variable-default var))) +(defun list-variables () + (alexandria:hash-table-values *custom-vars*)) + +(defun list-groups () + (alexandria:hash-table-values *custom-groups*)) + (defgeneric %prompt-for-type-instance (type-discriminator type-arguments prompt &rest args)) (defmethod %prompt-for-type-instance ((type (eql 'string)) type-args prompt &rest args) @@ -373,4 +379,12 @@ (or (forward-button p) (progn (buffer-start p) - (forward-button p))))) \ No newline at end of file + (forward-button p))))) + +(defun load-variables () + "Load the value of variables from disk." + (dolist (var (list-variables)) + (load-variable var))) + +;; Load the value of saved variables after initialization +(lem/common/hooks:add-hook lem-core:*after-init-hook* #'load-variables) \ No newline at end of file From 312fcd4d848aa044cf3779a00bf62e7d9374dc3b Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 14:51:26 -0300 Subject: [PATCH 24/32] settings: conversions of defvar --- src/settings.lisp | 65 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/settings.lisp b/src/settings.lisp index 0da209568..68b9d11f1 100644 --- a/src/settings.lisp +++ b/src/settings.lisp @@ -352,11 +352,6 @@ (switch-to-buffer buf))) -(lem/settings:defgroup lem - () - "Top-level Lem settings." - ) - (define-command customize () () (customize-group 'lem)) @@ -387,4 +382,62 @@ (load-variable var))) ;; Load the value of saved variables after initialization -(lem/common/hooks:add-hook lem-core:*after-init-hook* #'load-variables) \ No newline at end of file +(lem/common/hooks:add-hook lem-core:*after-init-hook* #'load-variables) + +;; Lift existing defvar in Lem modules, to custom-variables +(defun customize-defvar (name group &key type documentation) + (let ((vartype (or type (type-of (symbol-value name))))) + (unless (typep (symbol-value name) type) + (error "~a value (~s) is not of type ~a" name (symbol-value name) type)) + (setf (gethash name *custom-vars*) + (make-instance 'custom-variable + :name name + :type vartype + :group group + :default (symbol-value name) + :documentation (or documentation (documentation name 'variable)))))) + +(defgroup lem + () + "Top-level Lem settings." + ) + +(defgroup files + () + "Files settings." + :group lem) + +(customize-defvar 'lem-core/commands/file::*find-program-timeout* + 'files + :type 'integer) + +(defgroup gui + () + "GUI settings." + :group lem) + +(customize-defvar 'lem/popup-window::*extra-right-margin* + 'gui + :type 'integer :documentation "Extra right margin for popup windows.") +(customize-defvar 'lem/popup-window::*extra-width-margin* + 'gui + :type 'integer :documentation "Extra width margin for popup windows.") +(customize-defvar 'lem/prompt-window::*prompt-completion-window-shape* 'gui + :type '(member nil :drop-curtain) + :documentation "Shape of prompt completion windows.") +(customize-defvar 'lem/prompt-window::*prompt-completion-window-gravity* 'gui + :type '(member :center :top-display :bottom-display :top + :topright :cursor :follow-cursor :mouse-cursor + :vertically-adjacent-window + :vertically-adjacent-window-dynamic + :horizontally-adjacent-window + :horizontally-above-window)) +(defgroup grep + () + "Grep settings" + :group lem) + +(customize-defvar 'lem/grep:*grep-command* 'grep + :type 'string :documentation "Grep command") +(customize-defvar 'lem/grep:*grep-args* 'grep + :type 'string :documentation "Grep arguments") \ No newline at end of file From 588d7f5b9a969f56be6228d00da6fed4552bfd24 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 14:57:43 -0300 Subject: [PATCH 25/32] settings: rename to customize --- src/{settings.lisp => customize.lisp} | 58 +++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) rename src/{settings.lisp => customize.lisp} (92%) diff --git a/src/settings.lisp b/src/customize.lisp similarity index 92% rename from src/settings.lisp rename to src/customize.lisp index 68b9d11f1..d379146af 100644 --- a/src/settings.lisp +++ b/src/customize.lisp @@ -1,6 +1,6 @@ ;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Customization.html -(defpackage :lem/settings +(defpackage :lem/customize (:use :cl :lem-core) (:import-from :lem/button :button-at @@ -17,17 +17,17 @@ #:find-variable #:find-group)) -(in-package :lem/settings) +(in-package :lem/customize) -(define-attribute settings-label-attribute) +(define-attribute customize-label-attribute) -(define-attribute settings-value-attribute +(define-attribute customize-value-attribute (t :foreground :base0D :bold t)) -(define-attribute settings-action-attribute +(define-attribute customize-action-attribute (:dark :foreground :base09 :bold t)) -(define-attribute settings-docs-attribute) +(define-attribute customize-docs-attribute) (defvar *custom-vars* (make-hash-table) "map of customization variables.") @@ -237,9 +237,9 @@ (define-command apropos-custom-variable (pattern) (:universal-nil) (error "TODO")) -(defun make-settings-buffer (name &rest args) +(defun make-customize-buffer (name &rest args) (let ((buffer (apply #'make-buffer name args))) - (change-buffer-mode buffer 'settings-mode) + (change-buffer-mode buffer 'customize-mode) buffer)) (define-command save-variable (var-designator) (:universal-nil) @@ -260,7 +260,7 @@ (define-command customize-variable (var-designator) (:universal-nil) (let* ((variable (or (and var-designator (ensure-variable var-designator)) (prompt-for-variable "Customize variable: "))) - (buf (make-settings-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) + (buf (make-customize-buffer (format nil "*Customize variable: ~a*" (variable-name variable))))) (labels ((render-buffer () (with-buffer-read-only buf nil (erase-buffer buf) @@ -275,42 +275,42 @@ (customize-group (group-of variable))) :attribute 'document-link-attribute) (terpri stream) (terpri stream) - (insert-string (current-point) "Value: " :attribute 'settings-label-attribute) + (insert-string (current-point) "Value: " :attribute 'customize-label-attribute) (insert-button (current-point) (prin1-to-string (get-variable-value variable)) (lambda () (lem-lisp-mode/inspector:lisp-inspect (prin1-to-string (variable-name variable)))) - :attribute 'settings-value-attribute) + :attribute 'customize-value-attribute) (write-string " " stream) (insert-button (current-point) "[Set]" (lambda () (set-variable variable) (render-buffer)) - :attribute 'settings-action-attribute) + :attribute 'customize-action-attribute) (write-string " " stream) (lem/button:insert-button (current-point) "[Reset]" (lambda () (reset-variable variable) (render-buffer)) - :attribute 'settings-action-attribute) + :attribute 'customize-action-attribute) (write-string " " stream) (lem/button:insert-button (current-point) "[Save]" (lambda () (save-variable variable)) - :attribute 'settings-action-attribute) + :attribute 'customize-action-attribute) (terpri stream) (terpri stream) (insert-string (current-point) (documentation-of variable) - :attribute 'settings-docs-attribute)))))) + :attribute 'customize-docs-attribute)))))) (render-buffer) (switch-to-buffer buf)))) (define-command customize-group (group-designator) (:universal-nil) (let* ((group (or (and group-designator (ensure-group group-designator)) (prompt-for-group "Customize group: "))) - (buf (make-settings-buffer (format nil "*Customize group: ~a*" (group-name group))))) + (buf (make-customize-buffer (format nil "*Customize group: ~a*" (group-name group))))) (with-current-buffer buf (with-buffer-read-only buf nil (erase-buffer buf) @@ -355,21 +355,21 @@ (define-command customize () () (customize-group 'lem)) -(define-major-mode settings-mode nil - (:name "settings" - :keymap *settings-keymap*) +(define-major-mode customize-mode nil + (:name "customize" + :keymap *customize-keymap*) (setf (buffer-read-only-p (current-buffer)) t)) -(define-key *settings-keymap* "Return" 'settings-default-action) -(define-key *settings-keymap* "Tab" 'settings-forward-button) -(define-key *settings-keymap* "q" 'quit-active-window) -(define-key *settings-keymap* "M-q" 'quit-active-window) +(define-key *customize-keymap* "Return" 'customize-default-action) +(define-key *customize-keymap* "Tab" 'customize-forward-button) +(define-key *customize-keymap* "q" 'quit-active-window) +(define-key *customize-keymap* "M-q" 'quit-active-window) -(define-command settings-default-action () () +(define-command customize-default-action () () (let ((button (button-at (current-point)))) (when button (button-action button)))) -(define-command settings-forward-button () () +(define-command customize-forward-button () () (let ((p (current-point))) (or (forward-button p) (progn @@ -399,12 +399,12 @@ (defgroup lem () - "Top-level Lem settings." + "Top-level Lem customize." ) (defgroup files () - "Files settings." + "Files customize." :group lem) (customize-defvar 'lem-core/commands/file::*find-program-timeout* @@ -434,10 +434,10 @@ :horizontally-above-window)) (defgroup grep () - "Grep settings" + "Grep settings." :group lem) (customize-defvar 'lem/grep:*grep-command* 'grep :type 'string :documentation "Grep command") (customize-defvar 'lem/grep:*grep-args* 'grep - :type 'string :documentation "Grep arguments") \ No newline at end of file + :type 'string :documentation "Grep arguments") From 98869fa7c8c16bb2f9ffb8d321e81dfb463a4ab5 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 15:03:56 -0300 Subject: [PATCH 26/32] customize: print-object --- src/customize.lisp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/customize.lisp b/src/customize.lisp index d379146af..685f53871 100644 --- a/src/customize.lisp +++ b/src/customize.lisp @@ -64,6 +64,10 @@ :initform nil :documentation "The variable documentation"))) +(defmethod print-object ((var custom-variable) stream) + (print-unreadable-object (var stream :type t :identity t) + (format stream "~s" (variable-name var)))) + (defclass custom-group () ((name :initarg :name :accessor group-name @@ -80,6 +84,10 @@ :initform nil :documentation "The group documentation"))) +(defmethod print-object ((group custom-group) stream) + (print-unreadable-object (group stream :type t :identity t) + (format stream "~s" (group-name group)))) + (defmethod group-of ((var custom-variable)) (find-group (slot-value var 'group) nil)) From 17b82eb6fb9de07a275f453b03b6127294a90807 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 16:05:51 -0300 Subject: [PATCH 27/32] customize --- src/customize.lisp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/customize.lisp b/src/customize.lisp index 685f53871..0929a79eb 100644 --- a/src/customize.lisp +++ b/src/customize.lisp @@ -172,7 +172,8 @@ (defun list-groups () (alexandria:hash-table-values *custom-groups*)) -(defgeneric %prompt-for-type-instance (type-discriminator type-arguments prompt &rest args)) +(defgeneric %prompt-for-type-instance (type-discriminator type-arguments prompt &rest args) + (:documentation "This is the generic-function to extend to support more customization types.")) (defmethod %prompt-for-type-instance ((type (eql 'string)) type-args prompt &rest args) (prompt-for-string prompt :initial-value (getf args :initial-value))) @@ -217,7 +218,8 @@ (define-command set-variable (var-designator) (:universal-nil) (let* ((variable (or (and var-designator (ensure-variable var-designator)) (prompt-for-variable "Customize variable: "))) - (value (prompt-for-type-instance (variable-type variable) "Value: "))) + (value (prompt-for-type-instance (variable-type variable) "Value: " + :initial-value (get-variable-value variable)))) (set-variable-value variable value))) (defun prompt-for-group (prompt &optional group-names) @@ -308,10 +310,12 @@ (lambda () (save-variable variable)) :attribute 'customize-action-attribute) - (terpri stream) - (terpri stream) - (insert-string (current-point) (documentation-of variable) - :attribute 'customize-docs-attribute)))))) + (when (documentation-of variable) + (terpri stream) + (terpri stream) + (insert-string (current-point) (documentation-of variable) + :attribute 'customize-docs-attribute)) + ))))) (render-buffer) (switch-to-buffer buf)))) @@ -343,8 +347,9 @@ (lambda () (customize-variable var)) :attribute 'document-link-attribute) - (write-string " - " stream) - (write-string (documentation-of var) stream)) + (when (documentation-of var) + (write-string " - " stream) + (write-string (documentation-of var) stream))) (when (subgroups group) (terpri stream) (terpri stream) @@ -439,7 +444,8 @@ :vertically-adjacent-window :vertically-adjacent-window-dynamic :horizontally-adjacent-window - :horizontally-above-window)) + :horizontally-above-window) + :documentation ) (defgroup grep () "Grep settings." From 4ecd1a44374c0ce448465814ce9ae143c81712d3 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 16:39:26 -0300 Subject: [PATCH 28/32] customize: prompts --- src/customize.lisp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/customize.lisp b/src/customize.lisp index 0929a79eb..7946fb503 100644 --- a/src/customize.lisp +++ b/src/customize.lisp @@ -159,6 +159,8 @@ (defun set-variable-value (var-designator value) (let ((var (ensure-variable var-designator))) + (unless (typep value (variable-type var)) + (error "~s is not of type ~s" value (variable-type var))) (alexandria:if-let (setter (variable-setter var)) (funcall setter value var) (setf (symbol-value (variable-name var)) value)))) @@ -185,6 +187,30 @@ (declare (ignore args)) (prompt-for-y-or-n-p prompt)) +(defmethod %prompt-for-type-instance ((type t) type-args prompt &rest args) + ;; When TYPE is not recognized, prompt for a string, evaluate it, and use the result + (declare (ignore args)) + (let* ((source (lem-lisp-mode/internal:prompt-for-sexp (concatenate 'string prompt "(evaluated) "))) + (value (lem-lisp-mode/internal:lisp-eval-from-string + source + ;; fixme: use current variable name package + (LEM-LISP-MODE/INTERNAL:CURRENT-PACKAGE))) + (type-spec (if (null type-args) + type + (cons type type-args)))) + (unless (typep value type-spec) + (error "~s is not of type ~s" value type-spec)) + value)) + +(defmethod %prompt-for-type-instance ((type (eql 'member)) type-args prompt &rest args) + (let ((members-strs (mapcar #'prin1-to-string type-args))) + (let ((selection + (prompt-for-string prompt + :test-function (lambda (str) (< 0 (length str))) + :completion-function (lambda (string) + (completion string members-strs))))) + (read-from-string selection)))) + (defun prompt-for-type-instance (type-spec prompt &rest args) "Prompt for an instance of TYPE-SPEC using PROMPT." (let ((type-discriminator (if (listp type-spec) @@ -254,14 +280,14 @@ (define-command save-variable (var-designator) (:universal-nil) (let ((variable (or (and var-designator (ensure-variable var-designator)) - (prompt-for-variable "Save variable: ")))) + (prompt-for-variable "Save variable: ")))) (setf (config (variable-name variable)) (get-variable-value variable)) (message "~s saved" (variable-name variable)))) (define-command load-variable (var-designator) (:universal-nil) (let* ((variable (or (and var-designator (ensure-variable var-designator)) - (prompt-for-variable "Load variable: "))) + (prompt-for-variable "Load variable: "))) (not-saved (gensym)) (value (config (variable-name variable) not-saved))) (unless (eq value not-saved) From a4541bd1e14e624fa0adfbbc57d11145cbc1d66d Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 16:55:08 -0300 Subject: [PATCH 29/32] customize: fixes --- src/customize.lisp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/customize.lisp b/src/customize.lisp index 7946fb503..b81f19ebe 100644 --- a/src/customize.lisp +++ b/src/customize.lisp @@ -203,6 +203,7 @@ value)) (defmethod %prompt-for-type-instance ((type (eql 'member)) type-args prompt &rest args) + (declare (ignore args)) (let ((members-strs (mapcar #'prin1-to-string type-args))) (let ((selection (prompt-for-string prompt @@ -254,7 +255,7 @@ (alexandria:compose #'prin1-to-string #'group-name) (alexandria:hash-table-values *custom-groups*)))) (group-name - (prompt-for-string "Customize group: " + (prompt-for-string prompt :test-function (lambda (str) (< 0 (length str))) :completion-function (lambda (string) (completion string actual-group-names))))) @@ -271,6 +272,7 @@ (set-variable-value variable value))) (define-command apropos-custom-variable (pattern) (:universal-nil) + (declare (ignore pattern)) (error "TODO")) (defun make-customize-buffer (name &rest args) @@ -304,7 +306,11 @@ (with-open-stream (stream (make-buffer-output-stream (buffer-end-point buf))) (write-string "Customize: " stream) - (insert-string (current-point) (prin1-to-string (variable-name variable)) :attribute 'document-header1-attribute) + (insert-button (current-point) + (prin1-to-string (variable-name variable)) + (lambda () + (lem-lisp-mode/inspector:lisp-inspect (prin1-to-string (variable-name variable)) :self-evaluation t)) + :attribute 'document-header1-attribute) (write-string " in: " stream) (insert-button (current-point) (string (group-name (group-of variable))) (lambda () @@ -471,7 +477,7 @@ :vertically-adjacent-window-dynamic :horizontally-adjacent-window :horizontally-above-window) - :documentation ) + :documentation "Window gravity for prompt completion.") (defgroup grep () "Grep settings." From 90d3a797e6135cffce63e107ffa37c034ee254da Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 18:16:47 -0300 Subject: [PATCH 30/32] customize: TODO --- src/customize.lisp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/customize.lisp b/src/customize.lisp index b81f19ebe..baaf18bb1 100644 --- a/src/customize.lisp +++ b/src/customize.lisp @@ -1,4 +1,10 @@ +;; A customization system for Lem based on Emacs ;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Customization.html +;; Author: Mariano Montone + +;; TODO: +;; - Better lisp evaluation prompt (use correct package, etc). +;; - Adjustments to UI. Strip long documentation strings, etc. (defpackage :lem/customize (:use :cl :lem-core) From ececdc55f1d748e46bac4341bcc7b2b8e1a0c105 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 18:23:34 -0300 Subject: [PATCH 31/32] customize --- src/customize.lisp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/customize.lisp b/src/customize.lisp index baaf18bb1..66209f9d1 100644 --- a/src/customize.lisp +++ b/src/customize.lisp @@ -1,10 +1,12 @@ -;; A customization system for Lem based on Emacs +;; A customization system for Lem inspired by Emacs'es ;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Customization.html ;; Author: Mariano Montone ;; TODO: ;; - Better lisp evaluation prompt (use correct package, etc). ;; - Adjustments to UI. Strip long documentation strings, etc. +;; - Documentation strings. For commands specially. +;; - Implement apropos. (defpackage :lem/customize (:use :cl :lem-core) @@ -15,11 +17,13 @@ :insert-button) (:import-from :lem-core/commands/window :quit-active-window) - (:export #:customize-variable + (:export #:customize + #:customize-variable #:customize-group + #:reset-variable + #:set-variable #:defcustom #:defgroup - #:set-variable #:find-variable #:find-group)) From 08d1236cfa9eb9cf31fdce56a84b2b2fd49240f9 Mon Sep 17 00:00:00 2001 From: Mariano Montone Date: Wed, 9 Oct 2024 18:27:33 -0300 Subject: [PATCH 32/32] customize: kill buffers --- src/customize.lisp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/customize.lisp b/src/customize.lisp index 66209f9d1..e11d1ff55 100644 --- a/src/customize.lisp +++ b/src/customize.lisp @@ -15,8 +15,6 @@ :button-action :forward-button :insert-button) - (:import-from :lem-core/commands/window - :quit-active-window) (:export #:customize #:customize-variable #:customize-group @@ -415,10 +413,13 @@ :keymap *customize-keymap*) (setf (buffer-read-only-p (current-buffer)) t)) +(define-command kill-current-buffer () () + (LEM-CORE/COMMANDS/WINDOW:KILL-BUFFER (current-buffer))) + (define-key *customize-keymap* "Return" 'customize-default-action) (define-key *customize-keymap* "Tab" 'customize-forward-button) -(define-key *customize-keymap* "q" 'quit-active-window) -(define-key *customize-keymap* "M-q" 'quit-active-window) +(define-key *customize-keymap* "q" 'kill-current-buffer) +(define-key *customize-keymap* "M-q" 'kill-current-buffer) (define-command customize-default-action () () (let ((button (button-at (current-point))))