1 84b5784c 2018-03-11 rnkn ;;; side-notes.el --- Easy access to a directory notes file -*- lexical-binding: t; -*-
3 96a142df 2024-06-29 rnkn ;; Copyright (c) 2019-2024 Paul W. Rankin
5 96a142df 2024-06-29 rnkn ;; Author: Paul W. Rankin <rnkn@rnkn.xyz>
6 84b5784c 2018-03-11 rnkn ;; Keywords: convenience
7 452378c6 2021-01-31 rnkn ;; Version: 0.4.1
8 578d0782 2021-02-01 rnkn ;; Package-Requires: ((emacs "24.4"))
9 f8d1e63d 2019-07-15 rnkn ;; URL: https://github.com/rnkn/side-notes
11 e2000753 2019-09-03 rnkn ;; This file is not part of GNU Emacs.
13 84b5784c 2018-03-11 rnkn ;; This program is free software; you can redistribute it and/or modify
14 84b5784c 2018-03-11 rnkn ;; it under the terms of the GNU General Public License as published by
15 e2000753 2019-09-03 rnkn ;; the Free Software Foundation, either version 3 of the License, or (at
16 e2000753 2019-09-03 rnkn ;; your option) any later version.
18 e2000753 2019-09-03 rnkn ;; This program is distributed in the hope that it will be useful, but
19 e2000753 2019-09-03 rnkn ;; WITHOUT ANY WARRANTY; without even the implied warranty of
20 e2000753 2019-09-03 rnkn ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 e2000753 2019-09-03 rnkn ;; General Public License for more details.
23 84b5784c 2018-03-11 rnkn ;; You should have received a copy of the GNU General Public License
24 e2000753 2019-09-03 rnkn ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
26 84b5784c 2018-03-11 rnkn ;;; Commentary:
28 b4370ff5 2020-09-26 rnkn ;; Side Notes
29 b4370ff5 2020-09-26 rnkn ;; ==========
31 d2efd288 2018-03-11 rnkn ;; Quickly display your quick side notes in quick side window.
33 b4370ff5 2020-09-26 rnkn ;; Side notes live in a plain text file, called notes.txt by default, in
34 dbd9052e 2021-02-01 rnkn ;; the current directory or any parent directory (i.e. when locating notes,
35 dbd9052e 2021-02-01 rnkn ;; we first look in the current directory, then one directory up, then two
36 dbd9052e 2021-02-01 rnkn ;; directories up, and so forth.)
38 50fb7007 2020-06-10 rnkn ;; Side notes are displayed in a side window with the command
39 50fb7007 2020-06-10 rnkn ;; side-notes-toggle-notes.
41 50fb7007 2020-06-10 rnkn ;; The filename is defined by user option side-notes-file.
43 50fb7007 2020-06-10 rnkn ;; To really mix things up, there's the user option
44 50fb7007 2020-06-10 rnkn ;; side-notes-secondary-file, which defaults to notes-2.txt, and will
45 50fb7007 2020-06-10 rnkn ;; display a separate notes file in a lower side window when the command
46 4e7e78bf 2020-03-11 rnkn ;; side-notes-toggle-notes is prefixed with an argument (C-u).
48 dbd9052e 2021-02-01 rnkn ;; By default a notes file found in any parent directory will open that
49 b4370ff5 2020-09-26 rnkn ;; file rather than visit a non-existing file in the current directory, but
50 b4370ff5 2020-09-26 rnkn ;; you can override this by prefixing side-notes-toggle-notes with...
52 dbd9052e 2021-02-01 rnkn ;; - C-u C-u to force visiting side-notes-file within the current
53 b4370ff5 2020-09-26 rnkn ;; directory.
54 dbd9052e 2021-02-01 rnkn ;; - C-u C-u C-u to force visiting side-notes-secondary-file within
55 b4370ff5 2020-09-26 rnkn ;; the current directory.
57 dbd9052e 2021-02-01 rnkn ;; Of course, you can use Markdown or Org Mode or whatever by changing the
58 b4370ff5 2020-09-26 rnkn ;; file extensions of side-notes-file and/or side-notes-secondary-file.
60 50fb7007 2020-06-10 rnkn ;; For more information on how to change the way the side window is
61 dbd9052e 2021-02-01 rnkn ;; displayed, see (info "(elisp) Side Windows").
64 b4370ff5 2020-09-26 rnkn ;; Installation
65 b4370ff5 2020-09-26 rnkn ;; ------------
67 b4370ff5 2020-09-26 rnkn ;; Install from [MELPA stable][1] then add something like the following to
68 4e7e78bf 2020-03-11 rnkn ;; your init file:
70 4e7e78bf 2020-03-11 rnkn ;; (define-key (current-global-map) (kbd "M-s n") #'side-notes-toggle-notes)
73 dbd9052e 2021-02-01 rnkn ;; Bugs and Feature Requests
74 dbd9052e 2021-02-01 rnkn ;; -------------------------
76 dbd9052e 2021-02-01 rnkn ;; Send me an email (address in the package header). For bugs, please
77 dbd9052e 2021-02-01 rnkn ;; ensure you can reproduce with:
79 dbd9052e 2021-02-01 rnkn ;; $ emacs -Q -l side-notes.el
81 dbd9052e 2021-02-01 rnkn ;; Known issues are tracked with FIXME comments in the source.
84 b4370ff5 2020-09-26 rnkn ;; [1]: https://stable.melpa.org/#/side-notes
85 b4370ff5 2020-09-26 rnkn ;; [2]: https://melpa.org/#/side-notes
90 84b5784c 2018-03-11 rnkn (defgroup side-notes ()
91 84b5784c 2018-03-11 rnkn "Display a notes file."
92 84b5784c 2018-03-11 rnkn :group 'convenience)
94 84b5784c 2018-03-11 rnkn (defcustom side-notes-hook
96 84b5784c 2018-03-11 rnkn "Hook run after showing notes buffer."
98 84b5784c 2018-03-11 rnkn :group 'side-notes)
100 84b5784c 2018-03-11 rnkn (defcustom side-notes-file
101 84b5784c 2018-03-11 rnkn "notes.txt"
102 aba24426 2019-11-28 rnkn "Name of the notes file.
104 56cd2bfe 2019-05-23 rnkn This file lives in the current directory or any parent directory
105 56cd2bfe 2019-05-23 rnkn thereof, which allows you to keep a notes file in the top level
106 56cd2bfe 2019-05-23 rnkn of a multi-directory project.
108 56cd2bfe 2019-05-23 rnkn If you would like to use a file-specific notes file, specify a
109 56cd2bfe 2019-05-23 rnkn string with `add-file-local-variable'. Likewise you can specify a
110 56cd2bfe 2019-05-23 rnkn directory-specific notes file with `add-dir-local-variable'."
111 84b5784c 2018-03-11 rnkn :type 'string
112 57143a83 2018-05-24 rnkn :safe 'stringp
113 84b5784c 2018-03-11 rnkn :group 'side-notes)
114 84b5784c 2018-03-11 rnkn (make-variable-buffer-local 'side-notes-file)
116 aba24426 2019-11-28 rnkn (defcustom side-notes-secondary-file
117 75cf91fd 2020-06-10 rnkn "notes-2.txt"
118 aba24426 2019-11-28 rnkn "Name of an optional secondary notes file.
120 aba24426 2019-11-28 rnkn Like `side-notes-file' but displayed when `side-notes-toggle-notes'
121 aba24426 2019-11-28 rnkn is prefixed with \\[universal-argument].
123 aba24426 2019-11-28 rnkn If you would like to use a file-specific notes file, specify a
124 aba24426 2019-11-28 rnkn string with `add-file-local-variable'. Likewise you can specify a
125 aba24426 2019-11-28 rnkn directory-specific notes file with `add-dir-local-variable'."
126 75cf91fd 2020-06-10 rnkn :type 'string
127 aba24426 2019-11-28 rnkn :safe 'stringp
128 aba24426 2019-11-28 rnkn :group 'side-notes)
129 aba24426 2019-11-28 rnkn (make-variable-buffer-local 'side-notes-secondary-file)
131 84b5784c 2018-03-11 rnkn (defcustom side-notes-select-window
133 84b5784c 2018-03-11 rnkn "If non-nil, switch to notes window upon displaying it."
134 84b5784c 2018-03-11 rnkn :type 'boolean
135 57143a83 2018-05-24 rnkn :safe 'booleanp
136 49718449 2018-03-13 rnkn :group 'side-notes)
138 84b5784c 2018-03-11 rnkn (defcustom side-notes-display-alist
139 84b5784c 2018-03-11 rnkn '((side . right)
140 aba24426 2019-11-28 rnkn (window-width . 35))
141 84b5784c 2018-03-11 rnkn "Alist used to display notes buffer.
143 aba24426 2019-11-28 rnkn n.b. the special symbol `slot' added automatically to ensure that
144 aba24426 2019-11-28 rnkn `side-notes-file' is displayed above `side-notes-secondary-file'."
145 84b5784c 2018-03-11 rnkn :type 'alist
146 9d5ca0ba 2021-05-02 rnkn :link '(info-link "(elisp) Buffer Display Action Alists")
147 49718449 2018-03-13 rnkn :group 'side-notes)
149 6e73a47c 2018-03-13 rnkn (defface side-notes
151 6e73a47c 2018-03-13 rnkn "Default face for notes buffer."
152 6e73a47c 2018-03-13 rnkn :group 'side-notes)
154 84b5784c 2018-03-11 rnkn (defvar-local side-notes-buffer-identify
156 84b5784c 2018-03-11 rnkn "Buffer local variable to identify a notes buffer.")
158 aba24426 2019-11-28 rnkn (defun side-notes-locate-notes (&optional arg)
159 8597ddd2 2019-04-03 rnkn "Look up directory hierachy for file `side-notes-file'.
161 8597ddd2 2019-04-03 rnkn Return nil if no notes file found."
162 75cf91fd 2020-06-10 rnkn (cond ((and side-notes-secondary-file (= arg 64))
163 75cf91fd 2020-06-10 rnkn (expand-file-name side-notes-secondary-file default-directory))
164 75cf91fd 2020-06-10 rnkn ((= arg 16)
165 75cf91fd 2020-06-10 rnkn (expand-file-name side-notes-file default-directory))
166 75cf91fd 2020-06-10 rnkn ((and side-notes-secondary-file (= arg 4))
167 75cf91fd 2020-06-10 rnkn (expand-file-name side-notes-secondary-file
168 75cf91fd 2020-06-10 rnkn (locate-dominating-file default-directory
169 75cf91fd 2020-06-10 rnkn side-notes-secondary-file)))
171 75cf91fd 2020-06-10 rnkn (expand-file-name side-notes-file
172 75cf91fd 2020-06-10 rnkn (locate-dominating-file default-directory
173 75cf91fd 2020-06-10 rnkn side-notes-file)))))
175 d8aebc7f 2019-08-16 noreply ;;;###autoload
176 aba24426 2019-11-28 rnkn (defun side-notes-toggle-notes (arg)
177 aba24426 2019-11-28 rnkn "Pop up a side window containing `side-notes-file'.
179 75cf91fd 2020-06-10 rnkn When prefixed with...
181 75cf91fd 2020-06-10 rnkn 1. \\[universal-argument], locate `side-notes-secondary-file' instead.
182 75cf91fd 2020-06-10 rnkn 2. \\[universal-argument] \\[universal-argument], force visiting `side-notes-file' within current directory.
183 75cf91fd 2020-06-10 rnkn 3. \\[universal-argument] \\[universal-argument] \\[universal-argument], force visiting `side-notes-secondary-file' within
184 75cf91fd 2020-06-10 rnkn current directory.
186 8597ddd2 2019-04-03 rnkn See `side-notes-display-alist' for options concerning displaying
187 8597ddd2 2019-04-03 rnkn the notes buffer."
188 75cf91fd 2020-06-10 rnkn (interactive "p")
189 84b5784c 2018-03-11 rnkn (if side-notes-buffer-identify
190 84b5784c 2018-03-11 rnkn (quit-window)
191 84b5784c 2018-03-11 rnkn (let ((display-buffer-mark-dedicated t)
192 aba24426 2019-11-28 rnkn (buffer (find-file-noselect (side-notes-locate-notes arg))))
193 84b5784c 2018-03-11 rnkn (if (get-buffer-window buffer (selected-frame))
194 84b5784c 2018-03-11 rnkn (delete-windows-on buffer (selected-frame))
195 aba24426 2019-11-28 rnkn (display-buffer-in-side-window
196 75cf91fd 2020-06-10 rnkn buffer (cons (cons 'slot (if (or (= arg 4) (= arg 64)) 1 -1))
197 75cf91fd 2020-06-10 rnkn side-notes-display-alist))
198 84b5784c 2018-03-11 rnkn (with-current-buffer buffer
199 84b5784c 2018-03-11 rnkn (setq side-notes-buffer-identify t)
200 6e73a47c 2018-03-13 rnkn (face-remap-add-relative 'default 'side-notes)
201 84b5784c 2018-03-11 rnkn (run-hooks 'side-notes-hook))
202 84b5784c 2018-03-11 rnkn (if side-notes-select-window
203 84b5784c 2018-03-11 rnkn (select-window (get-buffer-window buffer (selected-frame))))
204 84b5784c 2018-03-11 rnkn (message "Showing `%s'; %s to hide" buffer
205 84b5784c 2018-03-11 rnkn (key-description (where-is-internal this-command
206 84b5784c 2018-03-11 rnkn overriding-local-map t)))))))
208 84b5784c 2018-03-11 rnkn (provide 'side-notes)
209 84b5784c 2018-03-11 rnkn ;;; side-notes.el ends here
211 133498c2 2020-03-11 rnkn ;; Local Variables:
212 133498c2 2020-03-11 rnkn ;; coding: utf-8-unix
213 133498c2 2020-03-11 rnkn ;; fill-column: 80
214 133498c2 2020-03-11 rnkn ;; require-final-newline: t
215 133498c2 2020-03-11 rnkn ;; sentence-end-double-space: nil
216 62a82a72 2021-07-09 rnkn ;; indent-tabs-mode: nil