1 ;;; guix-prettify.el --- Prettify Guix store file names
3 ;; Copyright © 2014 Alex Kost <alezost@gmail.com>
5 ;; This file is part of GNU Guix.
7 ;; GNU Guix is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; GNU Guix is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ;; This package provides minor-mode for prettifying Guix store file
23 ;; names — i.e., after enabling `guix-prettify-mode',
24 ;; '/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' names will be
25 ;; replaced with '/gnu/store/…-foo-0.1' in the current buffer. There is
26 ;; also `global-guix-prettify-mode' for global prettifying.
28 ;; To install, add the following to your emacs init file:
30 ;; (add-to-list 'load-path "/path/to/dir-with-guix-prettify")
31 ;; (autoload 'guix-prettify-mode "guix-prettify" nil t)
32 ;; (autoload 'global-guix-prettify-mode "guix-prettify" nil t)
34 ;; If you want to enable/disable composition after "M-x font-lock-mode",
35 ;; use the following setting:
37 ;; (setq font-lock-extra-managed-props
38 ;; (cons 'composition font-lock-extra-managed-props))
42 ;; Thanks to Ludovic Courtès for the idea of this package.
44 ;; Thanks to the authors of `prettify-symbols-mode' (part of Emacs 24.4)
45 ;; and "pretty-symbols.el" <http://github.com/drothlis/pretty-symbols>
46 ;; for the code. It helped to write this package.
50 (defgroup guix-prettify nil
51 "Prettify Guix store file names."
52 :prefix
"guix-prettify-"
56 (defcustom guix-prettify-char ?…
57 "Character used for prettifying."
59 :group
'guix-prettify
)
61 (defcustom guix-prettify-decompose-force nil
62 "If non-nil, remove any composition.
64 By default, after disabling `guix-prettify-mode',
65 compositions (prettifying names with `guix-prettify-char') are
66 removed only from strings matching `guix-prettify-regexp', so
67 that compositions created by other modes are left untouched.
69 Set this variable to non-nil, if you want to remove any
70 composition unconditionally (like `prettify-symbols-mode' does).
71 Most likely it will do no harm and will make the process of
72 disabling `guix-prettify-mode' a little faster."
74 :group
'guix-prettify
)
76 (defcustom guix-prettify-regexp
80 ;; Hash-parts do not include "e", "o", "u" and "t". See base32Chars
81 ;; at <https://github.com/NixOS/nix/blob/master/src/libutil/hash.cc>
82 (group (= 32 (any "0-9" "a-d" "f-n" "p-s" "v-z"))))
83 "Regexp matching file names for prettifying.
85 Disable `guix-prettify-mode' before modifying this variable and
86 make sure to modify `guix-prettify-regexp-group' if needed.
88 Example of a \"deeper\" prettifying:
90 (setq guix-prettify-regexp \"store/[[:alnum:]]\\\\\\={32\\\\}\"
91 guix-prettify-regexp-group 0)
94 '/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' into
97 :group
'guix-prettify
)
99 (defcustom guix-prettify-regexp-group
1
100 "Regexp group in `guix-prettify-regexp' for prettifying."
102 :group
'guix-prettify
)
104 (defvar guix-prettify-special-modes
105 '(guix-info-mode ibuffer-mode
)
106 "List of special modes that support font-locking.
108 By default, \\[global-guix-prettify-mode] enables prettifying in
109 all buffers except the ones where `font-lock-defaults' is
110 nil (see Info node `(elisp) Font Lock Basics'), because it may
111 break the existing highlighting.
113 Modes from this list and all derived modes are exceptions
114 \(`global-guix-prettify-mode' enables prettifying there).")
116 (defvar guix-prettify-flush-function
117 (cond ((fboundp 'font-lock-flush
) #'font-lock-flush
)
118 ((fboundp 'jit-lock-refontify
) #'jit-lock-refontify
))
119 "Function used to refontify buffer.
120 This function is called without arguments after
121 enabling/disabling `guix-prettify-mode'. If nil, do nothing.")
123 (defun guix-prettify-compose ()
124 "Compose matching region in the current buffer."
125 (let ((beg (match-beginning guix-prettify-regexp-group
))
126 (end (match-end guix-prettify-regexp-group
)))
127 (compose-region beg end guix-prettify-char
'decompose-region
))
128 ;; Return nil because we're not adding any face property.
131 (defun guix-prettify-decompose-buffer ()
132 "Remove file names compositions from the current buffer."
133 (with-silent-modifications
134 (let ((inhibit-read-only t
))
135 (if guix-prettify-decompose-force
136 (remove-text-properties (point-min)
140 (goto-char (point-min))
141 (while (re-search-forward guix-prettify-regexp nil t
)
142 (remove-text-properties
143 (match-beginning guix-prettify-regexp-group
)
144 (match-end guix-prettify-regexp-group
)
145 '(composition nil
))))))))
148 (define-minor-mode guix-prettify-mode
149 "Toggle Guix Prettify mode.
151 With a prefix argument ARG, enable Guix Prettify mode if ARG is
152 positive, and disable it otherwise. If called from Lisp, enable
153 the mode if ARG is omitted or nil.
155 When Guix Prettify mode is enabled, hash-parts of the Guix store
156 file names (see `guix-prettify-regexp') are prettified,
157 i.e. displayed as `guix-prettify-char' character. This mode can
158 be enabled programmatically using hooks:
160 (add-hook 'shell-mode-hook 'guix-prettify-mode)
162 It is possible to enable the mode in any buffer, however not any
163 buffer's highlighting may survive after adding new elements to
164 `font-lock-keywords' (see `guix-prettify-special-modes' for
167 Also you can use `global-guix-prettify-mode' to enable Guix
168 Prettify mode for all modes that support font-locking."
171 (let ((keywords `((,guix-prettify-regexp
172 (,guix-prettify-regexp-group
173 (guix-prettify-compose))))))
174 (if guix-prettify-mode
176 (font-lock-add-keywords nil keywords
)
178 (font-lock-remove-keywords nil keywords
)
179 (guix-prettify-decompose-buffer))
180 (and guix-prettify-flush-function
181 (funcall guix-prettify-flush-function
))))
183 (defun guix-prettify-supported-p ()
184 "Return non-nil, if the mode can be harmlessly enabled in current buffer."
185 (or font-lock-defaults
186 (apply #'derived-mode-p guix-prettify-special-modes
)))
188 (defun guix-prettify-turn-on ()
189 "Enable `guix-prettify-mode' in the current buffer if needed.
190 See `guix-prettify-special-modes' for details."
191 (and (not guix-prettify-mode
)
192 (guix-prettify-supported-p)
193 (guix-prettify-mode)))
196 (define-globalized-minor-mode global-guix-prettify-mode
197 guix-prettify-mode guix-prettify-turn-on
)
200 (defalias 'guix-prettify-global-mode
'global-guix-prettify-mode
)
202 (provide 'guix-prettify
)
204 ;;; guix-prettify.el ends here