-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathac-html-csswatcher.el
200 lines (176 loc) · 7.51 KB
/
ac-html-csswatcher.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
;;; ac-html-csswatcher.el --- css/less class/id completion with `ac-html' or `company-web'
;; Copyright (C) 2015 Olexandr Sydorchuck
;; Author: Olexandr Sydorchuck <[email protected]>
;; Version: 0.1.7
;; Keywords: html, css, less, auto-complete
;; Package-Requires: ((web-completion-data "0.1"))
;; URL: https://github.com/osv/ac-html-csswatcher
;; 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/>.
;; Prefix: ac-html-csswatcher-
;;; Commentary:
;; This package work `ac-html' and `company-web', please, install one of these.
;;
;; For `ac-html' users: Since ac-html 0.4 is alpha stage, and not stable yet. This
;; package works with ac-html 0.3 series, if you are using ac-html 0.4
;; series, you may downgrade ac-html aka reinstall from melpa-stable.
;;
;; Preinstall:
;;
;; Install `csswatcher':
;;
;; sudo cpan i CSS::Watcher
;;
;; Note:
;;
;; Please, keep CSS::Watcher up-to-date.
;; Recommended version of csswatcher is 0.4.7 (run `csswatcher -v'). Update:
;;
;; sudo cpan i CSS::Watcher
;;
;; Configuration, Emacs:
;;
;; (require 'ac-html-csswatcher)
;; (ac-html-csswatcher-setup)
;; ;; or if you prefer company-style names:
;; (company-web-csswatcher-setup)
;;
;; To enable completion when editing html use M-x `ac-html-csswatcher+' (or `company-web-csswatcher+') or add it in your hook.
;;
;; Configuration, project:
;;
;; File ".csswatcher" may indicate root of your project and used for set ignored files:
;;
;; % cat .csswatcher
;; # ignore all css
;; ignore: \.css$
;; # except app.css
;; use: app\.css
;; # and skip recursive scanning node_modules, it may be slow!
;; skip: node_modules
;;
;; Otherwise projectile way used for root directory.
;;
;; So if you use `ac-html-bootstrap' and don't want to parse your bootstrap.css
;; create in your project file .csswatcher with line:
;;
;; ignore: bootstrap
;;
;; Note: completion will regenerated by csswatcher after saving css,
;; less, opening html(jade,slim,haml) files, or manually by
;; `ac-html-csswatcher-refresh' or `company-web-csswatcher-refresh'.
;;
;;; Code:
(eval-when-compile
(require 'cl))
(require 'web-completion-data)
(defvar ac-html-csswatcher-source-dir nil
"This is variable bounded as alist in `web-completion-data-sources',
value is computed by csswatcher programm.")
(make-variable-buffer-local 'ac-html-csswatcher-source-dir)
(defcustom ac-html-csswatcher-command "csswatcher"
"The \"csswatcher\" command to be run."
:type 'string
:group 'ac-html-csswatcher)
(defcustom ac-html-csswatcher-command-args '()
"The extra arguments to pass to ac-html-csswatcher-command'.
For example you can set --logfile, --pidfile, --debug, --outputdir."
:type 'list
:group 'ac-html-csswatcher)
;;; log util
(defvar ac-html-csswatcher-debug nil)
(defvar ac-html-csswatcher-log-buf-name "*ac-html-csswatcher debug*")
(defun ac-html-csswatcher-log-buf ()
(get-buffer-create ac-html-csswatcher-log-buf-name))
(defsubst AC-HTML-CSSWATCHER-LOG (&rest messages)
(ignore-errors
(when ac-html-csswatcher-debug
(require 'pp)
(let* ((str (or (ignore-errors (apply 'format messages))
(pp-to-string (car messages))))
(strn (concat str "\n")))
(with-current-buffer (ac-html-csswatcher-log-buf)
(goto-char (point-max))
(insert strn))
str))))
(defun ac-html-csswatcher-setup-html-stuff-async ()
"Asynchronous call \"csswatcher\".
Set `ac-html-csswatcher-source-dir' with returned by csswatcher value after \"ACSOURCE: \""
(when (buffer-file-name)
(lexical-let ((csswatcher-process-name (concat "csswatcher-" (md5 (buffer-file-name))))
(csswatcher-output-bufffer (generate-new-buffer-name "*csswatcher-output*"))
(args (append ac-html-csswatcher-command-args (list buffer-file-name))))
(AC-HTML-CSSWATCHER-LOG "=> Start process [%s]\n to buffer: %s" csswatcher-process-name csswatcher-output-bufffer)
(set-process-sentinel
(apply 'start-process
csswatcher-process-name
csswatcher-output-bufffer
ac-html-csswatcher-command
args)
(lambda (proc event)
(when (and (string= event "finished\n")
(= (process-exit-status proc) 0))
(AC-HTML-CSSWATCHER-LOG "=> Process finished [%s]" proc)
(setq ac-html-csswatcher-source-dir
(with-current-buffer csswatcher-output-bufffer
(AC-HTML-CSSWATCHER-LOG "-- Result was: \n%s\n-- End of result\n" (buffer-string))
(when (string-match "PROJECT: \\(.*\\)$" (buffer-string))
(let ((project-dir (match-string 1 (buffer-string))))
(message "[csswatcher] parsed %s" project-dir)
(AC-HTML-CSSWATCHER-LOG "Project located: %s" project-dir))
(when (string-match "ACSOURCE: \\(.*\\)$" (buffer-string))
(match-string 1 (buffer-string))))))
(AC-HTML-CSSWATCHER-LOG "Set ac-html-csswatcher-source-dir to %s\n"
ac-html-csswatcher-source-dir proc )
(kill-buffer csswatcher-output-bufffer)))))))
;;;###autoload
(defun ac-html-csswatcher-refresh ()
"Interactive version of `ac-html-csswatcher-setup-html-stuff-async' with nice name.
Refresh csswatcher."
(interactive)
(ac-html-csswatcher-setup-html-stuff-async))
;;;###autoload
(defalias 'company-web-csswatcher-refresh 'ac-html-csswatcher-refresh)
;;;###autoload
(defun ac-html-csswatcher+ ()
"Enable csswatcher for this buffer, csswatcher called after each current buffer save.
`ac-html-csswatcher+' automatically added to mode hook when you `ac-html-csswatcher-setup'."
(interactive)
(make-local-variable 'web-completion-data-sources)
(unless (assoc "Project" web-completion-data-sources)
(setq web-completion-data-sources (cons (cons "Project" 'ac-html-csswatcher-source-dir) web-completion-data-sources)))
(ac-html-csswatcher-setup-html-stuff-async))
;;;###autoload
(defalias 'company-web-csswatcher+ 'ac-html-csswatcher+)
;;;###autoload
(defun ac-html-csswatcher-setup ()
"1. Enable for web, html, haml etc hooks `ac-html-csswatcher+'
2. Setup `after-save-hook' for CSS modes.
Currently we suport only `css-mode' and `less-mode', but later style, sass, scsc etc will be included
when `csswatcher' support them."
(mapc #'(lambda (mode)
(add-hook mode 'ac-html-csswatcher+))
'(html-mode-hook
web-mode-hook
slim-mode-hook
jade-mode-hook
haml-mode-hook))
(mapc #'(lambda (mode)
(add-hook mode
(lambda ()
(add-hook 'after-save-hook
'ac-html-csswatcher-setup-html-stuff-async nil 'make-it-local))))
'(css-mode-hook
less-mode-hook)))
;;;###autoload
(defalias 'company-web-csswatcher-setup 'ac-html-csswatcher-setup)
(provide 'ac-html-csswatcher)
;;; ac-html-csswatcher.el ends here