~a-roehler/python-mode/XEmacs-compat-test

620 by Andreas Roehler
column-marker.el added
1
;;; column-marker.el --- Highlight certain character columns
2
;; 
3
;; Filename: column-marker.el
4
;; Description: Highlight certain character columns
5
;; Author: Rick Bielawski <rbielaws@i1.net>
6
;; Maintainer: Rick Bielawski <rbielaws@i1.net>
7
;; Created: Tue Nov 22 10:26:03 2005
8
;; Version: 
9
;; Last-Updated: Fri Jan 22 11:28:48 2010 (-0800)
10
;;           By: dradams
11
;;     Update #: 312
12
;; Keywords: tools convenience highlight
13
;; Compatibility: GNU Emacs 21, GNU Emacs 22, GNU Emacs 23
14
;; 
15
;; Features that might be required by this library:
16
;;
17
;;   None
18
;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
;; 
21
;;; Commentary: 
22
;; 
23
;; Highlights the background at a given character column.
24
;; 
25
;; Commands `column-marker-1', `column-marker-2', and
26
;; `column-marker-3' each highlight a given column (using different
27
;; background colors, by default).
28
;;
29
;; - With no prefix argument, each highlights the current column
30
;;   (where the cursor is).
31
;;
32
;; - With a non-negative numeric prefix argument, each highlights that
33
;;   column.
34
;;
35
;; - With plain `C-u' (no number), each turns off its highlighting.
36
;;
37
;; - With `C-u C-u', each turns off all column highlighting.
38
;;
39
;; If two commands highlight the same column, the last-issued
40
;; highlighting command shadows the other - only the last-issued
41
;; highlighting is seen.  If that "topmost" highlighting is then
42
;; turned off, the other highlighting for that column then shows
43
;; through.
44
;;
45
;; Examples:
46
;;
47
;; M-x column-marker-1 highlights the column where the cursor is, in
48
;; face `column-marker-1'.
49
;;
50
;; C-u 70 M-x column-marker-2 highlights column 70 in face
51
;; `column-marker-2'.
52
;;
53
;; C-u 70 M-x column-marker-3 highlights column 70 in face
54
;; `column-marker-3'.  The face `column-marker-2' highlighting no
55
;; longer shows.
56
;;
57
;; C-u M-x column-marker-3 turns off highlighting for column-marker-3,
58
;; so face `column-marker-2' highlighting shows again for column 70.
59
;;
60
;; C-u C-u M-x column-marker-1 (or -2 or -3) erases all column
61
;; highlighting.
62
;;
63
;; These commands use `font-lock-fontify-buffer', so syntax
64
;; highlighting (`font-lock-mode') must be turned on.  There might be
65
;; a performance impact during refontification.
66
;;
67
;;
68
;; Installation: Place this file on your load path, and put this in
69
;; your init file (`.emacs'):
70
;;
71
;; (require 'column-marker)
72
;;
73
;; Other init file suggestions (examples):
74
;;
75
;; ;; Highlight column 80 in foo mode.
76
;; (add-hook 'foo-mode-hook (lambda () (interactive) (column-marker-1 80)))
77
;;
78
;; ;; Use `C-c m' interactively to highlight with face `column-marker-1'.
79
;; (global-set-key [?\C-c ?m] 'column-marker-1)
80
;;
81
;;
82
;; Please report any bugs!
83
;;
84
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
85
;; 
86
;;; Change log:
87
;;
88
;; 2009/12/10 dadams
89
;;     column-marker-internal: Quote the face.  Thx to Johan Bockgård.
90
;; 2009/12/09 dadams
91
;;     column-marker-find: fset a symbol to the function, and return the symbol.
92
;; 2008/01/21 dadams
93
;;     Renamed faces by dropping suffix "-face".
94
;; 2006/08/18 dadams
95
;;     column-marker-create: Add newlines to doc-string sentences.
96
;; 2005/12/31 dadams
97
;;     column-marker-create: Add marker to column-marker-vars inside the defun,
98
;;       so it is done in the right buffer, updating column-marker-vars buffer-locally.
99
;;     column-marker-find: Corrected comment.  Changed or to progn for clarity.
100
;; 2005/12/29 dadams
101
;;     Updated wrt new version of column-marker.el (multi-column characters).
102
;;     Corrected stray occurrences of column-marker-here to column-marker-1.
103
;;     column-marker-vars: Added make-local-variable.
104
;;     column-marker-create: Changed positive to non-negative.
105
;;     column-marker-internal: Turn off marker when col is negative, not < 1.
106
;; 2005-12-29 RGB
107
;;     column-marker.el now supports multi-column characters.
108
;; 2005/11/21 dadams
109
;;     Combined static and dynamic. 
110
;;     Use separate faces for each marker.  Different interactive spec.
111
;; 2005/10/19 RGB
112
;;     Initial release of column-marker.el.
113
;;
114
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
115
;;
116
;; This program is free software; you can redistribute it and/or modify
117
;; it under the terms of the GNU General Public License as published by
118
;; the Free Software Foundation; either version 2, or (at your option)
119
;; any later version.
120
121
;; This program is distributed in the hope that it will be useful,
122
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
123
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
124
;; GNU General Public License for more details.
125
126
;; You should have received a copy of the GNU General Public License
127
;; along with this program; see the file COPYING.  If not, write to
128
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
129
;; Floor, Boston, MA 02110-1301, USA.
130
;;
131
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
132
;; 
133
;;; Code:
134
135
;;;;;;;;;;;;;;;;;;;;;;
136
137
138
(defface column-marker-1 '((t (:background "gray")))
139
  "Face used for a column marker.  Usually a background color."
140
  :group 'faces)
141
142
(defvar column-marker-1-face 'column-marker-1
143
    "Face used for a column marker.  Usually a background color.
144
Changing this directly affects only new markers.")
145
146
(defface column-marker-2 '((t (:background "cyan3")))
147
  "Face used for a column marker.  Usually a background color."
148
  :group 'faces)
149
150
(defvar column-marker-2-face 'column-marker-2
151
    "Face used for a column marker.  Usually a background color.
152
Changing this directly affects only new markers." )
153
154
(defface column-marker-3 '((t (:background "orchid3")))
155
  "Face used for a column marker.  Usually a background color."
156
  :group 'faces)
157
158
(defvar column-marker-3-face 'column-marker-3
159
    "Face used for a column marker.  Usually a background color.
160
Changing this directly affects only new markers." )
161
162
(defvar column-marker-vars ()
163
  "List of all internal column-marker variables")
164
(make-variable-buffer-local 'column-marker-vars) ; Buffer local in all buffers.
165
166
(defmacro column-marker-create (var &optional face)
167
  "Define a column marker named VAR.
168
FACE is the face to use.  If nil, then face `column-marker-1' is used."
169
  (setq face (or face 'column-marker-1))
170
  `(progn
171
     ;; define context variable ,VAR so marker can be removed if desired
172
     (defvar ,var ()
173
       "Buffer local. Used internally to store column marker spec.")
174
     ;; context must be buffer local since font-lock is 
175
     (make-variable-buffer-local ',var)
176
     ;; Define wrapper function named ,VAR to call `column-marker-internal'
177
     (defun ,var (arg)
178
       ,(concat "Highlight column with face `" (symbol-name face)
179
                "'.\nWith no prefix argument, highlight current column.\n"
180
                "With non-negative numeric prefix arg, highlight that column number.\n"
181
                "With plain `C-u' (no number), turn off this column marker.\n"
182
                "With `C-u C-u' or negative prefix arg, turn off all column-marker highlighting.")
183
       (interactive "P")
184
       (unless (memq ',var column-marker-vars) (push ',var column-marker-vars))
185
       (cond ((null arg)          ; Default: highlight current column.
186
              (column-marker-internal ',var (1+ (current-column)) ,face))
187
             ((consp arg)
188
              (if (= 4 (car arg))
189
                  (column-marker-internal ',var nil) ; `C-u': Remove this column highlighting.
190
                (dolist (var column-marker-vars)
191
                  (column-marker-internal var nil)))) ; `C-u C-u': Remove all column highlighting.
192
             ((and (integerp arg) (>= arg 0)) ; `C-u 70': Highlight that column.
193
              (column-marker-internal ',var (1+ (prefix-numeric-value arg)) ,face))
194
             (t           ; `C-u -40': Remove all column highlighting.
195
              (dolist (var column-marker-vars)
196
                (column-marker-internal var nil)))))))
197
198
(defun column-marker-find (col)
199
  "Defines a function to locate a character in column COL.
200
Returns the function symbol, named `column-marker-move-to-COL'."
201
  (let ((fn-symb  (intern (format "column-marker-move-to-%d" col))))
202
    (fset `,fn-symb
203
          `(lambda (end)
204
             (let ((start (point)))
205
               (when (> end (point-max)) (setq end (point-max)))
206
207
               ;; Try to keep `move-to-column' from going backward, though it still can.
208
               (unless (< (current-column) ,col) (forward-line 1))
209
210
               ;; Again, don't go backward.  Try to move to correct column.
211
               (when (< (current-column) ,col) (move-to-column ,col))
212
213
               ;; If not at target column, try to move to it.
214
               (while (and (< (current-column) ,col) (< (point) end)
215
                           (= 0 (+ (forward-line 1) (current-column)))) ; Should be bol.
216
                 (move-to-column ,col))
217
218
               ;; If at target column, not past end, and not prior to start,
219
               ;; then set match data and return t.  Otherwise go to start
220
               ;; and return nil.
221
               (if (and (= ,col (current-column)) (<= (point) end) (> (point) start))
222
                   (progn (set-match-data (list (1- (point)) (point)))
223
                          t)            ; Return t.
224
                 (goto-char start)
225
                 nil))))                ; Return nil.
226
    fn-symb))
227
228
(defun column-marker-internal (sym col &optional face)
229
  "SYM is the symbol for holding the column marker context.
230
COL is the column in which a marker should be set.
231
Supplying nil or 0 for COL turns off the marker.
232
FACE is the face to use.  If nil, then face `column-marker-1' is used."
233
  (setq face (or face 'column-marker-1))
234
  (when (symbol-value sym)   ; Remove any previously set column marker
235
    (font-lock-remove-keywords nil (symbol-value sym))
236
    (set sym nil))
237
  (when (or (listp col) (< col 0)) (setq col nil)) ; Allow nonsense stuff to turn off the marker
238
  (when col                             ; Generate a new column marker
239
    (set sym `((,(column-marker-find col) (0 ',face prepend t))))
240
    (font-lock-add-keywords nil (symbol-value sym) t))
241
  (font-lock-fontify-buffer))
242
243
;; If you need more markers you can create your own similarly.
244
;; All markers can be in use at once, and each is buffer-local,
245
;; so there is no good reason to define more unless you need more
246
;; markers in a single buffer.
247
(column-marker-create column-marker-1 column-marker-1-face)
248
(column-marker-create column-marker-2 column-marker-2-face)
249
(column-marker-create column-marker-3 column-marker-3-face)
250
251
;;;###autoload
252
(autoload 'column-marker-1 "column-marker" "Highlight a column." t)
253
254
;;;;;;;;;;;;;;;;;;
255
256
(provide 'column-marker)
257
258
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
259
;;; column-marker.el ends here