diff --git a/core/autoload/help.el b/core/autoload/help.el new file mode 100644 index 000000000..f492618f5 --- /dev/null +++ b/core/autoload/help.el @@ -0,0 +1,37 @@ +;;; ../core/autoload/help.el + +;;;###autoload +(defun doom/describe-setting (setting) + "Open the documentation of SETTING (a keyword defined with `def-setting!')." + (interactive + ;; TODO try to read setting from whole line + (let ((keyword (thing-at-point 'symbol t))) + (list (completing-read + (format "Describe setting%s: " + (if (equal (substring keyword 0 1) ":") + (format " (default %s)" keyword) + "")) + doom-settings + nil t nil nil keyword)))) + (let ((fn (intern-soft (format "doom-setting--setter%s" setting)))) + (unless fn + (error "'%s' is not a valid DOOM setting" setting)) + (describe-function fn))) + +;;;###autoload +(defun doom/describe-module (module) + "Open the documentation of MODULE (a string that represents the category and +submodule in the format, e.g. ':feature evil')." + (interactive + ;; TODO try to read module from whole line + (list (completing-read "Describe module: " + (mapcar (lambda (x) (format "%s %s" (car x) (cdr x))) + (reverse (hash-table-keys doom-modules))) + nil t))) + (destructuring-bind (category submodule) (mapcar #'intern (split-string module " ")) + (unless (member (cons category submodule) (doom--module-pairs)) + (error "'%s' isn't a valid module" module)) + (let ((doc-path (expand-file-name "README.org" (doom-module-path category submodule)))) + (unless (file-exists-p doc-path) + (error "There is no documentation for this module")) + (find-file doc-path)))) diff --git a/core/core-lib.el b/core/core-lib.el index 902dd3866..38ac70698 100644 --- a/core/core-lib.el +++ b/core/core-lib.el @@ -205,15 +205,19 @@ Body forms can access the hook's arguments through the let-bound variable ;; concise, do-what-I-mean front-facing configuration, believe it or not. ;; ;; Plus, it can benefit from byte-compilation. +(defvar doom-settings nil) + (defmacro def-setting! (keyword arglist &optional docstring &rest forms) "Define a setting macro. Like `defmacro', this should return a form to be executed when called with `set!'. FORMS are not evaluated until `set!' calls it." (declare (indent defun) (doc-string 3)) (unless (keywordp keyword) (error "Not a valid property name: %s" keyword)) - `(defun ,(intern (format "doom-setting--setter%s" keyword)) ,arglist - ,docstring - ,@forms)) + `(progn + (defun ,(intern (format "doom-setting--setter%s" keyword)) ,arglist + ,docstring + ,@forms) + (cl-pushnew ,keyword doom-settings))) (defmacro set! (keyword &rest values) "Set an option defined by `def-setting!'. Skip if doesn't exist."