Leaf.el
Flexible, declarative, and modern init.el package configuration
Install / Use
/learn @conao3/Leaf.elREADME
- Description
- Install
- Usage
- Customize
- Syntax
- Basic keywords
- Configure variables keywords
- Configure list keywords
- Condition keywords
- Byte compile keywords
- Documentation keywords
- Misc keywords
- System keywords
- Tips
- Information
Description
leaf.el is yet another use-package.
leaf solves the stress that I feel while using the use-package for 2.5 years. By developing from scratch, we have a cleaner and more predictable implementation than use-package.
This makes it easy to maintain and add new keywords. (see leaf-keywords.el)
leaf has keywords almost identical to use-package, but some of usage of the keywords is different.
The quickest way to solve problem is using macroexpand-1 to see the unfolded result if it is not what you intended. And also there are also a number of samples in this README and more in the test file.
Currently, leaf.el and leaf-keywords.el has below rich keywords.
(leaf-available-keywords)
;;=> (:disabled
;; :leaf-protect
;; :load-path :load-path*
;; :leaf-autoload
;; :doc :req :tag :file :url
;; :defun :defvar :leaf-defun :leaf-defvar
;; :preface
;; :when :unless :if
;; :emacs< :emacs<= :emacs= :emacs> :emacs>=
;; :ensure :package :vc :feather :straight :el-get
;; :after
;; :commands
;; :bind :bind*
;; :mode :interpreter :magic :magic-fallback
;; :hook
;; :advice :advice-remove
;; :init
;; :pre-setq :pl-pre-setq :auth-pre-setq
;; :custom :custom* :pl-custom :auth-custom :custom-face
;; :require
;; :hydra :transient :combo :combo*
;; :smartrep :smartrep* :chord :chord*
;; :mode-hook
;; :leaf-defer
;; :config
;; :diminish :delight
;; :global-minor-mode
;; :setq :setq-default
;; :pl-setq :auth-setq :pl-setq-default :auth-setq-default)
Install
leaf.el and leaf-keywords.el can install with package.el from MELPA.
Please put the following code (<leaf-install-code> to </leaf-install-code>) to the top of your init.el.
Package to be developed
-
feather.el instead of
package.el-> (Achieved! Now available but it is just a package.el wraper) -
leaf-key.el instead of
bind-key-> (Achieved! Nowleafbuiltin)
;; <leaf-install-code>
(eval-and-compile
(customize-set-variable
'package-archives '(("org" . "https://orgmode.org/elpa/")
("melpa" . "https://melpa.org/packages/")
("gnu" . "https://elpa.gnu.org/packages/")))
(package-initialize)
(unless (package-installed-p 'leaf)
(package-refresh-contents)
(package-install 'leaf))
(leaf leaf-keywords
:ensure t
:init
;; optional packages if you want to use :hydra, :el-get, :blackout,,,
(leaf hydra :ensure t)
(leaf el-get :ensure t)
(leaf blackout :ensure t)
:config
;; initialize leaf-keywords.el
(leaf-keywords-init)))
;; </leaf-install-code>
;; Now you can use leaf!
(leaf leaf-tree :ensure t)
(leaf leaf-convert :ensure t)
(leaf transient-dwim
:ensure t
:bind (("M-=" . transient-dwim-dispatch)))
;; You can also configure builtin package via leaf!
(leaf cus-start
:doc "define customization properties of builtins"
:tag "builtin" "internal"
:custom ((user-full-name . "Naoya Yamashita")
(user-mail-address . "conao3@gmail.com")
(user-login-name . "conao3")
(truncate-lines . t)
(menu-bar-mode . t)
(tool-bar-mode . nil)
(scroll-bar-mode . nil)
(indent-tabs-mode . nil)))
(leaf autorevert
:doc "revert buffers when files on disk change"
:tag "builtin"
:custom ((auto-revert-interval . 0.1))
:global-minor-mode global-auto-revert-mode)
;; Nest package configurations
(leaf flycheck
:doc "On-the-fly syntax checking"
:emacs>= 24.3
:ensure t
:bind (("M-n" . flycheck-next-error)
("M-p" . flycheck-previous-error))
:custom ((flycheck-emacs-lisp-initialize-packages . t))
:hook (emacs-lisp-mode-hook lisp-interaction-mode-hook)
:config
(leaf flycheck-package
:doc "A Flycheck checker for elisp package authors"
:ensure t
:config
(flycheck-package-setup))
(leaf flycheck-elsa
:doc "Flycheck for Elsa."
:emacs>= 25
:ensure t
:config
(flycheck-elsa-setup))
;; ...
)
;; ...
Usage
Use leaf in your init.el like use-package.
You declaratively tell the leaf to configure the package using special keywords.
leaf converts your declaration into Elisp for Emacs to understand, and Emacs executes it to configure the package.
Customize
leaf-defaults: Default arguments for all leaf-block.leaf-expand-{{keyword}}: If nil, not to expand that keyword.leaf-expand-minimally: If nil, disable keywords that are not needed for debugging.leaf-default-plstore: defaultplstorestored variableleaf-alias-keyword-alist: Alist represents keyword alias. Handle KEY is alias of VALUE.
(defcustom leaf-alias-keyword-alist '((:ensure . :package))
"The alias keyword. KEY is treated as an alias for VALUE."
:type 'sexp
:group 'leaf)
This default value means :ensure is alias :package.
If you want to use :ensure as :feather, please set this value as ((:ensure . :feather)). Please more info related feather is here.
Syntax
All below examples are excerpts from leaf-tests.el.
These examples are defined in the following format. We expect FORM will be expanded to EXPECT.
(cort-deftest-with-macroexpand TESTCASE-NAME
'((FORM ; will be expand by `macroexpand-1'
EXPECT) ; expect FORM's expansion will be EXPECT (test by `equal')
(FORM

