about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180908.2240/nix-prettify-mode.el
blob: 99fa9e270c9955a7a09f5025a7dc2a4c4c83027f (plain) (blame)
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
;;; nix-prettify.el -- Prettify Nix store file names  -*- lexical-binding: t -*-

;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
;; Modified by Matthew Bauer for use in nix-mode

;; Author: Alex Kost
;; Maintainer: Matthew Bauer <mjbauer95@gmail.com>
;; Homepage: https://github.com/NixOS/nix-mode
;; Version: 1.1
;; Keywords: nix

;; This file is NOT part of GNU Emacs.

;;; Commentary:

;; This package provides minor-mode for prettifying Nix store file
;; names — i.e., after enabling `nix-prettify-mode',
;; '/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' names will be
;; replaced with '/gnu/store/…-foo-0.1' in the current buffer.  There is
;; also `global-nix-prettify-mode' for global prettifying.

;; To install, add the following to your Emacs init file:
;;
;;   (add-to-list 'load-path "/path/to/dir-with-nix-prettify")
;;   (autoload 'nix-prettify-mode "nix-prettify" nil t)
;;   (autoload 'global-nix-prettify-mode "nix-prettify" nil t)

;; If you want to enable/disable composition after "M-x font-lock-mode",
;; use the following setting:
;;
;;   (setq font-lock-extra-managed-props
;;         (cons 'composition font-lock-extra-managed-props))

;; Credits:
;;
;; Thanks to Ludovic Courtès for the idea of this package.
;;
;; Thanks to the authors of `prettify-symbols-mode' (part of Emacs 24.4)
;; and "pretty-symbols.el" <http://github.com/drothlis/pretty-symbols>
;; for the code.  It helped to write this package.

;;; Code:

(defgroup nix-prettify nil
  "Prettify Nix store file names."
  :prefix "nix-prettify-"
  :group 'nix
  :group 'font-lock
  :group 'convenience)

(defcustom nix-prettify-char ?…
  "Character used for prettifying."
  :type 'character
  :group 'nix-prettify)

(defcustom nix-prettify-decompose-force nil
  "If non-nil, remove any composition.

By default, after disabling `nix-prettify-mode',
compositions (prettifying names with `nix-prettify-char') are
removed only from strings matching `nix-prettify-regexp', so
that compositions created by other modes are left untouched.

Set this variable to non-nil, if you want to remove any
composition unconditionally (like variable `prettify-symbols-mode' does).
Most likely it will do no harm and will make the process of
disabling `nix-prettify-mode' a little faster."
  :type 'boolean
  :group 'nix-prettify)

(defcustom nix-prettify-regexp
  ;; The following file names / URLs should be abbreviated:

  ;; /gnu/store/…-foo-0.1
  ;; /nix/store/…-foo-0.1
  ;; http://hydra.gnu.org/nar/…-foo-0.1
  ;; http://hydra.gnu.org/log/…-foo-0.1

  (rx "/" (or "store" "nar" "log") "/"
      ;; Hash-parts do not include "e", "o", "u" and "t".  See base32Chars
      ;; at <https://github.com/NixOS/nix/blob/master/src/libutil/hash.cc>
      (group (= 32 (any "0-9" "a-d" "f-n" "p-s" "v-z"))))
  "Regexp matching file names for prettifying.

Disable `nix-prettify-mode' before modifying this variable and
make sure to modify `nix-prettify-regexp-group' if needed.

Example of a \"deeper\" prettifying:

  (setq nix-prettify-regexp \"store/[[:alnum:]]\\\\\\={32\\\\}\"
        nix-prettify-regexp-group 0)

This will transform
'/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' into
'/gnu/…-foo-0.1'"
  :type 'regexp
  :group 'nix-prettify)

(defcustom nix-prettify-regexp-group 1
  "Regexp group in `nix-prettify-regexp' for prettifying."
  :type 'integer
  :group 'nix-prettify)

(defvar nix-prettify-special-modes
  '(nix-info-mode ibuffer-mode)
  "List of special modes that support font-locking.

By default, \\[global-nix-prettify-mode] enables prettifying in
all buffers except the ones where `font-lock-defaults' is
nil (see Info node `(elisp) Font Lock Basics'), because it may
break the existing highlighting.

Modes from this list and all derived modes are exceptions
\(`global-nix-prettify-mode' enables prettifying there).")

(defvar nix-prettify-flush-function
  (cond ((fboundp 'font-lock-flush) #'font-lock-flush)
        ((fboundp 'jit-lock-refontify) #'jit-lock-refontify))
  "Function used to refontify buffer.
This function is called without arguments after
enabling/disabling `nix-prettify-mode'.  If nil, do nothing.")

(defun nix-prettify-compose ()
  "Compose matching region in the current buffer."
  (let ((beg (match-beginning nix-prettify-regexp-group))
        (end (match-end       nix-prettify-regexp-group)))
    (compose-region beg end nix-prettify-char 'decompose-region))
  ;; Return nil because we're not adding any face property.
  nil)

(defun nix-prettify-decompose-buffer ()
  "Remove file names compositions from the current buffer."
  (with-silent-modifications
    (let ((inhibit-read-only t))
      (if nix-prettify-decompose-force
          (remove-text-properties (point-min)
                                  (point-max)
                                  '(composition nil))
        (nix-while-search nix-prettify-regexp
          (remove-text-properties
           (match-beginning nix-prettify-regexp-group)
           (match-end       nix-prettify-regexp-group)
           '(composition nil)))))))

;;;###autoload
(define-minor-mode nix-prettify-mode
  "Toggle Nix Prettify mode.

With a prefix argument ARG, enable Nix Prettify mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
the mode if ARG is omitted or nil.

When Nix Prettify mode is enabled, hash-parts of the Nix store
file names (see `nix-prettify-regexp') are prettified,
i.e. displayed as `nix-prettify-char' character.  This mode can
be enabled programmatically using hooks:

  (add-hook 'shell-mode-hook 'nix-prettify-mode)

It is possible to enable the mode in any buffer, however not any
buffer's highlighting may survive after adding new elements to
`font-lock-keywords' (see `nix-prettify-special-modes' for
details).

Also you can use `global-nix-prettify-mode' to enable Nix
Prettify mode for all modes that support font-locking."
  :init-value nil
  :lighter " …"
  (let ((keywords `((,nix-prettify-regexp
                     (,nix-prettify-regexp-group
                      (nix-prettify-compose))))))
    (if nix-prettify-mode
        ;; Turn on.
        (font-lock-add-keywords nil keywords)
      ;; Turn off.
      (font-lock-remove-keywords nil keywords)
      (nix-prettify-decompose-buffer))
    (and nix-prettify-flush-function
         (funcall nix-prettify-flush-function))))

(defun nix-prettify-supported-p ()
  "Return non-nil, if the mode can be harmlessly enabled in current buffer."
  (or font-lock-defaults
      (apply #'derived-mode-p nix-prettify-special-modes)))

(defun nix-prettify-turn-on ()
  "Enable `nix-prettify-mode' in the current buffer if needed.
See `nix-prettify-special-modes' for details."
  (and (not nix-prettify-mode)
       (nix-prettify-supported-p)
       (nix-prettify-mode)))

;;;###autoload
(define-globalized-minor-mode nix-prettify-global-mode
  nix-prettify-mode nix-prettify-turn-on)

;;;###autoload
(define-obsolete-function-alias 'global-nix-prettify-mode 'nix-prettify-global-mode)

(provide 'nix-prettify-mode)

;;; nix-prettify-mode.el ends here