22
|
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
|
30
|
27 ;; $Header: /afs/informatik.uni-tuebingen.de/local/web/xemacs/xemacs-cvs/XEmacs/xemacs-19/lisp/modes/verilog-mode.el,v 1.2 1997/03/09 02:37:23 steve Exp $
|
22
|
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
|
30
|
328 (defconst verilog-mode-version "$$Revision: 1.2 $$"
|
22
|
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)
|
30
|
867 Non-nil means automatically newline after semicolons and the punctuation mark
|
22
|
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)
|
30
|
875 Non-nil means to indent begin statements following a preceding
|
22
|
876 if, else, while, for and repeat statements, if any. otherwise,
|
30
|
877 the begin is lined up with the preceding token. If t, you get:
|
22
|
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
|