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