Chezmoi and Emacs

Chezmoi and Emacs

September 11, 2021 | emacs, dotfiles


I’ve recently wanted to integrate Chezmoi with Emacs, so I can avoid switching to the terminal or eshell whenever I needed Chezmoi. I’ve searched for a few Emacs and Chezmoi integration and I found this. However, I wanted to play a bit with Elisp, so I decided to write my own.

The code is still a work-in-progress, but I already have the basic functionality set up.

chezmoi.el provides three functions: apply, edit and diff – all three run asynchronously. All logs and diffs are stored in the *chezmoi* buffer. Further, chezmoi-mode is a minor-mode that sets up keybindings for all three functions.

The following variables are available: chezmoi-bin, chezmoi-apply and chezmoi-edit.

;;; chezmoi.el --- Handle chezmoi configuration -*- lexical-binding: t -*-
;;
;;; Author: Ben Mezger
;; https://github.com/benmezger
;;
;;; Commentary:
;; Work in progress.
;;
;;; Code:

(defvar chezmoi-bin "chezmoi"
  "Path to chezmoi's binary.")

(defvar chezmoi-flags "--color false -v --force -i noscripts"
  "Flags to pass to chezmoi in every run.")

(defun chezmoi-apply()
  "Run chezmoi apply without running scripts."
  (interactive)
  (apply 'start-process
         "chezmoi" "*chezmoi*"
         chezmoi-bin "apply" (split-string chezmoi-flags " "))
  (with-current-buffer "*chezmoi*"
    (diff-mode)))

(defun chezmoi-diff()
  "Run chezmoi diff."
  (interactive)
  (message "Running chezmoi diff...")
  (apply 'start-process
         "chezmoi" "*chezmoi*"
         chezmoi-bin "diff" (split-string chezmoi-flags " "))
  (with-current-buffer "*chezmoi*"
    (diff-mode)
    (read-only-mode)))

(defun chezmoi-edit()
  "Edit a chezmoi file."
  (interactive)
  (ivy-read "File: "
            (process-lines chezmoi-bin "managed")
            :require-match t
            :action
            (lambda (n)
              (find-file
               (nth 0 (process-lines
                       chezmoi-bin "source-path"
                       (expand-file-name (concat "~/" n))))))))

(define-minor-mode chezmoi-mode
  "Enable chezmoi functionality."
  :lighter " chezmoi"
  :keymap (let ((map (make-sparse-keymap)))
            (define-key map (kbd "C-c A") 'chezmoi-apply)
            (define-key map (kbd "C-c E") 'chezmoi-edit)
            (define-key map (kbd "C-c D") 'chezmoi-diff)
            map))

(provide 'chezmoi)

;;; chezmoi.el ends here

TODOs #

These are things I want to implement.

TODO Open *chezmoi* buffer as a popup buffer #

TODO Differentiate between .tmpl files, similar to diff-mode, magit, etc #

TODO Open Chezmoi configuration function #


Go to random page