SkillAgentSearch skills...

Leaf.el

Flexible, declarative, and modern init.el package configuration

Install / Use

/learn @conao3/Leaf.el
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

img img img img img img img img img img

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! Now leaf builtin)

;; <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: default plstore stored variable
  • leaf-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
View on GitHub
GitHub Stars551
CategoryDevelopment
Updated13d ago
Forks27

Languages

Emacs Lisp

Security Score

95/100

Audited on Mar 21, 2026

No findings