Mercurial > hg > xemacs-beta
comparison lisp/modes/xrdb-mode.el @ 24:4103f0995bd7 r19-15b95
Import from CVS: tag r19-15b95
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:51:03 +0200 |
parents | |
children | 441bb1e64a06 |
comparison
equal
deleted
inserted
replaced
23:0edd3412f124 | 24:4103f0995bd7 |
---|---|
1 ;;; xrdb-mode.el --- mode for editing X resource database files | |
2 | |
3 ;; Author: 1994-1997 Barry A. Warsaw | |
4 ;; Maintainer: tools-help@python.org | |
5 ;; Created: May 1994 | |
6 ;; Version: 1.17 | |
7 ;; Last Modified: 1997/02/21 22:28:59 | |
8 ;; Keywords: data languages | |
9 | |
10 ;; Copyright (C) 1994 Barry A. Warsaw | |
11 | |
12 ;; This file is not part of GNU Emacs. | |
13 | |
14 ;; This program is free software; you can redistribute it and/or modify | |
15 ;; it under the terms of the GNU General Public License as published by | |
16 ;; the Free Software Foundation; either version 2 of the License, or | |
17 ;; (at your option) any later version. | |
18 ;; | |
19 ;; This program is distributed in the hope that it will be useful, | |
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 ;; GNU General Public License for more details. | |
23 ;; | |
24 ;; You should have received a copy of the GNU General Public License | |
25 ;; along with this program; if not, write to the Free Software | |
26 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
27 | |
28 ;;; Commentary: | |
29 ;; | |
30 ;; In 1994 I wrote: | |
31 ;; | |
32 ;; "I used to be like you. I used to hack on X resource database files | |
33 ;; all the time, and when I did, I found this mode to be fairly | |
34 ;; useful. It's by no means perfect. At one time I had a collection | |
35 ;; of hacks that did some nice indentation of resource lines, but | |
36 ;; they were not organized in any way. This mode was my attempt to | |
37 ;; congeal this mess into a proper major mode. I release it now, not | |
38 ;; because it will change your life, but because I don't plan to do | |
39 ;; anything more with it. | |
40 ;; | |
41 ;; I have since been enlightened and no longer have to cavort with | |
42 ;; mere mortal X hackers anymore. I like my brain cells, so now I | |
43 ;; use NEXTSTEP where all is glory. Or would you say I traded one | |
44 ;; vice for another? Hmm... Anyway, if you are still down in the | |
45 ;; trenches and would like to inherit this file, let me know. I | |
46 ;; don't intend to do any work on it any more... unless I lose my | |
47 ;; place in paradise. I promise to be good, Steve. :-) :-)" | |
48 ;; | |
49 ;; I have fallen from grace. | |
50 | |
51 ;; Code: | |
52 | |
53 | |
54 ;; These variables are available for your customization | |
55 (defvar xrdb-mode-hook nil | |
56 "*Hook to be run when `xrdb-mode' is entered.") | |
57 | |
58 (defvar xrdb-subdivide-by 'paragraph | |
59 "*Extent of alignment calculations. | |
60 Can be one of `buffer', `paragraph', `page', or `line'. Do a | |
61 \\[describe-function] xrdb-indent-buffer RET for more information.") | |
62 | |
63 | |
64 | |
65 ;; no need to customize anything below this line | |
66 (defconst xrdb-comment-re "^[ \t]*[!]" | |
67 "Character which starts a comment.") | |
68 (defconst xrdb-separator-char ?: | |
69 "Character which separates resource specs from values.") | |
70 | |
71 | |
72 ;; utilities | |
73 (defsubst xrdb-point (position) | |
74 ;; Returns the value of point at certain commonly referenced POSITIONs. | |
75 ;; POSITION can be one of the following symbols: | |
76 ;; | |
77 ;; bol -- beginning of line | |
78 ;; eol -- end of line | |
79 ;; bod -- beginning of defun | |
80 ;; boi -- back to indentation | |
81 ;; ionl -- indentation of next line | |
82 ;; iopl -- indentation of previous line | |
83 ;; bonl -- beginning of next line | |
84 ;; bopl -- beginning of previous line | |
85 ;; bop -- beginning of paragraph | |
86 ;; eop -- end of paragraph | |
87 ;; bopg -- beginning of page | |
88 ;; eopg -- end of page | |
89 ;; | |
90 ;; This function does not modify point or mark. | |
91 (let ((here (point))) | |
92 (cond | |
93 ((eq position 'bol) (beginning-of-line)) | |
94 ((eq position 'eol) (end-of-line)) | |
95 ((eq position 'boi) (back-to-indentation)) | |
96 ((eq position 'bonl) (forward-line 1)) | |
97 ((eq position 'bopl) (forward-line -1)) | |
98 ((eq position 'bop) (forward-paragraph -1)) | |
99 ((eq position 'eop) (forward-paragraph 1)) | |
100 ((eq position 'bopg) (forward-page -1)) | |
101 ((eq position 'eopg) (forward-page 1)) | |
102 (t | |
103 (error "unknown buffer position requested: %s" position))) | |
104 (prog1 | |
105 (point) | |
106 (goto-char here)) | |
107 )) | |
108 | |
109 (defsubst xrdb-skip-to-separator () | |
110 ;; skip forward from the beginning of the line to the separator | |
111 ;; character as given by xrdb-separator-char. Returns t if the | |
112 ;; char was found, otherwise, nil. | |
113 (beginning-of-line) | |
114 (skip-chars-forward | |
115 (concat "^" (char-to-string xrdb-separator-char)) | |
116 (xrdb-point 'eol)) | |
117 (= (following-char) xrdb-separator-char)) | |
118 | |
119 | |
120 | |
121 ;; commands | |
122 (defun xrdb-electric-separator (arg) | |
123 "Insert the separator character. | |
124 Re-align the line unless an argument is given." | |
125 (interactive "P") | |
126 ;; first insert the character | |
127 (self-insert-command (prefix-numeric-value arg)) | |
128 ;; only do electric behavior if arg is not given | |
129 (if (not arg) | |
130 (xrdb-align-to (xrdb-point 'bol) | |
131 (xrdb-point 'bonl) | |
132 (save-excursion | |
133 (beginning-of-line) | |
134 (forward-comment (- (point-max))) | |
135 (beginning-of-line) | |
136 (xrdb-skip-to-separator) | |
137 (current-column))))) | |
138 | |
139 (defun xrdb-align-to (start end goalcolumn) | |
140 (interactive "r\nnAlign to column: ") | |
141 (save-excursion | |
142 (save-restriction | |
143 (narrow-to-region start end) | |
144 (beginning-of-buffer) | |
145 (while (< (point) (point-max)) | |
146 (if (and (not (looking-at xrdb-comment-re)) | |
147 (xrdb-skip-to-separator) | |
148 goalcolumn) | |
149 (indent-code-rigidly (xrdb-point 'bol) | |
150 (xrdb-point 'bonl) | |
151 (- goalcolumn (current-column)))) | |
152 (forward-line 1))))) | |
153 | |
154 (defun xrdb-indent-line (arg) | |
155 "Re-align current line." | |
156 (interactive "P") | |
157 ;; narrow to the region specified by xrdb-subdivide-by | |
158 (save-excursion | |
159 (save-restriction | |
160 (widen) | |
161 (cond | |
162 ((eq xrdb-subdivide-by 'buffer)) | |
163 ((eq xrdb-subdivide-by 'page) | |
164 (narrow-to-page)) | |
165 ((eq xrdb-subdivide-by 'paragraph) | |
166 (narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop))) | |
167 (t | |
168 (narrow-to-region (xrdb-point 'bopl) (xrdb-point 'bonl)) | |
169 )) | |
170 ;; indent line | |
171 (xrdb-align-to (xrdb-point 'bol) (xrdb-point 'bonl) | |
172 (xrdb-region-goal-column)) | |
173 ))) | |
174 | |
175 (defun xrdb-indent-region (start end) | |
176 "Re-align region." | |
177 (interactive "r") | |
178 ;; narrow to region | |
179 (save-excursion | |
180 (save-restriction | |
181 (narrow-to-region start end) | |
182 (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column)) | |
183 ))) | |
184 | |
185 (defun xrdb-indent-page () | |
186 "Re-align the current page." | |
187 (interactive) | |
188 (save-excursion | |
189 (save-restriction | |
190 (narrow-to-page) | |
191 (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column)) | |
192 ))) | |
193 | |
194 (defun xrdb-indent-paragraph () | |
195 "Re-align the current paragraph." | |
196 (interactive) | |
197 (save-excursion | |
198 (save-restriction | |
199 (narrow-to-region (xrdb-point 'bop) (xrdb-point 'eop)) | |
200 (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column)) | |
201 ))) | |
202 | |
203 (defun xrdb-indent-buffer (arg) | |
204 "Re-align the entire buffer. | |
205 Alignment calculations are controlled by the variable | |
206 `xrdb-subdivide-by', which can take the values `buffer', `paragraph', | |
207 `page', or `line', with the following meanings: | |
208 | |
209 buffer - all non-comment lines are aligned with the longest line in | |
210 the buffer. Since every line must be scanned, this will | |
211 take the longest to perform. | |
212 | |
213 paragraph - alignment of lines spanning paragraphs. A paragraph is | |
214 defined as all contiguous lines between blank or comment | |
215 lines. | |
216 | |
217 page - alignment of lines spanning pages (i.e. separated by | |
218 page-delimiter, usually ^L). | |
219 | |
220 none - alignment of lines based on the previous line. | |
221 | |
222 With optional \\[universal-argument], queries for alignment subdivision." | |
223 (interactive "P") | |
224 (let ((align-by (if (not arg) | |
225 xrdb-subdivide-by | |
226 (completing-read | |
227 "Align by: " | |
228 '(("buffer" . buffer) | |
229 ("paragraph" . paragraph) | |
230 ("page" . page) | |
231 ("line" . line)) | |
232 nil t (format "%s" xrdb-subdivide-by))))) | |
233 (message "Aligning by %s..." align-by) | |
234 (save-excursion | |
235 (save-restriction | |
236 (widen) | |
237 (cond | |
238 ;; by buffer | |
239 ((eq align-by 'buffer) | |
240 (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column))) | |
241 ;; by paragraph | |
242 ((eq align-by 'paragraph) | |
243 (beginning-of-buffer) | |
244 (while (< (point) (point-max)) | |
245 (narrow-to-region (point) (xrdb-point 'eop)) | |
246 (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column)) | |
247 (beginning-of-buffer) | |
248 (widen) | |
249 (forward-paragraph 1) | |
250 )) | |
251 ;; by page | |
252 ((eq align-by 'page) | |
253 (beginning-of-buffer) | |
254 (while (< (point) (point-max)) | |
255 (narrow-to-region (point) (xrdb-point 'eopg)) | |
256 (xrdb-align-to (point-min) (point-max) (xrdb-region-goal-column)) | |
257 (beginning-of-buffer) | |
258 (widen) | |
259 (forward-page 1) | |
260 )) | |
261 ;; by line | |
262 (t | |
263 (beginning-of-buffer) | |
264 (let ((prev-goalcol 0)) | |
265 (while (< (point) (point-max)) | |
266 ;; skip comments and blank lines | |
267 (if (not (looking-at paragraph-start)) | |
268 (progn | |
269 (xrdb-align-to (xrdb-point 'bol) (xrdb-point 'bonl) | |
270 prev-goalcol) | |
271 (xrdb-skip-to-separator) | |
272 (setq prev-goalcol (- (point) (xrdb-point 'boi))) | |
273 )) | |
274 (forward-line 1)))) | |
275 ))) | |
276 (message "Aligning by %s... done." align-by) | |
277 )) | |
278 | |
279 | |
280 ;; major-mode stuff | |
281 (defvar xrdb-mode-abbrev-table nil | |
282 "Abbrev table used in `xrdb-mode' buffers.") | |
283 (define-abbrev-table 'xrdb-mode-abbrev-table ()) | |
284 | |
285 | |
286 (defvar xrdb-mode-syntax-table nil | |
287 "Syntax table used in `xrdb-mode' buffers.") | |
288 (if xrdb-mode-syntax-table | |
289 () | |
290 (setq xrdb-mode-syntax-table (make-syntax-table)) | |
291 (modify-syntax-entry ?! "<" xrdb-mode-syntax-table) | |
292 (modify-syntax-entry ?\n ">" xrdb-mode-syntax-table)) | |
293 | |
294 | |
295 (defvar xrdb-mode-map () | |
296 "Keymap used in `xrdb-mode' buffers.") | |
297 (if xrdb-mode-map | |
298 () | |
299 (setq xrdb-mode-map (make-sparse-keymap)) | |
300 (let ((ekey (char-to-string xrdb-separator-char))) | |
301 ;; make the separator key electric | |
302 (define-key xrdb-mode-map ekey 'xrdb-electric-separator) | |
303 (define-key xrdb-mode-map "\t" 'xrdb-indent-line) | |
304 (define-key xrdb-mode-map "\C-c\C-a" 'xrdb-indent-paragraph) | |
305 (define-key xrdb-mode-map "\C-c\C-b" 'xrdb-submit-bug-report) | |
306 (define-key xrdb-mode-map "\C-c\C-p" 'xrdb-indent-page) | |
307 (define-key xrdb-mode-map "\C-c\C-r" 'xrdb-indent-region) | |
308 (define-key xrdb-mode-map "\C-c\C-u" 'xrdb-indent-buffer) | |
309 (define-key xrdb-mode-map "\C-c>" 'xrdb-align-to) | |
310 )) | |
311 | |
312 (defun xrdb-mode () | |
313 "Major mode for editing xrdb config files" | |
314 (interactive) | |
315 (kill-all-local-variables) | |
316 (set-syntax-table xrdb-mode-syntax-table) | |
317 (setq major-mode 'xrdb-mode | |
318 mode-name "xrdb" | |
319 local-abbrev-table xrdb-mode-abbrev-table) | |
320 (use-local-map xrdb-mode-map) | |
321 ;; local variables | |
322 (make-local-variable 'parse-sexp-ignore-comments) | |
323 (make-local-variable 'comment-start) | |
324 (make-local-variable 'comment-end) | |
325 (make-local-variable 'paragraph-start) | |
326 (make-local-variable 'paragraph-separate) | |
327 (make-local-variable 'paragraph-ignore-fill-prefix) | |
328 ;; now set their values | |
329 (setq parse-sexp-ignore-comments t | |
330 comment-start "! " | |
331 comment-end "") | |
332 (setq indent-region-function 'xrdb-indent-region | |
333 paragraph-ignore-fill-prefix t | |
334 paragraph-start (concat "^[ \t]*$\\|^[ \t]*[!]\\|" page-delimiter) | |
335 paragraph-separate paragraph-start) | |
336 (run-hooks 'xrdb-mode-hook)) | |
337 | |
338 | |
339 | |
340 ;; faces and font-locking | |
341 (require 'font-lock) | |
342 (make-face 'xrdb-option-name-face) | |
343 (make-face 'xrdb-option-value-face) | |
344 (or (face-differs-from-default-p 'xrdb-option-name-face) | |
345 (copy-face 'font-lock-keyword-face 'xrdb-option-name-face)) | |
346 (or (face-differs-from-default-p 'xrdb-option-value-face) | |
347 (copy-face 'font-lock-string-face 'xrdb-option-value-face)) | |
348 | |
349 (defvar xrdb-font-lock-keywords | |
350 (list '("^[ \t]*\\([^\n:]*:\\)[ \t]*\\(.*\\)$" | |
351 (1 xrdb-option-name-face) | |
352 (2 xrdb-option-value-face))) | |
353 "Additional expressions to highlight in Xrdb mode.") | |
354 | |
355 (put 'xrdb-mode 'font-lock-defaults '(xrdb-font-lock-keywords nil)) | |
356 | |
357 | |
358 | |
359 ;; commands | |
360 (defun xrdb-region-goal-column () | |
361 ;; Returns the goal column of the current region. Assumes the | |
362 ;; buffer has been narrowed to the region to scan. | |
363 (save-excursion | |
364 (beginning-of-buffer) | |
365 (let ((goalcol -1) | |
366 linecol) | |
367 (while (< (point) (point-max)) | |
368 ;; skip any comments | |
369 (if (and (not (looking-at xrdb-comment-re)) | |
370 (xrdb-skip-to-separator) | |
371 (< goalcol (setq linecol (current-column))) | |
372 ) | |
373 (setq goalcol linecol)) | |
374 (forward-line 1)) | |
375 (if (< goalcol 0) | |
376 nil | |
377 goalcol)))) | |
378 | |
379 | |
380 | |
381 ;; submitting bug reports | |
382 | |
383 (defconst xrdb-version "1.17" | |
384 "xrdb-mode version number.") | |
385 | |
386 (defconst xrdb-mode-help-address "tools-help@python.org" | |
387 "Address for xrdb-mode bug reports.") | |
388 | |
389 (eval-when-compile | |
390 (require 'reporter)) | |
391 | |
392 (defun xrdb-submit-bug-report () | |
393 "Submit via mail a bug report on xrdb-mode." | |
394 (interactive) | |
395 ;; load in reporter | |
396 (let ((reporter-prompt-for-summary-p t) | |
397 (varlist '(xrdb-subdivide-by | |
398 xrdb-mode-hook | |
399 ))) | |
400 (and (if (y-or-n-p "Do you want to submit a report on xrdb-mode? ") | |
401 t | |
402 (message "") | |
403 nil) | |
404 (require 'reporter) | |
405 (reporter-submit-bug-report | |
406 xrdb-mode-help-address "xrdb-mode" varlist nil nil "Dear Barry,") | |
407 ))) | |
408 | |
409 | |
410 (provide 'xrdb-mode) | |
411 ;; xrdb-mode.el ends here |