global: Corrected absolute paths in bin/ symbolic links
[h316.git] / resources / dap16-mode.el
CommitLineData
d6a1a234 1;;; dap16-mode.el --- mode for editing DAP-16 assembler code
6f7368da 2
d6a1a234 3;;; Commentary:
4
5;; This mode was written by Philipp Hachtmann <hachti@hachti.de>.
6;; It is based on the asm mode by Eric S. Raymond <esr@snark.thyrsus.com>
7
8;; This minor mode is based on text mode. It defines a private abbrev table
9;; that can be used to save abbrevs for assembler mnemonics. It binds just
10;; five keys:
11;;
12;; TAB tab to next tab stop
13;; : outdent preceding label, tab to tab stop
14;; comment char place or move comment
15;; dap16-comment-char specifies which character this is;
16;; you can use a different character in different
17;; Asm mode buffers.
18;; C-j, C-m newline and tab to tab stop
19;;
20;; Code is indented to the first tab stop level.
21
22;; This mode runs two hooks:
23;; 1) An dap16-mode-set-comment-hook before the part of the initialization
24;; depending on dap16-comment-char, and
25;; 2) an dap16-mode-hook at the end of initialization.
26
27;;; Code:
28
29(defgroup dap16 nil
30 "DAP-16 Assembler programming"
31 :group 'languages)
32
33(defcustom dap16-comment-char ?*
34 "*The comment-start character assumed by Asm mode."
35 :type 'sexp
36 :group 'asm)
37
38;; XEmacs change (This is the primary difference, why was this
39;; feature removed? -sb)
40(defcustom dap16-support-c-comments-p nil
41 "*Support C style comments. If t C style comments will be
42supported. This is mainly for the benefit of font-lock."
43 :type 'boolean
44 :group 'asm)
45
46(defcustom dap16-mode-syntax-table nil
47 "Syntax table used while in Asm mode.")
48
49(defvar dap16-mode-abbrev-table nil
50 "Abbrev table used while in Asm mode.")
51(define-abbrev-table 'dap16-mode-abbrev-table ())
52
53(defvar dap16-mode-map nil
54 "Keymap for Asm mode.")
55
56;;(if dap16-mode-map
57;; nil
58 ;; XEmacs change
59 (setq dap16-mode-map (make-sparse-keymap 'dap16-mode-map))
60 ;; Note that the comment character isn't set up until dap16-mode is called.
61 (define-key dap16-mode-map ":" 'dap16-colon)
62 (define-key dap16-mode-map "\C-h" 'dap16-backspace)
63 (define-key dap16-mode-map "\C-l" 'dap16-halfdelim)
64 (define-key dap16-mode-map "\M-l" 'dap16-fulldelim)
65 (define-key dap16-mode-map "\C-i" 'dap16-tabulator)
66 (define-key dap16-mode-map "\C-cc" 'dap16-comment-region)
67 (define-key dap16-mode-map "\C-c\C-c" 'dap16-comment-region)
68 (define-key dap16-mode-map "\C-a" 'beginning-of-line)
69 (define-key dap16-mode-map "\C-j" 'dap16-newline)
70 (define-key dap16-mode-map "\C-m" 'dap16-newline)
71;; )
72
73;;(defconst dap16-font-lock-keywords
74;; '(("^\\(\\(\\sw\\|\\s_\\)+\\)\\>:?[ \t]*\\(\\sw+\\)?"
75;; (1 font-lock-function-name-face) (3 font-lock-keyword-face nil t))
76;; ("^\\s +\\(\\(\\sw\\|\\s_\\)+\\)" 1 font-lock-keyword-face))
77
78;; "Additional expressions to highlight in Assembler mode.")
79
80;; XEmacs change
81;;(put 'dap16-mode 'font-lock-defaults '(dap16-font-lock-keywords))
82
83;;(defvar dap16-code-level-empty-comment-pattern nil)
84;;(defvar dap16-flush-left-empty-comment-pattern nil)
85;;(defvar dap16-inline-empty-comment-pattern nil)
86
87;;;###autoload
88(defun dap16-mode ()
89 "Major mode for editing Honeywell DAP-16 assembler code.
90Features a private abbrev table and the following bindings:
91
92\\[dap16-colon]\toutdent a preceding label, tab to next tab stop.
93\\[tab-to-tab-stop]\ttab to next tab stop.
94\\[dap16-newline]\tnewline, then tab to next tab stop.
95\\[dap16-comment]\tsmart placement of assembler comments.
96
97Turning on Asm mode runs the hook `dap16-mode-hook' at the end of initialization.
98
99Special commands:
100\\{dap16-mode-map}
101"
102 (interactive)
103
104 (kill-all-local-variables)
105
106 ;; The space after a comment char at the beginning of a line
107 (make-local-variable 'dap16-comment-space)
108 (setq dap16-comment-space " ")
109
110 (setq mode-name "DAP-16")
111 (setq major-mode 'dap16-mode)
112 (setq local-abbrev-table dap16-mode-abbrev-table)
113
114;; (make-local-variable 'tab-stop-list)
115;; (setq tab-stop-list '(6 12 30))
116
117;;(defconst dap16-font-lock-keywords
118;; '(("^\\(\\(\\sw\\|\\s_\\)+\\)\\>:?[ \t]*\\(\\sw+\\)?"
119;; (1 font-lock-function-name-face) (3 font-lock-keyword-face nil t))
120;; ("^\\s +\\(\\(\\sw\\|\\s_\\)+\\)" 1 font-lock-keyword-face))
121
122;; "Additional expressions to highlight in Assembler mode.")
123
124
125 (setq dap16-font-lock-keywords
126 '(
127 (dap16-comment-matcher . font-lock-comment-face)
128;; ("\\<[0-9]+H[^ \t\n]*\\>" . font-lock-keyword-face)
129
130 ("^\\(\\(\\sw\\|\\s_\\)+\\)\\>:?[ \t]*\\(\\sw+\\)?"
131 (1 font-lock-function-name-face) (3 font-lock-keyword-face nil t))
132 ("^\\s +\\(\\(\\sw\\|\\s_\\)+\\)" (1 font-lock-keyword-face))
133)
134
135
136 )
137
138
139 (make-local-variable 'dap16-mode-syntax-table)
140 (setq dap16-mode-syntax-table (make-syntax-table))
141
142 (set-syntax-table dap16-mode-syntax-table)
143
144 (make-local-variable 'font-lock-defaults)
145
146 (setq font-lock-defaults '(
147 dap16-font-lock-keywords
148 nil
149 nil
150 )
151 )
152
153
154
155 (run-hooks 'dap16-mode-set-comment-hook)
156 ;; Make our own local child of dap16-mode-map
157 ;; so we can define our own comment character.
158
159 ;; XEmacs change
160 (let ((ourmap (make-sparse-keymap)))
161 (set-keymap-parents ourmap (list dap16-mode-map))
162 (use-local-map ourmap))
163 (local-set-key (vector dap16-comment-char) 'dap16-comment)
164 ;; XEmacs change
165
166;; (modify-syntax-entry dap16-comment-char "<" dap16-mode-syntax-table)
167;; (modify-syntax-entry ?\n ">" dap16-mode-syntax-table)
168
169;; (modify-syntax-entry ?a "w" dap16-mode-syntax-table)
170
171
172;; (let ((cs (regexp-quote (char-to-string dap16-comment-char))))
173;; (make-local-variable 'comment-start)
174;; (setq comment-start (concat cs dap16-comment-space))
175;; (make-local-variable 'comment-start-skip)
176;; (setq comment-start-skip (concat cs "+[ \t]*"))
177;; (setq dap16-inline-empty-comment-pattern (concat "^.+" cs "+ *$"))
178;; (setq dap16-code-level-empty-comment-pattern (concat "^[\t ]+" cs cs " *$"))
179;; (setq dap16-flush-left-empty-comment-pattern (concat "^" cs cs cs " *$"))
180;; )
181;; (make-local-variable 'comment-end)
182;; (setq comment-end "")
183 (make-local-variable 'comment-column)
184 (setq comment-column 32)
185;; (setq fill-prefix "\t")
186 (run-hooks 'dap16-mode-hook))
187
188(defun dap16-colon ()
189 "Insert a colon; if it follows a label, delete the label's indentation."
190 (interactive)
191 (cond
192 ( (and (is-comment-line) (= (current-column) (length '(dap16-comment-char dap16-comment-space))))
193 (dap16-comment-line)
194 (tab-to-tab-stop)
195 )
196
197 ( (and (not (is-comment-line)) (save-excursion (beginning-of-line) (looking-at "[ \t]+\\(\\sw\\|\\s_\\)+$")))
198 (save-excursion (beginning-of-line) (delete-horizontal-space))
199 (tab-to-tab-stop)
200 )
201
202 (t
203 (insert ":")
204 )
205 )
206 )
207
208
209;_____________________________________________________________________________________________
210
211(defun col ()
212 (+ 1 (current-column))
213)
214
215(defun fc-pos()
216 (save-excursion
217 (end-of-line)
218 (setq cstart (col))
219 (while (> (col) 16)
220 (if (or (= (following-char) ? ) (= (following-char) ?\t) (= (following-char) ?\n))
221 (setq cstart (col)))
222 (backward-char 1))
223 )
224 cstart
225)
226
227(defun dap16-comment-matcher (limit)
228;;(setq p1 (point))
229;;(setq p2 (+ 2 (point)))
230
231 (setq success nil)
232 (setq end-of-buffer-exit nil)
233
234 ;; Consume Newline characters if present.
235 (while (and (< (point) limit) (= (following-char) ?\n) ) (forward-char))
236
237 ;; Save first location to highlight
238 (setq p1 (point))
239 (while (and (< (point) limit) (not (and (= (following-char) ?\n) success)) (not end-of-buffer-exit))
240 (if (or (> (col) (fc-pos)) (is-comment-line))
241 (progn (setq p2 (+ 1 (point)))
242 (if success nil (progn (setq success t) (setq p1 (- (point) 0))))))
243
244 (forward-char))
245
246 (if success (set-match-data (list (- p1 0) (- p2 0))))
247 success
248)
249
250
251;_____________________________________________________________________________________________
252
253(defun dap16-line-matches (pattern &optional withcomment)
254 (save-excursion
255 (beginning-of-line)
256 (looking-at pattern)))
257
258(defun dap16-pop-comment-level ()
259 ;; Delete an empty comment ending current line. Then set up for a new one,
260 ;; on the current line if it was all comment, otherwise above it
261 (end-of-line)
262 (delete-horizontal-space)
263 (while (= (preceding-char) dap16-comment-char)
264 (delete-backward-char 1))
265 (delete-horizontal-space)
266 (if (bolp)
267 nil
268 (beginning-of-line)
269 (open-line 1))
270 )
271
272
273(defun dap16-comment ()
274 "Convert an empty comment to a `larger' kind, or start a new one.
275These are the known comment classes:
276
277 1 -- comment to the right of the code (at the comment-column)
278 2 -- comment on its own line, indented like code
279 3 -- comment on its own line, beginning at the left-most column.
280
281Suggested usage: while writing your code, trigger dap16-comment
282repeatedly until you are satisfied with the kind of comment."
283 (interactive)
284
285 (setq comment-start "")
286
287 (cond
288
289 ;; Blank line? Then start comment.
290 ((dap16-line-matches "^[ \t]*$")
291 (delete-horizontal-space)
292 (insert dap16-comment-char dap16-comment-space)
293 )
294
295 ;; Nonblank line with no comment chars in it?
296 ;; Then start a comment at the current comment column
297 ((and (= (col) 1) (is-comment-line))
298 (dap16-comment-line)
299 )
300
301 ;; Flush-left comment present? Just insert character.
302;; ((dap16-line-matches dap16-flush-left-empty-comment-pattern)
303;; (insert dap16-comment-char))
304
305 ;; Fresh comment line??
306 ((dap16-line-matches (format "^%c%s$" dap16-comment-char dap16-comment-space))
307 (end-of-line)
308 (delete-backward-char (length dap16-comment-space))
309 (insert dap16-comment-char dap16-comment-char)
310 (end-of-line)
311 )
312
313
314 ;; Empty code-level comment already present?
315 ;; Then start flush-left comment, on line above if this one is nonempty.
316;; ((dap16-line-matches dap16-code-level-empty-comment-pattern)
317;; (dap16-pop-comment-level)
318;; (insert dap16-comment-char dap16-comment-char comment-start))
319
320 ;; Empty comment ends line?
321 ;; Then make code-level comment, on line above if this one is nonempty.
322;; ((dap16-line-matches dap16-inline-empty-comment-pattern)
323;; (dap16-pop-comment-level)
324;; (tab-to-tab-stop)
325;; (insert dap16-comment-char comment-start))
326
327 ;; If all else fails, insert character
328 (t
329 (insert dap16-comment-char))
330
331 )
332
333 )
334
335;; ****************************************************************************
336
337
338(defun pos-in-line ()
339 (- (point) (save-excursion (beginning-of-line) (point))))
340
341
342;; Muss verbessert werden!
343(defun at-begin-of-line ()
344;; (interactive)
345;; (setq pos (point) )
346;;(save-excursion
347;; (beginning-of-line)
348;; (if (= pos (point)) t nil)
349;; )
350;;)
351 (interactive)
352 (if (= 0 (current-column)) t nil))
353
354
355(defun is-comment-line ()
356 (if (dap16-line-matches (format "^%c" dap16-comment-char))
357 t
358 nil)
359)
360
361(defun in-comment-spacing ()
362 (if (> (current-column) (length (format "%c%s" dap16-comment-char dap16-comment-space))) nil t)
363)
364
365(defun dap16-comment-line()
366 (interactive)
367 (if (is-comment-line)
368 (save-excursion
369 (beginning-of-line)
370 (delete-char 1)
371 (if (looking-at "^ ")
372 (delete-char 1)
373 )
374 )
375 (save-excursion (beginning-of-line) (insert dap16-comment-char dap16-comment-space))
376 )
377)
378
379(defun line-start()
380 (save-excursion
381 (beginning-of-line)
382 (point)
383 )
384)
385
386
387(defun line-end()
388 (save-excursion
389 (end-of-line)
390 (point)
391 )
392)
393
394(defun dap16-comment-region()
395 (interactive)
396
397 (if (not (region-active-p)) (dap16-comment-line)
398 (save-excursion
399 (goto-char (region-end))
400 (setq lastline (line-number))
401 (goto-char (region-beginning))
402 (while (< (line-number) lastline)
403 (dap16-comment-line)
404 (next-line 1)
405 ))))
406
407
408(defun dap16-backspace ()
409 (interactive)
410 (if (and (is-comment-line) (in-comment-spacing))
411 (delete-region (max (- (line-start) 1) 1) (point))
412 (delete-backward-char 1)
413 )
414;;delete-backward-char (length (format "%c%s" dap16-comment-char dap16-comment-space))) (tab-to-tab-stop))
415;; (delete-backward-char 1)
416 )
417
418(defun dap16-fulldelim ()
419 (interactive)
420 (make-local-variable 'count)
421 (setq count 0)
422 (if (dap16-line-matches (format "^%c%s$" dap16-comment-char dap16-comment-space))
423 (progn (setq count 1)
424 (end-of-line)
425 (delete-backward-char (length dap16-comment-space)))
426 )
427
428 (while (< count 80)
429 (insert dap16-comment-char)
430 (setq count ( 1+ count)))
431)
432
433
434(defun dap16-halfdelim ()
435 (interactive)
436 (make-local-variable 'count)
437 (setq count 0)
438 (if (dap16-line-matches (format "^%c%s$" dap16-comment-char dap16-comment-space))
439 (progn (setq count 1)
440 (end-of-line)
441 (delete-backward-char (length dap16-comment-space)))
442 )
443
444 (while (< count 40)
445 (insert dap16-comment-char)
446 (setq count ( 1+ count)))
447
448)
449
450
451(defun dap16-tabulator ()
452 (interactive)
453 (if (is-comment-line)
454 (progn
455 (setq target (prog2 (insert "\t") (current-column) (delete-backward-char 1) ))
456 (while (< (current-column) target) (insert " "))
457 )
458
459 (tab-to-tab-stop)
460 )
461)
462
463
464(defun dap16-newline ()
465 "Insert LFD + fill-prefix, to bring us back to code-indent level."
466 (interactive)
467
468 (if (is-comment-line)
469 (progn
470 (if (at-begin-of-line) (goto-char (+ (point) 1)))
471 (insert "\n" dap16-comment-char dap16-comment-space))
472 ;; Not comment line
473 (if (eolp)
474 (progn (delete-horizontal-space)
475 (insert "\n")
476 (tab-to-tab-stop)
477 )
478 (insert "\n")
479 ;; (tab-to-tab-stop)
480 )
481 )
482)
483
484
485;; XEmacs addition
486;;;###autoload(add-to-list 'auto-mode-alist '("\\.[sS]\\'" . dap16-mode))
487;;;###autoload(add-to-list 'auto-mode-alist '("\\.asm\\'" . dap16-mode))
488
489;;; dap16-mode.el ends here