-
-
Notifications
You must be signed in to change notification settings - Fork 76
/
dired-rainbow.el
179 lines (148 loc) · 6.68 KB
/
dired-rainbow.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
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
;;; dired-rainbow.el --- Extended file highlighting according to its type
;; Copyright (C) 2014-2017 Matus Goljer
;; Author: Matus Goljer <matus.goljer@gmail.com>
;; Maintainer: Matus Goljer <matus.goljer@gmail.com>
;; Keywords: files
;; Version: 0.0.3
;; Created: 16th February 2014
;; Package-Requires: ((dash "2.5.0") (dired-hacks-utils "0.0.1") (emacs "24"))
;; URL: https://github.com/Fuco1/dired-hacks
;; 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 <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This package adds more customizable highlighting for files in dired
;; listings. The group `dired-faces' provides only nine faces and
;; isn't very fine-grained.
;;
;; The definitions are added by several macros, currently available
;; are:
;;
;; * `dired-rainbow-define` - add face by file extension
;; * `dired-rainbow-define-chmod` - add face by file permissions
;;
;; You can display their documentation by calling (substituting the
;; desired macro name):
;;
;; M-x describe-function RET dired-rainbow-define RET
;;
;; Here are some example uses:
;;
;; (defconst my-dired-media-files-extensions
;; '("mp3" "mp4" "MP3" "MP4" "avi" "mpg" "flv" "ogg")
;; "Media files.")
;;
;; (dired-rainbow-define html "#4e9a06" ("htm" "html" "xhtml"))
;; (dired-rainbow-define media "#ce5c00" my-dired-media-files-extensions)
;;
;; ; boring regexp due to lack of imagination
;; (dired-rainbow-define log (:inherit default
;; :italic t) ".*\\.log")
;;
;; ; highlight executable files, but not directories
;; (dired-rainbow-define-chmod executable-unix "Green" "-.*x.*")
;;
;; See https://github.com/Fuco1/dired-hacks for the entire collection.
;;; Code:
(require 'dired-hacks-utils)
(require 'dash)
(defgroup dired-rainbow ()
"Extended file highlighting according to its type."
:group 'dired-hacks
:prefix "dired-rainbow-")
(defvar dired-rainbow-ext-to-face nil
"An alist mapping extension groups to face and compiled regexp.
This alist is constructed in `dired-rainbow-define' for the case
when the user wants to reuse the associations outside of dired.")
(defun dired-rainbow--get-face (face-props)
"Return face specification according to FACE-PROPS.
See `dired-rainbow-define'."
(cond
((stringp face-props)
`(:foreground ,face-props))
((symbolp face-props)
`(:inherit ,face-props))
(t face-props)))
(defmacro dired-rainbow-define (symbol face-props extensions &optional how)
"Define a custom dired face highlighting files by extension.
SYMBOL is the identifier of the face. The macro will define a face named
dired-rainbow-SYMBOL-face.
FACE-PROPS is a string, a list or a symbol. If a string, it is
assumed to be either a color name or a hexadecimal code (#......)
describing a color. If a list, it is assumed to be a property
list describing the face. See `defface' for list of possible
attributes. If a symbol it is taken as the name of an existing
face which is used.
EXTENSIONS is either a list or a symbol evaluating to a list of
extensions that should be highlighted with this face. Note that
if you specify a symbol, its value *must* be known during
compilation and must be defined before this macro is processed.
Additionally, EXTENSIONS can be a single string or a symbol
evaluating to a string that is interpreted as a regexp matching
the entire file name.
HOW is a parameter that is passed directly to `font-lock-add-keywords'
to control the order."
(declare (debug (symbolp [&or stringp listp symbolp] [&or symbolp listp stringp])))
(let* ((matcher (if (or (listp extensions)
(stringp extensions))
extensions
(symbol-value extensions)))
(regexp (concat
"^[^!].[^d].*[ ]"
dired-hacks-datetime-regexp
"[ ]\\("
(if (listp matcher)
(concat ".*\\." (regexp-opt matcher))
matcher)
"\\)$"))
(face-name (intern (concat "dired-rainbow-" (symbol-name symbol) "-face"))))
`(progn
(defface ,face-name
'((t ,(dired-rainbow--get-face face-props)))
,(concat "dired-rainbow face matching " (symbol-name symbol) " files.")
:group 'dired-rainbow)
(font-lock-add-keywords 'dired-mode '((,regexp 1 ',face-name prepend)) ,how)
(font-lock-add-keywords 'wdired-mode '((,regexp 1 ',face-name prepend)) ,how)
,(if (listp matcher) `(push
'(,matcher ,face-name ,(concat "\\." (regexp-opt matcher)))
dired-rainbow-ext-to-face)))))
(defmacro dired-rainbow-define-chmod (symbol face-props chmod &optional how)
"Define a custom dired face highlighting files by chmod permissions.
SYMBOL is the identifier of the face. The macro will define a face named
dired-rainbow-SYMBOL-face.
FACE-PROPS is a string, a list or a symbol. If a string, it is
assumed to be either a color name or a hexadecimal code (#......)
describing a color. If a list, it is assumed to be a property
list describing the face. See `defface' for list of possible
attributes. If a symbol it is taken as the name of an existing
face which is used.
CHMOD is a regexp matching \"ls -l\" style permissions string.
For example, the pattern
\"-.*x.*\"
matches any file with executable flag set for user, group or everyone.
HOW is a parameter that is passed directly to `font-lock-add-keywords'
to control the order."
(declare (debug (symbolp [&or stringp listp symbolp] stringp)))
(let* ((regexp (concat
"^[^!]."
chmod
".*[ ]"
dired-hacks-datetime-regexp
"[ ]\\(.*?\\)$"))
(face-name (intern (concat "dired-rainbow-" (symbol-name symbol) "-face"))))
`(progn
(defface ,face-name
'((t ,(dired-rainbow--get-face face-props)))
,(concat "dired-rainbow face matching " (symbol-name symbol) " files.")
:group 'dired-rainbow)
(font-lock-add-keywords 'dired-mode '((,regexp 1 ',face-name prepend)) ,how)
(font-lock-add-keywords 'wdired-mode '((,regexp 1 ',face-name prepend)) ,how))))
(provide 'dired-rainbow)
;;; dired-rainbow.el ends here