Mercurial > hg > xemacs-beta
comparison lisp/modes/verilog-mode.el @ 22:8fc7fe29b841 r19-15b94
Import from CVS: tag r19-15b94
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:50:29 +0200 |
parents | |
children | ec9a17fef872 |
comparison
equal
deleted
inserted
replaced
21:b88636d63495 | 22:8fc7fe29b841 |
---|---|
1 ;;; verilog-mode.el --- major mode for editing verilog source in Emacs | |
2 | |
3 ;; Copyright (C) 1996 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Michael McNamara (mac@silicon-sorcery.com) | |
6 ;; President, Silicon Sorcery | |
7 ;; Keywords: languages | |
8 | |
9 ;; This file is part of GNU Emacs. | |
10 | |
11 ;; This program is free software; you can redistribute it and/or modify | |
12 ;; it under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation; either version 2 of the License, or | |
14 ;; (at your option) any later version. | |
15 | |
16 ;; This program is distributed in the hope that it will be useful, | |
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with this program; if not, write to the Free Software | |
23 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
24 | |
25 ;;; Commentary: | |
26 | |
27 ;; $Header: /afs/informatik.uni-tuebingen.de/local/web/xemacs/xemacs-cvs/XEmacs/xemacs-19/lisp/modes/verilog-mode.el,v 1.1 1997/02/13 18:53:08 steve Exp $ | |
28 ;; For help figuring out what to do with this file, visit | |
29 ;; <http://www.silicon-sorcery.com/emacs_install.html> | |
30 | |
31 ;; This mode borrows heavily from the pascal-mode and the cc-mode of emacs | |
32 | |
33 ;; USAGE | |
34 ;; ===== | |
35 | |
36 ;; A major mode for editing Verilog HDL source code. When you have | |
37 ;; entered Verilog mode, you may get more info by pressing C-h m. You | |
38 ;; may also get online help describing various functions by: C-h f | |
39 ;; <Name of function you want described> | |
40 | |
41 ;; To set up automatic verilog mode, put this file in your load path, | |
42 ;; and include stuff like this in your .emacs: | |
43 | |
44 ;; (autoload 'verilog-mode "verilog-mode" "Verilog mode" t ) | |
45 ;; (setq auto-mode-alist (cons '("\\.v\\'" . verilog-mode) auto-mode-alist)) | |
46 ;; (setq auto-mode-alist (cons '("\\.dv\\'" . verilog-mode) auto-mode-alist)) | |
47 | |
48 ;; If you want to customize Verilog mode to fit your needs better, | |
49 ;; you may add these lines (the values of the variables presented | |
50 ;; here are the defaults): | |
51 ;; | |
52 ;; ;; User customization for Verilog mode | |
53 ;; (setq verilog-indent-level 3 | |
54 ;; verilog-case-indent 2 | |
55 ;; verilog-auto-newline t | |
56 ;; verilog-auto-indent-on-newline t | |
57 ;; verilog-tab-always-indent t | |
58 ;; verilog-auto-endcomments t | |
59 ;; verilog-minimum-comment-distance 40 | |
60 ;; verilog-indent-begin-after-if t | |
61 ;; verilog-auto-lineup '(all)) | |
62 | |
63 ;; I've put in the common support for colored displays for older | |
64 ;; emacs-19 behaviour, and newer emacs-19 behaviour, as well as | |
65 ;; support for xemacs. After that, customizing according to your | |
66 ;; particular emacs version is up to you. I've used the following | |
67 ;; for emacs 19.27 and emacs 19.30; also xemacs seems to work for me | |
68 ;; as well. I must caution that since the font-lock package doesn't | |
69 ;; have a version number, I've had to key off the emacs version | |
70 ;; number, which might not corrolate with the font-lock package you | |
71 ;; happen to be using... | |
72 | |
73 ;; Cut the following (From ";;;; - HERE - " to ";;;; - THERE -") and | |
74 ;; place the text in your .emacs file. The delete all the single ; | |
75 ;; at the beginning of the lines. | |
76 | |
77 ;; (If you set the mark at the word HERE, (get cursor of the word | |
78 ;; and type C-@) and point at word THERE, and then type C-u M-x | |
79 ;; comment-region it will magically delete all the ; for you) | |
80 | |
81 ;; As coded this should work for modern versions of emacs, and also | |
82 ;; should be a basis where you could build from to get colors for | |
83 ;; other modes. It owes a fair bit to the excellent sample.emacs | |
84 ;; from Xemacs. | |
85 | |
86 | |
87 ;; ;;; - HERE - | |
88 ;;(defvar background-mode 'light) | |
89 ;;(defvar display-type 'color) | |
90 ;; ;; figure out background color. We could ask the user, but that would be too easy | |
91 ;;(cond | |
92 ;; ((and | |
93 ;; (fboundp 'device-type) | |
94 ;; (string= "x" (device-type))) | |
95 ;; (setq display-type (device-class) | |
96 ;; background-mode | |
97 ;; (condition-case nil | |
98 ;; (let ((bg-resource (x-get-resource ".backgroundMode" "BackgroundMode" 'string)) | |
99 ;; (params (frame-parameters))) | |
100 ;; (cond (bg-resource (intern (downcase bg-resource))) | |
101 ;; ((and (cdr (assq 'background-color params)) | |
102 ;; (< (apply '+ (x-color-values | |
103 ;; (cdr (assq 'background-color params)))) | |
104 ;; (/ (apply '+ (x-color-values "white")) 3))) | |
105 ;; 'dark) | |
106 ;; ((and (cdr (assq 'border-color params)) | |
107 ;; (> (apply '+ (color-instance-rgb-components | |
108 ;; (make-color-instance (cdr (assq 'border-color params))))) | |
109 ;; (/ 255 3))) | |
110 ;; 'dark) | |
111 ;; (t 'light))) | |
112 ;; (error 'light)) | |
113 ;; ) | |
114 ;; ) | |
115 ;; ((and | |
116 ;; (boundp 'window-system) | |
117 ;; (string= window-system "x")) | |
118 ;; (setq display-type | |
119 ;; (condition-case nil | |
120 ;; (let ((display-resource (x-get-resource ".displayType" "DisplayType"))) | |
121 ;; (cond (display-resource (intern (downcase display-resource))) | |
122 ;; ((x-display-color-p) 'color) | |
123 ;; ((x-display-grayscale-p) 'grayscale) | |
124 ;; (t 'mono))) | |
125 ;; (error 'mono)) | |
126 ;; ) | |
127 ;; (setq background-mode | |
128 ;; (condition-case nil | |
129 ;; (let ((bg-resource (x-get-resource ".backgroundMode" | |
130 ;; "BackgroundMode" )) | |
131 ;; (params (frame-parameters))) | |
132 ;; (cond (bg-resource (intern (downcase bg-resource))) | |
133 ;; ((and (cdr (assq 'background-color params)) | |
134 ;; (< (apply '+ (x-color-values | |
135 ;; (cdr (assq 'background-color params)))) | |
136 ;; (/ (apply '+ (x-color-values "white")) 3))) | |
137 ;; 'dark) | |
138 ;; ((and (fboundp 'color-instance-rgb-components ) | |
139 ;; (cdr (assq 'border-color params)) | |
140 ;; (> (apply '+ (color-instance-rgb-components | |
141 ;; (make-color-instance (cdr (assq 'border-color params))))) | |
142 ;; (/ 255 3))) | |
143 ;; 'dark) | |
144 ;; (t 'light))) | |
145 ;; (error 'light)) | |
146 ;; ) | |
147 ;; )) | |
148 | |
149 ;;(message "It appears you have a %s background" background-mode) | |
150 | |
151 ;; ; Now do emacs version specific color setup | |
152 ;;(cond | |
153 ;; ((and (string-match "XEmacs" emacs-version) | |
154 ;; (boundp 'emacs-major-version) | |
155 ;; (= emacs-major-version 19) | |
156 ;; (>= emacs-minor-version 12)) | |
157 | |
158 ;; ;; If you want the default colors, you could do this: | |
159 ;; ;; (setq font-lock-use-default-fonts nil) | |
160 ;; ;; (setq font-lock-use-default-colors t) | |
161 ;; ;; but I want to specify my own colors, so I turn off all | |
162 ;; ;; default values. | |
163 ;; (setq font-lock-use-default-fonts nil) | |
164 ;; (setq font-lock-use-default-colors nil) | |
165 ;; (require 'font-lock) | |
166 | |
167 ;; ;; Mess around with the faces a bit. Note that you have | |
168 ;; ;; to change the font-lock-use-default-* variables *before* | |
169 ;; ;; loading font-lock, and wait till *after* loading font-lock | |
170 ;; ;; to customize the faces. | |
171 | |
172 ;; ;; (use copy-face instead of make-face-italic/make-face-bold because | |
173 ;; ;; the startup code does intelligent things to the 'italic and 'bold | |
174 ;; ;; faces to ensure that they are different from the default face. | |
175 ;; ;; For example, if the default face is bold, then the 'bold face | |
176 ;; ;; will be unbold.) | |
177 ;; ;; Underling comments looks terrible on tty's | |
178 ;; (set-face-underline-p 'font-lock-comment-face nil 'global 'tty) | |
179 ;; (set-face-highlight-p 'font-lock-comment-face t 'global 'tty) | |
180 | |
181 ;; (make-face-unitalic 'font-lock-comment-face) | |
182 ;; (make-face-unitalic 'font-lock-string-face) | |
183 ;; (copy-face 'bold 'font-lock-function-name-face) | |
184 ;; (cond | |
185 ;; ((eq background-mode 'light) | |
186 ;; (set-face-foreground 'font-lock-comment-face "orchid") | |
187 ;; (set-face-foreground 'font-lock-function-name-face "red") | |
188 ;; (set-face-foreground 'font-lock-keyword-face "blue") | |
189 ;; (set-face-foreground 'font-lock-string-face "steelblue") | |
190 ;; (set-face-foreground 'font-lock-type-face "darkgreen") | |
191 ;; ) | |
192 ;; ((eq background-mode 'dark) | |
193 ;; (set-face-foreground 'font-lock-comment-face "#efc80c") | |
194 ;; (set-face-foreground 'font-lock-function-name-face "red") | |
195 ;; (set-face-foreground 'font-lock-keyword-face "tan") | |
196 ;; (set-face-foreground 'font-lock-string-face "lightskyblue") | |
197 ;; (set-face-foreground 'font-lock-type-face "Aquamarine") | |
198 ;; ) | |
199 ;; ) | |
200 ;; ;; misc. faces | |
201 ;; (and (find-face 'font-lock-preprocessor-face) ; 19.13 and above | |
202 ;; (copy-face 'bold 'font-lock-preprocessor-face)) | |
203 ;; ) | |
204 ;; ((> emacs-minor-version 29) | |
205 ;; (if (eq background-mode 'light) | |
206 ;; (setq font-lock-face-attributes | |
207 ;; '( | |
208 ;; (font-lock-comment-face "orchid" nil nil t nil) | |
209 ;; (font-lock-function-name-face "red" nil t nil nil) | |
210 ;; (font-lock-keyword-face "blue" nil nil nil nil) | |
211 ;; (font-lock-reference-face "indianred" nil t nil nil ) | |
212 ;; (font-lock-string-face "steelblue" nil nil nil nil) | |
213 ;; (font-lock-type-face "darkgreen" nil nil nil nil) | |
214 ;; (font-lock-variable-name-face "brown") | |
215 ;; ) | |
216 ;; ) | |
217 ;; (setq font-lock-face-attributes | |
218 ;; '( | |
219 ;; (font-lock-comment-face "#efc80c" nil nil t nil) | |
220 ;; (font-lock-function-name-face "red" nil t nil nil) | |
221 ;; (font-lock-keyword-face "tan" nil nil nil nil) | |
222 ;; (font-lock-reference-face "indianred" nil t nil nil ) | |
223 ;; (font-lock-string-face "lightskyblue" nil nil nil nil) | |
224 ;; (font-lock-type-face "Aquamarine" nil nil nil nil) | |
225 ;; (font-lock-variable-name-face "LightGoldenrod") | |
226 ;; ) | |
227 ;; ) | |
228 ;; ) | |
229 ;; ) | |
230 ;; (t | |
231 ;; (if (eq background-mode 'dark) | |
232 ;; (progn | |
233 ;; (make-face 'my-font-lock-function-name-face) | |
234 ;; (set-face-foreground 'my-font-lock-function-name-face "red") | |
235 ;; (setq font-lock-function-name-face 'my-font-lock-function-name-face) | |
236 | |
237 ;; (make-face 'my-font-lock-keyword-face) | |
238 ;; (set-face-foreground 'my-font-lock-keyword-face "tan") | |
239 ;; (setq font-lock-keyword-face 'my-font-lock-keyword-face) | |
240 | |
241 ;; (make-face 'my-font-lock-string-face) | |
242 ;; (set-face-foreground 'my-font-lock-string-face "lightskyblue") | |
243 ;; (setq font-lock-string-face 'my-font-lock-string-face) | |
244 | |
245 ;; (make-face 'my-font-lock-type-face) | |
246 ;; (set-face-foreground 'my-font-lock-type-face "#efc80c") ; yellow | |
247 ;; (setq font-lock-type-face 'my-font-lock-type-face) | |
248 | |
249 ;; (make-face 'my-font-lock-variable-name-face) | |
250 ;; (set-face-foreground 'my-font-lock-variable-name-face "LightGoldenrod") | |
251 ;; (setq font-lock-variable-name-face 'my-font-lock-variable-name-face) | |
252 ;; ) | |
253 ;; (progn | |
254 ;; (make-face 'my-font-lock-function-name-face) | |
255 ;; (set-face-foreground 'my-font-lock-function-name-face "DarkGreen") | |
256 ;; (setq font-lock-function-name-face 'my-font-lock-function-name-face) | |
257 | |
258 ;; (make-face 'my-font-lock-keyword-face) | |
259 ;; (set-face-foreground 'my-font-lock-keyword-face "indianred") | |
260 ;; (setq font-lock-keyword-face 'my-font-lock-keyword-face) | |
261 | |
262 ;; (make-face 'my-font-lock-string-face) | |
263 ;; (set-face-foreground 'my-font-lock-string-face "RoyalBlue") | |
264 ;; (setq font-lock-string-face 'my-font-lock-string-face) | |
265 | |
266 ;; (make-face 'my-font-lock-type-face) | |
267 ;; (set-face-foreground 'my-font-lock-type-face "#003800") ; yellow | |
268 ;; (setq font-lock-type-face 'my-font-lock-type-face) | |
269 | |
270 ;; (make-face 'my-font-lock-variable-name-face) | |
271 ;; (set-face-foreground 'my-font-lock-variable-name-face "LightGoldenrod") | |
272 ;; (setq font-lock-variable-name-face 'my-font-lock-variable-name-face) | |
273 ;; ) | |
274 ;; ) | |
275 ;; ) | |
276 ;; ) | |
277 | |
278 ;;(cond | |
279 ;; ((eq display-type 'color) | |
280 ;; ;; Pretty Colors in source windows. | |
281 ;; (require 'font-lock) | |
282 ;; (autoload 'turn-on-fast-lock "fast-lock" | |
283 ;; "Unconditionally turn on Fast Lock mode.") | |
284 ;; (add-hook 'c-mode-hook 'font-lock-mode) | |
285 ;; (add-hook 'verilog-mode-hook 'font-lock-mode) | |
286 ;; (add-hook 'perl-mode-hook 'font-lock-mode) | |
287 ;; (add-hook 'elisp-mode-hook 'font-lock-mode) | |
288 ;; (add-hook 'asm-mode-hook 'font-lock-mode) | |
289 ;; (setq fast-lock-cache-directories '("~/.backups" ".")) | |
290 ;; (setq c-font-lock-keywords c-font-lock-keywords-2) | |
291 ;; (setq c++-font-lock-keywords c++-font-lock-keywords-2) | |
292 ;; (autoload 'verilog-make-faces "verilog-mode" "Set up faces for verilog") | |
293 ;; (if (not (string-match "XEmacs" emacs-version)) | |
294 ;; (progn | |
295 ;; (cond | |
296 ;; ((eq background-mode 'dark) | |
297 ;; ;; Make background a light gray | |
298 ;; (set-face-background (quote region) "gray30")) | |
299 ;; ;; Make background a dark gray | |
300 ;; ((eq background-mode 'light) | |
301 ;; (set-face-background (quote region) "gray70")) | |
302 ;; ) | |
303 ;; ) | |
304 ;; ) | |
305 ;; ) | |
306 ;; ((eq display-type 'mono) | |
307 ;; (progn | |
308 ;; ;; Frames are too expensive to create | |
309 ;; ;; on my NCD running x-remote, which happens | |
310 ;; ;; to be the only place I run X mono color | |
311 ;; (setq vm-frame-per-composition nil | |
312 ;; vm-frame-per-folder nil) | |
313 ;; ) | |
314 ;; ) | |
315 ;; ) | |
316 ;; ;;; - THERE - | |
317 | |
318 ;; KNOWN BUGS / BUGREPORTS | |
319 ;; ======================= This is beta code, and likely has | |
320 ;; bugs. Please report any and all bugs to me at mac@silicon-sorcery.com. | |
321 ;; | |
322 | |
323 ;;; Code: | |
324 | |
325 (provide 'verilog-mode) | |
326 | |
327 ;; This variable will always hold the version number of the mode | |
328 (defconst verilog-mode-version "$$Revision: 1.1 $$" | |
329 "Version of this verilog mode.") | |
330 | |
331 (defvar verilog-indent-level 3 | |
332 "*Indentation of Verilog statements with respect to containing block.") | |
333 | |
334 (defvar verilog-cexp-indent 1 | |
335 "*Indentation of Verilog statements split across lines.") | |
336 | |
337 (defvar verilog-case-indent 2 | |
338 "*Indentation for case statements.") | |
339 | |
340 (defvar verilog-auto-newline t | |
341 "*Non-nil means automatically newline after semicolons") | |
342 | |
343 (defvar verilog-auto-indent-on-newline t | |
344 "*Non-nil means automatically indent line after newline") | |
345 | |
346 (defvar verilog-tab-always-indent t | |
347 "*Non-nil means TAB in Verilog mode should always reindent the current line, | |
348 regardless of where in the line point is when the TAB command is used.") | |
349 | |
350 (defvar verilog-indent-begin-after-if t | |
351 "*If true, indent begin statements following if, else, while, for and repeat. | |
352 otherwise, line them up.") | |
353 | |
354 (defvar verilog-auto-endcomments t | |
355 "*Non-nil means a comment /* ... */ is set after the ends which ends cases and | |
356 functions. The name of the function or case will be set between the braces.") | |
357 | |
358 (defvar verilog-minimum-comment-distance 40 | |
359 "*Minimum distance between begin and end required before a comment will be inserted. | |
360 Setting this variable to zero results in every end aquiring a comment; the default avoids | |
361 too many redundanet comments in tight quarters") | |
362 | |
363 (defvar verilog-auto-lineup '(all) "*List of contexts where auto | |
364 lineup of :'s or ='s should be done. Elements can be of type: | |
365 'declaration' or 'case', which will do auto lineup in declarations | |
366 or case-statements respectively. The word 'all' will do all | |
367 lineups. '(case declaration) for instance will do lineup in | |
368 case-statements and parameterlist, while '(all) will do all | |
369 lineups." ) | |
370 | |
371 (defvar verilog-mode-abbrev-table nil | |
372 "Abbrev table in use in Verilog-mode buffers.") | |
373 | |
374 (defvar verilog-font-lock-keywords-after-1930 | |
375 '( | |
376 ("^[ \t]*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>[ \t]*" | |
377 1 font-lock-keyword-face) | |
378 ("^[ \t]*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>[ \t]*\\(\\sw+\\)" | |
379 2 font-lock-function-name-face nil t) | |
380 ("\\\\[^ \t]*" 0 'font-lock-function-name-face) ( | |
381 "\\(@\\)\\|\\(#\[ \t\]*\\(\\(\[0-9\]+\\('[hdxbo][0-9_xz]*\\)?\\)\\|\\((\[^)\]*)\\)\\)\\)" | |
382 0 font-lock-type-face) | |
383 ("\\(`[ \t]*[A-Za-z][A-Za-z0-9_]*\\)" 0 font-lock-type-face) | |
384 ("\\<\\(in\\(teger\\|put\\|out\\)\\|parameter\\|defparam\\|output\\|supply[01]?\\|event\\|tri\\(0\\|1\\|reg\\|and\\|or\\)?\\|w\\(ire\\|or\\|and\\)\\|time\\|re\\(al\\(time\\)?\\|g\\)\\)\\>" | |
385 0 font-lock-type-face) | |
386 ("\\(\\$[a-zA-Z][a-zA-Z0-9_\\$]*\\)\\|\\(\\<\\(begin\\|case[xz]?\\|end\\(case\\|function\\|task\\|module\\|table\\|primitive\\|specify\\)?\\|a\\(ssign\\|lways\\)\\|default\\|initial\\|table\\|\\(pos\\|neg\\)edge\\|else\\|for\\(ever\\|k\\)?\\|join\\|if\\|repeat\\|then\\|while\\|specify\\)\\>\\)" | |
387 0 font-lock-keyword-face) | |
388 ) | |
389 ) | |
390 (defvar verilog-font-lock-keywords nil) | |
391 (defvar verilog-font-lock-keywords-before-1930 | |
392 '( | |
393 ("^[ \t]*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>[ \t]*" . 1) | |
394 ("^[ \t]*\\(function\\|task\\|module\\|macromodule\\|primitive\\)\\>[ \t]*\\(\\sw+\\)" | |
395 2 font-lock-function-name-face nil t) | |
396 ("\\(\\\\[^ \t]*\\)\\|\\(`[ \t]*[A-Za-z][A-Za-z0-9_]*\\)" 0 font-lock-function-name-face) | |
397 ("[@#]" . font-lock-type-face) | |
398 ("\\<\\(in\\(teger\\|put\\|out\\)\\|parameter\\|defparam\\|output\\|supply[01]?\\|event\\|tri\\(0\\|1\\|reg\\|and\\|or\\)?\\|w\\(ire\\|or\\|and\\)\\|time\\|re\\(al\\(time\\)?\\|g\\)\\)\\>" | |
399 0 font-lock-type-face) | |
400 ("\\(\\$[a-zA-Z][a-zA-Z0-9_\\$]*\\)\\|\\(\\<\\(begin\\|case[xz]?\\|end\\(case\\|function\\|task\\|module\\|table\\|primitive\\|specify\\)?\\|a\\(ssign\\|lways\\)\\|default\\|initial\\|table\\|\\(pos\\|neg\\)edge\\|else\\|for\\(ever\\|k\\)?\\|join\\|if\\|repeat\\|then\\|while\\|specify\\)\\>\\)" . font-lock-keyword-face) | |
401 ) | |
402 ) | |
403 | |
404 (defvar verilog-imenu-generic-expression | |
405 '("^[ \t]*\\(module\\|macromodule\\|primitive\\)[ \t\n]+\\([a-zA-Z0-9_.:]+\\)" . (2)) | |
406 "Imenu expression for Verilog-mode. See `imenu-generic-expression'.") | |
407 | |
408 (defvar verilog-mode-abbrev-table nil | |
409 "Abbrev table in use in Verilog-mode buffers.") | |
410 | |
411 | |
412 (define-abbrev-table 'verilog-mode-abbrev-table ()) | |
413 | |
414 (defvar verilog-mode-map () | |
415 "Keymap used in Verilog mode.") | |
416 (if verilog-mode-map | |
417 () | |
418 (setq verilog-mode-map (make-sparse-keymap)) | |
419 (define-key verilog-mode-map ";" 'electric-verilog-semi) | |
420 (define-key verilog-mode-map ":" 'electric-verilog-colon) | |
421 (define-key verilog-mode-map "=" 'electric-verilog-equal) | |
422 (define-key verilog-mode-map "\`" 'electric-verilog-tick) | |
423 (define-key verilog-mode-map "\t" 'electric-verilog-tab) | |
424 (define-key verilog-mode-map "\r" 'electric-verilog-terminate-line) | |
425 (define-key verilog-mode-map "\M-\C-b" 'electric-verilog-backward-sexp) | |
426 (define-key verilog-mode-map "\M-\C-f" 'electric-verilog-forward-sexp) | |
427 (define-key verilog-mode-map "\M-\r" (function (lambda () | |
428 (interactive) (electric-verilog-terminate-line 1)))) | |
429 (define-key verilog-mode-map "\177" 'backward-delete-char-untabify) | |
430 (define-key verilog-mode-map "\M-\t" 'verilog-complete-word) | |
431 (define-key verilog-mode-map "\M-?" 'verilog-show-completions) | |
432 (define-key verilog-mode-map "\M-\C-h" 'verilog-mark-defun) | |
433 (define-key verilog-mode-map "\C-c\C-b" 'verilog-insert-block) | |
434 (define-key verilog-mode-map "\C-cb" 'verilog-label-be) | |
435 (define-key verilog-mode-map "\M-*" 'verilog-star-comment) | |
436 (define-key verilog-mode-map "\C-c\C-c" 'verilog-comment-area) | |
437 (define-key verilog-mode-map "\C-c\C-u" 'verilog-uncomment-area) | |
438 (define-key verilog-mode-map "\M-\C-a" 'verilog-beg-of-defun) | |
439 (define-key verilog-mode-map "\M-\C-e" 'verilog-end-of-defun) | |
440 (define-key verilog-mode-map "\C-c\C-d" 'verilog-goto-defun) | |
441 ) | |
442 | |
443 | |
444 | |
445 ;;; | |
446 ;;; Regular expressions used to calculate indent, etc. | |
447 ;;; | |
448 (defconst verilog-symbol-re "\\<[a-zA-Z_][a-zA-Z_0-9.]*\\>") | |
449 (defconst verilog-case-re "\\(\\<case[xz]?\\>[^:]\\)") | |
450 ;; Want to match | |
451 ;; aa : | |
452 ;; aa,bb : | |
453 ;; a[34:32] : | |
454 ;; a, | |
455 ;; b : | |
456 (defconst verilog-no-indent-begin-re "\\<\\(if\\|else\\|while\\|for\\|repeat\\|always\\)\\>") | |
457 (defconst verilog-endcomment-reason-re | |
458 (concat | |
459 "\\(\\<fork\\>\\)\\|\\(\\<begin\\>\\)\\|\\(\\<if\\>\\)\\|\\(\\<else\\>\\)\\|" | |
460 "\\(\\<task\\>\\)\\|\\(\\<function\\>\\)\\|\\(\\<initial\\>\\)\\|\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|" | |
461 "\\(\\<while\\>\\)\\|\\(\\<for\\(ever\\)?\\>\\)\\|\\(\\<repeat\\>\\)\\|\\(\\<wait\\>\\)\\|" | |
462 "#")) | |
463 | |
464 (defconst verilog-named-block-re "begin[ \t]*:") | |
465 (defconst verilog-beg-block-re "\\<\\(begin\\|case\\|casex\\|casez\\|fork\\|table\\|specify\\)\\>") | |
466 (defconst verilog-beg-block-re-1 "\\<\\(begin\\)\\|\\(case[xz]?\\)\\|\\(fork\\)\\|\\(table\\)\\|\\(specify\\)\\|\\(function\\)\\|\\(task\\)\\>") | |
467 (defconst verilog-end-block-re "\\<\\(end\\|join\\|endcase\\|endtable\\|endspecify\\)\\>") | |
468 (defconst verilog-end-block-re-1 "\\(\\<end\\>\\)\\|\\(\\<endcase\\>\\)\\|\\(\\<join\\>\\)\\|\\(\\<endtable\\>\\)\\|\\(\\<endspecify\\>\\)\\|\\(\\<endfunction\\>\\)\\|\\(\\<endtask\\>\\)") | |
469 (defconst verilog-declaration-re | |
470 (concat "\\(\\<in\\(put\\|out\\|teger\\)\\>\\|" | |
471 "\\<parameter\\>\\|\\<defparam\\>\\|\\<output\\>\\|\\<event\\>\\|" | |
472 "\\<re\\(al\\|g\\|altime\\)\\>\\|" | |
473 "\\<time\\>\\|\\<tri\\(0\\|1\\|and\\|or\\|reg\\)?\\>\\|" | |
474 "\\<supply[01]\\>\\|\\<w\\(and\\|or\\|ire\\)\\>\\)")) | |
475 (defconst verilog-declaration-re-1 (concat "^[ \t]*" verilog-declaration-re "[ \t]*\\(\\[[^]]*\\][ \t]*\\)?")) | |
476 (defconst verilog-defun-re "\\<\\(module\\|macromodule\\|primitive\\)\\>") | |
477 (defconst verilog-end-defun-re "\\<\\(endmodule\\|endprimitive\\)\\>") | |
478 (defconst verilog-zero-indent-re | |
479 (concat verilog-defun-re "\\|" verilog-end-defun-re)) | |
480 (defconst verilog-directive-re | |
481 "\\(`else\\)\\|\\(`ifdef\\)\\|\\(`endif\\)\\|\\(`define\\)\\|\\(`undef\\)\\|\\(`include\\)") | |
482 (defconst verilog-autoindent-lines-re | |
483 (concat | |
484 "\\<\\(\\(macro\\)?module\\|primitive\\|end\\(case\\|function\\|task\\|module\\|primitive\\|specify\\|table\\)?\\|join\\|begin\\|else\\)\\>\\|`\\(else\\|ifdef\\|endif\\)\\|" | |
485 verilog-directive-re | |
486 "\\>")) | |
487 (defconst verilog-behavorial-block-beg-re | |
488 "\\(\\<initial\\>\\|\\<always\\>\\|\\<function\\>\\|\\<task\\>\\)") | |
489 (defconst verilog-indent-reg | |
490 (concat "\\(\\<begin\\>\\|\\<case[xz]?\\>[^:]\\|\\<specify\\>\\|\\<fork\\>\\|\\<table\\>\\)\\|" | |
491 "\\(\\<end\\>\\|\\<join\\>\\|\\<endcase\\>\\|\\<endtable\\>\\|\\<endspecify\\>\\)\\|" | |
492 "\\(\\<module\\>\\|\\<macromodule\\>\\|\\<primitive\\>\\|\\<initial\\>\\|\\<always\\>\\)\\|" | |
493 "\\(\\<endmodule\\>\\|\\<endprimitive\\>\\)\\|" | |
494 "\\(\\<endtask\\>\\|\\<endfunction\\>\\)\\|" | |
495 "\\(\\<function\\>\\|\\<task\\>\\)" | |
496 ;; "\\|\\(\\<if\\>\\|\\<else\\>\\)" | |
497 )) | |
498 (defconst verilog-complete-reg | |
499 "\\(\\<always\\>\\)\\|\\(\\<repeat\\>\\)\\|\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<while\\>\\)\\|\\(\\<if\\>\\)\\|\\(\\<for\\(ever\\)?\\>\\)") | |
500 (defconst verilog-end-statement-re | |
501 (concat "\\(" verilog-beg-block-re "\\)\\|\\(" | |
502 verilog-end-block-re "\\)")) | |
503 (defconst verilog-endcase-re | |
504 (concat verilog-case-re "\\|" | |
505 "\\(endcase\\)\\|" | |
506 verilog-defun-re | |
507 )) | |
508 ;;; Strings used to mark beginning and end of excluded text | |
509 (defconst verilog-exclude-str-start "/* -----\\/----- EXCLUDED -----\\/-----") | |
510 (defconst verilog-exclude-str-end " -----/\\----- EXCLUDED -----/\\----- */") | |
511 | |
512 (defconst verilog-emacs-features | |
513 (let ((major (and (boundp 'emacs-major-version) | |
514 emacs-major-version)) | |
515 (minor (and (boundp 'emacs-minor-version) | |
516 emacs-minor-version)) | |
517 flavor comments) | |
518 ;; figure out version numbers if not already discovered | |
519 (and (or (not major) (not minor)) | |
520 (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version) | |
521 (setq major (string-to-int (substring emacs-version | |
522 (match-beginning 1) | |
523 (match-end 1))) | |
524 minor (string-to-int (substring emacs-version | |
525 (match-beginning 2) | |
526 (match-end 2))))) | |
527 (if (not (and major minor)) | |
528 (error "Cannot figure out the major and minor version numbers.")) | |
529 ;; calculate the major version | |
530 (cond | |
531 ((= major 18) (setq major 'v18)) ;Emacs 18 | |
532 ((= major 4) (setq major 'v18)) ;Epoch 4 | |
533 ((= major 19) (setq major 'v19 ;Emacs 19 | |
534 flavor (if (or (string-match "Lucid" emacs-version) | |
535 (string-match "XEmacs" emacs-version)) | |
536 'XEmacs 'FSF))) | |
537 ((= major 20) (setq major 'v20 ;XEmacs 20 | |
538 flavor 'XEmacs)) | |
539 ;; I don't know | |
540 (t (error "Cannot recognize major version number: %s" major))) | |
541 ;; All XEmacs 19's (formerly Lucid) use 8-bit modify-syntax-entry | |
542 ;; flags, as do all patched (obsolete) Emacs 19, Emacs 18, | |
543 ;; Epoch 4's. Only vanilla Emacs 19 uses 1-bit flag. Lets be | |
544 ;; as smart as we can about figuring this out. | |
545 (if (or (eq major 'v20) (eq major 'v19)) | |
546 (let ((table (copy-syntax-table))) | |
547 (modify-syntax-entry ?a ". 12345678" table) | |
548 (cond | |
549 ;; XEmacs pre 20 and Emacs pre 19.30 use vectors for syntax tables. | |
550 ((vectorp table) | |
551 (if (= (logand (lsh (aref table ?a) -16) 255) 255) | |
552 (setq comments '8-bit) | |
553 (setq comments '1-bit))) | |
554 ;; XEmacs 20 is known to be 8-bit | |
555 ((eq flavor 'XEmacs) (setq comments '8-bit)) | |
556 ;; Emacs 19.30 and beyond are known to be 1-bit | |
557 ((eq flavor 'FSF) (setq comments '1-bit)) | |
558 ;; Don't know what this is | |
559 (t (error "Couldn't figure out syntax table format.")) | |
560 )) | |
561 ;; Emacs 18 has no support for dual comments | |
562 (setq comments 'no-dual-comments)) | |
563 ;; lets do some minimal sanity checking. | |
564 (if (or | |
565 ;; Lemacs before 19.6 had bugs | |
566 (and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6)) | |
567 ;; Emacs 19 before 19.21 has known bugs | |
568 (and (eq major 'v19) (eq flavor 'FSF) (< minor 21)) | |
569 ) | |
570 (with-output-to-temp-buffer "*verilog-mode warnings*" | |
571 (print (format | |
572 "The version of Emacs that you are running, %s, | |
573 has known bugs in its syntax parsing routines which will affect the | |
574 performance of verilog-mode. You should strongly consider upgrading to the | |
575 latest available version. verilog-mode may continue to work, after a | |
576 fashion, but strange indentation errors could be encountered." | |
577 emacs-version)))) | |
578 ;; Emacs 18, with no patch is not too good | |
579 (if (and (eq major 'v18) (eq comments 'no-dual-comments)) | |
580 (with-output-to-temp-buffer "*verilog-mode warnings*" | |
581 (print (format | |
582 "The version of Emacs 18 you are running, %s, | |
583 has known deficiencies in its ability to handle the dual verilog | |
584 (and C++) comments, (e.g. the // and /* */ comments). This will | |
585 not be much of a problem for you if you only use the /* */ comments, | |
586 but you really should strongly consider upgrading to one of the latest | |
587 Emacs 19's. In Emacs 18, you may also experience performance degradations. | |
588 Emacs 19 has some new built-in routines which will speed things up for you. | |
589 Because of these inherent problems, verilog-mode is not supported | |
590 on emacs-18." | |
591 emacs-version)))) | |
592 ;; Emacs 18 with the syntax patches are no longer supported | |
593 (if (and (eq major 'v18) (not (eq comments 'no-dual-comments))) | |
594 (with-output-to-temp-buffer "*verilog-mode warnings*" | |
595 (print (format | |
596 "You are running a syntax patched Emacs 18 variant. While this should | |
597 work for you, you may want to consider upgrading to Emacs 19. | |
598 The syntax patches are no longer supported either for verilog-mode.")))) | |
599 (list major comments)) | |
600 "A list of features extant in the Emacs you are using. | |
601 There are many flavors of Emacs out there, each with different | |
602 features supporting those needed by verilog-mode. Here's the current | |
603 supported list, along with the values for this variable: | |
604 | |
605 Vanilla Emacs 18/Epoch 4: (v18 no-dual-comments) | |
606 Emacs 18/Epoch 4 (patch2): (v18 8-bit) | |
607 XEmacs (formerly Lucid) 19: (v19 8-bit) | |
608 Emacs 19: (v19 1-bit).") | |
609 | |
610 (defconst verilog-comment-start-regexp "//\\|/\\*" | |
611 "Dual comment value for `comment-start-regexp'.") | |
612 | |
613 (defun verilog-populate-syntax-table (table) | |
614 ;; Populate the syntax TABLE | |
615 ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS! | |
616 (modify-syntax-entry ?\\ "\\" table) | |
617 (modify-syntax-entry ?+ "." table) | |
618 (modify-syntax-entry ?- "." table) | |
619 (modify-syntax-entry ?= "." table) | |
620 (modify-syntax-entry ?% "." table) | |
621 (modify-syntax-entry ?< "." table) | |
622 (modify-syntax-entry ?> "." table) | |
623 (modify-syntax-entry ?& "." table) | |
624 (modify-syntax-entry ?| "." table) | |
625 (modify-syntax-entry ?_ "w" table) | |
626 (modify-syntax-entry ?\' "." table) | |
627 ) | |
628 | |
629 (defun verilog-setup-dual-comments (table) | |
630 ;; Set up TABLE to handle block and line style comments | |
631 (cond | |
632 ((memq '8-bit verilog-emacs-features) | |
633 ;; XEmacs (formerly Lucid) has the best implementation | |
634 (modify-syntax-entry ?/ ". 1456" table) | |
635 (modify-syntax-entry ?* ". 23" table) | |
636 (modify-syntax-entry ?\n "> b" table) | |
637 ;; Give CR the same syntax as newline, for selective-display | |
638 (modify-syntax-entry ?\^m "> b" table)) | |
639 ((memq '1-bit verilog-emacs-features) | |
640 ;; Emacs 19 does things differently, but we can work with it | |
641 (modify-syntax-entry ?/ ". 124b" table) | |
642 (modify-syntax-entry ?* ". 23" table) | |
643 (modify-syntax-entry ?\n "> b" table) | |
644 ;; Give CR the same syntax as newline, for selective-display | |
645 (modify-syntax-entry ?\^m "> b" table)) | |
646 )) | |
647 | |
648 (defvar verilog-mode-syntax-table nil | |
649 "Syntax table used in verilog-mode buffers.") | |
650 (if verilog-mode-syntax-table | |
651 () | |
652 (setq verilog-mode-syntax-table (make-syntax-table)) | |
653 (verilog-populate-syntax-table verilog-mode-syntax-table) | |
654 ;; add extra comment syntax | |
655 (verilog-setup-dual-comments verilog-mode-syntax-table) | |
656 ) | |
657 ;;; | |
658 ;;; Macros | |
659 ;;; | |
660 | |
661 (defsubst verilog-re-search-forward (REGEXP BOUND NOERROR) | |
662 "Like re-search-forward, but skips over matches in comments or strings" | |
663 (set-match-data '(nil nil)) | |
664 (while (and | |
665 (re-search-forward REGEXP BOUND NOERROR) | |
666 (and (verilog-skip-forward-comment-or-string) | |
667 (progn | |
668 (store-match-data '(nil nil)) | |
669 (if BOUND | |
670 (< (point) BOUND) | |
671 t) | |
672 ) | |
673 ) | |
674 ) | |
675 ) | |
676 (match-end 0)) | |
677 | |
678 (defsubst verilog-re-search-backward (REGEXP BOUND NOERROR) | |
679 "Like re-search-backward, but skips over matches in comments or strings" | |
680 (set-match-data '(nil nil)) | |
681 (while (and | |
682 (re-search-backward REGEXP BOUND NOERROR) | |
683 (verilog-skip-backward-comment-or-string) | |
684 (not (set-match-data '(nil nil)))) | |
685 ()) | |
686 (match-end 0)) | |
687 | |
688 (defsubst verilog-get-beg-of-line (&optional arg) | |
689 (save-excursion | |
690 (beginning-of-line arg) | |
691 (point))) | |
692 | |
693 (defsubst verilog-get-end-of-line (&optional arg) | |
694 (save-excursion | |
695 (end-of-line arg) | |
696 (point))) | |
697 | |
698 (defun verilog-declaration-end () | |
699 (search-forward ";")) | |
700 | |
701 (defun electric-verilog-backward-sexp () | |
702 "Move backward over a sexp" | |
703 (interactive) | |
704 ;; before that see if we are in a comment | |
705 (verilog-backward-sexp) | |
706 ) | |
707 (defun electric-verilog-forward-sexp () | |
708 "Move backward over a sexp" | |
709 (interactive) | |
710 ;; before that see if we are in a comment | |
711 (verilog-forward-sexp) | |
712 ) | |
713 | |
714 (defun verilog-backward-sexp () | |
715 (let ((reg) | |
716 (elsec 1) | |
717 (found nil) | |
718 ) | |
719 (if (not (looking-at "\\<")) | |
720 (forward-word -1)) | |
721 (cond | |
722 ((verilog-skip-backward-comment-or-string) | |
723 ) | |
724 ((looking-at "\\<else\\>") | |
725 (setq reg (concat | |
726 verilog-end-block-re | |
727 "\\|\\(\\<else\\>\\)" | |
728 "\\|\\(\\<if\\>\\)" | |
729 )) | |
730 (while (and (not found) | |
731 (verilog-re-search-backward reg nil 'move)) | |
732 (cond | |
733 ((match-end 1) ; endblock | |
734 ; try to leap back to matching outward block by striding across | |
735 ; indent level changing tokens then immediately | |
736 ; previous line governs indentation. | |
737 (verilog-leap-to-head) | |
738 ) | |
739 ((match-end 2) ; else, we're in deep | |
740 (setq elsec (1+ elsec)) | |
741 ) | |
742 ((match-end 3) ; found it | |
743 (setq elsec (1- elsec)) | |
744 (if (= 0 elsec) | |
745 ;; Now previous line describes syntax | |
746 (setq found 't) | |
747 )) | |
748 ) | |
749 ) | |
750 ) | |
751 ((looking-at verilog-end-block-re-1);; end|join|endcase|endtable|endspecify | |
752 (verilog-leap-to-head) | |
753 ) | |
754 ((looking-at "\\(endmodule\\>\\)\\|\\(\\<endprimitive\\>\\)") | |
755 (cond | |
756 ((match-end 1) | |
757 (verilog-re-search-backward "\\<\\(macro\\)?module\\>" nil 'move)) | |
758 ((match-end 2) | |
759 (verilog-re-search-backward "\\<primitive\\>" nil 'move)) | |
760 (t | |
761 (backward-sexp 1)))) | |
762 (t | |
763 (backward-sexp)) | |
764 ) ;; cond | |
765 ) | |
766 ) | |
767 (defun verilog-forward-sexp () | |
768 (let ((reg) | |
769 (st (point))) | |
770 (if (not (looking-at "\\<")) | |
771 (forward-word -1)) | |
772 (cond | |
773 ((verilog-skip-forward-comment-or-string) | |
774 (verilog-forward-syntactic-ws) | |
775 ) | |
776 ((looking-at verilog-beg-block-re-1);; begin|fork|case|table|specify | |
777 (cond | |
778 ((match-end 1) ; end | |
779 ;; Search forward for matching begin | |
780 (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ) | |
781 ) | |
782 ((match-end 2) ; endcase | |
783 ;; Search forward for matching case | |
784 (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ) | |
785 ) | |
786 ((match-end 3) ; join | |
787 ;; Search forward for matching fork | |
788 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" ) | |
789 ) | |
790 ((match-end 4) ; endtable | |
791 ;; Search forward for matching table | |
792 (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ) | |
793 ) | |
794 ((match-end 5) ; endspecify | |
795 ;; Search forward for matching specify | |
796 (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ) | |
797 ) | |
798 ((match-end 6) ; endfunction | |
799 ;; Search forward for matching function | |
800 (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ) | |
801 ) | |
802 ((match-end 7) ; endspecify | |
803 ;; Search forward for matching task | |
804 (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ) | |
805 ) | |
806 ) | |
807 (if (forward-word 1) | |
808 (catch 'skip | |
809 (let ((nest 1)) | |
810 (while (verilog-re-search-forward reg nil 'move) | |
811 (cond | |
812 ((match-end 2) ; end | |
813 (setq nest (1- nest)) | |
814 (if (= 0 nest) | |
815 (throw 'skip 1))) | |
816 ((match-end 1) ; begin | |
817 (setq nest (1+ nest))))) | |
818 ) | |
819 ) | |
820 ) | |
821 ) | |
822 ((looking-at "\\(\\<\\(macro\\)?module\\>\\)\\|\\(\\<primitive\\>\\)") | |
823 (cond | |
824 ((match-end 1) | |
825 (verilog-re-search-forward "\\<endmodule\\>" nil 'move)) | |
826 ((match-end 2) | |
827 (verilog-re-search-forward "\\<endprimitive\\>" nil 'move)) | |
828 (t | |
829 (goto-char st) | |
830 (if (= (following-char) ?\) ) | |
831 (forward-char 1) | |
832 (forward-sexp 1))))) | |
833 (t | |
834 (goto-char st) | |
835 (if (= (following-char) ?\) ) | |
836 (forward-char 1) | |
837 (forward-sexp 1))) | |
838 ) ;; cond | |
839 ) | |
840 ) | |
841 | |
842 | |
843 (defun verilog-declaration-beg () | |
844 (verilog-re-search-backward verilog-declaration-re (bobp) t)) | |
845 | |
846 (defsubst verilog-within-string () | |
847 (save-excursion | |
848 (nth 3 (parse-partial-sexp (verilog-get-beg-of-line) (point))))) | |
849 | |
850 | |
851 ;;;###autoload | |
852 (defun verilog-mode () | |
853 "Major mode for editing Verilog code. \\<verilog-mode-map> | |
854 NEWLINE, TAB indents for Verilog code. | |
855 Delete converts tabs to spaces as it moves back. | |
856 Supports highlighting. | |
857 | |
858 Variables controlling indentation/edit style: | |
859 | |
860 verilog-indent-level (default 3) | |
861 Indentation of Verilog statements with respect to containing block. | |
862 verilog-cexp-indent (default 1) | |
863 Indentation of Verilog statements broken across lines. | |
864 verilog-case-indent (default 2) | |
865 Indentation for case statements. | |
866 verilog-auto-newline (default nil) | |
867 Non-nil means automatically newline after simcolons and the punctation mark | |
868 after an end. | |
869 verilog-auto-indent-on-newline (default t) | |
870 Non-nil means automatically indent line after newline | |
871 verilog-tab-always-indent (default t) | |
872 Non-nil means TAB in Verilog mode should always reindent the current line, | |
873 regardless of where in the line point is when the TAB command is used. | |
874 verilog-indent-begin-after-if (default t) | |
875 Non-nil means to indent begin statements following a preceeding | |
876 if, else, while, for and repeat statements, if any. otherwise, | |
877 the begin is lined up with the preceeding token. If t, you get: | |
878 if (a) | |
879 begin | |
880 otherwise you get: | |
881 if (a) | |
882 begin | |
883 verilog-auto-endcomments (default t) | |
884 Non-nil means a comment /* ... */ is set after the ends which ends cases, tasks, functions and modules. | |
885 The type and name of the object will be set between the braces. | |
886 verilog-auto-lineup (default `(all)) | |
887 List of contexts where auto lineup of :'s or ='s should be done. | |
888 | |
889 Turning on Verilog mode calls the value of the variable verilog-mode-hook with | |
890 no args, if that value is non-nil. | |
891 Other useful functions are: | |
892 \\[verilog-complete-word]\t-complete word with appropriate possibilities (functions, verilog keywords...) | |
893 \\[verilog-comment-area]\t- Put marked area in a comment, fixing nested comments. | |
894 \\[verilog-uncomment-area]\t- Uncomment an area commented with \ | |
895 \\[verilog-comment-area]. | |
896 \\[verilog-insert-block]\t- insert begin ... end; | |
897 \\[verilog-star-comment]\t- insert /* ... */ | |
898 \\[verilog-mark-defun]\t- Mark function. | |
899 \\[verilog-beg-of-defun]\t- Move to beginning of current function. | |
900 \\[verilog-end-of-defun]\t- Move to end of current function. | |
901 \\[verilog-label-be]\t- Label matching begin ... end, fork ... join and case ... endcase statements; | |
902 " | |
903 (interactive) | |
904 (kill-all-local-variables) | |
905 (use-local-map verilog-mode-map) | |
906 (setq major-mode 'verilog-mode) | |
907 (setq mode-name "Verilog") | |
908 (setq local-abbrev-table verilog-mode-abbrev-table) | |
909 (set-syntax-table verilog-mode-syntax-table) | |
910 (make-local-variable 'indent-line-function) | |
911 (setq indent-line-function 'verilog-indent-line) | |
912 (setq comment-indent-function 'verilog-indent-comment) | |
913 (make-local-variable 'parse-sexp-ignore-comments) | |
914 (setq parse-sexp-ignore-comments nil) | |
915 (make-local-variable 'comment-start) | |
916 (make-local-variable 'comment-end) | |
917 (make-local-variable 'comment-multi-line) | |
918 (make-local-variable 'comment-start-skip) | |
919 (setq comment-start "// " | |
920 comment-end "" | |
921 comment-start-skip "/\\*+ *\\|// *" | |
922 comment-multi-line nil) | |
923 ;; Imenu support | |
924 (make-local-variable 'imenu-generic-expression) | |
925 (setq imenu-generic-expression verilog-imenu-generic-expression) | |
926 ;; Font lock support | |
927 (make-local-variable 'font-lock-keywords) | |
928 (if (string-match "XEmacs\\|Lucid" emacs-version) | |
929 (setq verilog-font-lock-keywords verilog-font-lock-keywords-after-1930 ) | |
930 (cond ((> emacs-minor-version 29) | |
931 (setq verilog-font-lock-keywords verilog-font-lock-keywords-after-1930 )) | |
932 ('t | |
933 (setq verilog-font-lock-keywords verilog-font-lock-keywords-before-1930 )) | |
934 )) | |
935 (setq font-lock-keywords verilog-font-lock-keywords) | |
936 (run-hooks 'verilog-mode-hook)) | |
937 | |
938 | |
939 ;;; | |
940 ;;; Electric functions | |
941 ;;; | |
942 (defun electric-verilog-terminate-line (&optional arg) | |
943 "Terminate line and indent next line." | |
944 (interactive) | |
945 ;; before that see if we are in a comment | |
946 (let ((state | |
947 (save-excursion | |
948 (parse-partial-sexp (point-min) (point))))) | |
949 (cond | |
950 ((nth 7 state) ; Inside // comment | |
951 (if (eolp) | |
952 (progn | |
953 (delete-horizontal-space) | |
954 (newline)) | |
955 (progn | |
956 (newline) | |
957 (insert-string "// ") | |
958 (beginning-of-line) | |
959 )) | |
960 (verilog-indent-line) | |
961 ) | |
962 ((nth 4 state) ; Inside any comment (hence /**/) | |
963 (newline) | |
964 (beginning-of-line) | |
965 | |
966 (verilog-indent-comment t) | |
967 (insert-string "* ") | |
968 ) | |
969 ((eolp) | |
970 ;; First, check if current line should be indented | |
971 (if (save-excursion | |
972 (delete-horizontal-space) | |
973 (beginning-of-line) | |
974 (skip-chars-forward " \t") | |
975 (if (looking-at verilog-autoindent-lines-re) | |
976 (let ((indent-str (verilog-indent-line))) | |
977 ;; Maybe we should set some endcomments | |
978 (if verilog-auto-endcomments | |
979 (verilog-set-auto-endcomments indent-str arg)) | |
980 (end-of-line) | |
981 (delete-horizontal-space) | |
982 (if arg | |
983 () | |
984 (newline)) | |
985 nil) | |
986 (progn | |
987 (end-of-line) | |
988 (delete-horizontal-space) | |
989 (newline)))) | |
990 (newline) | |
991 (forward-line 1)) | |
992 ;; Indent next line | |
993 (if verilog-auto-indent-on-newline | |
994 (verilog-indent-line)) | |
995 ) | |
996 (t | |
997 (newline) | |
998 ) | |
999 ) | |
1000 ) | |
1001 ) | |
1002 | |
1003 (defun electric-verilog-semi () | |
1004 "Insert `;' character and reindent the line." | |
1005 (interactive) | |
1006 (insert last-command-char) | |
1007 (save-excursion | |
1008 (beginning-of-line) | |
1009 (verilog-indent-line)) | |
1010 (if (and verilog-auto-newline | |
1011 (= 0 (verilog-parenthesis-depth))) | |
1012 (electric-verilog-terminate-line))) | |
1013 | |
1014 (defun electric-verilog-colon () | |
1015 "Insert `:' and do all indentions except line indent on this line." | |
1016 (interactive) | |
1017 (insert last-command-char) | |
1018 ;; Do nothing if within string. | |
1019 (if (or | |
1020 (verilog-within-string) | |
1021 (not (verilog-in-case-region-p))) | |
1022 () | |
1023 (save-excursion | |
1024 (let ((p (point)) | |
1025 (lim (progn (verilog-beg-of-statement) (point)))) | |
1026 (goto-char p) | |
1027 (verilog-backward-case-item lim) | |
1028 (verilog-indent-line))) | |
1029 ;; (let ((verilog-tab-always-indent nil)) | |
1030 ;; (verilog-indent-line)) | |
1031 ) | |
1032 ) | |
1033 | |
1034 (defun electric-verilog-equal () | |
1035 "Insert `=', and do indention if within block." | |
1036 (interactive) | |
1037 (insert last-command-char) | |
1038 ;; Could auto line up expressions, but not yet | |
1039 ;; (if (eq (car (verilog-calculate-indent)) 'block) | |
1040 ;; (let ((verilog-tab-always-indent nil)) | |
1041 ;; (verilog-indent-command))) | |
1042 ) | |
1043 | |
1044 | |
1045 (defun electric-verilog-tick () | |
1046 "Insert back-tick, and indent to coulmn 0 if this is a CPP directive." | |
1047 (interactive) | |
1048 (insert last-command-char) | |
1049 (if (save-excursion (beginning-of-line) (looking-at "^[ \t]*\`\\(\\<ifdef\\>\\|\\\<else\\>\\|\\<endif\\>\\|\\<define\\>\\)")) | |
1050 (save-excursion (beginning-of-line) | |
1051 (delete-horizontal-space)))) | |
1052 | |
1053 (defun electric-verilog-tab () | |
1054 "Function called when TAB is pressed in Verilog mode." | |
1055 (interactive) | |
1056 ;; If verilog-tab-always-indent, indent the beginning of the line. | |
1057 (if verilog-tab-always-indent | |
1058 (let* ((boi-point (save-excursion | |
1059 (beginning-of-line) | |
1060 (skip-chars-forward " \t") | |
1061 (let (type state ) | |
1062 (setq type (verilog-indent-line)) | |
1063 (setq state (car type)) | |
1064 (cond | |
1065 ((eq state 'block) | |
1066 (if (looking-at verilog-behavorial-block-beg-re ) | |
1067 (error (concat "The reserved word \"" | |
1068 (buffer-substring (match-beginning 0) (match-end 0)) | |
1069 "\" must be at the behavorial level!")))) | |
1070 )) | |
1071 (back-to-indentation) | |
1072 (point)))) | |
1073 (if (< (point) boi-point) | |
1074 (back-to-indentation))) | |
1075 (progn (insert "\t")) | |
1076 ) | |
1077 ) | |
1078 | |
1079 | |
1080 | |
1081 ;;; | |
1082 ;;; Interactive functions | |
1083 ;;; | |
1084 (defun verilog-insert-block () | |
1085 "Insert Verilog begin ... end; block in the code with right indentation." | |
1086 (interactive) | |
1087 (verilog-indent-line) | |
1088 (insert "begin") | |
1089 (electric-verilog-terminate-line) | |
1090 (save-excursion | |
1091 (electric-verilog-terminate-line) | |
1092 (insert "end") | |
1093 (beginning-of-line) | |
1094 (verilog-indent-line))) | |
1095 | |
1096 (defun verilog-star-comment () | |
1097 "Insert Verilog star comment at point." | |
1098 (interactive) | |
1099 (verilog-indent-line) | |
1100 (insert "/*") | |
1101 (save-excursion | |
1102 (newline) | |
1103 (insert " */")) | |
1104 (newline) | |
1105 (insert " * ")) | |
1106 | |
1107 (defun verilog-mark-defun () | |
1108 "Mark the current verilog function (or procedure). | |
1109 This puts the mark at the end, and point at the beginning." | |
1110 (interactive) | |
1111 (push-mark (point)) | |
1112 (verilog-end-of-defun) | |
1113 (push-mark (point)) | |
1114 (verilog-beg-of-defun) | |
1115 (if (fboundp 'zmacs-activate-region) | |
1116 (zmacs-activate-region))) | |
1117 | |
1118 (defun verilog-comment-area (start end) | |
1119 "Put the region into a Verilog comment. | |
1120 The comments that are in this area are \"deformed\": | |
1121 `*)' becomes `!(*' and `}' becomes `!{'. | |
1122 These deformed comments are returned to normal if you use | |
1123 \\[verilog-uncomment-area] to undo the commenting. | |
1124 | |
1125 The commented area starts with `verilog-exclude-str-start', and ends with | |
1126 `verilog-include-str-end'. But if you change these variables, | |
1127 \\[verilog-uncomment-area] won't recognize the comments." | |
1128 (interactive "r") | |
1129 (save-excursion | |
1130 ;; Insert start and endcomments | |
1131 (goto-char end) | |
1132 (if (and (save-excursion (skip-chars-forward " \t") (eolp)) | |
1133 (not (save-excursion (skip-chars-backward " \t") (bolp)))) | |
1134 (forward-line 1) | |
1135 (beginning-of-line)) | |
1136 (insert verilog-exclude-str-end) | |
1137 (setq end (point)) | |
1138 (newline) | |
1139 (goto-char start) | |
1140 (beginning-of-line) | |
1141 (insert verilog-exclude-str-start) | |
1142 (newline) | |
1143 ;; Replace end-comments within commented area | |
1144 (goto-char end) | |
1145 (save-excursion | |
1146 (while (re-search-backward "\\*/" start t) | |
1147 (replace-match "!/*" t t))) | |
1148 ) | |
1149 ) | |
1150 | |
1151 (defun verilog-uncomment-area () | |
1152 "Uncomment a commented area; change deformed comments back to normal. | |
1153 This command does nothing if the pointer is not in a commented | |
1154 area. See also `verilog-comment-area'." | |
1155 (interactive) | |
1156 (save-excursion | |
1157 (let ((start (point)) | |
1158 (end (point))) | |
1159 ;; Find the boundaries of the comment | |
1160 (save-excursion | |
1161 (setq start (progn (search-backward verilog-exclude-str-start nil t) | |
1162 (point))) | |
1163 (setq end (progn (search-forward verilog-exclude-str-end nil t) | |
1164 (point)))) | |
1165 ;; Check if we're really inside a comment | |
1166 (if (or (equal start (point)) (<= end (point))) | |
1167 (message "Not standing within commented area.") | |
1168 (progn | |
1169 ;; Remove endcomment | |
1170 (goto-char end) | |
1171 (beginning-of-line) | |
1172 (let ((pos (point))) | |
1173 (end-of-line) | |
1174 (delete-region pos (1+ (point)))) | |
1175 ;; Change comments back to normal | |
1176 (save-excursion | |
1177 (while (re-search-backward "!/\\*" start t) | |
1178 (replace-match "*/" t t))) | |
1179 ;; Remove startcomment | |
1180 (goto-char start) | |
1181 (beginning-of-line) | |
1182 (let ((pos (point))) | |
1183 (end-of-line) | |
1184 (delete-region pos (1+ (point))))))))) | |
1185 | |
1186 (defun verilog-beg-of-defun () | |
1187 "Move backward to the beginning of the current function or procedure." | |
1188 (interactive) | |
1189 (verilog-re-search-backward verilog-defun-re nil 'move) | |
1190 ) | |
1191 (defun verilog-end-of-defun () | |
1192 (interactive) | |
1193 (verilog-re-search-forward verilog-end-defun-re nil 'move) | |
1194 ) | |
1195 | |
1196 (defun verilog-label-be (&optional arg) | |
1197 "Label matching begin ... end, fork ... join and case ... endcase statements in this module; | |
1198 With argument, first kill any existing labels." | |
1199 (interactive) | |
1200 (let ((cnt 0) | |
1201 (oldpos (point)) | |
1202 (b (progn | |
1203 (verilog-beg-of-defun) | |
1204 (point-marker))) | |
1205 (e (progn | |
1206 (verilog-end-of-defun) | |
1207 (point-marker))) | |
1208 ) | |
1209 (goto-char (marker-position b)) | |
1210 (if (> (- e b) 200) | |
1211 (message "Relabeling module...")) | |
1212 (while (and | |
1213 (> (marker-position e) (point)) | |
1214 (verilog-re-search-forward | |
1215 (concat | |
1216 "\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\|\\(case\\)\\)?\\>" | |
1217 "\\|\\(`endif\\)\\|\\(`else\\)") | |
1218 nil 'move)) | |
1219 (goto-char (match-beginning 0)) | |
1220 (let ((indent-str (verilog-indent-line))) | |
1221 (verilog-set-auto-endcomments indent-str 't) | |
1222 (end-of-line) | |
1223 (delete-horizontal-space) | |
1224 ) | |
1225 (setq cnt (1+ cnt)) | |
1226 (if (= 9 (% cnt 10)) | |
1227 (message "%d..." cnt)) | |
1228 ) | |
1229 (goto-char oldpos) | |
1230 (if (or | |
1231 (> (- e b) 200) | |
1232 (> cnt 20)) | |
1233 (message "%d lines autocommented" cnt)) | |
1234 ) | |
1235 ) | |
1236 | |
1237 (defun verilog-beg-of-statement () | |
1238 "Move backward to beginning of statement" | |
1239 (interactive) | |
1240 (while (save-excursion | |
1241 (and | |
1242 (not (looking-at verilog-complete-reg)) | |
1243 (skip-chars-backward " \t") | |
1244 (not (or (bolp) (= (preceding-char) ?\;))) | |
1245 ) | |
1246 ) | |
1247 (skip-chars-backward " \t") | |
1248 (verilog-backward-token)) | |
1249 (let ((last (point))) | |
1250 (while (progn | |
1251 (setq last (point)) | |
1252 (and (not (looking-at verilog-complete-reg)) | |
1253 (verilog-continued-line)))) | |
1254 (goto-char last) | |
1255 (verilog-forward-syntactic-ws) | |
1256 ) | |
1257 ) | |
1258 (defun verilog-end-of-statement () | |
1259 "Move forward to end of current statement." | |
1260 (interactive) | |
1261 (let ((nest 0) pos) | |
1262 (if (not (looking-at "[ \t\n]")) (forward-sexp -1)) | |
1263 (or (looking-at verilog-beg-block-re) | |
1264 ;; Skip to end of statement | |
1265 (setq pos (catch 'found | |
1266 (while t | |
1267 (forward-sexp 1) | |
1268 (verilog-skip-forward-comment-or-string) | |
1269 (cond ((looking-at "[ \t]*;") | |
1270 (skip-chars-forward "^;") | |
1271 (forward-char 1) | |
1272 (throw 'found (point))) | |
1273 ((save-excursion | |
1274 (forward-sexp -1) | |
1275 (looking-at verilog-beg-block-re)) | |
1276 (goto-char (match-beginning 0)) | |
1277 (throw 'found nil)) | |
1278 ((eobp) | |
1279 (throw 'found (point)))))))) | |
1280 (if (not pos) | |
1281 ;; Skip a whole block | |
1282 (catch 'found | |
1283 (while t | |
1284 (verilog-re-search-forward verilog-end-statement-re nil 'move) | |
1285 (setq nest (if (match-end 1) | |
1286 (1+ nest) | |
1287 (1- nest))) | |
1288 (cond ((eobp) | |
1289 (throw 'found (point))) | |
1290 ((= 0 nest) | |
1291 (throw 'found (verilog-end-of-statement)))))) | |
1292 pos))) | |
1293 (defun verilog-in-case-region-p () | |
1294 "Return TRUE if in a case region: more specifically, point @ in the line foo : @ begin" | |
1295 (interactive) | |
1296 (save-excursion | |
1297 (if (and | |
1298 (progn (verilog-forward-syntactic-ws) | |
1299 (looking-at "\\<begin\\>")) | |
1300 (progn (verilog-backward-syntactic-ws) | |
1301 (= (preceding-char) ?\:))) | |
1302 (catch 'found | |
1303 (let ((nest 1)) | |
1304 (while t | |
1305 (verilog-re-search-backward "\\(\\<module\\>\\)\\|\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)\\>" nil 'move) | |
1306 (cond | |
1307 ((match-end 3) | |
1308 (setq nest (1+ nest))) | |
1309 ((match-end 2) | |
1310 (if (= nest 1) | |
1311 (throw 'found 1)) | |
1312 (setq nest (1- nest)) | |
1313 ) | |
1314 ( t | |
1315 (throw 'found (= nest 0))) | |
1316 ) | |
1317 ) | |
1318 ) | |
1319 ) | |
1320 nil) | |
1321 ) | |
1322 ) | |
1323 (defun verilog-backward-case-item (lim) | |
1324 "Skip backward to nearest enclosing case item" | |
1325 (interactive) | |
1326 (let ( | |
1327 (str 'nil) | |
1328 (lim1 (progn | |
1329 (save-excursion (verilog-re-search-backward verilog-endcomment-reason-re lim 'move) | |
1330 (point))))) | |
1331 ;; Try to find the real : | |
1332 (if (save-excursion (search-backward ":" lim1 t)) | |
1333 (let ((colon 0) | |
1334 b e ) | |
1335 (while (and (< colon 1) | |
1336 (verilog-re-search-backward "\\(\\[\\)\\|\\(\\]\\)\\|\\(:\\)" lim1 'move)) | |
1337 (cond | |
1338 ((match-end 1) ;; [ | |
1339 (setq colon (1+ colon)) | |
1340 (if (>= colon 0) | |
1341 (error "unbalanced ["))) | |
1342 ((match-end 2) ;; ] | |
1343 (setq colon (1- colon))) | |
1344 | |
1345 ((match-end 3) ;; : | |
1346 (setq colon (1+ colon))) | |
1347 | |
1348 ) | |
1349 ) | |
1350 ;; Skip back to begining of case item | |
1351 (skip-chars-backward "\t ") | |
1352 (verilog-skip-backward-comment-or-string) | |
1353 (setq e (point)) | |
1354 (setq b (progn | |
1355 (if (verilog-re-search-backward "\\<\\(case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move) | |
1356 (progn | |
1357 (cond | |
1358 ((match-end 1) | |
1359 (goto-char (match-end 1)) | |
1360 (verilog-forward-ws&directives) | |
1361 (if (looking-at "(") | |
1362 (progn | |
1363 (forward-sexp) | |
1364 (verilog-forward-ws&directives) | |
1365 )) | |
1366 (point)) | |
1367 (t | |
1368 (goto-char (match-end 0)) | |
1369 (verilog-forward-ws&directives) | |
1370 (point)) | |
1371 )) | |
1372 (error "Malformed case item") | |
1373 ) | |
1374 ) | |
1375 ) | |
1376 (setq str (buffer-substring b e)) | |
1377 (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str)) | |
1378 (setq str (concat (substring str 0 e) "..."))) | |
1379 str) | |
1380 'nil) | |
1381 ) | |
1382 ) | |
1383 | |
1384 | |
1385 ;;; | |
1386 ;;; Other functions | |
1387 ;;; | |
1388 | |
1389 (defun kill-existing-comment () | |
1390 "kill autocomment on this line" | |
1391 (save-excursion | |
1392 (let* ( | |
1393 (e (progn | |
1394 (end-of-line) | |
1395 (point))) | |
1396 (b (progn | |
1397 (beginning-of-line) | |
1398 (search-forward "//" e t)))) | |
1399 (if b | |
1400 (delete-region (- b 2) e)) | |
1401 ) | |
1402 ) | |
1403 ) | |
1404 | |
1405 (defun verilog-set-auto-endcomments (indent-str kill-existing-comment) | |
1406 "Insert `// case: 7 ' or `// NAME ' on this line if appropriate. | |
1407 Insert `// case expr ' if this line ends a case block. | |
1408 Insert `// ifdef FOO ' if this line ends code conditional on FOO. | |
1409 Insert `// NAME ' if this line ends a module or primitive named NAME." | |
1410 (save-excursion | |
1411 (cond | |
1412 (; Comment close preprocessor directives | |
1413 (and | |
1414 (looking-at "\\(`endif\\)\\|\\(`else\\)") | |
1415 (or kill-existing-comment | |
1416 (not (save-excursion | |
1417 (end-of-line) | |
1418 (search-backward "//" (verilog-get-beg-of-line) t))))) | |
1419 (let ( (reg "\\(`else\\)\\|\\(`ifdef\\)\\|\\(`endif\\)") | |
1420 (nest 1) | |
1421 b e | |
1422 (else (if (match-end 2) | |
1423 1 | |
1424 0)) | |
1425 ) | |
1426 (end-of-line) | |
1427 (if kill-existing-comment | |
1428 (kill-existing-comment)) | |
1429 (delete-horizontal-space) | |
1430 (save-excursion | |
1431 (backward-sexp 1) | |
1432 (while (and (/= nest 0) | |
1433 (verilog-re-search-backward reg nil 'move)) | |
1434 (cond | |
1435 ((match-end 1) ; `else | |
1436 (if (= nest 1) | |
1437 (setq else 1))) | |
1438 ((match-end 2) ; `ifdef | |
1439 (setq nest (1- nest))) | |
1440 ((match-end 3) ; `endif | |
1441 (setq nest (1+ nest))) | |
1442 )) | |
1443 (if (match-end 0) | |
1444 (setq b (progn | |
1445 (skip-chars-forward "^ \t") | |
1446 (verilog-forward-syntactic-ws) | |
1447 (point)) | |
1448 e (progn | |
1449 (skip-chars-forward "a-zA-Z0-9_") | |
1450 (point) | |
1451 )))) | |
1452 (if b | |
1453 (if (> (- (point) b) verilog-minimum-comment-distance) | |
1454 (insert (concat (if | |
1455 (= else 0) | |
1456 " // ifdef " | |
1457 " // !ifdef ") | |
1458 (buffer-substring b e)))) | |
1459 (progn | |
1460 (insert " // unmatched `endif") | |
1461 (ding 't)) | |
1462 ))) | |
1463 | |
1464 (; Comment close case/function/task/module and named block | |
1465 (and (looking-at "\\<end") | |
1466 (or kill-existing-comment | |
1467 (not (save-excursion | |
1468 (end-of-line) | |
1469 (search-backward "//" (verilog-get-beg-of-line) t))))) | |
1470 (let ((type (car indent-str))) | |
1471 (if (eq type 'declaration) | |
1472 () | |
1473 (if | |
1474 (looking-at "\\(\\<endcase\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\)\\>\\)") | |
1475 (cond | |
1476 (;- This is a case block; search back for the start of this case | |
1477 (match-end 1) | |
1478 | |
1479 (let ((err 't) | |
1480 (str "UNMATCHED!!")) | |
1481 (save-excursion | |
1482 (verilog-leap-to-head) | |
1483 (if (match-end 0) | |
1484 (progn | |
1485 (goto-char (match-end 1)) | |
1486 (setq str (concat (buffer-substring (match-beginning 1) (match-end 1)) | |
1487 (verilog-get-expr))) | |
1488 (setq err nil)))) | |
1489 (end-of-line) | |
1490 (if kill-existing-comment | |
1491 (kill-existing-comment)) | |
1492 (delete-horizontal-space) | |
1493 (insert (concat " // " str )) | |
1494 (if err (ding 't)) | |
1495 )) | |
1496 | |
1497 (;- This is a begin..end block | |
1498 (match-end 2) | |
1499 (let ((str " // UNMATCHED !!") | |
1500 (err 't) | |
1501 (here (point)) | |
1502 there | |
1503 cntx | |
1504 ) | |
1505 (save-excursion | |
1506 (verilog-leap-to-head) | |
1507 (setq there (point)) | |
1508 (if (not (match-end 0)) | |
1509 (progn | |
1510 (goto-char here) | |
1511 (end-of-line) | |
1512 (if kill-existing-comment | |
1513 (kill-existing-comment)) | |
1514 (delete-horizontal-space) | |
1515 (insert str) | |
1516 (ding 't) | |
1517 ) | |
1518 (let ( sp | |
1519 (lim (save-excursion (verilog-beg-of-defun) (point))) | |
1520 (here (point)) | |
1521 ) | |
1522 (cond | |
1523 (;-- handle named block differently | |
1524 (looking-at verilog-named-block-re) | |
1525 (search-forward ":") | |
1526 (setq there (point)) | |
1527 (setq str (verilog-get-expr)) | |
1528 (setq err nil) | |
1529 (setq str (concat " // block: " str ))) | |
1530 | |
1531 ((verilog-in-case-region-p) ;-- handle case item differently | |
1532 (goto-char here) | |
1533 (setq str (verilog-backward-case-item lim)) | |
1534 (setq there (point)) | |
1535 (setq err nil) | |
1536 (setq str (concat " // case: " str )) | |
1537 ) | |
1538 (;- try to find "reason" for this begin | |
1539 (cond | |
1540 (; | |
1541 (eq here (progn (verilog-beg-of-statement) (point))) | |
1542 (setq err nil) | |
1543 (setq str "")) | |
1544 ((looking-at verilog-endcomment-reason-re) | |
1545 (setq there (match-end 0)) | |
1546 (setq cntx (concat | |
1547 (buffer-substring (match-beginning 0) (match-end 0)) " ")) | |
1548 (cond | |
1549 (; | |
1550 (match-end 2) | |
1551 (setq err nil) | |
1552 (save-excursion | |
1553 (goto-char sp) | |
1554 (if (and (verilog-continued-line) | |
1555 (looking-at "\\<repeat\\>\\|\\<wait\\>\\|\\<always\\>")) | |
1556 (progn | |
1557 (goto-char (match-end 0)) | |
1558 (setq there (point)) | |
1559 (setq str | |
1560 (concat " // " | |
1561 (buffer-substring (match-beginning 0) (match-end 0)) " " | |
1562 (verilog-get-expr)))) | |
1563 (setq str "") | |
1564 ) | |
1565 ) | |
1566 ) | |
1567 (;- else | |
1568 (match-end 4) | |
1569 (let ((nest 0) | |
1570 ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)") | |
1571 ) | |
1572 (catch 'skip | |
1573 (while (verilog-re-search-backward reg nil 'move) | |
1574 (cond | |
1575 ((match-end 1) ; begin | |
1576 (setq nest (1- nest))) | |
1577 ((match-end 2) ; end | |
1578 (setq nest (1+ nest))) | |
1579 ((match-end 3) | |
1580 (if (= 0 nest) | |
1581 (progn | |
1582 (goto-char (match-end 0)) | |
1583 (setq there (point)) | |
1584 (setq err nil) | |
1585 (setq str (verilog-get-expr)) | |
1586 (setq str (concat " // else: !if" str )) | |
1587 (throw 'skip 1)) | |
1588 ))) | |
1589 ) | |
1590 ) | |
1591 ) | |
1592 ) | |
1593 (;- task/function/initial et cetera | |
1594 t | |
1595 (match-end 0) | |
1596 (goto-char (match-end 0)) | |
1597 (setq there (point)) | |
1598 (setq err nil) | |
1599 (setq str (verilog-get-expr)) | |
1600 (setq str (concat " // " cntx str ))) | |
1601 | |
1602 (;-- otherwise... | |
1603 (setq str " // auto-endcomment confused ") | |
1604 ) | |
1605 ) | |
1606 ) | |
1607 ((and | |
1608 (verilog-in-case-region-p) ;-- handle case item differently | |
1609 (progn | |
1610 (setq there (point)) | |
1611 (goto-char here) | |
1612 (setq str (verilog-backward-case-item lim)))) | |
1613 (setq err nil) | |
1614 (setq str (concat " // case: " str )) | |
1615 ) | |
1616 ) | |
1617 ) | |
1618 ) | |
1619 ) | |
1620 (goto-char here) | |
1621 (end-of-line) | |
1622 (if kill-existing-comment | |
1623 (kill-existing-comment)) | |
1624 (delete-horizontal-space) | |
1625 (if (or err | |
1626 (> (- here there) verilog-minimum-comment-distance)) | |
1627 (insert str)) | |
1628 (if err (ding 't)) | |
1629 ) | |
1630 ) | |
1631 ) | |
1632 ) | |
1633 | |
1634 | |
1635 (;- this is end{function,task,module} | |
1636 t | |
1637 (let (string reg (width nil)) | |
1638 (end-of-line) | |
1639 (if kill-existing-comment | |
1640 (kill-existing-comment)) | |
1641 (delete-horizontal-space) | |
1642 (backward-sexp) | |
1643 (cond | |
1644 ((match-end 5) | |
1645 (setq reg "\\(\\<function\\>\\)\\|\\(\\<\\(endfunction\\|task\\|\\(macro\\)?module\\|primitive\\)\\>\\)") | |
1646 (setq width "\\([ \t]*\\[[^]]*\\]\\)?") | |
1647 ) | |
1648 ((match-end 6) | |
1649 (setq reg "\\(\\<task\\>\\)\\|\\(\\<\\(endtask\\|function\\|\\(macro\\)?module\\|primitive\\)\\>\\)")) | |
1650 ((match-end 7) | |
1651 (setq reg "\\(\\<\\(macro\\)?module\\>\\)\\|\\<endmodule\\>")) | |
1652 ((match-end 8) | |
1653 (setq reg "\\(\\<primitive\\>\\)\\|\\(\\<\\(endprimitive\\|function\\|task\\|\\(macro\\)?module\\)\\>\\)")) | |
1654 ) | |
1655 (let (b e) | |
1656 (save-excursion | |
1657 (verilog-re-search-backward reg nil 'move) | |
1658 (cond | |
1659 ((match-end 1) | |
1660 (setq b (progn | |
1661 (skip-chars-forward "^ \t") | |
1662 (verilog-forward-ws&directives) | |
1663 (if (and width (looking-at width)) | |
1664 (progn | |
1665 (goto-char (match-end 0)) | |
1666 (verilog-forward-ws&directives) | |
1667 )) | |
1668 (point)) | |
1669 e (progn | |
1670 (skip-chars-forward "a-zA-Z0-9_") | |
1671 (point))) | |
1672 (setq string (buffer-substring b e))) | |
1673 (t | |
1674 (ding 't) | |
1675 (setq string "unmactched end(function|task|module|primitive)"))))) | |
1676 (end-of-line) | |
1677 (insert (concat " // " string ))) | |
1678 ) | |
1679 ) | |
1680 ) | |
1681 ) | |
1682 ) | |
1683 ) | |
1684 ) | |
1685 ) | |
1686 ) | |
1687 | |
1688 (defun verilog-get-expr() | |
1689 "Grab expression at point, e.g, case ( a | b & (c ^d))" | |
1690 (let* ((b (progn | |
1691 (verilog-forward-syntactic-ws) | |
1692 (skip-chars-forward " \t") | |
1693 (point))) | |
1694 (e (let ((par 1)) | |
1695 (cond | |
1696 ((looking-at "(") | |
1697 (forward-char 1) | |
1698 (while (and (/= par 0) | |
1699 (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move)) | |
1700 (cond | |
1701 ((match-end 1) | |
1702 (setq par (1+ par))) | |
1703 ((match-end 2) | |
1704 (setq par (1- par))))) | |
1705 (point)) | |
1706 ((looking-at "\\[") | |
1707 (forward-char 1) | |
1708 (while (and (/= par 0) | |
1709 (verilog-re-search-forward "\\(\\[\\)\\|\\(\\]\\)" nil 'move)) | |
1710 (cond | |
1711 ((match-end 1) | |
1712 (setq par (1+ par))) | |
1713 ((match-end 2) | |
1714 (setq par (1- par))))) | |
1715 (verilog-forward-syntactic-ws) | |
1716 (skip-chars-forward "^ \t\n") | |
1717 (point)) | |
1718 ((looking-at "/[/\\*]") | |
1719 b) | |
1720 ('t | |
1721 (skip-chars-forward "^: \t\n") | |
1722 (point) | |
1723 )))) | |
1724 (str (buffer-substring b e))) | |
1725 (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str)) | |
1726 (setq str (concat (substring str 0 e) "..."))) | |
1727 str) | |
1728 ) | |
1729 | |
1730 | |
1731 ;;; | |
1732 ;;; Indentation | |
1733 ;;; | |
1734 (defconst verilog-indent-alist | |
1735 '((block . (+ ind verilog-indent-level)) | |
1736 (case . (+ ind verilog-case-indent)) | |
1737 (cparenexp . (+ ind verilog-indent-level)) | |
1738 (cexp . (+ ind verilog-indent-level)) | |
1739 (defun . verilog-indent-level) | |
1740 (declaration . verilog-indent-level) | |
1741 (tf . verilog-indent-level) | |
1742 (behavorial . verilog-indent-level) | |
1743 (statement . ind) | |
1744 (cpp . 0) | |
1745 (comment . (verilog-indent-comment)) | |
1746 (unknown . 3) | |
1747 (string . 0))) | |
1748 | |
1749 (defun verilog-calculate-indent () | |
1750 "Calculate the indent of the current Verilog line, through examination | |
1751 of previous lines. Once a line is found that is definitive as to the | |
1752 type of the current line, return that lines' indent level and it's | |
1753 type. Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)." | |
1754 (save-excursion | |
1755 (let* ((starting_position (point)) | |
1756 (par 0) | |
1757 (begin (looking-at "[ \t]*begin\\>")) | |
1758 (type (catch 'nesting | |
1759 ;; Keep working backwards until we can figure out | |
1760 ;; what type of statement this is. | |
1761 ;; Basically we need to figure out | |
1762 ;; 1) if this is a continuation of the previous line; | |
1763 ;; 2) are we in a block scope (begin..end) | |
1764 | |
1765 ;; if we are in a comment, done. | |
1766 (if (verilog-in-star-comment-p) (throw 'nesting 'comment)) | |
1767 | |
1768 ;; if we are in a parenthesized list, done. | |
1769 (if (verilog-in-paren) (progn (setq par 1) (throw 'nesting 'block))) | |
1770 | |
1771 ;; See if we are continuing a previous line | |
1772 (while t | |
1773 ;; trap out if we crawl off the top of the buffer | |
1774 (if (bobp) (throw 'nesting 'cpp)) | |
1775 | |
1776 (if (verilog-continued-line) | |
1777 (let ((sp (point))) | |
1778 (if (and | |
1779 (not (looking-at verilog-complete-reg)) | |
1780 (verilog-continued-line)) | |
1781 (progn (goto-char sp) | |
1782 (throw 'nesting 'cexp)) | |
1783 (goto-char sp)) | |
1784 (if (and begin | |
1785 (not verilog-indent-begin-after-if) | |
1786 (looking-at verilog-no-indent-begin-re)) | |
1787 (throw 'nesting 'statement) | |
1788 (throw 'nesting 'cexp))) | |
1789 | |
1790 ;; not a continued line | |
1791 (goto-char starting_position)) | |
1792 | |
1793 (if (looking-at "\\<else\\>") | |
1794 ;; search back for governing if, striding across begin..end pairs | |
1795 ;; appropriately | |
1796 (let ((reg (concat | |
1797 verilog-end-block-re | |
1798 "\\|\\(\\<else\\>\\)" | |
1799 "\\|\\(\\<if\\>\\)" | |
1800 )) | |
1801 (elsec 1) | |
1802 ) | |
1803 (while (verilog-re-search-backward reg nil 'move) | |
1804 (cond | |
1805 ((match-end 1) ; endblock | |
1806 ; try to leap back to matching outward block by striding across | |
1807 ; indent level changing tokens then immediately | |
1808 ; previous line governs indentation. | |
1809 (let ((reg)(nest 1)) | |
1810 (looking-at verilog-end-block-re-1);; end|join|endcase|endtable|endspecify | |
1811 (cond | |
1812 ((match-end 1) ; end | |
1813 ;; Search back for matching begin | |
1814 (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" ) | |
1815 ) | |
1816 ((match-end 2) ; endcase | |
1817 ;; Search back for matching case | |
1818 (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ) | |
1819 ) | |
1820 ((match-end 3) ; join | |
1821 ;; Search back for matching fork | |
1822 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" ) | |
1823 ) | |
1824 ((match-end 4) ; endtable | |
1825 ;; Search back for matching table | |
1826 (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ) | |
1827 ) | |
1828 ((match-end 5) ; endspecify | |
1829 ;; Search back for matching specify | |
1830 (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ) | |
1831 ) | |
1832 ((match-end 6) ; endfunction | |
1833 ;; Search back for matching function | |
1834 (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ) | |
1835 ) | |
1836 ((match-end 7) ; endspecify | |
1837 ;; Search back for matching task | |
1838 (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ) | |
1839 ) | |
1840 ) | |
1841 (catch 'skip | |
1842 (while (verilog-re-search-backward reg nil 'move) | |
1843 (cond | |
1844 ((match-end 1) ; begin | |
1845 (setq nest (1- nest)) | |
1846 (if (= 0 nest) | |
1847 (throw 'skip 1))) | |
1848 ((match-end 2) ; end | |
1849 (setq nest (1+ nest))))) | |
1850 ) | |
1851 ) | |
1852 ) | |
1853 ((match-end 2) ; else, we're in deep | |
1854 (setq elsec (1+ elsec)) | |
1855 ) | |
1856 ((match-end 3) ; found it | |
1857 (setq elsec (1- elsec)) | |
1858 (if (= 0 elsec) | |
1859 ;; Now previous line describes syntax | |
1860 (throw 'nesting 'statement) | |
1861 ))) | |
1862 ) | |
1863 ) | |
1864 ) | |
1865 (while (verilog-re-search-backward verilog-indent-reg nil 'move) | |
1866 (cond | |
1867 ((match-end 1) ; beg-block | |
1868 (looking-at verilog-beg-block-re-1) | |
1869 (cond | |
1870 ((match-end 2) (throw 'nesting 'case)) | |
1871 (t (throw 'nesting 'block)))) | |
1872 | |
1873 ((match-end 2) ;; end-block | |
1874 (verilog-leap-to-head) | |
1875 (if (verilog-in-case-region-p) | |
1876 (progn | |
1877 (verilog-leap-to-case-head) | |
1878 (if (looking-at verilog-case-re) | |
1879 (throw 'nesting 'case)) | |
1880 ))) | |
1881 | |
1882 ((or (match-end 3) ;; module.. primitive | |
1883 (match-end 5)) ;; endtask.. | |
1884 (throw 'nesting 'defun)) | |
1885 | |
1886 ((match-end 4) ;; endmodule | |
1887 (throw 'nesting 'cpp)) | |
1888 | |
1889 ((match-end 6) ;; function/task | |
1890 (throw 'nesting 'behavorial)) | |
1891 | |
1892 ((bobp) | |
1893 (throw 'nesting 'cpp)) | |
1894 ) | |
1895 ) | |
1896 ) | |
1897 ) | |
1898 ) | |
1899 ) | |
1900 ;; Return type of block and indent level. | |
1901 (if (not type) | |
1902 (setq type 'cpp)) | |
1903 (if (> par 0) ; Unclosed Parenthesis | |
1904 (list 'cparenexp par) | |
1905 (if (eq type 'case) | |
1906 (list type (verilog-case-indent-level)) | |
1907 (list type (verilog-indent-level))))))) | |
1908 (defun verilog-leap-to-case-head () "" | |
1909 (let ((nest 1)) | |
1910 (while (/= 0 nest) | |
1911 (verilog-re-search-backward "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" nil 'move) | |
1912 (cond | |
1913 ((match-end 1) | |
1914 (setq nest (1- nest))) | |
1915 ((match-end 2) | |
1916 (setq nest (1+ nest))) | |
1917 ((bobp) | |
1918 (ding 't) | |
1919 (setq nest 0)) | |
1920 ) | |
1921 ) | |
1922 ) | |
1923 ) | |
1924 | |
1925 (defun verilog-leap-to-head () "foo" | |
1926 (let (reg | |
1927 snest | |
1928 (nest 1)) | |
1929 (if (looking-at verilog-end-block-re-1);; end|join|endcase|endtable|endspecify | |
1930 (progn | |
1931 (cond | |
1932 ((match-end 1) ; end | |
1933 ;; Search back for matching begin | |
1934 (setq reg (concat "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|" | |
1935 "\\(\\<endcase\\>\\)\\|\\(\\<join\\>\\)" ))) | |
1936 | |
1937 ((match-end 2) ; endcase | |
1938 ;; Search back for matching case | |
1939 (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ) | |
1940 ) | |
1941 ((match-end 3) ; join | |
1942 ;; Search back for matching fork | |
1943 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" ) | |
1944 ) | |
1945 ((match-end 4) ; endtable | |
1946 ;; Search back for matching table | |
1947 (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" ) | |
1948 ) | |
1949 ((match-end 5) ; endspecify | |
1950 ;; Search back for matching specify | |
1951 (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" ) | |
1952 ) | |
1953 ((match-end 6) ; endfunction | |
1954 ;; Search back for matching function | |
1955 (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" ) | |
1956 ) | |
1957 ((match-end 7) ; endspecify | |
1958 ;; Search back for matching task | |
1959 (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" ) | |
1960 ) | |
1961 ) | |
1962 (catch 'skip | |
1963 (let (sreg) | |
1964 (while (verilog-re-search-backward reg nil 'move) | |
1965 | |
1966 (cond | |
1967 ((match-end 1) ; begin | |
1968 (setq nest (1- nest)) | |
1969 (if (= 0 nest) | |
1970 ;; Now previous line describes syntax | |
1971 (throw 'skip 1)) | |
1972 (if (and snest | |
1973 (= snest nest)) | |
1974 (setq reg sreg)) | |
1975 ) | |
1976 ((match-end 2) ; end | |
1977 (setq nest (1+ nest)) | |
1978 ) | |
1979 ((match-end 3) | |
1980 ;; endcase, jump to case | |
1981 (setq snest nest) | |
1982 (setq nest (1+ nest)) | |
1983 (setq sreg reg) | |
1984 (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" ) | |
1985 ) | |
1986 ((match-end 4) | |
1987 ;; join, jump to fork | |
1988 (setq snest nest) | |
1989 (setq nest (1+ nest)) | |
1990 (setq sreg reg) | |
1991 (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" ) | |
1992 ) | |
1993 ) | |
1994 ) | |
1995 ) | |
1996 ) | |
1997 ) | |
1998 ) | |
1999 ) | |
2000 ) | |
2001 (defun verilog-continued-line () | |
2002 "Return true if this is a continued line. | |
2003 Set point to where line starts" | |
2004 (let ((continued 't)) | |
2005 (if (eq 0 (forward-line -1)) | |
2006 (progn | |
2007 (end-of-line) | |
2008 (verilog-backward-ws&directives) | |
2009 (if (bobp) | |
2010 (setq continued nil) | |
2011 (while (and continued | |
2012 (save-excursion | |
2013 (skip-chars-backward " \t") | |
2014 (not (bolp)))) | |
2015 (setq continued (verilog-backward-token)) | |
2016 ) ;; while | |
2017 ) | |
2018 ) | |
2019 (setq continued nil) | |
2020 ) | |
2021 continued) | |
2022 ) | |
2023 | |
2024 (defun verilog-backward-token () | |
2025 "step backward token, returning true if we are now at an end of line token" | |
2026 (verilog-backward-syntactic-ws) | |
2027 (cond | |
2028 ((bolp) | |
2029 nil) | |
2030 (;-- Anything ending in a ; is complete | |
2031 (= (preceding-char) ?\;) | |
2032 nil) | |
2033 ;; (;-- Anything ending in a , is deemed complete | |
2034 ;; (= (preceding-char) ?\,) | |
2035 ;; nil) | |
2036 | |
2037 (;-- Could be 'case (foo)' or 'always @(bar)' which is complete | |
2038 (= (preceding-char) ?\)) | |
2039 (progn | |
2040 (backward-char) | |
2041 (backward-up-list 1) | |
2042 (verilog-backward-syntactic-ws) | |
2043 (forward-word -1) | |
2044 (not (looking-at "\\<case[xz]?\\>[^:]")))) | |
2045 | |
2046 (;-- any of begin|initial|while are complete statements; 'begin : foo' is also complete | |
2047 t | |
2048 (forward-word -1) | |
2049 (cond | |
2050 ( | |
2051 (looking-at "\\(initial\\>\\)\\|\\(always\\>\\)") | |
2052 t) | |
2053 ( | |
2054 (looking-at verilog-indent-reg) | |
2055 nil) | |
2056 (t | |
2057 (let | |
2058 ((back (point))) | |
2059 (verilog-backward-syntactic-ws) | |
2060 (cond | |
2061 ((= (preceding-char) ?\:) | |
2062 (backward-char) | |
2063 (verilog-backward-syntactic-ws) | |
2064 (backward-sexp) | |
2065 (if (looking-at "begin") | |
2066 nil | |
2067 t) | |
2068 ) | |
2069 ((= (preceding-char) ?\#) | |
2070 (backward-char) | |
2071 t) | |
2072 | |
2073 (t | |
2074 (goto-char back) | |
2075 t) | |
2076 ) | |
2077 ) | |
2078 ) | |
2079 ) | |
2080 ) | |
2081 ) | |
2082 ) | |
2083 | |
2084 (defun verilog-backward-syntactic-ws (&optional lim) | |
2085 ;; Backward skip over syntactic whitespace for Emacs 19. | |
2086 (save-restriction | |
2087 (let* ((lim (or lim (point-min))) | |
2088 (here lim) | |
2089 bol | |
2090 ) | |
2091 (if (< lim (point)) | |
2092 (progn | |
2093 (narrow-to-region lim (point)) | |
2094 (while (/= here (point)) | |
2095 (setq here (point)) | |
2096 (forward-comment (-(buffer-size))) | |
2097 (save-excursion | |
2098 (setq bol (progn (beginning-of-line) (point)))) | |
2099 (search-backward "//" bol t) | |
2100 ))) | |
2101 ))) | |
2102 | |
2103 (defun verilog-forward-syntactic-ws (&optional lim) | |
2104 ;; forward skip over syntactic whitespace for Emacs 19. | |
2105 (save-restriction | |
2106 (let* ((lim (or lim (point-max))) | |
2107 (here lim) | |
2108 ) | |
2109 (if (> lim (point)) | |
2110 (progn | |
2111 (narrow-to-region (point) lim) | |
2112 (while (/= here (point)) | |
2113 (setq here (point)) | |
2114 (forward-comment (buffer-size)) | |
2115 ))) | |
2116 ))) | |
2117 | |
2118 (defun verilog-backward-ws&directives (&optional lim) | |
2119 ;; Backward skip over syntactic whitespace and compiler directives for Emacs 19. | |
2120 (save-restriction | |
2121 (let* ((lim (or lim (point-min))) | |
2122 (here lim) | |
2123 jump | |
2124 ) | |
2125 (if (< lim (point)) | |
2126 (progn | |
2127 (let ((state | |
2128 (save-excursion | |
2129 (parse-partial-sexp (point-min) (point))))) | |
2130 (cond | |
2131 ((nth 4 state) ;; in /* */ comment | |
2132 (verilog-re-search-backward "/\*" nil 'move) | |
2133 ) | |
2134 ((nth 7 state) ;; in // comment | |
2135 (verilog-re-search-backward "//" nil 'move) | |
2136 ))) | |
2137 (narrow-to-region lim (point)) | |
2138 (while (/= here (point)) | |
2139 (setq here (point)) | |
2140 (forward-comment (-(buffer-size))) | |
2141 (save-excursion | |
2142 (beginning-of-line) | |
2143 (if (looking-at "[ \t]*\\(`define\\)\\|\\(`ifdef\\)\\|\\(`else\\)\\|\\(`endif\\)\\|\\(`timescale\\)\\|\\(`include\\)") | |
2144 (setq jump t) | |
2145 (setq jump nil))) | |
2146 (if jump | |
2147 (beginning-of-line)) | |
2148 ))) | |
2149 ))) | |
2150 | |
2151 (defun verilog-forward-ws&directives (&optional lim) | |
2152 ;; forward skip over syntactic whitespace and compiler directives for Emacs 19. | |
2153 (save-restriction | |
2154 (let* ((lim (or lim (point-max))) | |
2155 (here lim) | |
2156 jump | |
2157 ) | |
2158 (if (> lim (point)) | |
2159 (progn | |
2160 (let ((state | |
2161 (save-excursion | |
2162 (parse-partial-sexp (point-min) (point))))) | |
2163 (cond | |
2164 ((nth 4 state) ;; in /* */ comment | |
2165 (verilog-re-search-forward "/\*" nil 'move) | |
2166 ) | |
2167 ((nth 7 state) ;; in // comment | |
2168 (verilog-re-search-forward "//" nil 'move) | |
2169 ))) | |
2170 (narrow-to-region (point) lim) | |
2171 (while (/= here (point)) | |
2172 (setq here (point)) | |
2173 (forward-comment (buffer-size)) | |
2174 (save-excursion | |
2175 (beginning-of-line) | |
2176 (if (looking-at "[ \t]*\\(`define\\)\\|\\(`ifdef\\)\\|\\(`else\\)\\|\\(`endif\\)\\|\\(`timescale\\)") | |
2177 (setq jump t))) | |
2178 (if jump | |
2179 (beginning-of-line 2)) | |
2180 ))) | |
2181 ))) | |
2182 (defun verilog-parenthesis-depth () | |
2183 "Return non zero if in parenthetical-expression" | |
2184 (save-excursion | |
2185 (car (parse-partial-sexp (point-min) (point))))) | |
2186 | |
2187 (defun verilog-in-comment-or-string-p () | |
2188 "Return true if in a string or comment" | |
2189 (let ((state | |
2190 (save-excursion | |
2191 (parse-partial-sexp (point-min) (point))))) | |
2192 (or (nth 3 state) (nth 4 state) (nth 7 state))) ; Inside string or comment | |
2193 ) | |
2194 | |
2195 (defun verilog-in-star-comment-p () | |
2196 "Return true if in a star comment" | |
2197 (let ((state | |
2198 (save-excursion | |
2199 (parse-partial-sexp (point-min) (point))))) | |
2200 (nth 4 state)) | |
2201 ) | |
2202 | |
2203 (defun verilog-in-paren () | |
2204 "Return true if in a parenthetical expression" | |
2205 (let ((state | |
2206 (save-excursion | |
2207 (parse-partial-sexp (point-min) (point))))) | |
2208 (/= 0 (nth 0 state))) | |
2209 ) | |
2210 | |
2211 (defun verilog-skip-forward-comment-or-string () | |
2212 "Return true if in a string or comment" | |
2213 (let ((state | |
2214 (save-excursion | |
2215 (parse-partial-sexp (point-min) (point))))) | |
2216 (cond | |
2217 ((nth 3 state) ;Inside string | |
2218 (goto-char (nth 3 state)) | |
2219 t) | |
2220 ((nth 7 state) ;Inside // comment | |
2221 (forward-line 1) | |
2222 t) | |
2223 ((nth 4 state) ;Inside any comment (hence /**/) | |
2224 (search-forward "*/")) | |
2225 (t | |
2226 nil) | |
2227 ) | |
2228 ) | |
2229 ) | |
2230 | |
2231 (defun verilog-skip-backward-comment-or-string () | |
2232 "Return true if in a string or comment" | |
2233 (let ((state | |
2234 (save-excursion | |
2235 (parse-partial-sexp (point-min) (point))))) | |
2236 (cond | |
2237 ((nth 3 state) ;Inside string | |
2238 (search-backward "\"") | |
2239 t) | |
2240 ((nth 7 state) ;Inside // comment | |
2241 (search-backward "//") | |
2242 t) | |
2243 ((nth 4 state) ;Inside /* */ comment | |
2244 (search-backward "/*") | |
2245 t) | |
2246 (t | |
2247 nil) | |
2248 ) | |
2249 ) | |
2250 ) | |
2251 | |
2252 (defun verilog-skip-forward-comment-p () | |
2253 "If in comment, move to end and return true" | |
2254 (let (state) | |
2255 (progn | |
2256 (setq state | |
2257 (save-excursion | |
2258 (parse-partial-sexp (point-min) (point)))) | |
2259 (cond | |
2260 ((nth 3 state) | |
2261 t) | |
2262 ((nth 7 state) ;Inside // comment | |
2263 (end-of-line) | |
2264 (forward-char 1) | |
2265 t) | |
2266 ((nth 4 state) ;Inside any comment | |
2267 t) | |
2268 (t | |
2269 nil) | |
2270 ) | |
2271 ) | |
2272 ) | |
2273 ) | |
2274 | |
2275 (defun verilog-indent-line-relative () | |
2276 "Cheap version of indent line that only looks at | |
2277 a few lines to determine indent level" | |
2278 (interactive) | |
2279 (let ((indent-str)) | |
2280 (save-excursion | |
2281 (beginning-of-line) | |
2282 (if (looking-at "^[ \t]*$") | |
2283 (cond ;- A blank line; No need to be too smart. | |
2284 ((bobp) | |
2285 (setq indent-str (list 'cpp 0))) | |
2286 ((verilog-continued-line) | |
2287 (let ((sp (point))) | |
2288 (if (verilog-continued-line) | |
2289 (progn (goto-char sp) | |
2290 (setq indent-str (list 'statement (verilog-indent-level)))) | |
2291 (goto-char sp) | |
2292 (setq indent-str (list 'block (verilog-indent-level)))))) | |
2293 (t | |
2294 (setq indent-str (verilog-calculate-indent)))) | |
2295 (setq indent-str (verilog-calculate-indent)) | |
2296 ) | |
2297 ) | |
2298 (verilog-do-indent indent-str) | |
2299 ) | |
2300 ) | |
2301 (defun verilog-indent-line () | |
2302 "Indent for special part of code." | |
2303 (if (looking-at verilog-directive-re) | |
2304 ;; We could nicely nest `ifdef's, but... | |
2305 (progn | |
2306 (delete-horizontal-space) | |
2307 (indent-to 0) | |
2308 (list 'cpp 0)) ; Return verilog-calculate-indent data | |
2309 (verilog-do-indent (verilog-calculate-indent))) | |
2310 ) | |
2311 | |
2312 (defun verilog-do-indent (indent-str) | |
2313 "" | |
2314 (let ((type (car indent-str)) | |
2315 (ind (car (cdr indent-str)))) | |
2316 (delete-horizontal-space) | |
2317 (cond | |
2318 (; handle comma continued exp | |
2319 (eq type 'cexp) | |
2320 (let ((here (point))) | |
2321 (if (progn (verilog-backward-syntactic-ws) | |
2322 (= (preceding-char) ?\,)) | |
2323 (let* ( fst | |
2324 (column | |
2325 (save-excursion | |
2326 (backward-char 1) | |
2327 (verilog-beg-of-statement) | |
2328 (setq fst (point)) | |
2329 (if (looking-at verilog-declaration-re) | |
2330 (progn ;; we have multiple words | |
2331 (goto-char (match-end 0)) | |
2332 (skip-chars-forward " \t") | |
2333 (if (= (following-char) ?\[) | |
2334 (progn | |
2335 (forward-char 1) | |
2336 (backward-up-list -1) | |
2337 (skip-chars-forward " \t") | |
2338 ) | |
2339 ) | |
2340 ) | |
2341 (;; we have a single word | |
2342 goto-char fst) | |
2343 ) | |
2344 (current-column) | |
2345 ) | |
2346 ) | |
2347 ) | |
2348 (goto-char here) | |
2349 (beginning-of-line) | |
2350 (delete-horizontal-space) | |
2351 (indent-to column)) | |
2352 (progn | |
2353 (goto-char here) | |
2354 (let ((val (eval (cdr (assoc type verilog-indent-alist))))) | |
2355 ;; (verilog-comment-depth type val) | |
2356 (delete-horizontal-space) | |
2357 (indent-to val) | |
2358 )) | |
2359 ) | |
2360 ) | |
2361 ) | |
2362 (;-- Declaration -- maybe line 'em up | |
2363 (and (not (or | |
2364 (eq type 'cpp) | |
2365 (eq type 'comment))) | |
2366 (looking-at verilog-declaration-re) | |
2367 (or (memq 'all verilog-auto-lineup) | |
2368 (memq 'declaration verilog-auto-lineup))) | |
2369 (verilog-indent-declaration (cond ((eq type 'defun) 0) | |
2370 (t ind))) | |
2371 ) | |
2372 (; handle inside parenthetical expressions | |
2373 (eq type 'cparenexp) | |
2374 (let ((column (save-excursion | |
2375 (backward-up-list 1) | |
2376 (forward-char 1) | |
2377 (skip-chars-forward " \t") | |
2378 (current-column)))) | |
2379 (beginning-of-line) | |
2380 (delete-horizontal-space) | |
2381 (indent-to column))) | |
2382 | |
2383 (;-- Case -- maybe line 'em up | |
2384 (and (eq type 'case) (not (looking-at "^[ \t]*$"))) | |
2385 (progn | |
2386 (cond | |
2387 ((looking-at "\\<endcase\\>") | |
2388 (indent-to ind)) | |
2389 (t | |
2390 (indent-to (eval (cdr (assoc type verilog-indent-alist)))) | |
2391 )))) | |
2392 | |
2393 (;-- Handle the ends | |
2394 (looking-at verilog-end-block-re) | |
2395 (if (eq type 'statement) | |
2396 (indent-to (- ind verilog-indent-level)) | |
2397 (indent-to ind))) | |
2398 (;-- defun | |
2399 (and (eq type 'defun) | |
2400 (looking-at verilog-zero-indent-re)) | |
2401 (indent-to 0)) | |
2402 | |
2403 (;-- Everything else | |
2404 t | |
2405 (let ((val (eval (cdr (assoc type verilog-indent-alist))))) | |
2406 ;; (verilog-comment-depth type val) | |
2407 (delete-horizontal-space) | |
2408 (indent-to val) | |
2409 )) | |
2410 ) | |
2411 (if (looking-at "[ \t]+$") | |
2412 (skip-chars-forward " \t")) | |
2413 indent-str ; Return verilog-calculate-indent data | |
2414 ) | |
2415 ) | |
2416 | |
2417 (defun verilog-indent-level () | |
2418 "Return the indent-level the current statement has." | |
2419 (save-excursion | |
2420 (beginning-of-line) | |
2421 (skip-chars-forward " \t") | |
2422 (current-column))) | |
2423 | |
2424 | |
2425 (defun verilog-case-indent-level () | |
2426 "Return the indent-level the current statement has. | |
2427 Do not count named blocks or case-statements." | |
2428 (save-excursion | |
2429 (beginning-of-line) | |
2430 (skip-chars-forward " \t") | |
2431 (cond | |
2432 ((looking-at verilog-named-block-re) | |
2433 (current-column)) | |
2434 ((and (not (looking-at verilog-case-re)) | |
2435 (looking-at "[^:;]+[ \t]*:")) | |
2436 (search-forward ":" nil t) | |
2437 (skip-chars-forward " \t") | |
2438 (current-column)) | |
2439 (t | |
2440 (current-column))))) | |
2441 | |
2442 (defun verilog-indent-comment (&optional arg) | |
2443 "Indent current line as comment. | |
2444 If optional arg is non-nil, just return the | |
2445 column number the line should be indented to." | |
2446 (let* ((stcol | |
2447 (cond | |
2448 ((verilog-in-star-comment-p) | |
2449 (save-excursion | |
2450 (re-search-backward "/\\*" nil t) | |
2451 (1+(current-column)))) | |
2452 ( comment-column | |
2453 comment-column ) | |
2454 (t | |
2455 (save-excursion | |
2456 (re-search-backward "//" nil t) | |
2457 (current-column))) | |
2458 ) | |
2459 )) | |
2460 (if arg | |
2461 (progn | |
2462 (delete-horizontal-space) | |
2463 (indent-to stcol)) | |
2464 stcol | |
2465 ) | |
2466 ) | |
2467 ) | |
2468 | |
2469 ;;; | |
2470 | |
2471 | |
2472 (defun verilog-indent-declaration (base-ind &optional arg start end) | |
2473 "Indent current lines as declaration, lining up the variable names" | |
2474 (interactive) | |
2475 (let ((pos (point-marker)) | |
2476 (lim (save-excursion (progn (end-of-line) (point-marker)))) | |
2477 ) | |
2478 (if (and (not (or arg start)) (not (verilog-re-search-forward verilog-declaration-re lim t))) | |
2479 () | |
2480 (progn | |
2481 (beginning-of-line) | |
2482 (delete-horizontal-space) | |
2483 (indent-to (+ base-ind (eval (cdr (assoc 'declaration verilog-indent-alist))))) | |
2484 (let* ((pos2 (point-marker)) | |
2485 (more 1) | |
2486 here | |
2487 (stpos (if start start | |
2488 (save-excursion | |
2489 | |
2490 (goto-char pos2) | |
2491 (catch 'first | |
2492 (while more | |
2493 (setq here (point)) | |
2494 (verilog-backward-syntactic-ws) | |
2495 (if (= (preceding-char) ?\;) | |
2496 (backward-char)) | |
2497 (verilog-beg-of-statement) | |
2498 (if (bobp) | |
2499 (throw 'first (point-marker))) | |
2500 (if (looking-at verilog-declaration-re) | |
2501 (setq more (/= (point) here)) | |
2502 (throw 'first (point-marker)))) | |
2503 (throw 'first (point-marker))) | |
2504 ) | |
2505 ) | |
2506 ) | |
2507 (edpos (if end | |
2508 (set-marker (make-marker) end) | |
2509 lim)) | |
2510 ind) | |
2511 (goto-char stpos) | |
2512 ;; Indent lines in declaration block | |
2513 (if arg | |
2514 (while (<= (point) (marker-position edpos)) | |
2515 (beginning-of-line) | |
2516 (delete-horizontal-space) | |
2517 (cond | |
2518 ((looking-at "^[ \t]*$") | |
2519 ()) | |
2520 ((not (looking-at verilog-declaration-re)) | |
2521 (indent-to arg)) | |
2522 (t | |
2523 (indent-to (+ arg verilog-indent-level)))) | |
2524 (forward-line 1))) | |
2525 | |
2526 ;; Do lineup | |
2527 (setq ind (verilog-get-lineup-indent stpos edpos)) | |
2528 (goto-char stpos) | |
2529 (if (> (- edpos stpos) 100) | |
2530 (message "Lining up declarations..(please stand by)")) | |
2531 (let (e) | |
2532 (while (progn (setq e (marker-position edpos)) | |
2533 (< (point) e)) | |
2534 (if (verilog-re-search-forward verilog-declaration-re-1 e 'move) | |
2535 (just-one-space)) | |
2536 ;; (forward-char -1)) | |
2537 (save-excursion | |
2538 (let ((p (point))) | |
2539 (beginning-of-line) | |
2540 (if (verilog-re-search-forward "\\[" p 'move) | |
2541 (progn | |
2542 (forward-char -1) | |
2543 (just-one-space))) | |
2544 )) | |
2545 (delete-horizontal-space) | |
2546 (indent-to ind) | |
2547 (beginning-of-line) | |
2548 (delete-horizontal-space) | |
2549 (indent-to (+ base-ind (eval (cdr (assoc 'declaration verilog-indent-alist))))) | |
2550 (forward-line 1))))) | |
2551 | |
2552 ;; If arg - move point | |
2553 (message "") | |
2554 (if arg (forward-line -1) | |
2555 (goto-char (marker-position pos)))))) | |
2556 | |
2557 ; "Return the indent level that will line up several lines within the region | |
2558 ;from b to e nicely. The lineup string is str." | |
2559 (defun verilog-get-lineup-indent (b edpos) | |
2560 (save-excursion | |
2561 (let ((ind 0) e) | |
2562 (goto-char b) | |
2563 ;; Get rightmost position | |
2564 (while (progn (setq e (marker-position edpos)) | |
2565 (< (point) e)) | |
2566 (if (verilog-re-search-forward verilog-declaration-re-1 e 'move) | |
2567 (progn | |
2568 (goto-char (match-end 0)) | |
2569 (verilog-backward-syntactic-ws) | |
2570 (if (> (current-column) ind) | |
2571 (setq ind (current-column))) | |
2572 (goto-char (match-end 0))))) | |
2573 (if (> ind 0) | |
2574 (1+ ind) | |
2575 ;; No lineup-string found | |
2576 (goto-char b) | |
2577 (end-of-line) | |
2578 (skip-chars-backward " \t") | |
2579 (1+ (current-column)))))) | |
2580 | |
2581 ;; A useful mode debugging aide | |
2582 (defun verilog-comment-depth (type val) | |
2583 "" | |
2584 (save-excursion | |
2585 (let | |
2586 ((b (prog2 | |
2587 (beginning-of-line) | |
2588 (point-marker) | |
2589 (end-of-line))) | |
2590 (e (point-marker))) | |
2591 (if (re-search-backward " /\\* \[#-\]# \[a-z\]+ \[0-9\]+ ## \\*/" b t) | |
2592 (progn | |
2593 (replace-match " /* -# ## */") | |
2594 (end-of-line)) | |
2595 (progn | |
2596 (end-of-line) | |
2597 (insert " /* ## ## */")))) | |
2598 (backward-char 6) | |
2599 (insert | |
2600 (format "%s %d" type val)) | |
2601 ) | |
2602 ) | |
2603 ;;; | |
2604 ;;; | |
2605 ;;; Completion | |
2606 ;;; | |
2607 (defvar verilog-str nil) | |
2608 (defvar verilog-all nil) | |
2609 (defvar verilog-pred nil) | |
2610 (defvar verilog-buffer-to-use nil) | |
2611 (defvar verilog-flag nil) | |
2612 (defvar verilog-toggle-completions nil | |
2613 "*Non-nil means \\<verilog-mode-map>\\[verilog-complete-word] should try all possible completions one by one. | |
2614 Repeated use of \\[verilog-complete-word] will show you all of them. | |
2615 Normally, when there is more than one possible completion, | |
2616 it displays a list of all possible completions.") | |
2617 | |
2618 | |
2619 (defvar verilog-type-keywords | |
2620 '("buf" "bufif0" "bufif1" "cmos" "defparam" "inout" "input" | |
2621 "integer" "nand" "nmos" "nor" "not" "notif0" "notif1" "or" "output" "parameter" | |
2622 "pmos" "pull0" "pull1" "pullup" "rcmos" "real" "realtime" "reg" "rnmos" "rpmos" "rtran" | |
2623 "rtranif0" "rtranif1" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1" | |
2624 "triand" "trior" "trireg" "wand" "wire" "wor" "xnor" "xor" ) | |
2625 "*Keywords for types used when completing a word in a declaration or parmlist. | |
2626 \(eg. integer, real, char.) The types defined within the Verilog program | |
2627 will be completed runtime, and should not be added to this list.") | |
2628 | |
2629 (defvar verilog-defun-keywords | |
2630 '("begin" "function" "task" "initial" "always" "assign" "posedge" "negedge" "endmodule") | |
2631 "*Keywords to complete when standing at first word of a line in declarative scope. | |
2632 \(eg. initial, always, begin, assign.) | |
2633 The procedures and variables defined within the Verilog program | |
2634 will be completed runtime and should not be added to this list.") | |
2635 | |
2636 (defvar verilog-block-keywords | |
2637 '("begin" "fork" "join" "case" "end" "if" "else" "for" "while" "repeat") | |
2638 "*Keywords to complete when standing at first word of a line in behavorial scope. | |
2639 \(eg. begin, if, then, else, for, fork.) | |
2640 The procedures and variables defined within the Verilog program | |
2641 will be completed runtime and should not be added to this list.") | |
2642 | |
2643 (defvar verilog-tf-keywords | |
2644 '("begin" "fork" "join" "case" "end" "endtask" "endfunction" "if" "else" "for" "while" "repeat") | |
2645 "*Keywords to complete when standing at first word of a line in a task or function scope. | |
2646 \(eg. begin, if, then, else, for, fork.) | |
2647 The procedures and variables defined within the Verilog program | |
2648 will be completed runtime and should not be added to this list.") | |
2649 | |
2650 (defvar verilog-case-keywords | |
2651 '("begin" "fork" "join" "case" "end" "endcase" "if" "else" "for" "repeat") | |
2652 "*Keywords to complete when standing at first word of a line in behavorial scope. | |
2653 \(eg. begin, if, then, else, for, fork.) | |
2654 The procedures and variables defined within the Verilog program | |
2655 will be completed runtime and should not be added to this list.") | |
2656 | |
2657 (defvar verilog-separator-keywords | |
2658 '("else" "then" "begin") | |
2659 "*Keywords to complete when NOT standing at the first word of a statement. | |
2660 \(eg. else, then.) | |
2661 Variables and function names defined within the | |
2662 Verilog program are completed runtime and should not be added to this list.") | |
2663 | |
2664 (defun verilog-string-diff (str1 str2) | |
2665 "Return index of first letter where STR1 and STR2 differs." | |
2666 (catch 'done | |
2667 (let ((diff 0)) | |
2668 (while t | |
2669 (if (or (> (1+ diff) (length str1)) | |
2670 (> (1+ diff) (length str2))) | |
2671 (throw 'done diff)) | |
2672 (or (equal (aref str1 diff) (aref str2 diff)) | |
2673 (throw 'done diff)) | |
2674 (setq diff (1+ diff)))))) | |
2675 | |
2676 ;; Calculate all possible completions for functions if argument is `function', | |
2677 ;; completions for procedures if argument is `procedure' or both functions and | |
2678 ;; procedures otherwise. | |
2679 | |
2680 (defun verilog-func-completion (type) | |
2681 ;; Build regular expression for module/task/function names | |
2682 (if (string= verilog-str "") | |
2683 (setq verilog-str "[a-zA-Z_]")) | |
2684 (let ((verilog-str (concat (cond | |
2685 ((eq type 'module) "\\<\\(module\\)\\s +") | |
2686 ((eq type 'tf) "\\<\\(task\\|function\\)\\s +") | |
2687 (t "\\<\\(task\\|function\\|module\\)\\s +")) | |
2688 "\\<\\(" verilog-str "[a-zA-Z0-9_.]*\\)\\>")) | |
2689 match) | |
2690 | |
2691 (if (not (looking-at verilog-defun-re)) | |
2692 (verilog-re-search-backward verilog-defun-re nil t)) | |
2693 (forward-char 1) | |
2694 | |
2695 ;; Search through all reachable functions | |
2696 (goto-char (point-min)) | |
2697 (while (verilog-re-search-forward verilog-str (point-max) t) | |
2698 (progn (setq match (buffer-substring (match-beginning 2) | |
2699 (match-end 2))) | |
2700 (if (or (null verilog-pred) | |
2701 (funcall verilog-pred match)) | |
2702 (setq verilog-all (cons match verilog-all))))) | |
2703 (if (match-beginning 0) | |
2704 (goto-char (match-beginning 0))))) | |
2705 | |
2706 (defun verilog-get-completion-decl () | |
2707 ;; Macro for searching through current declaration (var, type or const) | |
2708 ;; for matches of `str' and adding the occurence tp `all' | |
2709 (let ((end (save-excursion (verilog-declaration-end) | |
2710 (point))) | |
2711 match) | |
2712 ;; Traverse lines | |
2713 (while (< (point) end) | |
2714 (if (verilog-re-search-forward verilog-declaration-re-1 (verilog-get-end-of-line) t) | |
2715 ;; Traverse current line | |
2716 (while (and (verilog-re-search-forward | |
2717 (concat "\\((\\|\\<\\(var\\|type\\|const\\)\\>\\)\\|" | |
2718 verilog-symbol-re) | |
2719 (verilog-get-beg-of-line) t) | |
2720 (not (match-end 1))) | |
2721 (setq match (buffer-substring (match-beginning 0) (match-end 0))) | |
2722 (if (string-match (concat "\\<" verilog-str) match) | |
2723 (if (or (null verilog-pred) | |
2724 (funcall verilog-pred match)) | |
2725 (setq verilog-all (cons match verilog-all)))))) | |
2726 (if (verilog-re-search-forward "\\<record\\>" (verilog-get-end-of-line) t) | |
2727 (verilog-declaration-end) | |
2728 (forward-line 1))))) | |
2729 | |
2730 (defun verilog-type-completion () | |
2731 "Calculate all possible completions for types." | |
2732 (let ((start (point)) | |
2733 goon) | |
2734 ;; Search for all reachable type declarations | |
2735 (while (or (verilog-beg-of-defun) | |
2736 (setq goon (not goon))) | |
2737 (save-excursion | |
2738 (if (and (< start (prog1 (save-excursion (verilog-end-of-defun) | |
2739 (point)) | |
2740 (forward-char 1))) | |
2741 (verilog-re-search-forward | |
2742 "\\<type\\>\\|\\<\\(begin\\|function\\|procedure\\)\\>" | |
2743 start t) | |
2744 (not (match-end 1))) | |
2745 ;; Check current type declaration | |
2746 (verilog-get-completion-decl)))))) | |
2747 | |
2748 (defun verilog-var-completion () | |
2749 "Calculate all possible completions for variables (or constants)." | |
2750 nil) | |
2751 ; Not done yet; in 1.99 perhaps | |
2752 ; (let ((start (point)) | |
2753 ; goon twice) | |
2754 ; ;; Search for all reachable var declarations | |
2755 ; (while (or (verilog-beg-of-defun) | |
2756 ; (setq goon (not goon))) | |
2757 ; (save-excursion | |
2758 ; (if (> start (prog1 (save-excursion (verilog-end-of-defun) | |
2759 ; (point)))) | |
2760 ; () ; Declarations not reacable | |
2761 ; (cond ((and (verilog-re-search-forward verilog-declaration-re start t) | |
2762 ; ;; Check var/const declarations | |
2763 ; (verilog-get-completion-decl))))))))) | |
2764 | |
2765 | |
2766 (defun verilog-keyword-completion (keyword-list) | |
2767 "Give list of all possible completions of keywords in KEYWORD-LIST." | |
2768 (mapcar '(lambda (s) | |
2769 (if (string-match (concat "\\<" verilog-str) s) | |
2770 (if (or (null verilog-pred) | |
2771 (funcall verilog-pred s)) | |
2772 (setq verilog-all (cons s verilog-all))))) | |
2773 keyword-list)) | |
2774 | |
2775 ;; Function passed to completing-read, try-completion or | |
2776 ;; all-completions to get completion on STR. If predicate is non-nil, | |
2777 ;; it must be a function to be called for every match to check if this | |
2778 ;; should really be a match. If flag is t, the function returns a list | |
2779 ;; of all possible completions. If it is nil it returns a string, the | |
2780 ;; longest possible completion, or t if STR is an exact match. If flag | |
2781 ;; is 'lambda, the function returns t if STR is an exact match, nil | |
2782 ;; otherwise. | |
2783 | |
2784 (defun verilog-completion (verilog-str verilog-pred verilog-flag) | |
2785 (save-excursion | |
2786 (let ((verilog-all nil)) | |
2787 ;; Set buffer to use for searching labels. This should be set | |
2788 ;; within functins which use verilog-completions | |
2789 (set-buffer verilog-buffer-to-use) | |
2790 | |
2791 ;; Determine what should be completed | |
2792 (let ((state (car (verilog-calculate-indent)))) | |
2793 (cond ((eq state 'defun) | |
2794 (save-excursion (verilog-var-completion)) | |
2795 (verilog-func-completion 'module) | |
2796 (verilog-keyword-completion verilog-defun-keywords)) | |
2797 | |
2798 ((eq state 'block) | |
2799 (save-excursion (verilog-var-completion)) | |
2800 (verilog-func-completion 'tf) | |
2801 (verilog-keyword-completion verilog-block-keywords)) | |
2802 | |
2803 ((eq state 'case) | |
2804 (save-excursion (verilog-var-completion)) | |
2805 (verilog-func-completion 'tf) | |
2806 (verilog-keyword-completion verilog-case-keywords)) | |
2807 | |
2808 ((eq state 'tf) | |
2809 (save-excursion (verilog-var-completion)) | |
2810 (verilog-func-completion 'tf) | |
2811 (verilog-keyword-completion verilog-tf-keywords)) | |
2812 | |
2813 (t;--Anywhere else | |
2814 (save-excursion (verilog-var-completion)) | |
2815 (verilog-func-completion 'both) | |
2816 (verilog-keyword-completion verilog-separator-keywords)))) | |
2817 | |
2818 ;; Now we have built a list of all matches. Give response to caller | |
2819 (verilog-completion-response)))) | |
2820 | |
2821 (defun verilog-completion-response () | |
2822 (cond ((or (equal verilog-flag 'lambda) (null verilog-flag)) | |
2823 ;; This was not called by all-completions | |
2824 (if (null verilog-all) | |
2825 ;; Return nil if there was no matching label | |
2826 nil | |
2827 ;; Get longest string common in the labels | |
2828 (let* ((elm (cdr verilog-all)) | |
2829 (match (car verilog-all)) | |
2830 (min (length match)) | |
2831 tmp) | |
2832 (if (string= match verilog-str) | |
2833 ;; Return t if first match was an exact match | |
2834 (setq match t) | |
2835 (while (not (null elm)) | |
2836 ;; Find longest common string | |
2837 (if (< (setq tmp (verilog-string-diff match (car elm))) min) | |
2838 (progn | |
2839 (setq min tmp) | |
2840 (setq match (substring match 0 min)))) | |
2841 ;; Terminate with match=t if this is an exact match | |
2842 (if (string= (car elm) verilog-str) | |
2843 (progn | |
2844 (setq match t) | |
2845 (setq elm nil)) | |
2846 (setq elm (cdr elm))))) | |
2847 ;; If this is a test just for exact match, return nil ot t | |
2848 (if (and (equal verilog-flag 'lambda) (not (equal match 't))) | |
2849 nil | |
2850 match)))) | |
2851 ;; If flag is t, this was called by all-completions. Return | |
2852 ;; list of all possible completions | |
2853 (verilog-flag | |
2854 verilog-all))) | |
2855 | |
2856 (defvar verilog-last-word-numb 0) | |
2857 (defvar verilog-last-word-shown nil) | |
2858 (defvar verilog-last-completions nil) | |
2859 | |
2860 (defun verilog-complete-word () | |
2861 "Complete word at current point. | |
2862 \(See also `verilog-toggle-completions', `verilog-type-keywords', | |
2863 `verilog-start-keywords' and `verilog-separator-keywords'.)" | |
2864 (interactive) | |
2865 (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point))) | |
2866 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point))) | |
2867 (verilog-str (buffer-substring b e)) | |
2868 ;; The following variable is used in verilog-completion | |
2869 (verilog-buffer-to-use (current-buffer)) | |
2870 (allcomp (if (and verilog-toggle-completions | |
2871 (string= verilog-last-word-shown verilog-str)) | |
2872 verilog-last-completions | |
2873 (all-completions verilog-str 'verilog-completion))) | |
2874 (match (if verilog-toggle-completions | |
2875 "" (try-completion | |
2876 verilog-str (mapcar '(lambda (elm) | |
2877 (cons elm 0)) allcomp))))) | |
2878 ;; Delete old string | |
2879 (delete-region b e) | |
2880 | |
2881 ;; Toggle-completions inserts whole labels | |
2882 (if verilog-toggle-completions | |
2883 (progn | |
2884 ;; Update entry number in list | |
2885 (setq verilog-last-completions allcomp | |
2886 verilog-last-word-numb | |
2887 (if (>= verilog-last-word-numb (1- (length allcomp))) | |
2888 0 | |
2889 (1+ verilog-last-word-numb))) | |
2890 (setq verilog-last-word-shown (elt allcomp verilog-last-word-numb)) | |
2891 ;; Display next match or same string if no match was found | |
2892 (if (not (null allcomp)) | |
2893 (insert "" verilog-last-word-shown) | |
2894 (insert "" verilog-str) | |
2895 (message "(No match)"))) | |
2896 ;; The other form of completion does not necessarly do that. | |
2897 | |
2898 ;; Insert match if found, or the original string if no match | |
2899 (if (or (null match) (equal match 't)) | |
2900 (progn (insert "" verilog-str) | |
2901 (message "(No match)")) | |
2902 (insert "" match)) | |
2903 ;; Give message about current status of completion | |
2904 (cond ((equal match 't) | |
2905 (if (not (null (cdr allcomp))) | |
2906 (message "(Complete but not unique)") | |
2907 (message "(Sole completion)"))) | |
2908 ;; Display buffer if the current completion didn't help | |
2909 ;; on completing the label. | |
2910 ((and (not (null (cdr allcomp))) (= (length verilog-str) | |
2911 (length match))) | |
2912 (with-output-to-temp-buffer "*Completions*" | |
2913 (display-completion-list allcomp)) | |
2914 ;; Wait for a keypress. Then delete *Completion* window | |
2915 (momentary-string-display "" (point)) | |
2916 (delete-window (get-buffer-window (get-buffer "*Completions*"))) | |
2917 ))))) | |
2918 | |
2919 (defun verilog-show-completions () | |
2920 "Show all possible completions at current point." | |
2921 (interactive) | |
2922 (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point))) | |
2923 (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point))) | |
2924 (verilog-str (buffer-substring b e)) | |
2925 ;; The following variable is used in verilog-completion | |
2926 (verilog-buffer-to-use (current-buffer)) | |
2927 (allcomp (if (and verilog-toggle-completions | |
2928 (string= verilog-last-word-shown verilog-str)) | |
2929 verilog-last-completions | |
2930 (all-completions verilog-str 'verilog-completion)))) | |
2931 ;; Show possible completions in a temporary buffer. | |
2932 (with-output-to-temp-buffer "*Completions*" | |
2933 (display-completion-list allcomp)) | |
2934 ;; Wait for a keypress. Then delete *Completion* window | |
2935 (momentary-string-display "" (point)) | |
2936 (delete-window (get-buffer-window (get-buffer "*Completions*"))))) | |
2937 | |
2938 | |
2939 (defun verilog-get-default-symbol () | |
2940 "Return symbol around current point as a string." | |
2941 (save-excursion | |
2942 (buffer-substring (progn | |
2943 (skip-chars-backward " \t") | |
2944 (skip-chars-backward "a-zA-Z0-9_") | |
2945 (point)) | |
2946 (progn | |
2947 (skip-chars-forward "a-zA-Z0-9_") | |
2948 (point))))) | |
2949 | |
2950 (defun verilog-build-defun-re (str &optional arg) | |
2951 "Return function/task/module starting with STR as regular expression. | |
2952 With optional second arg non-nil, STR is the complete name of the instruction." | |
2953 (if arg | |
2954 (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "\\)\\>") | |
2955 (concat "^\\(function\\|task\\|module\\)[ \t]+\\(" str "[a-zA-Z0-9_]*\\)\\>"))) | |
2956 | |
2957 ;; Function passed to completing-read, try-completion or | |
2958 ;; all-completions to get completion on any function name. If | |
2959 ;; predicate is non-nil, it must be a function to be called for every | |
2960 ;; match to check if this should really be a match. If flag is t, the | |
2961 ;; function returns a list of all possible completions. If it is nil | |
2962 ;; it returns a string, the longest possible completion, or t if STR | |
2963 ;; is an exact match. If flag is 'lambda, the function returns t if | |
2964 ;; STR is an exact match, nil otherwise. | |
2965 | |
2966 | |
2967 (defun verilog-comp-defun (verilog-str verilog-pred verilog-flag) | |
2968 (save-excursion | |
2969 (let ((verilog-all nil) | |
2970 match) | |
2971 | |
2972 ;; Set buffer to use for searching labels. This should be set | |
2973 ;; within functins which use verilog-completions | |
2974 (set-buffer verilog-buffer-to-use) | |
2975 | |
2976 (let ((verilog-str verilog-str)) | |
2977 ;; Build regular expression for functions | |
2978 (if (string= verilog-str "") | |
2979 (setq verilog-str (verilog-build-defun-re "[a-zA-Z_]")) | |
2980 (setq verilog-str (verilog-build-defun-re verilog-str))) | |
2981 (goto-char (point-min)) | |
2982 | |
2983 ;; Build a list of all possible completions | |
2984 (while (verilog-re-search-forward verilog-str nil t) | |
2985 (setq match (buffer-substring (match-beginning 2) (match-end 2))) | |
2986 (if (or (null verilog-pred) | |
2987 (funcall verilog-pred match)) | |
2988 (setq verilog-all (cons match verilog-all))))) | |
2989 | |
2990 ;; Now we have built a list of all matches. Give response to caller | |
2991 (verilog-completion-response)))) | |
2992 | |
2993 (defun verilog-goto-defun () | |
2994 "Move to specified Verilog module/task/function. | |
2995 The default is a name found in the buffer around point." | |
2996 (interactive) | |
2997 (let* ((default (verilog-get-default-symbol)) | |
2998 ;; The following variable is used in verilog-comp-function | |
2999 (verilog-buffer-to-use (current-buffer)) | |
3000 (default (if (verilog-comp-defun default nil 'lambda) | |
3001 default "")) | |
3002 (label (if (not (string= default "")) | |
3003 ;; Do completion with default | |
3004 (completing-read (concat "Label: (default " default ") ") | |
3005 'verilog-comp-defun nil t "") | |
3006 ;; There is no default value. Complete without it | |
3007 (completing-read "Label: " | |
3008 'verilog-comp-defun nil t "")))) | |
3009 ;; If there was no response on prompt, use default value | |
3010 (if (string= label "") | |
3011 (setq label default)) | |
3012 ;; Goto right place in buffer if label is not an empty string | |
3013 (or (string= label "") | |
3014 (progn | |
3015 (goto-char (point-min)) | |
3016 (re-search-forward (verilog-build-defun-re label t)) | |
3017 (beginning-of-line))))) | |
3018 (defun verilog-showscopes () | |
3019 "list all scopes in this module" | |
3020 (interactive) | |
3021 (let ( | |
3022 (buffer (current-buffer)) | |
3023 (linenum 1) | |
3024 (nlines 0) | |
3025 (first 1) | |
3026 (prevpos (point-min)) | |
3027 (final-context-start (make-marker)) | |
3028 (regexp "\\(module\\s-+\\w+\\s-*(\\)\\|\\(\\w+\\s-+\\w+\\s-*(\\)") | |
3029 ) | |
3030 (with-output-to-temp-buffer "*Occur*" | |
3031 (save-excursion | |
3032 (message (format "Searching for %s ..." regexp)) | |
3033 ;; Find next match, but give up if prev match was at end of buffer. | |
3034 (while (and (not (= prevpos (point-max))) | |
3035 (verilog-re-search-forward regexp nil t)) | |
3036 (goto-char (match-beginning 0)) | |
3037 (beginning-of-line) | |
3038 (save-match-data | |
3039 (setq linenum (+ linenum (count-lines prevpos (point))))) | |
3040 (setq prevpos (point)) | |
3041 (goto-char (match-end 0)) | |
3042 (let* ((start (save-excursion | |
3043 (goto-char (match-beginning 0)) | |
3044 (forward-line (if (< nlines 0) nlines (- nlines))) | |
3045 (point))) | |
3046 (end (save-excursion | |
3047 (goto-char (match-end 0)) | |
3048 (if (> nlines 0) | |
3049 (forward-line (1+ nlines)) | |
3050 (forward-line 1)) | |
3051 (point))) | |
3052 (tag (format "%3d" linenum)) | |
3053 (empty (make-string (length tag) ?\ )) | |
3054 tem) | |
3055 (save-excursion | |
3056 (setq tem (make-marker)) | |
3057 (set-marker tem (point)) | |
3058 (set-buffer standard-output) | |
3059 (setq occur-pos-list (cons tem occur-pos-list)) | |
3060 (or first (zerop nlines) | |
3061 (insert "--------\n")) | |
3062 (setq first nil) | |
3063 (insert-buffer-substring buffer start end) | |
3064 (backward-char (- end start)) | |
3065 (setq tem (if (< nlines 0) (- nlines) nlines)) | |
3066 (while (> tem 0) | |
3067 (insert empty ?:) | |
3068 (forward-line 1) | |
3069 (setq tem (1- tem))) | |
3070 (let ((this-linenum linenum)) | |
3071 (set-marker final-context-start | |
3072 (+ (point) (- (match-end 0) (match-beginning 0)))) | |
3073 (while (< (point) final-context-start) | |
3074 (if (null tag) | |
3075 (setq tag (format "%3d" this-linenum))) | |
3076 (insert tag ?:))))))) | |
3077 (set-buffer-modified-p nil)))) | |
3078 ;;; verilog.el ends here |