forked from protesilaos/denote
-
Notifications
You must be signed in to change notification settings - Fork 0
/
denote-rename-buffer.el
152 lines (126 loc) · 6.24 KB
/
denote-rename-buffer.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
;;; denote-rename-buffer.el --- Rename Denote buffers to be shorter and easier to read -*- lexical-binding: t -*-
;; Copyright (C) 2023-2024 Free Software Foundation, Inc.
;; Author: Protesilaos Stavrou <[email protected]>
;; Maintainer: Protesilaos Stavrou <[email protected]>
;; URL: https://github.com/protesilaos/denote
;; This file is NOT part of GNU Emacs.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; Rename Denote buffers to be shorter and easier to read. Enable
;; `denote-rename-buffer-mode' to automatically rename the buffer of a
;; Denote file. The renaming function is specified in the user option
;; `denote-rename-buffer-function'.
;;; Code:
(require 'denote)
(defgroup denote-rename-buffer nil
"Rename Denote buffers to be shorter and easier to read."
:group 'denote
:link '(info-link "(denote) Top")
:link '(url-link :tag "Homepage" "https://protesilaos.com/emacs/denote"))
(defcustom denote-rename-buffer-format "%t"
"The format of the buffer name `denote-rename-buffer' should use.
Thie value is a string that treats specially the following
specifiers:
- The %t is the Denote TITLE of the file.
- The %i is the Denote IDENTIFIER of the file.
- The %d is the same as %i (DATE mnemonic).
- The %s is the Denote SIGNATURE of the file.
- The %k is the Denote KEYWORDS of the file.
- The %% is a literal percent sign.
In addition, the following flags are available for each of the specifiers:
- 0 :: Pad to the width, if given, with zeros instead of spaces.
- - :: Pad to the width, if given, on the right instead of the left.
- < :: Truncate to the width and precision, if given, on the left.
- > :: Truncate to the width and precision, if given, on the right.
- ^ :: Convert to upper case.
- _ :: Convert to lower case.
When combined all together, the above are written thus:
%<flags><width><precision>SPECIFIER-CHARACTER
Any other string it taken as-is. Users may want, for example, to
include some text that makes Denote buffers stand out, such as
a [D] prefix."
:type 'string
:package-version '(denote . "2.1.0")
:group 'denote-rename-buffer)
(defcustom denote-rename-buffer-function #'denote-rename-buffer
"Symbol of function that is called to rename the Denote file buffer.
The default `denote-rename-buffer' function uses the pattern
described in `denote-rename-buffer-format'.
Users can set this variable to an arbitrary function that does
something else. The function is called without arguments from
the `find-file-hook' and `denote-after-new-note-hook'.
A nil value for this variable means that the title of the Denote
buffer will be used, if available."
:type '(choice
(const :tag "Rename using the `denote-rename-buffer-format'" denote-rename-buffer)
(function :tag "Use a custom renaming function"))
:package-version '(denote . "2.1.0")
:group 'denote-rename-buffer)
(defun denote-rename-buffer--format (buffer)
"Parse the BUFFER through the `denote-rename-buffer-format'."
(when-let ((file (buffer-file-name buffer))
(type (denote-filetype-heuristics file)))
(string-trim
(format-spec denote-rename-buffer-format
(list (cons ?t (or (denote-retrieve-front-matter-title-value file type) ""))
(cons ?i (or (denote-retrieve-filename-identifier file) ""))
(cons ?d (or (denote-retrieve-filename-identifier file) ""))
(cons ?s (or (denote-retrieve-filename-signature file) ""))
(cons ?k (or (denote-retrieve-front-matter-keywords-value-as-string file type) ""))
(cons ?% "%"))
'delete))))
(defun denote-rename-buffer (&optional buffer)
"Rename current buffer or optional BUFFER with `denote-rename-buffer-format'.
The symbol of this function is the default value of the user
option `denote-rename-buffer-function' and is thus used by the
`denote-rename-buffer-mode'."
(when-let ((file (buffer-file-name buffer))
((denote-file-has-identifier-p file))
(new-name (denote-rename-buffer--format (or buffer (current-buffer))))
((not (string-blank-p new-name))))
(rename-buffer new-name :unique)))
(make-obsolete
'denote-rename-buffer-with-title
'denote-rename-buffer
"2.1.0")
(make-obsolete
'denote-rename-buffer-with-identifier
'denote-rename-buffer
"2.1.0")
(defun denote-rename-buffer--fallback (&optional buffer)
"Fallback to rename BUFFER or `current-buffer'.
This is called if `denote-rename-buffer-rename-function' is nil."
(let ((denote-rename-buffer-format "%t"))
(denote-rename-buffer buffer)))
(defun denote-rename-buffer-rename-function-or-fallback ()
"Call `denote-rename-buffer-function' or its fallback to rename with title.
Add this to `find-file-hook' and `denote-after-new-note-hook'."
(funcall (or denote-rename-buffer-function #'denote-rename-buffer--fallback)))
;;;###autoload
(define-minor-mode denote-rename-buffer-mode
"Automatically rename Denote buffers to be easier to read.
A buffer is renamed upon visiting the underlying file. This
means that existing buffers are not renamed until they are
visited again in a new buffer (files are visited with the command
`find-file' or related)."
:global t
(if denote-rename-buffer-mode
(progn
(add-hook 'denote-after-new-note-hook #'denote-rename-buffer-rename-function-or-fallback)
(add-hook 'find-file-hook #'denote-rename-buffer-rename-function-or-fallback))
(remove-hook 'denote-after-new-note-hook #'denote-rename-buffer-rename-function-or-fallback)
(remove-hook 'find-file-hook #'denote-rename-buffer-rename-function-or-fallback)))
(provide 'denote-rename-buffer)
;;; denote-rename-buffer.el ends here