aboutsummaryrefslogtreecommitdiffstats
path: root/admin/admin.el
diff options
context:
space:
mode:
Diffstat (limited to 'admin/admin.el')
-rw-r--r--admin/admin.el313
1 files changed, 229 insertions, 84 deletions
diff --git a/admin/admin.el b/admin/admin.el
index 9235144f6c6..ec78fb27865 100644
--- a/admin/admin.el
+++ b/admin/admin.el
@@ -1,6 +1,6 @@
1;;; admin.el --- utilities for Emacs administration 1;;; admin.el --- utilities for Emacs administration
2 2
3;; Copyright (C) 2001-2011 Free Software Foundation, Inc. 3;; Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -26,6 +26,8 @@
26 26
27;;; Code: 27;;; Code:
28 28
29(defvar add-log-time-format) ; in add-log
30
29(defun add-release-logs (root version) 31(defun add-release-logs (root version)
30 "Add \"Version VERSION released.\" change log entries in ROOT. 32 "Add \"Version VERSION released.\" change log entries in ROOT.
31Root must be the root of an Emacs source tree." 33Root must be the root of an Emacs source tree."
@@ -62,7 +64,7 @@ Root must be the root of an Emacs source tree."
62 (set-version-in-file root "README" version 64 (set-version-in-file root "README" version
63 (rx (and "version" (1+ space) 65 (rx (and "version" (1+ space)
64 (submatch (1+ (in "0-9.")))))) 66 (submatch (1+ (in "0-9."))))))
65 (set-version-in-file root "configure.in" version 67 (set-version-in-file root "configure.ac" version
66 (rx (and "AC_INIT" (1+ (not (in ?,))) 68 (rx (and "AC_INIT" (1+ (not (in ?,)))
67 ?, (0+ space) 69 ?, (0+ space)
68 (submatch (1+ (in "0-9.")))))) 70 (submatch (1+ (in "0-9."))))))
@@ -126,39 +128,20 @@ Root must be the root of an Emacs source tree."
126 (set-version-in-file root "nt/emacsclient.rc" comma-space-version 128 (set-version-in-file root "nt/emacsclient.rc" comma-space-version
127 (rx (and "\"ProductVersion\"" (0+ space) ?, 129 (rx (and "\"ProductVersion\"" (0+ space) ?,
128 (0+ space) ?\" (submatch (1+ (in "0-9, "))) 130 (0+ space) ?\" (submatch (1+ (in "0-9, ")))
129 "\\0\"")))) 131 "\\0\"")))
130 ;; nextstep. 132 ;; Major version only.
131 (set-version-in-file 133 (when (string-match "\\([0-9]\\{2,\\}\\)" version)
132 root "nextstep/Cocoa/Emacs.base/Contents/Info.plist" 134 (setq version (match-string 1 version))
133 version (rx (and "CFBundleGetInfoString" (1+ anything) "Emacs" (1+ space) 135 (set-version-in-file root "src/msdos.c" version
134 (submatch (1+ (in "0-9.")))))) 136 (rx (and "Vwindow_system_version" (1+ not-newline)
135 (set-version-in-file 137 ?\( (submatch (1+ (in "0-9"))) ?\))))
136 root "nextstep/Cocoa/Emacs.base/Contents/Info.plist" 138 (set-version-in-file root "etc/refcards/ru-refcard.tex" version
137 version (rx (and "CFBundleShortVersionString" (1+ not-newline) ?\n 139 "\\\\newcommand{\\\\versionemacs}\\[0\\]\
138 (0+ not-newline) "<string>" (0+ space) 140{\\([0-9]\\{2,\\}\\)}.+%.+version of Emacs")
139 (submatch (1+ (in "0-9.")))))) 141 (set-version-in-file root "etc/refcards/emacsver.tex" version
140 (set-version-in-file 142 "\\\\def\\\\versionemacs\
141 root "nextstep/Cocoa/Emacs.base/Contents/Resources/English.lproj/InfoPlist.strings" 143{\\([0-9]\\{2,\\}\\)}.+%.+version of Emacs"))))
142 version (rx (and "CFBundleShortVersionString" (0+ space) ?= (0+ space) 144
143 ?\" (0+ space) "Version" (1+ space)
144 (submatch (1+ (in "0-9."))))))
145 (set-version-in-file
146 root "nextstep/Cocoa/Emacs.base/Contents/Resources/English.lproj/InfoPlist.strings"
147 version (rx (and "CFBundleGetInfoString" (0+ space) ?= (0+ space)
148 ?\" (0+ space) "Emacs version" (1+ space)
149 (submatch (1+ (in "0-9."))))))
150 (set-version-in-file
151 root "nextstep/GNUstep/Emacs.base/Resources/Info-gnustep.plist"
152 version (rx (and "ApplicationRelease" (0+ space) ?= (0+ space)
153 ?\" (0+ space) (submatch (1+ (in "0-9."))))))
154 (set-version-in-file
155 root "nextstep/GNUstep/Emacs.base/Resources/Info-gnustep.plist"
156 version (rx (and "FullVersionID" (0+ space) ?= (0+ space)
157 ?\" (0+ space) "Emacs" (1+ space)
158 (submatch (1+ (in "0-9."))))))
159 (set-version-in-file
160 root "nextstep/GNUstep/Emacs.base/Resources/Emacs.desktop"
161 version (rx (and "Version=" (submatch (1+ (in "0-9.")))))))
162 145
163;; Note this makes some assumptions about form of short copyright. 146;; Note this makes some assumptions about form of short copyright.
164(defun set-copyright (root copyright) 147(defun set-copyright (root copyright)
@@ -172,45 +155,28 @@ Root must be the root of an Emacs source tree."
172 (format-time-string "%Y"))))) 155 (format-time-string "%Y")))))
173 (unless (file-exists-p (expand-file-name "src/emacs.c" root)) 156 (unless (file-exists-p (expand-file-name "src/emacs.c" root))
174 (error "%s doesn't seem to be the root of an Emacs source tree" root)) 157 (error "%s doesn't seem to be the root of an Emacs source tree" root))
175 (set-version-in-file root "src/emacs.c" copyright 158 (set-version-in-file root "configure.ac" copyright
176 (rx (and "emacs_copyright" (0+ (not (in ?\"))) 159 (rx (and bol "copyright" (0+ (not (in ?\")))
177 ?\" (submatch (1+ (not (in ?\")))) ?\")))
178 (set-version-in-file root "lib-src/ebrowse.c" copyright
179 (rx (and "emacs_copyright" (0+ (not (in ?\")))
180 ?\" (submatch (1+ (not (in ?\")))) ?\")))
181 (set-version-in-file root "lib-src/etags.c" copyright
182 (rx (and "emacs_copyright" (0+ (not (in ?\")))
183 ?\" (submatch (1+ (not (in ?\")))) ?\"))) 160 ?\" (submatch (1+ (not (in ?\")))) ?\")))
161 (set-version-in-file root "msdos/sed2v2.inp" copyright
162 (rx (and bol "/^#undef " (1+ not-newline)
163 "define COPYRIGHT" (1+ space)
164 ?\" (submatch (1+ (not (in ?\")))) ?\")))
165 (set-version-in-file root "nt/config.nt" copyright
166 (rx (and bol "#" (0+ blank) "define" (1+ blank)
167 "COPYRIGHT" (1+ blank)
168 ?\" (submatch (1+ (not (in ?\")))) ?\")))
184 (set-version-in-file root "lib-src/rcs2log" copyright 169 (set-version-in-file root "lib-src/rcs2log" copyright
185 (rx (and "Copyright" (0+ space) ?= (0+ space) 170 (rx (and "Copyright" (0+ space) ?= (0+ space)
186 ?\' (submatch (1+ nonl))))) 171 ?\' (submatch (1+ nonl)))))
187 ;; This one is a nuisance, as it needs to be split over two lines.
188 (string-match "\\(.*[0-9]\\{4\\} *\\)\\(.*\\)" copyright)
189 ;; nextstep.
190 (set-version-in-file
191 root "nextstep/Cocoa/Emacs.base/Contents/Info.plist"
192 copyright (rx (and "CFBundleGetInfoString" (1+ anything) "Emacs" (1+ space)
193 (1+ (in "0-9.")) (1+ space)
194 (submatch (1+ (not (in ?\<)))))))
195 (set-version-in-file
196 root "nextstep/Cocoa/Emacs.base/Contents/Resources/English.lproj/InfoPlist.strings"
197 copyright (rx (and "NSHumanReadableCopyright" (0+ space) ?\= (0+ space)
198 ?\" (submatch (1+ (not (in ?\")))))))
199 (set-version-in-file
200 root "nextstep/GNUstep/Emacs.base/Resources/Info-gnustep.plist"
201 copyright (rx (and "Copyright" (0+ space) ?\= (0+ space)
202 ?\" (submatch (1+ (not (in ?\")))))))
203 (when (string-match "\\([0-9]\\{4\\}\\)" copyright) 172 (when (string-match "\\([0-9]\\{4\\}\\)" copyright)
204 (setq copyright (match-string 1 copyright)) 173 (setq copyright (match-string 1 copyright))
205 (dolist (file (directory-files (expand-file-name "etc/refcards" root) 174 (set-version-in-file root "etc/refcards/ru-refcard.tex" copyright
206 t "\\.tex\\'")) 175 "\\\\newcommand{\\\\cyear}\\[0\\]\
207 (unless (string-match "gnus-refcard\\.tex" file) 176{\\([0-9]\\{4\\}\\)}.+%.+copyright year")
208 (set-version-in-file 177 (set-version-in-file root "etc/refcards/emacsver.tex" copyright
209 root file copyright 178 "\\\\def\\\\year\
210 (concat (if (string-match "ru-refcard\\.tex" file) 179{\\([0-9]\\{4\\}\\)}.+%.+copyright year")))
211 "\\\\newcommand{\\\\cyear}\\[0\\]{"
212 "\\\\def\\\\year{")
213 "\\([0-9]\\{4\\}\\)}.+%.+copyright year"))))))
214 180
215;;; Various bits of magic for generating the web manuals 181;;; Various bits of magic for generating the web manuals
216 182
@@ -240,7 +206,7 @@ Root must be the root of an Emacs source tree."
240 (manual-txt texi (expand-file-name "emacs.txt" txt-dir)) 206 (manual-txt texi (expand-file-name "emacs.txt" txt-dir))
241 (manual-pdf texi (expand-file-name "emacs.pdf" dest)) 207 (manual-pdf texi (expand-file-name "emacs.pdf" dest))
242 (manual-dvi texi (expand-file-name "emacs.dvi" dvi-dir) 208 (manual-dvi texi (expand-file-name "emacs.dvi" dvi-dir)
243 (expand-file-name "emacs.ps" ps-dir))) 209 (expand-file-name "emacs.ps" ps-dir)))
244 ;; Lisp manual 210 ;; Lisp manual
245 (let ((texi (expand-file-name "doc/lispref/elisp.texi" root))) 211 (let ((texi (expand-file-name "doc/lispref/elisp.texi" root)))
246 (manual-html-node texi (expand-file-name "elisp" html-node-dir)) 212 (manual-html-node texi (expand-file-name "elisp" html-node-dir))
@@ -248,7 +214,20 @@ Root must be the root of an Emacs source tree."
248 (manual-txt texi (expand-file-name "elisp.txt" txt-dir)) 214 (manual-txt texi (expand-file-name "elisp.txt" txt-dir))
249 (manual-pdf texi (expand-file-name "elisp.pdf" dest)) 215 (manual-pdf texi (expand-file-name "elisp.pdf" dest))
250 (manual-dvi texi (expand-file-name "elisp.dvi" dvi-dir) 216 (manual-dvi texi (expand-file-name "elisp.dvi" dvi-dir)
251 (expand-file-name "elisp.ps" ps-dir))) 217 (expand-file-name "elisp.ps" ps-dir)))
218 ;; Misc manuals
219 (let ((manuals '("ada-mode" "auth" "autotype" "calc" "cc-mode"
220 "cl" "dbus" "dired-x" "ebrowse" "ede" "ediff"
221 "edt" "eieio" "emacs-mime" "epa" "erc" "ert"
222 "eshell" "eudc" "faq" "flymake" "forms"
223 "gnus" "emacs-gnutls" "idlwave" "info"
224 "mairix-el" "message" "mh-e" "newsticker"
225 "nxml-mode" "org" "pcl-cvs" "pgg" "rcirc"
226 "remember" "reftex" "sasl" "sc" "semantic"
227 "ses" "sieve" "smtpmail" "speedbar" "tramp"
228 "url" "vip" "viper" "widget" "woman")))
229 (dolist (manual manuals)
230 (manual-misc-html manual root html-node-dir html-mono-dir)))
252 (message "Manuals created in %s" dest))) 231 (message "Manuals created in %s" dest)))
253 232
254(defconst manual-doctype-string 233(defconst manual-doctype-string
@@ -265,6 +244,12 @@ Root must be the root of an Emacs source tree."
265(defconst manual-style-string "<style type=\"text/css\"> 244(defconst manual-style-string "<style type=\"text/css\">
266@import url('/style.css');\n</style>\n") 245@import url('/style.css');\n</style>\n")
267 246
247(defun manual-misc-html (name root html-node-dir html-mono-dir)
248 (let ((texi (expand-file-name (format "doc/misc/%s.texi" name) root)))
249 (manual-html-node texi (expand-file-name name html-node-dir))
250 (manual-html-mono texi (expand-file-name (concat name ".html")
251 html-mono-dir))))
252
268(defun manual-html-mono (texi-file dest) 253(defun manual-html-mono (texi-file dest)
269 "Run Makeinfo on TEXI-FILE, emitting mono HTML output to DEST. 254 "Run Makeinfo on TEXI-FILE, emitting mono HTML output to DEST.
270This function also edits the HTML files so that they validate as 255This function also edits the HTML files so that they validate as
@@ -307,13 +292,15 @@ the @import directive."
307 (let (copyright-text) 292 (let (copyright-text)
308 (manual-html-fix-index-1) 293 (manual-html-fix-index-1)
309 ;; Move copyright notice to the end. 294 ;; Move copyright notice to the end.
310 (re-search-forward "[ \t]*<p>Copyright &copy;") 295 (when (re-search-forward "[ \t]*<p>Copyright &copy;" nil t)
311 (setq opoint (match-beginning 0)) 296 (setq opoint (match-beginning 0))
312 (re-search-forward "</blockquote>") 297 (re-search-forward "</blockquote>")
313 (setq copyright-text (buffer-substring opoint (point))) 298 (setq copyright-text (buffer-substring opoint (point)))
314 (delete-region opoint (point)) 299 (delete-region opoint (point)))
315 (manual-html-fix-index-2) 300 (manual-html-fix-index-2)
316 (insert copyright-text "\n</div>\n")) 301 (if copyright-text
302 (insert copyright-text))
303 (insert "\n</div>\n"))
317 ;; For normal nodes, give the header div a blue bg. 304 ;; For normal nodes, give the header div a blue bg.
318 (manual-html-fix-node-div)) 305 (manual-html-fix-node-div))
319 (save-buffer)))))) 306 (save-buffer))))))
@@ -369,9 +356,9 @@ Also generate PostScript output in PS-DEST."
369 356
370(defun manual-html-fix-index-1 () 357(defun manual-html-fix-index-1 ()
371 (let (opoint) 358 (let (opoint)
372 (re-search-forward "<body>\n\\(<h1 class=\"settitle\\)") 359 (re-search-forward "<body>\n")
373 (setq opoint (match-beginning 1)) 360 (setq opoint (match-end 0))
374 (search-forward "<h2 class=\"unnumbered") 361 (search-forward "<h2 class=\"")
375 (goto-char (match-beginning 0)) 362 (goto-char (match-beginning 0))
376 (delete-region opoint (point)) 363 (delete-region opoint (point))
377 (insert "<div id=\"content\" class=\"inner\">\n\n"))) 364 (insert "<div id=\"content\" class=\"inner\">\n\n")))
@@ -380,7 +367,8 @@ Also generate PostScript output in PS-DEST."
380 "Replace the index list in the current buffer with a HTML table." 367 "Replace the index list in the current buffer with a HTML table."
381 (let (done open-td tag desc) 368 (let (done open-td tag desc)
382 ;; Convert the list that Makeinfo made into a table. 369 ;; Convert the list that Makeinfo made into a table.
383 (search-forward "<ul class=\"menu\">") 370 (or (search-forward "<ul class=\"menu\">" nil t)
371 (search-forward "<ul>"))
384 (replace-match "<table style=\"float:left\" width=\"100%\">") 372 (replace-match "<table style=\"float:left\" width=\"100%\">")
385 (forward-line 1) 373 (forward-line 1)
386 (while (not done) 374 (while (not done)
@@ -413,7 +401,7 @@ Also generate PostScript output in PS-DEST."
413 (replace-match " </td></tr></table>\n 401 (replace-match " </td></tr></table>\n
414<h3>Detailed Node Listing</h3>\n\n" t t) 402<h3>Detailed Node Listing</h3>\n\n" t t)
415 (search-forward "<p>") 403 (search-forward "<p>")
416 (search-forward "<p>") 404 (search-forward "<p>" nil t)
417 (goto-char (match-beginning 0)) 405 (goto-char (match-beginning 0))
418 (skip-chars-backward "\n ") 406 (skip-chars-backward "\n ")
419 (setq open-td nil) 407 (setq open-td nil)
@@ -427,8 +415,8 @@ Also generate PostScript output in PS-DEST."
427 (setq open-td nil)) 415 (setq open-td nil))
428 (insert " <tr> 416 (insert " <tr>
429 <th colspan=\"2\" align=\"left\" style=\"text-align:left\">") 417 <th colspan=\"2\" align=\"left\" style=\"text-align:left\">")
430 (re-search-forward "</p>[ \t\n]*<ul class=\"menu\">") 418 (if (re-search-forward "</p>[ \t\n]*<ul class=\"menu\">" nil t)
431 (replace-match " </th></tr>")) 419 (replace-match " </th></tr>")))
432 ((looking-at "[ \t]*</ul>[ \t]*$") 420 ((looking-at "[ \t]*</ul>[ \t]*$")
433 (replace-match 421 (replace-match
434 (if open-td 422 (if open-td
@@ -437,11 +425,168 @@ Also generate PostScript output in PS-DEST."
437 (setq done t)) 425 (setq done t))
438 (t 426 (t
439 (if (eobp) 427 (if (eobp)
440 (error "Parse error in %s" f)) 428 (error "Parse error in %s" f)) ; f is bound in manual-html-node
441 (unless open-td 429 (unless open-td
442 (setq done t)))) 430 (setq done t))))
443 (forward-line 1)))) 431 (forward-line 1))))
444 432
433
434;; Stuff to check new defcustoms got :version tags.
435;; Adapted from check-declare.el.
436
437(defun cusver-find-files (root &optional old)
438 "Find .el files beneath directory ROOT that contain defcustoms.
439If optional OLD is non-nil, also include defvars."
440 (process-lines find-program root
441 "-name" "*.el"
442 "-exec" grep-program
443 "-l" "-E" (format "^[ \\t]*\\(def%s"
444 (if old "(custom|var)"
445 "custom"
446 ))
447 "{}" "+"))
448
449(defvar cusver-new-version (format "%s.%s" emacs-major-version
450 (1+ emacs-minor-version))
451 "Version number that new defcustoms should have.")
452
453(defun cusver-scan (file &optional old)
454 "Scan FILE for `defcustom' calls.
455Return a list with elements of the form (VAR . VER),
456This means that FILE contains a defcustom for variable VAR, with
457a :version tag having value VER (may be nil).
458If optional argument OLD is non-nil, also scan for defvars."
459 (let ((m (format "Scanning %s..." file))
460 (re (format "^[ \t]*\\((def%s\\)[ \t\n]"
461 (if old "\\(custom\\|var\\)" "\\(custom\\|group\\)")))
462 alist var ver form glist grp)
463 (message "%s" m)
464 (with-temp-buffer
465 (insert-file-contents file)
466 ;; FIXME we could theoretically be inside a string.
467 (while (re-search-forward re nil t)
468 (goto-char (match-beginning 1))
469 (if (and (setq form (ignore-errors (read (current-buffer))))
470 (setq var (car-safe (cdr-safe form)))
471 ;; Exclude macros, eg (defcustom ,varname ...).
472 (symbolp var))
473 (progn
474 (setq ver (car (cdr-safe (memq :version form))))
475 (if (equal "group" (match-string 2))
476 ;; Group :version could be old.
477 (if (equal ver cusver-new-version)
478 (setq glist (cons (cons var ver) glist)))
479 ;; If it specifies a group and the whole group has a
480 ;; version. use that.
481 (unless ver
482 (setq grp (car (cdr-safe (memq :group form))))
483 (and grp
484 (setq grp (car (cdr-safe grp))) ; (quote foo) -> foo
485 (setq ver (assq grp glist))))
486 (setq alist (cons (cons var ver) alist))))
487 (if form (message "Malformed defcustom: `%s'" form)))))
488 (message "%sdone" m)
489 alist))
490
491(defun cusver-scan-cus-start (file)
492 "Scan cus-start.el and return an alist with elements (VAR . VER)."
493 (if (file-readable-p file)
494 (with-temp-buffer
495 (insert-file-contents file)
496 (when (search-forward "(let ((all '(" nil t)
497 (backward-char 1)
498 (let (var ver alist)
499 (dolist (elem (ignore-errors (read (current-buffer))))
500 (when (symbolp (setq var (car-safe elem)))
501 (or (stringp (setq ver (nth 3 elem)))
502 (setq ver nil))
503 (setq alist (cons (cons var ver) alist))))
504 alist)))))
505
506(define-button-type 'cusver-xref 'action #'cusver-goto-xref)
507
508(defun cusver-goto-xref (button)
509 "Jump to a lisp file for the BUTTON at point."
510 (let ((file (button-get button 'file))
511 (var (button-get button 'var)))
512 (if (not (file-readable-p file))
513 (message "Cannot read `%s'" file)
514 (with-current-buffer (find-file-noselect file)
515 (goto-char (point-min))
516 (or (re-search-forward (format "^[ \t]*(defcustom[ \t]*%s" var) nil t)
517 (message "Unable to locate defcustom"))
518 (pop-to-buffer (current-buffer))))))
519
520;; You should probably at least do a grep over the old directory
521;; to check the results of this look sensible.
522;; TODO Check cus-start if something moved from C to Lisp.
523;; TODO Handle renamed things with aliases to the old names.
524(defun cusver-check (newdir olddir version)
525 "Check that defcustoms have :version tags where needed.
526NEWDIR is the current lisp/ directory, OLDDIR is that from the previous
527release. A defcustom that is only in NEWDIR should have a :version
528tag. We exclude cases where a defvar exists in OLDDIR, since
529just converting a defvar to a defcustom does not require a :version bump.
530
531Note that a :version tag should also be added if the value of a defcustom
532changes (in a non-trivial way). This function does not check for that."
533 (interactive (list (read-directory-name "New Lisp directory: ")
534 (read-directory-name "Old Lisp directory: ")
535 (number-to-string
536 (read-number "New version number: "
537 (string-to-number cusver-new-version)))))
538 (or (file-directory-p (setq newdir (expand-file-name newdir)))
539 (error "Directory `%s' not found" newdir))
540 (or (file-directory-p (setq olddir (expand-file-name olddir)))
541 (error "Directory `%s' not found" olddir))
542 (setq cusver-new-version version)
543 (let* ((newfiles (progn (message "Finding new files with defcustoms...")
544 (cusver-find-files newdir)))
545 (oldfiles (progn (message "Finding old files with defcustoms...")
546 (cusver-find-files olddir t)))
547 (newcus (progn (message "Reading new defcustoms...")
548 (mapcar
549 (lambda (file)
550 (cons file (cusver-scan file))) newfiles)))
551 oldcus result thisfile file)
552 (message "Reading old defcustoms...")
553 (dolist (file oldfiles)
554 (setq oldcus (append oldcus (cusver-scan file t))))
555 (setq oldcus (append oldcus (cusver-scan-cus-start
556 (expand-file-name "cus-start.el" olddir))))
557 ;; newcus has elements (FILE (VAR VER) ... ).
558 ;; oldcus just (VAR . VER).
559 (message "Checking for version tags...")
560 (dolist (new newcus)
561 (setq file (car new)
562 thisfile
563 (let (missing var)
564 (dolist (cons (cdr new))
565 (or (cdr cons)
566 (assq (setq var (car cons)) oldcus)
567 (push var missing)))
568 (if missing
569 (cons file missing))))
570 (if thisfile
571 (setq result (cons thisfile result))))
572 (message "Checking for version tags... done")
573 (if (not result)
574 (message "No missing :version tags")
575 (pop-to-buffer "*cusver*")
576 (erase-buffer)
577 (insert "These defcustoms might be missing :version tags:\n\n")
578 (dolist (elem result)
579 (let* ((str (file-relative-name (car elem) newdir))
580 (strlen (length str)))
581 (dolist (var (cdr elem))
582 (insert (format "%s: %s\n" str var))
583 (make-text-button (+ (line-beginning-position 0) strlen 2)
584 (line-end-position 0)
585 'file (car elem)
586 'var var
587 'help-echo "Mouse-2: visit this definition"
588 :type 'cusver-xref)))))))
589
445(provide 'admin) 590(provide 'admin)
446 591
447;;; admin.el ends here 592;;; admin.el ends here