;;; comint-ledger.el --- Command interpreter for the Ledger CLI -*- lexical-binding: t; -*- ;; Author: Bram Schoenmakers ;; URL: https://apps.bram85.nl/git/bram/comint-ledger ;; Version: 0.1 ;; Keywords: processes ;; Package-Requires: ((emacs "28.1")) ;;; This file is NOT part of GNU Emacs ;;; Commentary: ;; ;; Command interpreter (comint) for the Ledger CLI tool. ;; Starting point for this mode is Mickey Petersen's article on writing comint modes. ;; ;; https://www.masteringemacs.org/article/comint-writing-command-interpreter ;; ;;; Code: (require 'comint) (defvar ledger-cli-path (executable-find "ledger") "Path to the program used by `run-ledger'.") (defvar ledger-file-path nil "Path to the ledger data file.") (defvar ledger-cli-arguments '() "Commandline arguments to pass to `ledger'.") (defvar ledger-mode-map (let ((map (nconc (make-sparse-keymap) comint-mode-map))) ;; example definition (define-key map "\t" 'completion-at-point) map) "Basic mode map for `run-ledger'.") (defvar ledger-prompt-regexp (rx bol "] ") "Prompt for `run-ledger'.") (defvar ledger-buffer-name "*Ledger*" "Name of the buffer to use for the `run-ledger' comint instance.") ;;;###autoload (defun run-ledger () "Run an inferior instance of `ledger' inside Emacs." (interactive) (let* ((ledger-program ledger-cli-path) (ledger-file-arguments (list "-f" ledger-file-path)) (ledger-arguments (append ledger-file-arguments ledger-cli-arguments)) (buffer (get-buffer-create ledger-buffer-name)) (proc-alive (comint-check-proc buffer))) ;; if the process is dead then re-create the process and reset the ;; mode. (unless proc-alive (with-current-buffer buffer (apply 'make-comint-in-buffer "Ledger" buffer ledger-program nil ledger-arguments) (comint-ledger-mode))) ;; Regardless, provided we have a valid buffer, we pop to it. (when buffer (pop-to-buffer buffer)))) (defun ledger--initialize () "Helper function to initialize ledger." (setq comint-process-echoes t) (setq comint-use-prompt-regexp t)) (define-derived-mode comint-ledger-mode comint-mode "comint-ledger" "Major mode for `run-ledger'. \\" ;; this sets up the prompt so it matches things like: [foo@bar] (setq comint-prompt-regexp ledger-prompt-regexp) ;; this makes it read only; a contentious subject as some prefer the ;; buffer to be overwritable. (setq comint-prompt-read-only t) ;; this makes it so commands like M-{ and M-} work. (set (make-local-variable 'paragraph-separate) "\\'") (set (make-local-variable 'font-lock-defaults) '(ledger-font-lock-keywords t)) (set (make-local-variable 'paragraph-start) ledger-prompt-regexp)) (add-hook 'ledger-mode-hook 'ledger--initialize) (defconst ledger-keywords '() "List of keywords to highlight in `ledger-font-lock-keywords'.") (defvar ledger-font-lock-keywords (list ;; highlight all the reserved commands. `(,(concat "\\_<" (regexp-opt ledger-keywords) "\\_>") . font-lock-keyword-face)) "Additional expressions to highlight in `comint-ledger-mode'.") (provide 'comint-ledger) ;;; comint-ledger.el ends here