1 ;;; nxhtmlmaint.el --- Some maintenance helpers
3 ;; Author: Lennart Borgman (lennart O borgman A gmail O com)
4 ;; Created: 2008-09-27T15:29:35+0200 Sat
6 ;; Last-Updated: 2010-01-18 Mon
11 ;; Features that might be required by this library:
15 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19 ;; This module contains maintenance functions:
21 ;; `nxhtmlmaint-get-all-autoloads' (nxhtmlmaint-get-all-autoloads)
23 ;; `nxhtmlmaint-start-byte-compilation'
24 ;; `nxhtmlmaint-byte-uncompile-all'
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34 ;; This program is free software; you can redistribute it and/or
35 ;; modify it under the terms of the GNU General Public License as
36 ;; published by the Free Software Foundation; either version 2, or
37 ;; (at your option) any later version.
39 ;; This program is distributed in the hope that it will be useful,
40 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
41 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 ;; General Public License for more details.
44 ;; You should have received a copy of the GNU General Public License
45 ;; along with this program; see the file COPYING. If not, write to
46 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
47 ;; Floor, Boston, MA 02110-1301, USA.
49 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53 (eval-when-compile (require 'advice))
54 (eval-when-compile (require 'nxhtml-base))
55 (eval-when-compile (require 'nxhtml-web-vcs nil t))
56 (eval-when-compile (require 'web-vcs nil t))
57 (eval-when-compile (require 'ourcomments-util))
59 (defvar nxhtmlmaint-dir
60 ;;(file-name-directory (if load-file-name load-file-name buffer-file-name))
61 (file-name-directory (or load-file-name
62 (when (boundp 'bytecomp-filename) bytecomp-filename)
64 "Maintenance directory for nXhtml.")
66 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
69 (defun nxhtmlmaint-autoloads-file ()
70 "Return autoload file name for nXhtml."
71 (file-truename (expand-file-name "nxhtml-loaddefs.el" nxhtmlmaint-dir)))
73 (defun nxhtmlmaint-util-dir ()
74 "Return nXhtml util directory."
75 (file-truename (file-name-as-directory
76 (expand-file-name "util" nxhtmlmaint-dir))))
78 (defvar nxhtmlmaint-autoload-default-directory (nxhtmlmaint-util-dir))
80 (defvar generated-autoload-file)
82 (defun nxhtmlmaint-initialize-autoloads-file ()
83 "Initialize nXhtml autoload file."
84 (with-current-buffer (find-file-noselect generated-autoload-file)
85 (when (= 0 (buffer-size))
86 (insert ";; Autoloads for nXthml
88 ;; This file should be updated by `nxhtmlmaint-get-file-autoloads',
89 ;; `nxhtmlmaint-get-dir-autoloads' or `nxhtmlmaint-get-all-autoloads'.
90 \(eval-when-compile (require 'nxhtml-base))
91 \(eval-when-compile (require 'web-vcs))")
92 (basic-save-buffer))))
94 (defun nxmtmlmaint-advice-autoload (on)
95 "Activate advices if ON, otherwise turn them off."
98 (ad-activate 'autoload-file-load-name)
99 (ad-activate 'make-autoload))
100 (ad-deactivate 'autoload-file-load-name)
101 (ad-deactivate 'make-autoload)))
103 (defun nxhtmlmaint-get-file-autoloads (file)
104 "Get autoloads for file FILE.
105 Update nXhtml autoload file with them."
106 (interactive (list (buffer-file-name)))
107 (let* ((generated-autoload-file (nxhtmlmaint-autoloads-file))
108 (emacs-lisp-mode-hook nil)
109 (default-directory (nxhtmlmaint-util-dir)))
110 (nxhtmlmaint-initialize-autoloads-file)
111 ;; Get the autoloads using advice
112 (nxmtmlmaint-advice-autoload t)
113 (update-file-autoloads file nil)
114 (nxmtmlmaint-advice-autoload nil)
116 (display-buffer (find-file-noselect generated-autoload-file))))
118 (defun nxhtmlmaint-get-dir-autoloads (dir)
119 "Get autoloads for directory DIR.
120 Update nXhtml autoload file with them."
121 (interactive (list (or (when (buffer-file-name)
122 (file-name-directory (buffer-file-name)))
124 (let* ((generated-autoload-file (nxhtmlmaint-autoloads-file))
125 (emacs-lisp-mode-hook nil)
126 (auto-buf (find-file-noselect generated-autoload-file)))
127 (nxhtmlmaint-initialize-autoloads-file)
128 ;; Get the autoloads using advice
129 (nxmtmlmaint-advice-autoload t)
130 ;; Fix-me: Loop instead, some files must be avoided.
131 (update-directory-autoloads dir)
132 (nxmtmlmaint-advice-autoload nil)
134 (display-buffer (find-file-noselect generated-autoload-file))))
136 (defun nxhtmlmaint-get-tree-autoloads (root)
137 "Get autoloads for directory tree ROOT.
138 Update nXhtml autoload file with them."
139 (interactive (list (or (when (buffer-file-name)
140 (file-name-directory (buffer-file-name)))
142 (message "Getting autoloads in %s" root)
143 (nxhtmlmaint-get-dir-autoloads root)
144 (let* ((files (directory-files root))
145 (sub-dirs (mapcar (lambda (file)
146 (when (and (not (member file '("." "..")))
147 (not (member file '("nxml-mode-20041004" "old")))
148 (not (member file '("nxhtml-company-mode")))
149 (not (member file '("in")))
150 (file-directory-p (expand-file-name file root)))
153 (setq sub-dirs (delq nil sub-dirs))
154 ;;(message "sub-dirs=%s" sub-dirs)
155 (dolist (dir sub-dirs)
156 (let ((full-dir (expand-file-name dir root)))
157 (unless (or (string= full-dir nxhtmlmaint-dir)
158 (string= dir "alts"))
159 (nxhtmlmaint-get-tree-autoloads full-dir))))))
161 ;;(nxhtmlmaint-get-all-autoloads)
162 (defun nxhtmlmaint-get-all-autoloads ()
163 "Get all autoloads for nXhtml.
164 Update nXhtml autoload file with them."
166 (if nxhtml-autoload-web
167 (message "Skipping rebuilding autoloads, not possible when autoloading from web")
168 (let ((auto-buf (find-file-noselect (nxhtmlmaint-autoloads-file))))
169 (with-current-buffer auto-buf
172 (nxhtmlmaint-get-tree-autoloads nxhtmlmaint-dir)
173 ;; `nxhtml-mode' and `nxhtml-validation-header-mode' should only be
174 ;; autoloaded if nxml-mode if available.
175 (with-current-buffer auto-buf
176 (message "Fixing nxml autoloads")
177 (let ((frmt (if (= emacs-major-version 22)
178 "^(autoload (quote %s) "
180 (dolist (nxmode '(nxhtml-mode nxhtml-validation-header-mode))
181 (goto-char (point-min))
182 (when (re-search-forward (format frmt nxmode) nil t)
184 (insert "(when (fboundp 'nxml-mode)\n")
187 ;; Fix defcustom autoloads
188 (goto-char (point-min))
189 (let ((cus-auto "(\\(custom-autoload\\) +'.* +\\(\".*?\"\\)"))
190 (while (re-search-forward cus-auto nil t)
191 ;;(backward-char (1- (length cus-auto)))
193 (let ((lib (match-string 2)))
194 ;; Change to symbol to fix autoloading. This works because
195 ;; custom-load-symbol does require on symbols.
196 (setq lib (concat "'" (substring lib 1 -1)))
197 (replace-match "nxhtml-custom-autoload" t t nil 1)
198 (replace-match lib t t nil 2))))
199 ;; Fix autoload calls
200 (goto-char (point-min))
201 (let ((auto "(autoload "))
202 (while (search-forward auto nil t)
203 (backward-char (1- (length auto)))
205 ;; Fix autoload source
206 (goto-char (point-min))
207 (let* ((patt-src "^;;; Generated autoloads from \\(.*\\)$")
208 (patt-auto "^(nxhtml-autoload '[^ ]+ \\(\"[^\"]+\"\\)")
209 (patt-cust "^(nxhtml-custom-autoload '[^ ]+ \\(\"[^\"]+\"\\)")
210 (patt (concat "\\(?:" patt-src "\\)\\|\\(?:" patt-auto "\\)\\|\\(?:" patt-cust "\\)"))
212 (while (re-search-forward patt nil t)
215 (setq curr-src (match-string-no-properties 1))
217 (setq curr-src (substring curr-src 0 -3))
218 ;; Setup up for web autoload
219 (let* ((src-name (file-name-nondirectory curr-src))
220 (feature (make-symbol src-name))
224 "(web-autoload-require '"
225 (symbol-name feature)
227 " '(nxhtml-download-root-url nil)"
229 " nxhtml-install-dir"
230 " 'nxhtml-byte-compile-file"
234 ;; (custom-autoload 'sym "lib" nil) is will give a
235 ;; (require 'lib) so everything is ok here.
237 ( (or (match-string 2)
240 (let* ((subexp (if (match-string 2) 2 3))
241 (file (match-string-no-properties subexp)))
242 (replace-match (concat "`(lp '(nxhtml-download-root-url nil)"
244 " nxhtml-install-dir)")
251 (t (error "No match???")))))
253 (basic-save-buffer)))))
256 (defun nxhtmlmaint-autoload-file-load-name (file)
257 "Return relative file name for FILE to autoload file directory."
258 (let ((name (if (and nxhtmlmaint-autoload-default-directory
259 (file-name-absolute-p file))
261 file nxhtmlmaint-autoload-default-directory)
262 (file-name-nondirectory file))))
263 (if (string-match "\\.elc?\\(\\.\\|\\'\\)" name)
264 (substring name 0 (match-beginning 0))
267 (defadvice autoload-file-load-name (around
268 nxhtmlmaint-advice-autoload-file-load-name
271 "Advice to return relative file name."
272 (setq ad-return-value (nxhtmlmaint-autoload-file-load-name (ad-get-arg 0))))
274 (defun nxhtmlmaint-make-autoload (form file)
275 "Make autoload for multi major modes."
276 ;;(message "form=%S" form)
277 (if (or (not (listp form))
278 (not (eq 'define-mumamo-multi-major-mode (car form))))
282 ;; Fix-me: Maybe expand??
283 (let ((name (nth 1 form))
285 `(autoload ',name ,file ,doc t)
288 (defadvice make-autoload (after
289 nxhtmlmaint-advice-make-autoload
292 "Make autoload for multi major modes."
293 (setq ad-return-value
294 (nxhtmlmaint-make-autoload (ad-get-arg 0)
297 ;; (defun nxhtmlmaint-generate-library-autoloads (library)
298 ;; "Insert at point autoloads for Emacs library LIBRARY.
299 ;; Works like `generate-file-autoloads', but for a library."
301 ;; (list (completing-read "Generate autoloads for library: "
302 ;; 'locate-file-completion
303 ;; (cons load-path (get-load-suffixes)))))
304 ;; (let ((file (locate-library library)))
305 ;; ;; Fix-me: wasn't this defined???
306 ;; (generate-file-autoloads file)))
309 (defun nxhtmlmaint-start-byte-compilation ()
310 "Start byte compilation of nXhtml in new Emacs instance.
311 Byte compiling in general makes elisp code run 5-10 times faster
312 which is quite noticeable when you use nXhtml.
314 This will also update the file nxhtml-loaddefs.el.
316 You must restart Emacs to use the byte compiled files.
318 If for some reason the byte compiled files does not work you can
319 remove then with `nxhtmlmaint-byte-uncompile-all'."
321 ;; Fix-me: This message and redisplay seems only necessary sometimes.
322 (message "Preparing byte compilation of nXhtml ...") (redisplay t)
323 (let* ((this-file (expand-file-name "nxhtmlmaint.el" nxhtmlmaint-dir))
324 (auto-file (expand-file-name "autostart.el" nxhtmlmaint-dir))
325 (web-vcs-file (expand-file-name "nxhtml-web-vcs.el" nxhtmlmaint-dir))
326 (this-emacs (locate-file invocation-name
327 (list invocation-directory)
329 (process-args `(,this-emacs nil 0 nil "-Q")))
330 (nxhtmlmaint-byte-uncompile-all)
331 (if (or noninteractive
333 (nxhtmlmaint-byte-compile-all)
334 ;;(when noninteractive (setq process-args (append process-args '("-batch"))))
335 (setq process-args (append process-args
339 "-f" "nxhtmlmaint-byte-compile-all")))
340 (message "process-args=%S" process-args)
341 (message "Starting new Emacs instance for byte compiling ...")
342 (apply 'call-process process-args))))
344 ;;(nxhtmlmaint-byte-compile-all)
345 (defun nxhtmlmaint-byte-compile-all ()
346 "Byte recompile all files in nXhtml that needs it."
347 (message "nxhtmlmaint-byte-compile-all: nxhtmlmaint-dir=%S, exists=%s" nxhtmlmaint-dir (file-directory-p nxhtmlmaint-dir))
348 (let* ((load-path load-path)
349 (nxhtml-dir (file-name-as-directory
350 (expand-file-name "nxhtml"
352 (util-dir (file-name-as-directory
353 (expand-file-name "util"
355 ;; (nxhtml-company-dir (file-name-as-directory
356 ;; (expand-file-name "nxhtml-company-mode"
358 (related-dir (file-name-as-directory
359 (expand-file-name "related"
361 (tests-dir (file-name-as-directory
362 (expand-file-name "tests"
364 (emacsw32-dir (file-name-as-directory
365 (expand-file-name "../lisp"
367 (default-dir nxhtml-dir)
369 (message "nxhtmlmaint-byte-compile-all: nxhtml-dir=%S, exists=%s" nxhtml-dir (file-directory-p nxhtml-dir))
370 (message "nxhtmlmaint-byte-compile-all: util-dir=%S, exists=%s" util-dir (file-directory-p util-dir))
371 (message "nxhtmlmaint-byte-compile-all: related-dir=%S, exists=%s" related-dir (file-directory-p related-dir))
372 (message "nxhtmlmaint-byte-compile-all: tests-dir=%S, exists=%s" tests-dir (file-directory-p tests-dir))
373 (add-to-list 'load-path nxhtml-dir)
374 (add-to-list 'load-path util-dir)
375 ;;(add-to-list 'load-path nxhtml-company-dir)
376 (add-to-list 'load-path related-dir)
377 (add-to-list 'load-path tests-dir)
378 (when (file-directory-p emacsw32-dir)
379 (add-to-list 'load-path emacsw32-dir))
380 (require 'cl) ;; This is run in a new Emacs. Fix-me: This might not be true any more.
381 (message "load-path=%s" load-path)
382 (let ((dummy-debug-on-error t))
383 (nxhtmlmaint-byte-compile-dir nxhtmlmaint-dir nil nil nil))
384 (web-vcs-message-with-face 'web-vcs-gold "Byte compiling nXhtml is ready, restart Emacs to use the compiled files")))
387 (defun nxhtmlmaint-byte-recompile ()
388 "Recompile or compile all nXhtml files in current Emacs."
390 (nxhtmlmaint-byte-compile-dir nxhtmlmaint-dir nil nil t)
391 (web-vcs-message-with-face 'web-vcs-gold "Byte recompiling nXhtml ready"))
394 (defun nxhtmlmaint-byte-uncompile-all ()
395 "Delete byte compiled files in nXhtml.
396 This will also update the file nxhtml-loaddefs.el.
398 See `nxhtmlmaint-start-byte-compilation' for byte compiling."
400 (nxhtmlmaint-get-all-autoloads)
401 (let ((dummy-debug-on-error t))
402 (nxhtmlmaint-byte-compile-dir nxhtmlmaint-dir t t nil))
403 (message "Byte uncompiling is ready, restart Emacs to use the elisp files"))
405 (defconst nxhtmlmaint-nonbyte-compile-dirs
406 '("." ".." "alts" "nxml-mode-20041004" "old" "tests" "nxhtml-company-mode"))
408 ;; Fix-me: simplify this now that nxml is not included
409 (defun nxhtmlmaint-byte-compile-dir (dir force del-elc load)
410 "Byte compile or uncompile directory tree DIR.
411 If FORCE is non-nil byte recompile the elisp file even if the
412 compiled file is newer.
414 If DEL-ELC is nil then byte compile files. If DEL-ELC is non-nil
415 then instead delete the compiled files."
416 ;;(directory-files (file-name-directory buffer-file-name) t "\.el\\'")
417 (dolist (el-src (directory-files dir t "\.el\\'"))
418 (let ((elc-dst (concat el-src "c")))
420 (when (file-exists-p elc-dst)
421 (delete-file elc-dst)
422 (message "Deleted %s" elc-dst))
423 (setq debug-on-error t)
424 (when (or force (file-newer-than-file-p el-src elc-dst))
425 ;;(message "fn=%s" (file-name-nondirectory el-src))
426 (when t ;;(string= "nxhtml-menu.el" (file-name-nondirectory el-src))
427 ;;(message "(nxhtml-byte-compile-file %s)" el-src)
428 (unless (nxhtml-byte-compile-file el-src load)
429 (message "Couldn't compile %s" el-src)))))))
430 (dolist (f (directory-files dir t))
431 (when (file-directory-p f)
432 ;; Fix-me: Avoid some dirs
433 (let ((name (file-name-nondirectory f)))
434 (unless (member name nxhtmlmaint-nonbyte-compile-dirs)
435 (nxhtmlmaint-byte-compile-dir f force del-elc load))))))
437 (provide 'nxhtmlmaint)
438 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
439 ;;; nxhtmlmaint.el ends here