ledger-check.el (5330B)
1 ;;; ledger-check.el --- Helper code for use with the "ledger" command-line tool -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2015 Craig Earls (enderw88 AT gmail DOT com) 4 5 ;; This file is not part of GNU Emacs. 6 7 ;; This is free software; you can redistribute it and/or modify it under 8 ;; the terms of the GNU General Public License as published by the Free 9 ;; Software Foundation; either version 2, or (at your option) any later 10 ;; version. 11 ;; 12 ;; This is distributed in the hope that it will be useful, but WITHOUT 13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 ;; for more details. 16 ;; 17 ;; You should have received a copy of the GNU General Public License 18 ;; along with GNU Emacs; see the file COPYING. If not, write to the 19 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 20 ;; MA 02110-1301 USA. 21 22 ;;; Commentary: 23 ;; Provide secial mode to correct errors in ledger when running with --strict and --explicit 24 ;; 25 ;; Adapted to ledger mode by Craig Earls <enderw88 at gmail dot com> 26 27 ;;; Code: 28 29 (require 'easymenu) 30 (require 'ledger-navigate) 31 (require 'ledger-report) ; for ledger-master-file 32 33 34 (defvar ledger-check-buffer-name "*Ledger Check*") 35 (defvar-local ledger-check--original-window-configuration nil) 36 37 38 39 40 (defvar ledger-check-mode-map 41 (let ((map (make-sparse-keymap))) 42 (define-key map (kbd "RET") #'ledger-report-visit-source) 43 (define-key map (kbd "q") #'ledger-check-quit) 44 map) 45 "Keymap for `ledger-check-mode'.") 46 47 (easy-menu-define ledger-check-mode-menu ledger-check-mode-map 48 "Ledger check menu." 49 '("Check" 50 ;; ["Re-run Check" ledger-check-redo] 51 "---" 52 ["Visit Source" ledger-report-visit-source] 53 "---" 54 ["Quit" ledger-check-quit] 55 )) 56 57 (define-derived-mode ledger-check-mode text-mode "Ledger-Check" 58 "A mode for viewing ledger errors and warnings.") 59 60 61 (defun ledger-do-check () 62 "Run a check command ." 63 (goto-char (point-min)) 64 (let ((data-pos (point)) 65 (have-warnings nil)) 66 (shell-command 67 ;; ledger balance command will just return empty if you give it 68 ;; an account name that doesn't exist. I will assume that no 69 ;; one will ever have an account named "e342asd2131". If 70 ;; someones does, this will probably still work for them. 71 ;; I should only highlight error and warning lines. 72 "ledger bal e342asd2131 --strict --explicit " 73 t nil) 74 (goto-char data-pos) 75 76 ;; format check report to make it navigate the file 77 78 (while (re-search-forward "^.*: \"\\(.*\\)\", line \\([0-9]+\\)" nil t) 79 (let ((file (match-string 1)) 80 (line (string-to-number (match-string 2)))) 81 (when file 82 (set-text-properties (line-beginning-position) (line-end-position) 83 (list 'ledger-source (cons file (save-window-excursion 84 (save-excursion 85 (find-file file) 86 (widen) 87 (ledger-navigate-to-line line) 88 (point-marker)))))) 89 (add-text-properties (line-beginning-position) (line-end-position) 90 (list 'font-lock-face 'ledger-font-report-clickable-face)) 91 (setq have-warnings 'true) 92 (end-of-line)))) 93 (if (not have-warnings) 94 (insert "No errors or warnings reported.")))) 95 96 (defun ledger-check-goto () 97 "Goto the ledger check buffer." 98 (interactive) 99 (let ((rbuf (get-buffer ledger-check-buffer-name))) 100 (if (not rbuf) 101 (error "There is no ledger check buffer")) 102 (pop-to-buffer rbuf) 103 (shrink-window-if-larger-than-buffer))) 104 105 (defun ledger-check-quit () 106 "Quit the ledger check buffer." 107 (interactive) 108 (ledger-check-goto) 109 (set-window-configuration ledger-check--original-window-configuration) 110 (kill-buffer (get-buffer ledger-check-buffer-name))) 111 112 (defun ledger-check-buffer (&optional interactive) 113 "Check the current buffer for errors. 114 115 Runs ledger with --explicit and --strict report errors and assist 116 with fixing them. 117 118 The output buffer will be in `ledger-check-mode', which defines 119 commands for navigating the buffer to the errors found, etc. 120 121 When INTERACTIVE is non-nil (i.e., when called interactively), 122 prompt to save if the current buffer is modified." 123 (interactive "p") 124 (when (and interactive 125 (buffer-modified-p) 126 (y-or-n-p "Buffer modified, save it? ")) 127 (save-buffer)) 128 (let ((_buf (find-file-noselect (ledger-master-file))) 129 (cbuf (get-buffer ledger-check-buffer-name)) 130 (wcfg (current-window-configuration))) 131 (if cbuf 132 (kill-buffer cbuf)) 133 (with-current-buffer 134 (pop-to-buffer (get-buffer-create ledger-check-buffer-name)) 135 (ledger-check-mode) 136 (setq ledger-check--original-window-configuration wcfg) 137 (ledger-do-check) 138 (shrink-window-if-larger-than-buffer) 139 (set-buffer-modified-p nil) 140 (setq buffer-read-only t) 141 (message "q to quit; r to redo; k to kill")))) 142 143 144 (provide 'ledger-check) 145 146 ;;; ledger-check.el ends here