1 ;;; vhdl-mode.el --- major mode for editing VHDL code
3 ;; Copyright (C) 1992,93,94,95,96,97,98,99 Free Software Foundation, Inc.
5 ;; Authors: Reto Zimmermann <mailto:Reto.Zimmermann@iaeth.ch>
6 ;; <http://www.iis.ee.ethz.ch/~zimmi/>
7 ;; Rodney J. Whitby <mailto:rwhitby@geocities.com>
8 ;; <http://www.geocities.com/SiliconValley/Park/8287/>
9 ;; Maintainer: VHDL Mode Maintainers <vhdl-mode@geocities.com>
10 ;; <http://www.geocities.com/SiliconValley/Peaks/8287/>
12 ;; Keywords: languages vhdl
14 ;; This file is part of GNU Emacs.
16 ;; GNU Emacs is free software; you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation; either version 2, or (at your option)
21 ;; GNU Emacs is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details.
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with GNU Emacs; see the file COPYING. If not, write to the
28 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
29 ;; Boston, MA 02111-1307, USA.
31 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
35 ;; This package provides an Emacs major mode for editing VHDL code.
36 ;; It includes the following features:
38 ;; - Highlighting of VHDL syntax
39 ;; - Indentation based on versatile syntax analysis
40 ;; - Template insertion (electrification) for most VHDL constructs
41 ;; - Insertion of customizable VHDL file headers
42 ;; - Insertion of user-specified models
43 ;; - Word completion (dynamic abbreviations)
44 ;; - Comprehensive menu
45 ;; - File browser (using Speedbar or index/sources menu)
46 ;; - Design hierarchy browser (using Speedbar)
47 ;; - Source file compilation (syntax analysis)
48 ;; - Postscript printing with fontification
49 ;; - Lower and upper case keywords
50 ;; - Hiding code of design units
51 ;; - Code beautification
52 ;; - Port translation and test bench generation
53 ;; - VHDL'87/'93 and VHDL-AMS supported
54 ;; - Fully customizable
55 ;; - Works under GNU Emacs (Unix and Windows NT/95) and XEmacs
56 ;; (GNU Emacs is preferred due to higher robustness and functionality)
58 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ;; see below (comment in `vhdl-mode' function) or type `C-c C-h' in Emacs.
64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68 ;; supported: Emacs 20.X (Unix and Windows NT/95), XEmacs 20.X
69 ;; tested on: Emacs 20.3, XEmacs 20.4 (marginally)
71 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
73 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
75 ;; Electrification ideas by Bob Pack <rlpst@cislabs.pitt.edu>
78 ;; Fontification approach suggested by Ken Wood <ken@eda.com.au>.
79 ;; Ideas about alignment from John Wiegley <johnw@borland.com>.
81 ;; Many thanks to all the users who sent me bug reports and enhancement
82 ;; requests. Colin Marquardt, will you never stop asking for new features :-?
83 ;; Thanks to Dan Nicolaescu for reviewing the code and for his valuable hints.
84 ;; Thanks to Ulf Klaperski for the indentation speedup hint.
86 ;; Special thanks go to Wolfgang Fichtner and the crew from the Integrated
87 ;; Systems Laboratory, Swiss Federal Institute of Technology Zurich, for
88 ;; giving me the opportunity to develop this code.
89 ;; This work has been funded in part by MICROSWISS, a Microelectronics Program
90 ;; of the Swiss Government.
95 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
97 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
100 (defun vhdl-custom-set (variable value
&rest functions
)
101 "Set variables as in `custom-set-default' and call FUNCTIONS afterwards."
102 (if (fboundp 'custom-set-default
)
103 (custom-set-default variable value
)
104 (set-default variable value
))
106 (when (fboundp (car functions
)) (funcall (car functions
)))
107 (setq functions
(cdr functions
))))
109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
113 "Customizations for VHDL Mode."
116 :version
"20.4" ; comment out for XEmacs
119 (defgroup vhdl-mode nil
120 "Customizations for modes."
123 (defcustom vhdl-electric-mode t
124 "*Non-nil enables electrification (automatic template generation).
125 If nil, template generators can still be invoked through key bindings and
126 menu. Is indicated in the modeline by `/e' after the mode name and can be
127 toggled by `\\[vhdl-electric-mode]'."
131 (defcustom vhdl-stutter-mode t
132 "*Non-nil enables stuttering.
133 Is indicated in the modeline by `/s' after the mode name and can be toggled
134 by `\\[vhdl-stutter-mode]'."
138 (defcustom vhdl-indent-tabs-mode nil
139 "*Non-nil means indentation can insert tabs.
140 Overrides local variable `indent-tabs-mode'."
145 (defgroup vhdl-project nil
146 "Customizations for projects."
149 (defcustom vhdl-project-alist
150 '(("example 1" "Project with individual source files"
151 ("~/example1/vhdl/system.vhd" "~/example1/vhdl/component_*.vhd") "\
152 -------------------------------------------------------------------------------
153 -- This is a multi-line project description
154 -- that can be used as a project dependent part of the file header.
156 ("example 2" "Project where source files are located in two directories"
157 ("$EXAMPLE2/vhdl/components/" "$EXAMPLE2/vhdl/system/") "")
158 ("example 3" "Project where source files are located in some directory trees"
159 ("-r ~/example3/*/vhdl/") ""))
160 "*List of projects and their properties.
161 Name : name of project
162 Title : title of project (one-line string)
163 Sources : a) source files : path + \"/\" + file name
164 b) directory : path + \"/\"
165 c) directory tree: \"-r \" + path + \"/\"
166 Description: description of project (multi-line string)
168 Project name and description are used to insert into the file header (see
169 variable `vhdl-file-header').
171 Path and file name can contain wildcards `*' and `?'. Environment variables
172 \(e.g. \"$EXAMPLE2\") are resolved.
174 The hierarchy browser shows the hierarchy of the design units found in
175 `Sources'. If no directories or files are specified, the current directory is
178 NOTE: Reflect the new setting in the choice list of variable `vhdl-project'
179 by restarting Emacs."
180 :type
'(repeat (list :tag
"Project" :indent
2
181 (string :tag
"Name ")
182 (string :tag
"Title")
183 (repeat :tag
"Sources" :indent
4
184 (string :format
"%v"))
185 (string :tag
"Description: (type `C-j' for newline)"
187 :set
(lambda (variable value
)
188 (vhdl-custom-set variable value
'vhdl-update-mode-menu
))
189 :group
'vhdl-project
)
191 (defcustom vhdl-project
""
192 "*Specifies the default for the current project.
193 Select a project name from the ones defined in variable `vhdl-project-alist'.
194 Is used to determine the project title and description to be inserted in file
195 headers and the source files/directories to be scanned in the hierarchy
196 browser. The current project can also be changed temporarily in the menu."
197 :type
(let ((project-alist vhdl-project-alist
) choice-list
)
199 (setq choice-list
(cons (list 'const
(car (car project-alist
)))
201 (setq project-alist
(cdr project-alist
)))
202 (append '(choice (const :tag
"None" "") (const :tag
"--"))
203 (nreverse choice-list
)))
204 :group
'vhdl-project
)
207 (defgroup vhdl-compile nil
208 "Customizations for compilation."
211 (defcustom vhdl-compiler-alist
213 ;; Cadence Design Systems: cv -file test.vhd
214 ;; duluth: *E,430 (test.vhd,13): identifier (POSITIV) is not declared
215 ("Cadence" "cv -file" "" "" "./"
216 ("duluth: \\*E,[0-9]+ (\\(.+\\),\\([0-9]+\\)):" 1 2) ("" 0))
217 ;; Ikos Voyager: analyze test.vhd
218 ;; analyze sdrctl.vhd
219 ;; E L4/C5: this library unit is inaccessible
220 ("Ikos" "analyze" "" "" "./"
221 ("E L\\([0-9]+\\)/C[0-9]+:" 0 1)
222 ("^analyze +\\(.+ +\\)*\\(.+\\)$" 2))
223 ;; ModelSim, Model Technology: vcom test.vhd
224 ;; ERROR: test.vhd(14): Unknown identifier: positiv
225 ;; WARNING[2]: test.vhd(85): Possible infinite loop
226 ("ModelSim" "vcom" "" "vmake > Makefile" "./"
227 ("\\(ERROR\\|WARNING\\)[^:]*: \\(.+\\)(\\([0-9]+\\)):" 2 3) ("" 0))
228 ;; QuickHDL, Mentor Graphics: qvhcom test.vhd
229 ;; ERROR: test.vhd(24): near "dnd": expecting: END
230 ;; WARNING[4]: test.vhd(30): A space is required between ...
231 ("QuickHDL" "qvhcom" "" "qhmake >! Makefile" "./"
232 ("\\(ERROR\\|WARNING\\)[^:]*: \\(.+\\)(\\([0-9]+\\)):" 2 3) ("" 0))
233 ;; Synopsys, VHDL Analyzer: vhdlan test.vhd
234 ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context.
235 ("Synopsys" "vhdlan" "" "" "./"
236 ("\\*\\*Error: vhdlan,[0-9]+ \\(.+\\)(\\([0-9]+\\)):" 1 2) ("" 0))
237 ;; Vantage: analyze -libfile vsslib.ini -src test.vhd
238 ;; Compiling "pcu.vhd" line 1...
239 ;; **Error: LINE 499 *** No aggregate value is valid in this context.
240 ("Vantage" "analyze -libfile vsslib.ini -src" "" "" "./"
241 ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1)
242 ("^ *Compiling \"\\(.+\\)\" " 1))
243 ;; Viewlogic: analyze -libfile vsslib.ini -src test.vhd
244 ;; Compiling "pcu.vhd" line 1...
245 ;; **Error: LINE 499 *** No aggregate value is valid in this context.
246 ("Viewlogic" "analyze -libfile vsslib.ini -src" "" "" "./"
247 ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1)
248 ("^ *Compiling \"\\(.+\\)\" " 1))
250 "*List of available VHDL compilers and their properties.
251 Each list entry specifies the following items for a compiler:
253 Compiler Name : name used in variable `vhdl-compiler' to choose compiler
254 Compile Command : command including options used for syntax analysis
255 Make Command : command including options used instead of `make' (default)
256 Generate Makefile: command to generate a Makefile (used by `make' command)
257 From Directory : directory where compilation is run (must end with '/')
259 Regexp : regular expression to match error messages
260 File Subexp Index: index of subexpression that matches the file name
261 Line Subexp Index: index of subexpression that matches the line number
263 Regexp : regular expression to match a file name message
264 File Subexp Index: index of subexpression that matches the file name
266 See also variable `vhdl-compiler-options' to add options to the compile
269 Some compilers do not include the file name in the error message, but print
270 out a file name message in advance. In this case, set \"File Subexp Index\"
271 to 0 and fill out the \"File Message\" entries.
273 A compiler is selected for syntax analysis (`\\[vhdl-compile]') by
274 assigning its name to variable `vhdl-compiler'.
276 NOTE: Reflect the new setting in the choice list of variable `vhdl-compiler'
277 by restarting Emacs."
278 :type
'(repeat (list :tag
"Compiler" :indent
2
279 (string :tag
"Compiler Name ")
280 (string :tag
"Compile Command ")
281 (string :tag
"Make Command ")
282 (string :tag
"Generate Makefile")
283 (string :tag
"From Directory " "./")
284 (list :tag
"Error Message" :indent
4
285 (regexp :tag
"Regexp ")
286 (integer :tag
"File Subexp Index")
287 (integer :tag
"Line Subexp Index"))
288 (list :tag
"File Message" :indent
4
289 (regexp :tag
"Regexp ")
290 (integer :tag
"File Subexp Index"))))
291 :set
(lambda (variable value
)
292 (vhdl-custom-set variable value
'vhdl-update-mode-menu
))
293 :group
'vhdl-compile
)
295 (defcustom vhdl-compiler
"ModelSim"
296 "*Specifies the VHDL compiler to be used for syntax analysis.
297 Select a compiler name from the ones defined in variable `vhdl-compiler-alist'."
298 :type
(let ((compiler-alist vhdl-compiler-alist
) choice-list
)
299 (while compiler-alist
300 (setq choice-list
(cons (list 'const
(car (car compiler-alist
)))
302 (setq compiler-alist
(cdr compiler-alist
)))
303 (append '(choice) (nreverse choice-list
)))
304 :group
'vhdl-compile
)
306 (defcustom vhdl-compiler-options
""
307 "*Options to be added to the compile command."
309 :group
'vhdl-compile
)
312 (defgroup vhdl-style nil
313 "Customizations for code styles."
316 (defcustom vhdl-standard
'(87 nil
)
317 "*VHDL standards used.
319 VHDL'87 : IEEE Std 1076-1987
320 VHDL'93 : IEEE Std 1076-1993
321 Additional standards:
322 VHDL-AMS : IEEE Std 1076.1 (analog-mixed-signal)
323 Math Packages: IEEE Std 1076.2 (`math_real', `math_complex')
325 NOTE: Activate the new setting in a VHDL buffer using the menu entry
326 \"Activate New Customizations\"."
327 :type
'(list (choice :tag
"Basic standard"
328 (const :tag
"VHDL'87" 87)
329 (const :tag
"VHDL'93" 93))
330 (set :tag
"Additional standards" :indent
2
331 (const :tag
"VHDL-AMS" ams
)
332 (const :tag
"Math Packages" math
)))
333 :set
(lambda (variable value
)
334 (vhdl-custom-set variable value
335 'vhdl-template-map-init
336 'vhdl-mode-abbrev-table-init
337 'vhdl-template-construct-alist-init
338 'vhdl-template-package-alist-init
339 'vhdl-update-mode-menu
340 'vhdl-words-init
'vhdl-font-lock-init
))
343 (defcustom vhdl-basic-offset
2
344 "*Amount of basic offset used for indentation.
345 This value is used by + and - symbols in `vhdl-offsets-alist'."
349 (defcustom vhdl-upper-case-keywords nil
350 "*Non-nil means convert keywords to upper case.
351 This is done when typed or expanded or by the fix case functions."
353 :set
(lambda (variable value
)
354 (vhdl-custom-set variable value
'vhdl-abbrev-list-init
))
357 (defcustom vhdl-upper-case-types nil
358 "*Non-nil means convert standardized types to upper case.
359 This is done when expanded or by the fix case functions."
361 :set
(lambda (variable value
)
362 (vhdl-custom-set variable value
'vhdl-abbrev-list-init
))
365 (defcustom vhdl-upper-case-attributes nil
366 "*Non-nil means convert standardized attributes to upper case.
367 This is done when expanded or by the fix case functions."
369 :set
(lambda (variable value
)
370 (vhdl-custom-set variable value
'vhdl-abbrev-list-init
))
373 (defcustom vhdl-upper-case-enum-values nil
374 "*Non-nil means convert standardized enumeration values to upper case.
375 This is done when expanded or by the fix case functions."
377 :set
(lambda (variable value
)
378 (vhdl-custom-set variable value
'vhdl-abbrev-list-init
))
381 (defcustom vhdl-upper-case-constants t
382 "*Non-nil means convert standardized constants to upper case.
383 This is done when expanded."
385 :set
(lambda (variable value
)
386 (vhdl-custom-set variable value
'vhdl-abbrev-list-init
))
390 (defgroup vhdl-electric nil
391 "Customizations for electrification."
394 (defcustom vhdl-electric-keywords
'(vhdl user
)
395 "*Type of keywords for which electrification is enabled.
396 VHDL keywords: invoke built-in templates
397 User keywords: invoke user models (see variable `vhdl-model-alist')"
398 :type
'(set (const :tag
"VHDL keywords" vhdl
)
399 (const :tag
"User keywords" user
))
400 :set
(lambda (variable value
)
401 (vhdl-custom-set variable value
'vhdl-mode-abbrev-table-init
))
402 :group
'vhdl-electric
)
404 (defcustom vhdl-optional-labels
'process
405 "*Constructs for which labels are to be queried.
406 Template generators prompt for optional labels for:
408 Processes only: processes only (also procedurals in VHDL-AMS)
409 All constructs: all constructs with optional labels and keyword END"
410 :type
'(choice (const :tag
"None" none
)
411 (const :tag
"Processes only" process
)
412 (const :tag
"All constructs" all
))
413 :group
'vhdl-electric
)
415 (defcustom vhdl-insert-empty-lines
'unit
416 "*Specifies whether to insert empty lines in some templates.
417 This improves readability of code. Empty lines are inserted in:
419 Design units only: entities, architectures, configurations, packages only
420 All constructs : also all constructs with BEGIN...END parts
422 Replaces variable `vhdl-additional-empty-lines'."
423 :type
'(choice (const :tag
"None" none
)
424 (const :tag
"Design units only" unit
)
425 (const :tag
"All constructs" all
))
426 :group
'vhdl-electric
)
428 (defcustom vhdl-argument-list-indent nil
429 "*Non-nil means indent argument lists relative to opening parenthesis.
430 That is, argument, association, and port lists start on the same line as the
431 opening parenthesis and subsequent lines are indented accordingly.
432 Otherwise, lists start on a new line and are indented as normal code."
434 :group
'vhdl-electric
)
436 (defcustom vhdl-association-list-with-formals t
437 "*Non-nil means write association lists with formal parameters.
438 In templates, you are prompted for formal and actual parameters.
439 If nil, only a list of actual parameters is entered."
441 :group
'vhdl-electric
)
443 (defcustom vhdl-conditions-in-parenthesis nil
444 "*Non-nil means place parenthesis around condition expressions."
446 :group
'vhdl-electric
)
448 (defcustom vhdl-zero-string
"'0'"
449 "*String to use for a logic zero."
451 :group
'vhdl-electric
)
453 (defcustom vhdl-one-string
"'1'"
454 "*String to use for a logic one."
456 :group
'vhdl-electric
)
459 (defgroup vhdl-header nil
460 "Customizations for file header."
461 :group
'vhdl-electric
)
463 (defcustom vhdl-file-header
"\
464 -------------------------------------------------------------------------------
465 -- Title : <title string>
466 -- Project : <project>
467 -------------------------------------------------------------------------------
470 -- Company : <company>
471 -- Last update: <date>
472 -- Platform : <platform>
473 <projectdesc>-------------------------------------------------------------------------------
474 -- Description: <cursor>
475 -------------------------------------------------------------------------------
477 -- Date Version Author Description
478 -- <date> 1.0 <login>\tCreated
479 -------------------------------------------------------------------------------
482 "*String or file to insert as file header.
483 If the string specifies an existing file name, the contents of the file is
484 inserted, otherwise the string itself is inserted as file header.
485 Type `C-j' for newlines.
486 If the header contains RCS keywords, they may be written as <RCS>Keyword<RCS>
487 if the header needs to be version controlled.
489 The following keywords for template generation are supported:
490 <filename> : replaced by the name of the buffer
491 <author> : replaced by the user name and email address (customize
492 `mail-host-address' or `user-mail-address' if required)
493 <login> : replaced by user login name
494 <company> : replaced by contents of variable `vhdl-company-name'
495 <date> : replaced by the current date
496 <project> : replaced by title of current project (`vhdl-project')
497 <projectdesc>: replaced by description of current project (`vhdl-project')
498 <platform> : replaced by contents of variable `vhdl-platform-spec'
499 <... string> : replaced by a queried string (... is the prompt word)
500 <cursor> : final cursor position
502 The (multi-line) project description <projectdesc> can be used as a project
503 dependent part of the file header and can also contain the above keywords."
507 (defcustom vhdl-file-footer
""
508 "*String or file to insert as file footer.
509 If the string specifies an existing file name, the contents of the file is
510 inserted, otherwise the string itself is inserted as file footer (i.e. at
511 the end of the file).
512 Type `C-j' for newlines."
516 (defcustom vhdl-company-name
""
517 "*Name of company to insert in file header."
521 (defcustom vhdl-platform-spec
""
522 "*Specification of VHDL platform to insert in file header.
523 The platform specification should contain names and versions of the
524 simulation and synthesis tools used."
528 (defcustom vhdl-date-format
"%Y/%m/%d"
529 "*Specifies the date format to use in the header.
530 This string is passed as argument to the command `format-time-string'.
531 For more information on format strings, see the documentation for the
532 `format-time-string' command (C-h f `format-time-string')."
536 (defcustom vhdl-modify-date-prefix-string
"-- Last update: "
537 "*Prefix string of modification date in VHDL file header.
538 If actualization of the modification date is called (menu,
539 `\\[vhdl-template-modify]'), this string is searched and the rest
540 of the line replaced by the current date."
544 (defcustom vhdl-modify-date-on-saving t
545 "*Non-nil means update the modification date when the buffer is saved.
546 Calls function `\\[vhdl-template-modify]').
548 NOTE: Activate the new setting in a VHDL buffer using the menu entry
549 \"Activate New Customizations\""
554 (defgroup vhdl-sequential-process nil
555 "Customizations for sequential processes."
556 :group
'vhdl-electric
)
558 (defcustom vhdl-reset-kind
'async
559 "*Specifies which kind of reset to use in sequential processes."
560 :type
'(choice (const :tag
"None" none
)
561 (const :tag
"Synchronous" sync
)
562 (const :tag
"Asynchronous" async
))
563 :group
'vhdl-sequential-process
)
565 (defcustom vhdl-reset-active-high nil
566 "*Non-nil means reset in sequential processes is active high.
567 nil means active low."
569 :group
'vhdl-sequential-process
)
571 (defcustom vhdl-clock-rising-edge t
572 "*Non-nil means rising edge of clock triggers sequential processes.
573 nil means falling edge."
575 :group
'vhdl-sequential-process
)
577 (defcustom vhdl-clock-edge-condition
'standard
578 "*Syntax of the clock edge condition.
579 Standard: \"clk'event and clk = '1'\"
580 Function: \"rising_edge(clk)\""
581 :type
'(choice (const :tag
"Standard" standard
)
582 (const :tag
"Function" function
))
583 :group
'vhdl-sequential-process
)
585 (defcustom vhdl-clock-name
""
586 "*Name of clock signal to use in templates."
588 :group
'vhdl-sequential-process
)
590 (defcustom vhdl-reset-name
""
591 "*Name of reset signal to use in templates."
593 :group
'vhdl-sequential-process
)
596 (defgroup vhdl-model nil
597 "Customizations for user models."
600 (defcustom vhdl-model-alist
602 "<label> : process (<clock>, <reset>)
603 begin -- process <label>
604 if <reset> = '0' then -- asynchronous reset (active low)
606 elsif <clock>'event and <clock> = '1' then -- rising clock edge
607 if <enable> = '1' then -- synchronous load
611 end process <label>;"
613 "*List of user models.
614 VHDL models (templates) can be specified by the user in this list. They can be
615 invoked from the menu, through key bindings (`C-c C-m ...'), or by keyword
616 electrification (i.e. overriding existing or creating new keywords, see
617 variable `vhdl-electric-keywords').
618 Name : name of model (string of words and spaces)
619 String : string or name of file to be inserted as model (newline: `C-j')
620 Key Binding: key binding to invoke model, added to prefix `C-c C-m'
621 (must be in double-quotes, examples: \"i\", \"\\C-p\", \"\\M-s\")
622 Keyword : keyword to invoke model
624 The models can contain prompts to be queried. A prompt is of the form \"<...>\".
625 A prompt that appears several times is queried once and replaced throughout
626 the model. Special prompts are:
627 <clock> : name specified in `vhdl-clock-name' (if not empty)
628 <reset> : name specified in `vhdl-reset-name' (if not empty)
629 <cursor>: final cursor position
631 If the string specifies an existing file name, the contents of the file is
632 inserted, otherwise the string itself is inserted.
633 The code within the models should be correctly indented.
634 Type `C-j' for newlines.
636 NOTE: Activate the new setting in a VHDL buffer using the menu entry
637 \"Activate New Customizations\""
638 :type
'(repeat (list :tag
"Model" :indent
2
639 (string :tag
"Name ")
640 (string :tag
"String : (type `C-j' for newline)"
642 (sexp :tag
"Key Binding" x
)
643 (string :tag
"Keyword ")))
644 :set
(lambda (variable value
)
645 (vhdl-custom-set variable value
648 'vhdl-mode-abbrev-table-init
649 'vhdl-update-mode-menu
))
652 (defgroup vhdl-port nil
653 "Customizations for port transformation functions."
656 (defcustom vhdl-include-port-comments nil
657 "*Non-nil means include port comments when a port is pasted."
661 (defcustom vhdl-include-direction-comments nil
662 "*Non-nil means include signal direction in instantiations as comments."
666 (defconst vhdl-name-doc-string
"
668 FROM REGEXP is a regular expression matching the formal port name:
669 `.*' matches the entire name
670 `\\(...\\)' matches a substring
671 TO STRING specifies the string to be inserted as actual port name:
672 `\\&' means substitute original matched text
673 `\\N' means substitute what matched the Nth `\\(...\\)'
675 `.*' `\\&' leaves name as it is
676 `.*' `\\&_i' attaches `_i' to original name
677 `\\(.*\\)_[io]$' `\\1' strips off `_i' or `_o' from original name
678 `.*' `' leaves name empty")
680 (defcustom vhdl-actual-port-name
'(".*" .
"\\&_i")
682 "*Specifies how actual port names are obtained from formal port names.
683 In a component instantiation, an actual port name can be obtained by
684 modifying the formal port name (e.g. attaching or stripping off a substring)."
685 vhdl-name-doc-string
)
686 :type
'(cons (regexp :tag
"From Regexp")
687 (string :tag
"To String "))
690 (defcustom vhdl-instance-name
'(".*" .
"")
692 "*Specifies how an instance name is obtained.
693 The instance name can be obtained by modifying the name of the component to be
694 instantiated (e.g. attaching or stripping off a substring).
695 If TO STRING is empty, the instance name is queried."
696 vhdl-name-doc-string
)
697 :type
'(cons (regexp :tag
"From Regexp")
698 (string :tag
"To String "))
701 (defcustom vhdl-testbench-entity-name
'(".*" .
"\\&_tb")
703 "*Specifies how the test bench entity name is obtained.
704 The entity name of a test bench can be obtained by modifying the name of
705 the component to be tested (e.g. attaching or stripping off a substring)."
706 vhdl-name-doc-string
)
707 :type
'(cons (regexp :tag
"From Regexp")
708 (string :tag
"To String "))
711 (defcustom vhdl-testbench-architecture-name
'(".*" .
"")
713 "*Specifies how the test bench architecture name is obtained.
714 The test bench architecture name can be obtained by modifying the name of
715 the component to be tested (e.g. attaching or stripping off a substring).
716 If TO STRING is empty, the architecture name is queried."
717 vhdl-name-doc-string
)
718 :type
'(cons (regexp :tag
"From Regexp")
719 (string :tag
"To String "))
722 (defcustom vhdl-testbench-dut-name
'(".*" .
"DUT")
724 "*Specifies how a DUT instance name is obtained.
725 The design-under-test instance name (i.e. the component instantiated in the
726 test bench) can be obtained by modifying the component name (e.g. attaching
727 or stripping off a substring)."
728 vhdl-name-doc-string
)
729 :type
'(cons (regexp :tag
"From Regexp")
730 (string :tag
"To String "))
733 (defcustom vhdl-testbench-entity-header
""
734 "*String or file to be inserted as test bench entity header.
735 If the string specifies an existing file name, the contents of the file is
736 inserted, otherwise the string itself is inserted at the beginning of the test
737 bench entity template.
738 Type `C-j' for newlines."
742 (defcustom vhdl-testbench-architecture-header
""
743 "*String or file to be inserted as test bench architecture header.
744 If the string specifies an existing file name, the contents of the file is
745 inserted, otherwise the string itself is inserted at the beginning of the test
746 bench architecture template, if a separate file is created for the
748 Type `C-j' for newlines."
752 (defcustom vhdl-testbench-declarations
""
753 "*String or file to be inserted in the test bench declarative part.
754 If the string specifies an existing file name, the contents of the file is
755 inserted, otherwise the string itself is inserted in the test bench
756 architecture before the BEGIN keyword.
757 Type `C-j' for newlines."
761 (defcustom vhdl-testbench-statements
""
762 "*String or file to be inserted in the test bench statement part.
763 If the string specifies an existing file name, the contents of the file is
764 inserted, otherwise the string itself is inserted in the test bench
765 architecture before the END keyword.
766 Type `C-j' for newlines."
770 (defcustom vhdl-testbench-initialize-signals nil
771 "*Non-nil means initialize signals with `0' when declared in test bench."
775 (defcustom vhdl-testbench-create-files
'single
776 "*Specifies whether new files should be created for the test bench.
777 Test bench entity and architecture are inserted:
778 None : in current buffer
779 Single file : in new single file
780 Separate files: in two separate files
781 Note that the files have the same name as the contained design unit."
782 :type
'(choice (const :tag
"None" none
)
783 (const :tag
"Single file" single
)
784 (const :tag
"Separate files" separate
))
788 (defgroup vhdl-comment nil
789 "Customizations for comments."
792 (defcustom vhdl-self-insert-comments t
793 "*Non-nil means various templates automatically insert help comments."
795 :group
'vhdl-comment
)
797 (defcustom vhdl-prompt-for-comments t
798 "*Non-nil means various templates prompt for user definable comments."
800 :group
'vhdl-comment
)
802 (defcustom vhdl-inline-comment-column
40
803 "*Column to indent inline comments to.
804 Overrides local variable `comment-column'.
806 NOTE: Activate the new setting in a VHDL buffer using the menu entry
807 \"Activate New Customizations\""
809 :group
'vhdl-comment
)
811 (defcustom vhdl-end-comment-column
79
812 "*End of comment column.
813 Comments that exceed this column number are wrapped.
815 NOTE: Activate the new setting in a VHDL buffer using the menu entry
816 \"Activate New Customizations\""
818 :group
'vhdl-comment
)
820 (defvar end-comment-column
)
823 (defgroup vhdl-align nil
824 "Customizations for alignment."
827 (defcustom vhdl-auto-align t
828 "*Non-nil means align some templates automatically after generation."
832 (defcustom vhdl-align-groups t
833 "*Non-nil means align groups of code lines separately.
834 A group of code lines is a region of lines with no empty lines inbetween."
839 (defgroup vhdl-highlight nil
840 "Customizations for highlighting."
843 (defcustom vhdl-highlight-keywords t
844 "*Non-nil means highlight VHDL keywords and other standardized words.
845 The following faces are used:
846 `font-lock-keyword-face' : keywords
847 `font-lock-type-face' : standardized types
848 `vhdl-font-lock-attribute-face' : standardized attributes
849 `vhdl-font-lock-enumvalue-face' : standardized enumeration values
850 `vhdl-font-lock-function-face' : standardized function and package names
852 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
853 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
855 :set
(lambda (variable value
)
856 (vhdl-custom-set variable value
'vhdl-font-lock-init
))
857 :group
'vhdl-highlight
)
859 (defcustom vhdl-highlight-names t
860 "*Non-nil means highlight declaration names and construct labels.
861 The following faces are used:
862 `font-lock-function-name-face' : names in declarations of units,
863 subprograms, components, as well as labels of VHDL constructs
864 `font-lock-type-face' : names in type/nature declarations
865 `vhdl-font-lock-attribute-face' : names in attribute declarations
866 `font-lock-variable-name-face' : names in declarations of signals,
867 variables, constants, subprogram parameters, generics, and ports
869 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
870 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
872 :set
(lambda (variable value
)
873 (vhdl-custom-set variable value
'vhdl-font-lock-init
))
874 :group
'vhdl-highlight
)
876 (defcustom vhdl-highlight-special-words nil
877 "*Non-nil means highlight words with special syntax.
878 The words with syntax and color specified in variable
879 `vhdl-special-syntax-alist' are highlighted accordingly.
880 Can be used for visual support of naming conventions.
882 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
883 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
885 :set
(lambda (variable value
)
886 (vhdl-custom-set variable value
'vhdl-font-lock-init
))
887 :group
'vhdl-highlight
)
889 (defcustom vhdl-highlight-forbidden-words nil
890 "*Non-nil means highlight forbidden words.
891 The reserved words specified in variable `vhdl-forbidden-words' or having the
892 syntax specified in variable `vhdl-forbidden-syntax' are highlighted in a
893 warning color (face `vhdl-font-lock-reserved-words-face') to indicate not to
896 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
897 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
899 :set
(lambda (variable value
)
900 (vhdl-custom-set variable value
901 'vhdl-words-init
'vhdl-font-lock-init
))
902 :group
'vhdl-highlight
)
904 (defcustom vhdl-highlight-verilog-keywords nil
905 "*Non-nil means highlight Verilog keywords as reserved words.
906 Verilog keywords are highlighted in a warning color (face
907 `vhdl-font-lock-reserved-words-face') to indicate not to use them.
909 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
910 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
912 :set
(lambda (variable value
)
913 (vhdl-custom-set variable value
914 'vhdl-words-init
'vhdl-font-lock-init
))
915 :group
'vhdl-highlight
)
917 (defcustom vhdl-highlight-translate-off nil
918 "*Non-nil means background-highlight code excluded from translation.
919 That is, all code between \"-- pragma translate_off\" and
920 \"-- pragma translate_on\" is highlighted using a different background color
921 \(face `vhdl-font-lock-translate-off-face').
922 Note: this might slow down on-the-fly fontification (and thus editing).
924 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
925 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
927 :set
(lambda (variable value
)
928 (vhdl-custom-set variable value
'vhdl-font-lock-init
))
929 :group
'vhdl-highlight
)
931 (defcustom vhdl-highlight-case-sensitive nil
932 "*Non-nil means consider case for highlighting.
934 non-nil also upper-case VHDL words are highlighted, but case of words with
935 special syntax is not considered
936 nil only lower-case VHDL words are highlighted, but case of words with
937 special syntax is considered
938 Overrides local variable `font-lock-keywords-case-fold-search'.
940 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
941 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
943 :group
'vhdl-highlight
)
945 (defcustom vhdl-special-syntax-alist nil
946 "*List of special syntax to be highlighted.
947 If variable `vhdl-highlight-special-words' is non-nil, words with the specified
948 syntax (as regular expression) are highlighted in the corresponding color.
950 Name : string of words and spaces
951 Regexp : regular expression describing word syntax
952 (e.g. \"\\\w+_c\" matches word with suffix \"_c\")
953 Color (light): foreground color for light background
954 (matching color examples: Gold3, Grey50, LimeGreen, Tomato,
955 LightSeaGreen, DodgerBlue, Gold, PaleVioletRed)
956 Color (dark) : foreground color for dark background
957 (matching color examples: BurlyWood1, Grey80, Green, Coral,
958 AquaMarine2, LightSkyBlue1, Yellow, PaleVioletRed1)
960 Can be used for visual support of naming conventions, such as highlighting
961 different kinds of signals (e.g. \"Clk_c\", \"Rst_r\") or objects (e.g.
962 \"Signal_s\", \"Variable_v\", \"Constant_c\") by distinguishing them using
964 For each entry, a new face is generated with the specified colors and name
965 \"vhdl-font-lock-\" + name + \"-face\".
967 NOTE: Activate a changed regexp in a VHDL buffer by re-fontifying it (menu
968 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking.
969 All other changes require restarting Emacs."
970 :type
'(repeat (list :tag
"Face" :indent
2
971 (string :tag
"Name ")
972 (regexp :tag
"Regexp " "\\w+_")
973 (string :tag
"Color (light)")
974 (string :tag
"Color (dark) ")))
975 :set
(lambda (variable value
)
976 (vhdl-custom-set variable value
'vhdl-font-lock-init
))
977 :group
'vhdl-highlight
)
979 (defcustom vhdl-forbidden-words
'()
980 "*List of forbidden words to be highlighted.
981 If variable `vhdl-highlight-forbidden-words' is non-nil, these reserved
982 words are highlighted in a warning color to indicate not to use them.
984 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
985 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
986 :type
'(repeat (string :format
"%v"))
987 :set
(lambda (variable value
)
988 (vhdl-custom-set variable value
989 'vhdl-words-init
'vhdl-font-lock-init
))
990 :group
'vhdl-highlight
)
992 (defcustom vhdl-forbidden-syntax
""
993 "*Syntax of forbidden words to be highlighted.
994 If variable `vhdl-highlight-forbidden-words' is non-nil, words with this
995 syntax are highlighted in a warning color to indicate not to use them.
996 Can be used to highlight too long identifiers (e.g. \"\\w\\w\\w\\w\\w\\w\\w\\w\\w\\w+\"
997 highlights identifiers with 10 or more characters).
999 NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
1000 entry \"Fontify Buffer\"). XEmacs: turn off and on font locking."
1002 :set
(lambda (variable value
)
1003 (vhdl-custom-set variable value
1004 'vhdl-words-init
'vhdl-font-lock-init
))
1005 :group
'vhdl-highlight
)
1008 (defgroup vhdl-menu nil
1009 "Customizations for speedbar and menues."
1012 (defcustom vhdl-speedbar nil
1013 "*Non-nil means open the speedbar automatically at startup.
1014 Alternatively, the speedbar can be opened from the VHDL menu."
1018 (defcustom vhdl-speedbar-show-hierarchy nil
1019 "*Non-nil means open the speedbar as hierarchy browser at startup.
1020 Otherwise, the speedbar is opened as normal file browser."
1024 (defcustom vhdl-speedbar-hierarchy-indent
1
1025 "*Amount of indentation in hierarchy display of subcomponent."
1029 (defcustom vhdl-index-menu nil
1030 "*Non-nil means add an index menu for a source file when loading.
1031 Alternatively, the speedbar can be used. Note that the index menu scans a file
1032 when it is opened, while speedbar only scans the file upon request.
1033 Does not work under XEmacs."
1037 (defcustom vhdl-source-file-menu nil
1038 "*Non-nil means add a menu of all source files in current directory.
1039 Alternatively, the speedbar can be used."
1043 (defcustom vhdl-hideshow-menu nil
1044 "*Non-nil means add hideshow menu and functionality.
1045 Hideshow allows hiding code of VHDL design units.
1046 Does not work under XEmacs.
1048 NOTE: Activate the new setting in a VHDL buffer using the menu entry
1049 \"Activate New Customizations\""
1053 (defcustom vhdl-hide-all-init nil
1054 "*Non-nil means hide all design units initially after a file is loaded."
1059 (defgroup vhdl-print nil
1060 "Customizations for printing."
1063 (defcustom vhdl-print-two-column t
1064 "*Non-nil means print code in two columns and landscape format.
1066 NOTE: Activate the new setting by restarting Emacs.
1067 Overrides `ps-print' settings locally."
1071 (defcustom vhdl-print-customize-faces t
1072 "*Non-nil means use an optimized set of faces for postscript printing.
1074 NOTE: Activate the new setting by restarting Emacs.
1075 Overrides `ps-print' settings locally."
1080 (defgroup vhdl-misc nil
1081 "Miscellaneous customizations."
1084 (defcustom vhdl-intelligent-tab t
1085 "*Non-nil means `TAB' does indentation, word completion and tab insertion.
1086 That is, if preceeding character is part of a word then complete word,
1087 else if not at beginning of line then insert tab,
1088 else if last command was a `TAB' or `RET' then dedent one step,
1089 else indent current line (i.e. `TAB' is bound to `vhdl-electric-tab').
1090 If nil, TAB always indents current line (i.e. `TAB' is bound to
1091 `vhdl-indent-line').
1093 NOTE: Activate the new setting in a VHDL buffer using the menu entry
1094 \"Activate New Customizations\""
1098 (defcustom vhdl-word-completion-case-sensitive nil
1099 "*Non-nil means word completion using `TAB' is case sensitive.
1100 That is, `TAB' completes words that start with the same letters and case.
1101 Otherwise, case is ignored."
1105 (defcustom vhdl-word-completion-in-minibuffer t
1106 "*Non-nil enables word completion in minibuffer (for template prompts).
1108 NOTE: Activate the new setting by restarting Emacs."
1112 (defcustom vhdl-underscore-is-part-of-word nil
1113 "*Non-nil means consider the underscore character `_' as part of word.
1114 An identifier containing underscores is then treated as a single word in
1115 select and move operations. All parts of an identifier separated by underscore
1116 are treated as single words otherwise.
1118 NOTE: Activate the new setting in a VHDL buffer using the menu entry
1119 \"Activate New Customizations\""
1121 :set
(lambda (variable value
)
1122 (vhdl-custom-set variable value
'vhdl-mode-syntax-table-init
))
1126 (defgroup vhdl-related nil
1127 "Related general customizations."
1130 ;; add related general customizations
1131 (custom-add-to-group 'vhdl-related
'line-number-mode
'custom-variable
)
1132 (if (string-match "XEmacs" emacs-version
)
1133 (custom-add-to-group 'vhdl-related
'paren-mode
'custom-variable
)
1134 (custom-add-to-group 'vhdl-related
'paren-showing
'custom-group
))
1135 (unless (string-match "XEmacs" emacs-version
)
1136 (custom-add-to-group 'vhdl-related
'transient-mark-mode
'custom-variable
))
1137 (custom-add-to-group 'vhdl-related
'ps-print
'custom-group
)
1138 (custom-add-to-group 'vhdl-related
'mail-host-address
'custom-variable
)
1139 (custom-add-to-group 'vhdl-related
'user-mail-address
'custom-variable
)
1141 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1142 ;; Internal variables
1144 (defconst vhdl-version
"3.29"
1145 "VHDL Mode version number.")
1147 (defvar vhdl-progress-interval
1
1148 "*Interval used to update progress status during long operations.
1149 If a number, percentage complete gets updated after each interval of
1150 that many seconds. To inhibit all messages, set this variable to nil.")
1152 (defvar vhdl-inhibit-startup-warnings-p nil
1153 "*If non-nil, inhibits start up compatibility warnings.")
1155 (defvar vhdl-strict-syntax-p nil
1156 "*If non-nil, all syntactic symbols must be found in `vhdl-offsets-alist'.
1157 If the syntactic symbol for a particular line does not match a symbol
1158 in the offsets alist, an error is generated, otherwise no error is
1159 reported and the syntactic symbol is ignored.")
1161 (defvar vhdl-echo-syntactic-information-p nil
1162 "*If non-nil, syntactic info is echoed when the line is indented.")
1164 (defconst vhdl-offsets-alist-default
1169 (statement-cont . vhdl-lineup-statement-cont
)
1170 (statement-block-intro .
+)
1171 (statement-case-intro .
+)
1172 (case-alternative .
+)
1173 (comment . vhdl-lineup-comment
)
1176 (arglist-cont-nonempty . vhdl-lineup-arglist
)
1177 (arglist-close . vhdl-lineup-arglist
)
1184 "Default settings for offsets of syntactic elements.
1185 Do not change this constant! See the variable `vhdl-offsets-alist' for
1188 (defvar vhdl-offsets-alist
(copy-alist vhdl-offsets-alist-default
)
1189 "*Association list of syntactic element symbols and indentation offsets.
1190 As described below, each cons cell in this list has the form:
1192 (SYNTACTIC-SYMBOL . OFFSET)
1194 When a line is indented, `vhdl-mode' first determines the syntactic
1195 context of the line by generating a list of symbols called syntactic
1196 elements. This list can contain more than one syntactic element and
1197 the global variable `vhdl-syntactic-context' contains the context list
1198 for the line being indented. Each element in this list is actually a
1199 cons cell of the syntactic symbol and a buffer position. This buffer
1200 position is call the relative indent point for the line. Some
1201 syntactic symbols may not have a relative indent point associated with
1204 After the syntactic context list for a line is generated, `vhdl-mode'
1205 calculates the absolute indentation for the line by looking at each
1206 syntactic element in the list. First, it compares the syntactic
1207 element against the SYNTACTIC-SYMBOL's in `vhdl-offsets-alist'. When it
1208 finds a match, it adds the OFFSET to the column of the relative indent
1209 point. The sum of this calculation for each element in the syntactic
1210 list is the absolute offset for line being indented.
1212 If the syntactic element does not match any in the `vhdl-offsets-alist',
1213 an error is generated if `vhdl-strict-syntax-p' is non-nil, otherwise
1214 the element is ignored.
1216 Actually, OFFSET can be an integer, a function, a variable, or one of
1217 the following symbols: `+', `-', `++', or `--'. These latter
1218 designate positive or negative multiples of `vhdl-basic-offset',
1219 respectively: *1, *-1, *2, and *-2. If OFFSET is a function, it is
1220 called with a single argument containing the cons of the syntactic
1221 element symbol and the relative indent point. The function should
1222 return an integer offset.
1224 Here is the current list of valid syntactic element symbols:
1226 string -- inside multi-line string
1227 block-open -- statement block open
1228 block-close -- statement block close
1229 statement -- a VHDL statement
1230 statement-cont -- a continuation of a VHDL statement
1231 statement-block-intro -- the first line in a new statement block
1232 statement-case-intro -- the first line in a case alternative block
1233 case-alternative -- a case statement alternative clause
1234 comment -- a line containing only a comment
1235 arglist-intro -- the first line in an argument list
1236 arglist-cont -- subsequent argument list lines when no
1237 arguments follow on the same line as the
1238 the arglist opening paren
1239 arglist-cont-nonempty -- subsequent argument list lines when at
1240 least one argument follows on the same
1241 line as the arglist opening paren
1242 arglist-close -- the solo close paren of an argument list
1243 entity -- inside an entity declaration
1244 configuration -- inside a configuration declaration
1245 package -- inside a package declaration
1246 architecture -- inside an architecture body
1247 package-body -- inside a package body")
1249 (defvar vhdl-comment-only-line-offset
0
1250 "*Extra offset for line which contains only the start of a comment.
1251 Can contain an integer or a cons cell of the form:
1253 (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
1255 Where NON-ANCHORED-OFFSET is the amount of offset given to
1256 non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
1257 the amount of offset to give column-zero anchored comment-only lines.
1258 Just an integer as value is equivalent to (<val> . 0)")
1260 (defvar vhdl-special-indent-hook nil
1261 "*Hook for user defined special indentation adjustments.
1262 This hook gets called after a line is indented by the mode.")
1264 (defvar vhdl-style-alist
1266 (vhdl-basic-offset .
4)
1267 (vhdl-offsets-alist .
())
1270 "Styles of Indentation.
1271 Elements of this alist are of the form:
1273 (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
1275 where STYLE-STRING is a short descriptive string used to select a
1276 style, VARIABLE is any `vhdl-mode' variable, and VALUE is the intended
1277 value for that variable when using the selected style.
1279 There is one special case when VARIABLE is `vhdl-offsets-alist'. In this
1280 case, the VALUE is a list containing elements of the form:
1282 (SYNTACTIC-SYMBOL . VALUE)
1284 as described in `vhdl-offsets-alist'. These are passed directly to
1285 `vhdl-set-offset' so there is no need to set every syntactic symbol in
1286 your style, only those that are different from the default.")
1288 ;; dynamically append the default value of most variables
1289 (or (assoc "Default" vhdl-style-alist
)
1290 (let* ((varlist '(vhdl-inhibit-startup-warnings-p
1291 vhdl-strict-syntax-p
1292 vhdl-echo-syntactic-information-p
1295 vhdl-comment-only-line-offset
))
1296 (default (cons "Default"
1300 (cons var
(symbol-value var
))))
1302 (setq vhdl-style-alist
(cons default vhdl-style-alist
))))
1304 (defvar vhdl-mode-hook nil
1305 "*Hook called by `vhdl-mode'.")
1308 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1311 (defvar vhdl-startup-warnings nil
1312 "Warnings to tell the user during start up.")
1314 (defun vhdl-print-warnings ()
1315 "Print out messages in variable `vhdl-startup-warnings'."
1316 (let ((warnings vhdl-startup-warnings
))
1318 (message (concat "WARNING: " (car warnings
)))
1319 (setq warnings
(cdr warnings
))))
1320 (when (> (length vhdl-startup-warnings
) 1)
1321 (message "WARNING: See warning messages in *Messages* buffer.")))
1323 (defun vhdl-add-warning (string)
1324 "Add STRING to warning list `vhdl-startup-warnings'."
1325 (setq vhdl-startup-warnings
(cons string vhdl-startup-warnings
)))
1327 ;; Perform compatibility checks.
1328 (when (not (stringp vhdl-compiler
)) ; changed format of `vhdl-compiler'
1329 (setq vhdl-compiler
"ModelSim")
1330 (vhdl-add-warning "Variable `vhdl-compiler' has changed format; customize again"))
1331 (when (not (listp vhdl-standard
)) ; changed format of `vhdl-standard'
1332 (setq vhdl-standard
'(87 nil
))
1333 (vhdl-add-warning "Variable `vhdl-standard' has changed format; customize again"))
1334 (when (= (length (car vhdl-model-alist
)) 3)
1335 (let ((old-alist vhdl-model-alist
) ; changed format of `vhdl-model-alist'
1338 (setq new-alist
(cons (append (car old-alist
) '("")) new-alist
))
1339 (setq old-alist
(cdr old-alist
)))
1340 (setq vhdl-model-alist
(nreverse new-alist
))))
1341 (when (= (length (car vhdl-project-alist
)) 3)
1342 (let ((old-alist vhdl-project-alist
) ; changed format of `vhdl-project-alist'
1345 (setq new-alist
(cons (append (car old-alist
) '("")) new-alist
))
1346 (setq old-alist
(cdr old-alist
)))
1347 (setq vhdl-project-alist
(nreverse new-alist
))))
1349 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1352 (defsubst vhdl-standard-p
(standard)
1353 "Check if STANDARD is specified as used standard."
1354 (or (eq standard
(car vhdl-standard
))
1355 (memq standard
(cadr vhdl-standard
))))
1357 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1358 ;; Required packages
1363 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1364 ;;; Emacs variant handling
1365 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1369 (defun vhdl-keep-region-active ()
1370 "Do whatever is necessary to keep the region active in XEmacs.
1371 Ignore byte-compiler warnings you might see."
1372 (and (boundp 'zmacs-region-stays
)
1373 (setq zmacs-region-stays t
)))
1375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1378 (unless (fboundp 'wildcard-to-regexp
)
1379 (defun wildcard-to-regexp (wildcard)
1380 "Simplified version of `wildcard-to-regexp' from Emacs' `files.el'."
1381 (let* ((i (string-match "[*?]" wildcard
))
1382 (result (substring wildcard
0 i
))
1383 (len (length wildcard
)))
1386 (let ((ch (aref wildcard i
)))
1387 (setq result
(concat result
1388 (cond ((eq ch ?
*) "[^\000]*")
1389 ((eq ch ??
) "[^\000]")
1390 (t (char-to-string ch
)))))
1392 (concat "\\`" result
"\\'"))))
1395 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1399 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1402 (defvar vhdl-template-map
()
1403 "Keymap for VHDL templates.")
1405 (defun vhdl-template-map-init ()
1406 "Initialize `vhdl-template-map'."
1407 (setq vhdl-template-map
(make-sparse-keymap))
1408 ;; key bindings for VHDL templates
1409 (define-key vhdl-template-map
"al" 'vhdl-template-alias
)
1410 (define-key vhdl-template-map
"ar" 'vhdl-template-architecture
)
1411 (define-key vhdl-template-map
"at" 'vhdl-template-assert
)
1412 (define-key vhdl-template-map
"ad" 'vhdl-template-attribute-decl
)
1413 (define-key vhdl-template-map
"as" 'vhdl-template-attribute-spec
)
1414 (define-key vhdl-template-map
"bl" 'vhdl-template-block
)
1415 (define-key vhdl-template-map
"ca" 'vhdl-template-case-is
)
1416 (define-key vhdl-template-map
"cd" 'vhdl-template-component-decl
)
1417 (define-key vhdl-template-map
"ci" 'vhdl-template-component-inst
)
1418 (define-key vhdl-template-map
"cs" 'vhdl-template-conditional-signal-asst
)
1419 (define-key vhdl-template-map
"Cb" 'vhdl-template-block-configuration
)
1420 (define-key vhdl-template-map
"Cc" 'vhdl-template-component-conf
)
1421 (define-key vhdl-template-map
"Cd" 'vhdl-template-configuration-decl
)
1422 (define-key vhdl-template-map
"Cs" 'vhdl-template-configuration-spec
)
1423 (define-key vhdl-template-map
"co" 'vhdl-template-constant
)
1424 (define-key vhdl-template-map
"di" 'vhdl-template-disconnect
)
1425 (define-key vhdl-template-map
"el" 'vhdl-template-else
)
1426 (define-key vhdl-template-map
"ei" 'vhdl-template-elsif
)
1427 (define-key vhdl-template-map
"en" 'vhdl-template-entity
)
1428 (define-key vhdl-template-map
"ex" 'vhdl-template-exit
)
1429 (define-key vhdl-template-map
"fi" 'vhdl-template-file
)
1430 (define-key vhdl-template-map
"fg" 'vhdl-template-for-generate
)
1431 (define-key vhdl-template-map
"fl" 'vhdl-template-for-loop
)
1432 (define-key vhdl-template-map
"\C-f" 'vhdl-template-footer
)
1433 (define-key vhdl-template-map
"fb" 'vhdl-template-function-body
)
1434 (define-key vhdl-template-map
"fd" 'vhdl-template-function-decl
)
1435 (define-key vhdl-template-map
"ge" 'vhdl-template-generic
)
1436 (define-key vhdl-template-map
"gd" 'vhdl-template-group-decl
)
1437 (define-key vhdl-template-map
"gt" 'vhdl-template-group-template
)
1438 (define-key vhdl-template-map
"\C-h" 'vhdl-template-header
)
1439 (define-key vhdl-template-map
"ig" 'vhdl-template-if-generate
)
1440 (define-key vhdl-template-map
"it" 'vhdl-template-if-then
)
1441 (define-key vhdl-template-map
"li" 'vhdl-template-library
)
1442 (define-key vhdl-template-map
"lo" 'vhdl-template-bare-loop
)
1443 (define-key vhdl-template-map
"\C-m" 'vhdl-template-modify
)
1444 (define-key vhdl-template-map
"\C-t" 'vhdl-template-insert-date
)
1445 (define-key vhdl-template-map
"ma" 'vhdl-template-map
)
1446 (define-key vhdl-template-map
"ne" 'vhdl-template-next
)
1447 (define-key vhdl-template-map
"ot" 'vhdl-template-others
)
1448 (define-key vhdl-template-map
"Pd" 'vhdl-template-package-decl
)
1449 (define-key vhdl-template-map
"Pb" 'vhdl-template-package-body
)
1450 (define-key vhdl-template-map
"(" 'vhdl-template-paired-parens
)
1451 (define-key vhdl-template-map
"po" 'vhdl-template-port
)
1452 (define-key vhdl-template-map
"pb" 'vhdl-template-procedure-body
)
1453 (define-key vhdl-template-map
"pd" 'vhdl-template-procedure-decl
)
1454 (define-key vhdl-template-map
"pc" 'vhdl-template-process-comb
)
1455 (define-key vhdl-template-map
"ps" 'vhdl-template-process-seq
)
1456 (define-key vhdl-template-map
"rp" 'vhdl-template-report
)
1457 (define-key vhdl-template-map
"rt" 'vhdl-template-return
)
1458 (define-key vhdl-template-map
"ss" 'vhdl-template-selected-signal-asst
)
1459 (define-key vhdl-template-map
"si" 'vhdl-template-signal
)
1460 (define-key vhdl-template-map
"su" 'vhdl-template-subtype
)
1461 (define-key vhdl-template-map
"ty" 'vhdl-template-type
)
1462 (define-key vhdl-template-map
"us" 'vhdl-template-use
)
1463 (define-key vhdl-template-map
"va" 'vhdl-template-variable
)
1464 (define-key vhdl-template-map
"wa" 'vhdl-template-wait
)
1465 (define-key vhdl-template-map
"wl" 'vhdl-template-while-loop
)
1466 (define-key vhdl-template-map
"wi" 'vhdl-template-with
)
1467 (define-key vhdl-template-map
"wc" 'vhdl-template-clocked-wait
)
1468 (define-key vhdl-template-map
"\C-pb" 'vhdl-template-package-numeric-bit
)
1469 (define-key vhdl-template-map
"\C-pn" 'vhdl-template-package-numeric-std
)
1470 (define-key vhdl-template-map
"\C-ps" 'vhdl-template-package-std-logic-1164
)
1471 (define-key vhdl-template-map
"\C-pA" 'vhdl-template-package-std-logic-arith
)
1472 (define-key vhdl-template-map
"\C-pM" 'vhdl-template-package-std-logic-misc
)
1473 (define-key vhdl-template-map
"\C-pS" 'vhdl-template-package-std-logic-signed
)
1474 (define-key vhdl-template-map
"\C-pT" 'vhdl-template-package-std-logic-textio
)
1475 (define-key vhdl-template-map
"\C-pU" 'vhdl-template-package-std-logic-unsigned
)
1476 (define-key vhdl-template-map
"\C-pt" 'vhdl-template-package-textio
)
1477 (define-key vhdl-template-map
"\C-dn" 'vhdl-template-directive-translate-on
)
1478 (define-key vhdl-template-map
"\C-df" 'vhdl-template-directive-translate-off
)
1479 (define-key vhdl-template-map
"\C-dN" 'vhdl-template-directive-synthesis-on
)
1480 (define-key vhdl-template-map
"\C-dF" 'vhdl-template-directive-synthesis-off
)
1481 (define-key vhdl-template-map
"\C-q" 'vhdl-template-search-prompt
)
1482 (when (vhdl-standard-p 'ams
)
1483 (define-key vhdl-template-map
"br" 'vhdl-template-break
)
1484 (define-key vhdl-template-map
"cu" 'vhdl-template-case-use
)
1485 (define-key vhdl-template-map
"iu" 'vhdl-template-if-use
)
1486 (define-key vhdl-template-map
"lm" 'vhdl-template-limit
)
1487 (define-key vhdl-template-map
"na" 'vhdl-template-nature
)
1488 (define-key vhdl-template-map
"pa" 'vhdl-template-procedural
)
1489 (define-key vhdl-template-map
"qf" 'vhdl-template-quantity-free
)
1490 (define-key vhdl-template-map
"qb" 'vhdl-template-quantity-branch
)
1491 (define-key vhdl-template-map
"qs" 'vhdl-template-quantity-source
)
1492 (define-key vhdl-template-map
"sn" 'vhdl-template-subnature
)
1493 (define-key vhdl-template-map
"te" 'vhdl-template-terminal
)
1495 (when (vhdl-standard-p 'math
)
1496 (define-key vhdl-template-map
"\C-pc" 'vhdl-template-package-math-complex
)
1497 (define-key vhdl-template-map
"\C-pr" 'vhdl-template-package-math-real
)
1500 ;; initialize template map for VHDL Mode
1501 (vhdl-template-map-init)
1503 (defun vhdl-function-name (prefix string
&optional postfix
)
1504 "Generate a Lisp function name.
1505 PREFIX, STRING and optional POSTFIX are concatenated by '-' and spaces in
1506 STRING are replaced by `-' and substrings are converted to lower case."
1507 (let ((name prefix
))
1508 (while (string-match "\\(\\w+\\)\\s-*\\(.*\\)" string
)
1510 (concat name
"-" (downcase (substring string
0 (match-end 1)))))
1511 (setq string
(substring string
(match-beginning 2))))
1512 (when postfix
(setq name
(concat name
"-" postfix
)))
1515 (defvar vhdl-model-map
()
1516 "Keymap for VHDL models.")
1518 (defun vhdl-model-map-init ()
1519 "Initialize `vhdl-model-map'."
1520 (setq vhdl-model-map
(make-sparse-keymap))
1521 ;; key bindings for VHDL models
1522 (let ((model-alist vhdl-model-alist
) model
)
1524 (setq model
(car model-alist
))
1525 (define-key vhdl-model-map
(nth 2 model
)
1526 (vhdl-function-name "vhdl-model" (nth 0 model
)))
1527 (setq model-alist
(cdr model-alist
)))))
1529 ;; initialize user model map for VHDL Mode
1530 (vhdl-model-map-init)
1532 (defvar vhdl-mode-map
()
1533 "Keymap for VHDL Mode.")
1535 (defun vhdl-mode-map-init ()
1536 "Initialize `vhdl-mode-map'."
1537 (setq vhdl-mode-map
(make-sparse-keymap))
1538 ;; template key bindings
1539 (define-key vhdl-mode-map
"\C-c\C-t" vhdl-template-map
)
1540 ;; model key bindings
1541 (define-key vhdl-mode-map
"\C-c\C-m" vhdl-model-map
)
1542 ;; standard key bindings
1543 (define-key vhdl-mode-map
"\M-a" 'vhdl-beginning-of-statement
)
1544 (define-key vhdl-mode-map
"\M-e" 'vhdl-end-of-statement
)
1545 (define-key vhdl-mode-map
"\M-\C-f" 'vhdl-forward-sexp
)
1546 (define-key vhdl-mode-map
"\M-\C-b" 'vhdl-backward-sexp
)
1547 (define-key vhdl-mode-map
"\M-\C-u" 'vhdl-backward-up-list
)
1548 (define-key vhdl-mode-map
"\M-\C-a" 'vhdl-beginning-of-defun
)
1549 (define-key vhdl-mode-map
"\M-\C-e" 'vhdl-end-of-defun
)
1550 (define-key vhdl-mode-map
"\M-\C-h" 'vhdl-mark-defun
)
1551 (define-key vhdl-mode-map
"\M-\C-q" 'vhdl-indent-sexp
)
1552 ;; backspace/delete key bindings
1553 (define-key vhdl-mode-map
[backspace] 'backward-delete-char-untabify)
1554 (define-key vhdl-mode-map [delete] 'delete-char)
1555 (unless (string-match "XEmacs" emacs-version)
1556 (define-key vhdl-mode-map [M-delete] 'kill-word))
1557 ;; mode specific key bindings
1558 (define-key vhdl-mode-map "\C-c\C-e" 'vhdl-electric-mode)
1559 (define-key vhdl-mode-map "\C-c\C-s" 'vhdl-stutter-mode)
1560 (define-key vhdl-mode-map "\C-c\C-k" 'vhdl-compile)
1561 (define-key vhdl-mode-map "\C-c\M-\C-k" 'vhdl-make)
1562 (define-key vhdl-mode-map "\C-c\C-p\C-w" 'vhdl-port-copy)
1563 (define-key vhdl-mode-map "\C-c\C-p\M-w" 'vhdl-port-copy)
1564 (define-key vhdl-mode-map "\C-c\C-p\C-e" 'vhdl-port-paste-entity)
1565 (define-key vhdl-mode-map "\C-c\C-p\C-c" 'vhdl-port-paste-component)
1566 (define-key vhdl-mode-map "\C-c\C-p\C-i" 'vhdl-port-paste-instance)
1567 (define-key vhdl-mode-map "\C-c\C-p\C-s" 'vhdl-port-paste-signals)
1568 (define-key vhdl-mode-map "\C-c\C-p\M-c" 'vhdl-port-paste-constants)
1569 (if (string-match "XEmacs" emacs-version) ; `... C-g' not allowed in XEmacs
1570 (define-key vhdl-mode-map "\C-c\C-p\M-g" 'vhdl-port-paste-generic-map)
1571 (define-key vhdl-mode-map "\C-c\C-p\C-g" 'vhdl-port-paste-generic-map))
1572 (define-key vhdl-mode-map "\C-c\C-p\C-t" 'vhdl-port-paste-testbench)
1573 (define-key vhdl-mode-map "\C-c\C-p\C-f" 'vhdl-port-flatten)
1574 (define-key vhdl-mode-map "\C-c\C-c" 'vhdl-comment-uncomment-region)
1575 (define-key vhdl-mode-map "\C-c-" 'vhdl-comment-append-inline)
1576 (define-key vhdl-mode-map "\C-c\M--" 'vhdl-comment-display-line)
1577 (define-key vhdl-mode-map "\C-c\M-\C-i" 'vhdl-indent-line)
1578 (define-key vhdl-mode-map "\M-\C-\\" 'vhdl-indent-region)
1579 (define-key vhdl-mode-map "\C-c\C-a" 'vhdl-align-group)
1580 (define-key vhdl-mode-map "\C-c\C-r\C-a" 'vhdl-align-noindent-region)
1581 (define-key vhdl-mode-map "\C-c\M-\C-a" 'vhdl-align-inline-comment-group)
1582 (define-key vhdl-mode-map "\C-c\C-r\M-\C-a" 'vhdl-align-inline-comment-region)
1583 (define-key vhdl-mode-map "\C-c\C-w" 'vhdl-fixup-whitespace-region)
1584 (define-key vhdl-mode-map "\C-c\C-l\C-w" 'vhdl-line-kill)
1585 (define-key vhdl-mode-map "\C-c\C-l\M-w" 'vhdl-line-copy)
1586 (define-key vhdl-mode-map "\C-c\C-l\C-y" 'vhdl-line-yank)
1587 (define-key vhdl-mode-map "\C-c\C-l\t" 'vhdl-line-expand)
1588 (define-key vhdl-mode-map "\C-c\C-l\C-n" 'vhdl-line-transpose-next)
1589 (define-key vhdl-mode-map "\C-c\C-l\C-p" 'vhdl-line-transpose-previous)
1590 (define-key vhdl-mode-map "\C-c\C-l\C-o" 'vhdl-line-open)
1591 (define-key vhdl-mode-map "\C-c\C-l\C-g" 'goto-line)
1592 (define-key vhdl-mode-map "\C-c\C-l\C-c" 'vhdl-comment-uncomment-line)
1593 (define-key vhdl-mode-map "\C-c\C-r\C-u" 'vhdl-fix-case-region)
1594 (define-key vhdl-mode-map "\C-c\C-u" 'vhdl-fix-case-buffer)
1595 (define-key vhdl-mode-map "\C-c\C-f" 'vhdl-fontify-buffer)
1596 (define-key vhdl-mode-map "\C-c\C-x" 'vhdl-show-syntactic-information)
1597 (define-key vhdl-mode-map "\C-c\C-h" 'vhdl-doc-mode)
1598 (define-key vhdl-mode-map "\C-c\C-v" 'vhdl-version)
1599 (define-key vhdl-mode-map "\C-c\C-r\C-b" 'vhdl-beautify-region)
1600 (define-key vhdl-mode-map "\C-c\C-b" 'vhdl-beautify-buffer)
1601 (define-key vhdl-mode-map "\M-\t" 'tab-to-tab-stop)
1602 ;; insert commands bindings
1603 (define-key vhdl-mode-map "\C-c\C-i\C-c" 'vhdl-template-insert-construct)
1604 (define-key vhdl-mode-map "\C-c\C-i\C-p" 'vhdl-template-insert-package)
1605 (define-key vhdl-mode-map "\C-c\C-i\C-d" 'vhdl-template-insert-directive)
1606 (define-key vhdl-mode-map "\C-c\C-i\C-m" 'vhdl-model-insert)
1607 ;; electric key bindings
1608 (define-key vhdl-mode-map " " 'vhdl-electric-space)
1609 (if vhdl-intelligent-tab
1610 (define-key vhdl-mode-map "\t" 'vhdl-electric-tab)
1611 (define-key vhdl-mode-map "\t" 'vhdl-indent-line))
1612 (define-key vhdl-mode-map "\r" 'vhdl-electric-return)
1613 (define-key vhdl-mode-map "-" 'vhdl-electric-dash)
1614 (define-key vhdl-mode-map "[" 'vhdl-electric-open-bracket)
1615 (define-key vhdl-mode-map "]" 'vhdl-electric-close-bracket)
1616 (define-key vhdl-mode-map "'" 'vhdl-electric-quote)
1617 (define-key vhdl-mode-map ";" 'vhdl-electric-semicolon)
1618 (define-key vhdl-mode-map "," 'vhdl-electric-comma)
1619 (define-key vhdl-mode-map "." 'vhdl-electric-period)
1620 (when (vhdl-standard-p 'ams)
1621 (define-key vhdl-mode-map "=" 'vhdl-electric-equal)))
1623 ;; initialize mode map for VHDL Mode
1624 (vhdl-mode-map-init)
1626 ;; define special minibuffer keymap for enabling word completion in minibuffer
1627 ;; (useful in template generator prompts)
1628 (defvar vhdl-minibuffer-local-map (copy-keymap minibuffer-local-map)
1629 "Keymap for minibuffer used in VHDL Mode.")
1631 (when vhdl-word-completion-in-minibuffer
1632 (define-key vhdl-minibuffer-local-map "\t" 'vhdl-minibuffer-tab))
1634 ;; set up electric character functions to work with
1635 ;; `delete-selection-mode' (Emacs) and `pending-delete-mode' (XEmacs)
1639 (put sym 'delete-selection t) ; for `delete-selection-mode' (Emacs)
1640 (put sym 'pending-delete t))) ; for `pending-delete-mode' (XEmacs)
1641 '(vhdl-electric-space
1643 vhdl-electric-return
1645 vhdl-electric-open-bracket
1646 vhdl-electric-close-bracket
1648 vhdl-electric-semicolon
1650 vhdl-electric-period
1651 vhdl-electric-equal))
1654 (defvar vhdl-mode-syntax-table nil
1655 "Syntax table used in `vhdl-mode' buffers.")
1657 (defun vhdl-mode-syntax-table-init ()
1658 "Initialize `vhdl-mode-syntax-table'."
1659 (setq vhdl-mode-syntax-table (make-syntax-table))
1660 ;; define punctuation
1661 (modify-syntax-entry ?\# "." vhdl-mode-syntax-table)
1662 (modify-syntax-entry ?\$ "." vhdl-mode-syntax-table)
1663 (modify-syntax-entry ?\% "." vhdl-mode-syntax-table)
1664 (modify-syntax-entry ?\& "." vhdl-mode-syntax-table)
1665 (modify-syntax-entry ?\' "." vhdl-mode-syntax-table)
1666 (modify-syntax-entry ?\* "." vhdl-mode-syntax-table)
1667 (modify-syntax-entry ?\+ "." vhdl-mode-syntax-table)
1668 (modify-syntax-entry ?\. "." vhdl-mode-syntax-table)
1669 (modify-syntax-entry ?\/ "." vhdl-mode-syntax-table)
1670 (modify-syntax-entry ?\: "." vhdl-mode-syntax-table)
1671 (modify-syntax-entry ?\; "." vhdl-mode-syntax-table)
1672 (modify-syntax-entry ?\< "." vhdl-mode-syntax-table)
1673 (modify-syntax-entry ?\= "." vhdl-mode-syntax-table)
1674 (modify-syntax-entry ?\> "." vhdl-mode-syntax-table)
1675 (modify-syntax-entry ?\\ "." vhdl-mode-syntax-table)
1676 (modify-syntax-entry ?\| "." vhdl-mode-syntax-table)
1678 (modify-syntax-entry ?\" "\"" vhdl-mode-syntax-table)
1679 ;; define underscore
1680 (when vhdl-underscore-is-part-of-word
1681 (modify-syntax-entry ?_ "w" vhdl-mode-syntax-table))
1682 ;; a single hyphen is punctuation, but a double hyphen starts a comment
1683 (modify-syntax-entry ?\- ". 12" vhdl-mode-syntax-table)
1684 ;; and \n and \^M end a comment
1685 (modify-syntax-entry ?\n ">" vhdl-mode-syntax-table)
1686 (modify-syntax-entry ?\^M ">" vhdl-mode-syntax-table)
1687 ;; define parentheses to match
1688 (modify-syntax-entry ?\( "()" vhdl-mode-syntax-table)
1689 (modify-syntax-entry ?\) ")(" vhdl-mode-syntax-table)
1690 (modify-syntax-entry ?\[ "(]" vhdl-mode-syntax-table)
1691 (modify-syntax-entry ?\] ")[" vhdl-mode-syntax-table)
1692 (modify-syntax-entry ?\{ "(}" vhdl-mode-syntax-table)
1693 (modify-syntax-entry ?\} "){" vhdl-mode-syntax-table))
1695 ;; initialize syntax table for VHDL Mode
1696 (vhdl-mode-syntax-table-init)
1698 (defmacro vhdl-ext-syntax-table (&rest body)
1699 "Execute BODY with syntax table that includes `_' in word class."
1701 (modify-syntax-entry ?_ "w" vhdl-mode-syntax-table)
1702 (setq result (progn ,@body))
1703 (when (not vhdl-underscore-is-part-of-word)
1704 (modify-syntax-entry ?_ "_" vhdl-mode-syntax-table))
1707 (defvar vhdl-syntactic-context nil
1708 "Buffer local variable containing syntactic analysis list.")
1709 (make-variable-buffer-local 'vhdl-syntactic-context)
1711 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1712 ;; Abbrev hook bindings
1714 (defvar vhdl-mode-abbrev-table nil
1715 "Abbrev table to use in `vhdl-mode' buffers.")
1717 (defun vhdl-mode-abbrev-table-init ()
1718 "Initialize `vhdl-mode-abbrev-table'."
1719 (when vhdl-mode-abbrev-table (clear-abbrev-table vhdl-mode-abbrev-table))
1720 (define-abbrev-table 'vhdl-mode-abbrev-table
1722 (when (memq 'vhdl vhdl-electric-keywords)
1725 ("--" "" vhdl-template-display-comment-hook 0 t)
1726 ("abs" "" vhdl-template-default-hook 0 t)
1727 ("access" "" vhdl-template-default-hook 0 t)
1728 ("after" "" vhdl-template-default-hook 0 t)
1729 ("alias" "" vhdl-template-alias-hook 0 t)
1730 ("all" "" vhdl-template-default-hook 0 t)
1731 ("and" "" vhdl-template-default-hook 0 t)
1732 ("arch" "" vhdl-template-architecture-hook 0 t)
1733 ("architecture" "" vhdl-template-architecture-hook 0 t)
1734 ("array" "" vhdl-template-default-hook 0 t)
1735 ("assert" "" vhdl-template-assert-hook 0 t)
1736 ("attr" "" vhdl-template-attribute-hook 0 t)
1737 ("attribute" "" vhdl-template-attribute-hook 0 t)
1738 ("begin" "" vhdl-template-default-indent-hook 0 t)
1739 ("block" "" vhdl-template-block-hook 0 t)
1740 ("body" "" vhdl-template-default-hook 0 t)
1741 ("buffer" "" vhdl-template-default-hook 0 t)
1742 ("bus" "" vhdl-template-default-hook 0 t)
1743 ("case" "" vhdl-template-case-hook 0 t)
1744 ("comp" "" vhdl-template-component-hook 0 t)
1745 ("component" "" vhdl-template-component-hook 0 t)
1746 ("cond" "" vhdl-template-conditional-signal-asst-hook 0 t)
1747 ("conditional" "" vhdl-template-conditional-signal-asst-hook 0 t)
1748 ("conf" "" vhdl-template-configuration-hook 0 t)
1749 ("configuration" "" vhdl-template-configuration-hook 0 t)
1750 ("cons" "" vhdl-template-constant-hook 0 t)
1751 ("constant" "" vhdl-template-constant-hook 0 t)
1752 ("disconnect" "" vhdl-template-disconnect-hook 0 t)
1753 ("downto" "" vhdl-template-default-hook 0 t)
1754 ("else" "" vhdl-template-else-hook 0 t)
1755 ("elseif" "" vhdl-template-elsif-hook 0 t)
1756 ("elsif" "" vhdl-template-elsif-hook 0 t)
1757 ("end" "" vhdl-template-default-indent-hook 0 t)
1758 ("entity" "" vhdl-template-entity-hook 0 t)
1759 ("exit" "" vhdl-template-exit-hook 0 t)
1760 ("file" "" vhdl-template-file-hook 0 t)
1761 ("for" "" vhdl-template-for-hook 0 t)
1762 ("func" "" vhdl-template-function-hook 0 t)
1763 ("function" "" vhdl-template-function-hook 0 t)
1764 ("generic" "" vhdl-template-generic-hook 0 t)
1765 ("group" "" vhdl-template-group-hook 0 t)
1766 ("guarded" "" vhdl-template-default-hook 0 t)
1767 ("if" "" vhdl-template-if-hook 0 t)
1768 ("impure" "" vhdl-template-default-hook 0 t)
1769 ("in" "" vhdl-template-default-hook 0 t)
1770 ("inertial" "" vhdl-template-default-hook 0 t)
1771 ("inout" "" vhdl-template-default-hook 0 t)
1772 ("inst" "" vhdl-template-instance-hook 0 t)
1773 ("instance" "" vhdl-template-instance-hook 0 t)
1774 ("is" "" vhdl-template-default-hook 0 t)
1775 ("label" "" vhdl-template-default-hook 0 t)
1776 ("library" "" vhdl-template-library-hook 0 t)
1777 ("linkage" "" vhdl-template-default-hook 0 t)
1778 ("literal" "" vhdl-template-default-hook 0 t)
1779 ("loop" "" vhdl-template-bare-loop-hook 0 t)
1780 ("map" "" vhdl-template-map-hook 0 t)
1781 ("mod" "" vhdl-template-default-hook 0 t)
1782 ("nand" "" vhdl-template-default-hook 0 t)
1783 ("new" "" vhdl-template-default-hook 0 t)
1784 ("next" "" vhdl-template-next-hook 0 t)
1785 ("nor" "" vhdl-template-default-hook 0 t)
1786 ("not" "" vhdl-template-default-hook 0 t)
1787 ("null" "" vhdl-template-default-hook 0 t)
1788 ("of" "" vhdl-template-default-hook 0 t)
1789 ("on" "" vhdl-template-default-hook 0 t)
1790 ("open" "" vhdl-template-default-hook 0 t)
1791 ("or" "" vhdl-template-default-hook 0 t)
1792 ("others" "" vhdl-template-default-hook 0 t)
1793 ("out" "" vhdl-template-default-hook 0 t)
1794 ("pack" "" vhdl-template-package-hook 0 t)
1795 ("package" "" vhdl-template-package-hook 0 t)
1796 ("port" "" vhdl-template-port-hook 0 t)
1797 ("postponed" "" vhdl-template-default-hook 0 t)
1798 ("procedure" "" vhdl-template-procedure-hook 0 t)
1799 ("process" "" vhdl-template-process-hook 0 t)
1800 ("pure" "" vhdl-template-default-hook 0 t)
1801 ("range" "" vhdl-template-default-hook 0 t)
1802 ("record" "" vhdl-template-default-hook 0 t)
1803 ("register" "" vhdl-template-default-hook 0 t)
1804 ("reject" "" vhdl-template-default-hook 0 t)
1805 ("rem" "" vhdl-template-default-hook 0 t)
1806 ("report" "" vhdl-template-report-hook 0 t)
1807 ("return" "" vhdl-template-return-hook 0 t)
1808 ("rol" "" vhdl-template-default-hook 0 t)
1809 ("ror" "" vhdl-template-default-hook 0 t)
1810 ("select" "" vhdl-template-selected-signal-asst-hook 0 t)
1811 ("severity" "" vhdl-template-default-hook 0 t)
1812 ("shared" "" vhdl-template-default-hook 0 t)
1813 ("sig" "" vhdl-template-signal-hook 0 t)
1814 ("signal" "" vhdl-template-signal-hook 0 t)
1815 ("sla" "" vhdl-template-default-hook 0 t)
1816 ("sll" "" vhdl-template-default-hook 0 t)
1817 ("sra" "" vhdl-template-default-hook 0 t)
1818 ("srl" "" vhdl-template-default-hook 0 t)
1819 ("subtype" "" vhdl-template-subtype-hook 0 t)
1820 ("then" "" vhdl-template-default-hook 0 t)
1821 ("to" "" vhdl-template-default-hook 0 t)
1822 ("transport" "" vhdl-template-default-hook 0 t)
1823 ("type" "" vhdl-template-type-hook 0 t)
1824 ("unaffected" "" vhdl-template-default-hook 0 t)
1825 ("units" "" vhdl-template-default-hook 0 t)
1826 ("until" "" vhdl-template-default-hook 0 t)
1827 ("use" "" vhdl-template-use-hook 0 t)
1828 ("var" "" vhdl-template-variable-hook 0 t)
1829 ("variable" "" vhdl-template-variable-hook 0 t)
1830 ("wait" "" vhdl-template-wait-hook 0 t)
1831 ("when" "" vhdl-template-when-hook 0 t)
1832 ("while" "" vhdl-template-while-loop-hook 0 t)
1833 ("with" "" vhdl-template-with-hook 0 t)
1834 ("xnor" "" vhdl-template-default-hook 0 t)
1835 ("xor" "" vhdl-template-default-hook 0 t)
1837 ;; VHDL-AMS keywords
1838 (when (and (memq 'vhdl vhdl-electric-keywords) (vhdl-standard-p 'ams))
1840 ("across" "" vhdl-template-default-hook 0 t)
1841 ("break" "" vhdl-template-break-hook 0 t)
1842 ("limit" "" vhdl-template-limit-hook 0 t)
1843 ("nature" "" vhdl-template-nature-hook 0 t)
1844 ("noise" "" vhdl-template-default-hook 0 t)
1845 ("procedural" "" vhdl-template-procedural-hook 0 t)
1846 ("quantity" "" vhdl-template-quantity-hook 0 t)
1847 ("reference" "" vhdl-template-default-hook 0 t)
1848 ("spectrum" "" vhdl-template-default-hook 0 t)
1849 ("subnature" "" vhdl-template-subnature-hook 0 t)
1850 ("terminal" "" vhdl-template-terminal-hook 0 t)
1851 ("through" "" vhdl-template-default-hook 0 t)
1852 ("tolerance" "" vhdl-template-default-hook 0 t)
1854 ;; user model keywords
1855 (when (memq 'user vhdl-electric-keywords)
1856 (let ((alist vhdl-model-alist)
1857 abbrev-list keyword)
1859 (setq keyword (nth 3 (car alist)))
1860 (unless (equal keyword "")
1862 (cons (list keyword ""
1864 "vhdl-model" (nth 0 (car alist)) "hook") 0)
1866 (setq alist (cdr alist)))
1869 ;; initialize abbrev table for VHDL Mode
1870 (vhdl-mode-abbrev-table-init)
1872 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1873 ;; Template completion lists
1875 (defvar vhdl-template-construct-alist nil
1876 "List of built-in construct templates.")
1878 (defun vhdl-template-construct-alist-init ()
1879 "Initialize `vhdl-template-construct-alist'."
1881 vhdl-template-construct-alist
1884 ("alias declaration" vhdl-template-alias)
1885 ("architecture body" vhdl-template-architecture)
1886 ("assertion" vhdl-template-assert)
1887 ("attribute declaration" vhdl-template-attribute-decl)
1888 ("attribute specification" vhdl-template-attribute-spec)
1889 ("block configuration" vhdl-template-block-configuration)
1890 ("block statement" vhdl-template-block)
1891 ("case statement" vhdl-template-case-is)
1892 ("component configuration" vhdl-template-component-conf)
1893 ("component declaration" vhdl-template-component-decl)
1894 ("component instantiation statement" vhdl-template-component-inst)
1895 ("conditional signal assignment" vhdl-template-conditional-signal-asst)
1896 ("configuration declaration" vhdl-template-configuration-decl)
1897 ("configuration specification" vhdl-template-configuration-spec)
1898 ("constant declaration" vhdl-template-constant)
1899 ("disconnection specification" vhdl-template-disconnect)
1900 ("entity declaration" vhdl-template-entity)
1901 ("exit statement" vhdl-template-exit)
1902 ("file declaration" vhdl-template-file)
1903 ("generate statement" vhdl-template-generate)
1904 ("generic clause" vhdl-template-generic)
1905 ("group declaration" vhdl-template-group-decl)
1906 ("group template declaration" vhdl-template-group-template)
1907 ("if statement" vhdl-template-if-then)
1908 ("library clause" vhdl-template-library)
1909 ("loop statement" vhdl-template-loop)
1910 ("next statement" vhdl-template-next)
1911 ("package declaration" vhdl-template-package-decl)
1912 ("package body" vhdl-template-package-body)
1913 ("port clause" vhdl-template-port)
1914 ("process statement" vhdl-template-process)
1915 ("report statement" vhdl-template-report)
1916 ("return statement" vhdl-template-return)
1917 ("selected signal assignment" vhdl-template-selected-signal-asst)
1918 ("signal declaration" vhdl-template-signal)
1919 ("subprogram declaration" vhdl-template-subprogram-decl)
1920 ("subprogram body" vhdl-template-subprogram-body)
1921 ("subtype declaration" vhdl-template-subtype)
1922 ("type declaration" vhdl-template-type)
1923 ("use clause" vhdl-template-use)
1924 ("variable declaration" vhdl-template-variable)
1925 ("wait statement" vhdl-template-wait)
1927 (when (vhdl-standard-p 'ams)
1929 ("break statement" vhdl-template-break)
1930 ("nature declaration" vhdl-template-nature)
1931 ("quantity declaration" vhdl-template-quantity)
1932 ("simultaneous case statement" vhdl-template-case-use)
1933 ("simultaneous if statement" vhdl-template-if-use)
1934 ("simultaneous procedural statement" vhdl-template-procedural)
1935 ("step limit specification" vhdl-template-limit)
1936 ("subnature declaration" vhdl-template-subnature)
1937 ("terminal declaration" vhdl-template-terminal)
1940 ;; initialize for VHDL Mode
1941 (vhdl-template-construct-alist-init)
1943 (defvar vhdl-template-package-alist nil
1944 "List of built-in package templates.")
1946 (defun vhdl-template-package-alist-init ()
1947 "Initialize `vhdl-template-package-alist'."
1949 vhdl-template-package-alist
1952 ("numeric_bit" vhdl-template-package-numeric-bit)
1953 ("numeric_std" vhdl-template-package-numeric-std)
1954 ("std_logic_1164" vhdl-template-package-std-logic-1164)
1955 ("std_logic_arith" vhdl-template-package-std-logic-arith)
1956 ("std_logic_misc" vhdl-template-package-std-logic-misc)
1957 ("std_logic_signed" vhdl-template-package-std-logic-signed)
1958 ("std_logic_textio" vhdl-template-package-std-logic-textio)
1959 ("std_logic_unsigned" vhdl-template-package-std-logic-unsigned)
1960 ("textio" vhdl-template-package-textio)
1962 (when (vhdl-standard-p 'math)
1964 ("math_complex" vhdl-template-package-math-complex)
1965 ("math_real" vhdl-template-package-math-real)
1968 ;; initialize for VHDL Mode
1969 (vhdl-template-package-alist-init)
1971 (defvar vhdl-template-directive-alist
1974 ("translate_on" vhdl-template-directive-translate-on)
1975 ("translate_off" vhdl-template-directive-translate-off)
1976 ("synthesis_on" vhdl-template-directive-synthesis-on)
1977 ("synthesis_off" vhdl-template-directive-synthesis-off)
1979 "List of built-in directive templates.")
1982 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1984 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1986 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1987 ;; VHDL menu (using `easy-menu.el')
1989 (defun vhdl-customize ()
1990 "Call the customize function with `vhdl' as argument."
1992 (customize-browse 'vhdl))
1994 (defun vhdl-create-customize-menu ()
1995 "Create a full customization menu for VHDL, insert it into the menu."
1997 (if (fboundp 'customize-menu-create)
1999 '("VHDL") "Customize"
2000 `(["Browse VHDL Group..." vhdl-customize t]
2001 ,(customize-menu-create 'vhdl)
2003 ["Activate New Customizations" vhdl-activate-customizations t]))
2004 (error "Cannot expand menu (outdated version of cus-edit.el)")))
2006 (defun vhdl-create-mode-menu ()
2007 "Create VHDL Mode menu."
2011 ["Electric" vhdl-electric-mode :style toggle :selected vhdl-electric-mode]
2012 ["Stutter" vhdl-stutter-mode :style toggle :selected vhdl-stutter-mode]
2017 ["None" (vhdl-project-switch "")
2018 :style radio :selected (equal vhdl-project "")]
2021 ;; add menu entries for defined projects
2022 (let ((project-alist vhdl-project-alist) menu-alist name)
2023 (while project-alist
2024 (setq name (car (car project-alist)))
2025 (setq menu-alist (cons (vector name (list 'vhdl-project-switch name)
2026 :style 'radio :selected
2027 (list 'equal 'vhdl-project name))
2029 (setq project-alist (cdr project-alist)))
2030 (setq menu-alist (cons '["Add Project..."
2031 (customize-variable 'vhdl-project-alist) t]
2032 (cons "--" menu-alist)))
2033 (nreverse menu-alist)))
2037 ["Compile Buffer" vhdl-compile t]
2038 ["Stop Compilation" kill-compilation t]
2040 ["Make" vhdl-make t]
2041 ["Generate Makefile" vhdl-generate-makefile t]
2043 ["Next Error" next-error t]
2044 ["Previous Error" previous-error t]
2045 ["First Error" first-error t]
2049 ;; add menu entries for defined compilers
2050 (let ((comp-alist vhdl-compiler-alist) menu-alist name)
2052 (setq name (car (car comp-alist)))
2053 (setq menu-alist (cons (vector name (list 'setq 'vhdl-compiler name)
2054 :style 'radio :selected
2055 (list 'equal 'vhdl-compiler name))
2057 (setq comp-alist (cdr comp-alist)))
2058 (setq menu-alist (cons '["Add Compiler..."
2059 (customize-variable 'vhdl-compiler-alist) t]
2060 (cons "--" menu-alist)))
2061 (nreverse menu-alist))))
2066 ["Alias" vhdl-template-alias t]
2067 ["Architecture" vhdl-template-architecture t]
2068 ["Assert" vhdl-template-assert t]
2069 ["Attribute (Decl)" vhdl-template-attribute-decl t]
2070 ["Attribute (Spec)" vhdl-template-attribute-spec t]
2071 ["Block" vhdl-template-block t]
2072 ["Case" vhdl-template-case-is t]
2073 ["Component (Decl)" vhdl-template-component-decl t]
2074 ["(Component) Instance" vhdl-template-component-inst t]
2075 ["Conditional (Signal Asst)" vhdl-template-conditional-signal-asst t]
2076 ["Configuration (Block)"vhdl-template-block-configuration t]
2077 ["Configuration (Comp)" vhdl-template-component-conf t]
2078 ["Configuration (Decl)" vhdl-template-configuration-decl t]
2079 ["Configuration (Spec)" vhdl-template-configuration-spec t]
2080 ["Constant" vhdl-template-constant t]
2081 ["Disconnect" vhdl-template-disconnect t]
2082 ["Else" vhdl-template-else t]
2083 ["Elsif" vhdl-template-elsif t]
2084 ["Entity" vhdl-template-entity t]
2085 ["Exit" vhdl-template-exit t]
2086 ["File" vhdl-template-file t]
2087 ["For (Generate)" vhdl-template-for-generate t]
2088 ["For (Loop)" vhdl-template-for-loop t]
2089 ["Function (Body)" vhdl-template-function-body t]
2090 ["Function (Decl)" vhdl-template-function-decl t]
2091 ["Generic" vhdl-template-generic t]
2092 ["Group (Decl)" vhdl-template-group-decl t]
2093 ["Group (Template)" vhdl-template-group-template t]
2096 ["If (Generate)" vhdl-template-if-generate t]
2097 ["If (Then)" vhdl-template-if-then t]
2098 ["Library" vhdl-template-library t]
2099 ["Loop" vhdl-template-bare-loop t]
2100 ["Map" vhdl-template-map t]
2101 ["Next" vhdl-template-next t]
2102 ["(Others)" vhdl-template-others t]
2103 ["Package (Decl)" vhdl-template-package-decl t]
2104 ["Package (Body)" vhdl-template-package-body t]
2105 ["Port" vhdl-template-port t]
2106 ["Procedure (Body)" vhdl-template-procedure-body t]
2107 ["Procedure (Decl)" vhdl-template-procedure-decl t]
2108 ["Process (Comb)" vhdl-template-process-comb t]
2109 ["Process (Seq)" vhdl-template-process-seq t]
2110 ["Report" vhdl-template-report t]
2111 ["Return" vhdl-template-return t]
2112 ["Select" vhdl-template-selected-signal-asst t]
2113 ["Signal" vhdl-template-signal t]
2114 ["Subtype" vhdl-template-subtype t]
2115 ["Type" vhdl-template-type t]
2116 ["Use" vhdl-template-use t]
2117 ["Variable" vhdl-template-variable t]
2118 ["Wait" vhdl-template-wait t]
2119 ["(Clocked Wait)" vhdl-template-clocked-wait t]
2120 ["When" vhdl-template-when t]
2121 ["While (Loop)" vhdl-template-while-loop t]
2122 ["With" vhdl-template-with t]
2124 (when (vhdl-standard-p 'ams)
2125 '(("VHDL-AMS Construct"
2126 ["Break" vhdl-template-break t]
2127 ["Case (Use)" vhdl-template-case-use t]
2128 ["If (Use)" vhdl-template-if-use t]
2129 ["Limit" vhdl-template-limit t]
2130 ["Nature" vhdl-template-nature t]
2131 ["Procedural" vhdl-template-procedural t]
2132 ["Quantity (Free)" vhdl-template-quantity-free t]
2133 ["Quantity (Branch)" vhdl-template-quantity-branch t]
2134 ["Quantity (Source)" vhdl-template-quantity-source t]
2135 ["Subnature" vhdl-template-subnature t]
2136 ["Terminal" vhdl-template-terminal t]
2138 '(["Insert Construct" vhdl-template-insert-construct
2139 :keys "C-c C-i C-c"]
2144 (when (vhdl-standard-p 'math)
2146 ["math_complex" vhdl-template-package-math-complex t]
2147 ["math_real" vhdl-template-package-math-real t]
2150 ["numeric_bit" vhdl-template-package-numeric-bit t]
2151 ["numeric_std" vhdl-template-package-numeric-std t]
2152 ["std_logic_1164" vhdl-template-package-std-logic-1164 t]
2153 ["textio" vhdl-template-package-textio t]
2155 ["std_logic_arith" vhdl-template-package-std-logic-arith t]
2156 ["std_logic_signed" vhdl-template-package-std-logic-signed t]
2157 ["std_logic_unsigned" vhdl-template-package-std-logic-unsigned t]
2158 ["std_logic_misc" vhdl-template-package-std-logic-misc t]
2159 ["std_logic_textio" vhdl-template-package-std-logic-textio t]
2161 ["Insert Package" vhdl-template-insert-package
2162 :keys "C-c C-i C-p"]
2165 ["translate_on" vhdl-template-directive-translate-on t]
2166 ["translate_off" vhdl-template-directive-translate-off t]
2167 ["synthesis_on" vhdl-template-directive-synthesis-on t]
2168 ["synthesis_off" vhdl-template-directive-synthesis-off t]
2170 ["Insert Directive" vhdl-template-insert-directive
2171 :keys "C-c C-i C-d"]
2174 ["Insert Header" vhdl-template-header :keys "C-c C-t C-h"]
2175 ["Insert Footer" vhdl-template-footer t]
2176 ["Insert Date" vhdl-template-insert-date t]
2177 ["Modify Date" vhdl-template-modify :keys "C-c C-t C-m"]
2179 ["Query Next Prompt" vhdl-template-search-prompt t]
2183 ;; add menu entries for defined models
2184 (let ((model-alist vhdl-model-alist) menu-alist model)
2186 (setq model (car model-alist))
2190 (vhdl-function-name "vhdl-model" (nth 0 model))
2191 :keys (concat "C-c C-m " (key-description (nth 2 model))))
2193 (setq model-alist (cdr model-alist)))
2196 (nreverse menu-alist)
2198 ["Insert Model" vhdl-model-insert :keys "C-c C-i C-m"]
2199 ["Add Model..." (customize-variable 'vhdl-model-alist) t])))
2202 ["Copy" vhdl-port-copy t]
2204 ["Paste As Entity" vhdl-port-paste-entity vhdl-port-list]
2205 ["Paste As Component" vhdl-port-paste-component vhdl-port-list]
2206 ["Paste As Instance" vhdl-port-paste-instance
2207 :keys "C-c C-p C-i" :active vhdl-port-list]
2208 ["Paste As Signals" vhdl-port-paste-signals vhdl-port-list]
2209 ["Paste As Constants" vhdl-port-paste-constants vhdl-port-list]
2210 ["Paste As Generic Map" vhdl-port-paste-generic-map vhdl-port-list]
2211 ["Paste As Test Bench" vhdl-port-paste-testbench vhdl-port-list]
2213 ["Flatten" vhdl-port-flatten vhdl-port-list]
2217 ["(Un)Comment Out Region" vhdl-comment-uncomment-region (mark)]
2219 ["Insert Inline Comment" vhdl-comment-append-inline t]
2220 ["Insert Horizontal Line" vhdl-comment-display-line t]
2221 ["Insert Display Comment" vhdl-comment-display t]
2223 ["Fill Comment" fill-paragraph t]
2224 ["Fill Comment Region" fill-region (mark)]
2225 ["Kill Comment Region" vhdl-comment-kill-region (mark)]
2226 ["Kill Inline Comment Region" vhdl-comment-kill-inline-region (mark)]
2229 ["Kill" vhdl-line-kill t]
2230 ["Copy" vhdl-line-copy t]
2231 ["Yank" vhdl-line-yank t]
2232 ["Expand" vhdl-line-expand t]
2234 ["Transpose Next" vhdl-line-transpose-next t]
2235 ["Transpose Prev" vhdl-line-transpose-previous t]
2236 ["Open" vhdl-line-open t]
2237 ["Join" delete-indentation t]
2239 ["Goto" goto-line t]
2240 ["(Un)Comment Out" vhdl-comment-uncomment-line t]
2243 ["Forward Statement" vhdl-end-of-statement t]
2244 ["Backward Statement" vhdl-beginning-of-statement t]
2245 ["Forward Expression" vhdl-forward-sexp t]
2246 ["Backward Expression" vhdl-backward-sexp t]
2247 ["Forward Function" vhdl-end-of-defun t]
2248 ["Backward Function" vhdl-beginning-of-defun t]
2249 ["Mark Function" vhdl-mark-defun t]
2253 ["Line" vhdl-indent-line t]
2254 ["Region" vhdl-indent-region (mark)]
2255 ["Buffer" vhdl-indent-buffer t]
2258 ["Group" vhdl-align-group t]
2259 ["Region" vhdl-align-noindent-region (mark)]
2260 ["Buffer" vhdl-align-noindent-buffer t]
2262 ["Inline Comment Group" vhdl-align-inline-comment-group t]
2263 ["Inline Comment Region" vhdl-align-inline-comment-region (mark)]
2264 ["Inline Comment Buffer" vhdl-align-inline-comment-buffer t]
2266 ["Fixup Whitespace Region" vhdl-fixup-whitespace-region (mark)]
2267 ["Fixup Whitespace Buffer" vhdl-fixup-whitespace-buffer t]
2270 ["Region" vhdl-fix-case-region (mark)]
2271 ["Buffer" vhdl-fix-case-buffer t]
2274 ["Beautify Region" vhdl-beautify-region (mark)]
2275 ["Beautify Buffer" vhdl-beautify-buffer t]
2278 ["Fontify Buffer" vhdl-fontify-buffer t]
2279 ["Syntactic Info" vhdl-show-syntactic-information t]
2282 ["VHDL Mode" vhdl-doc-mode :keys "C-c C-h"]
2283 ["Reserved Words" (vhdl-doc-variable 'vhdl-doc-keywords) t]
2284 ["Coding Style" (vhdl-doc-variable 'vhdl-doc-coding-style) t]
2286 ["Version" vhdl-version t]
2287 ["Bug Report..." vhdl-submit-bug-report t]
2290 ["Open/Close" vhdl-speedbar t]
2292 ["Show Hierarchy" vhdl-speedbar-toggle-hierarchy
2295 (and (boundp 'speedbar-initial-expansion-list-name)
2296 (equal speedbar-initial-expansion-list-name "vhdl hierarchy"))
2297 :active (and (boundp 'speedbar-frame) speedbar-frame)]
2301 ["Browse VHDL Group..." vhdl-customize t]
2302 ["Build Customize Menu" vhdl-create-customize-menu
2303 (fboundp 'customize-menu-create)]
2305 ["Activate New Customizations" vhdl-activate-customizations t])
2308 (defvar vhdl-mode-menu-list (vhdl-create-mode-menu)
2311 (defun vhdl-update-mode-menu ()
2312 "Update VHDL mode menu."
2314 (easy-menu-remove vhdl-mode-menu-list) ; for XEmacs
2315 (setq vhdl-mode-menu-list (vhdl-create-mode-menu))
2316 (easy-menu-add vhdl-mode-menu-list) ; for XEmacs
2317 (easy-menu-define vhdl-mode-menu vhdl-mode-map
2318 "Menu keymap for VHDL Mode." vhdl-mode-menu-list))
2322 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2323 ;; Index menu (using `imenu.el'), also used for speedbar (using `speedbar.el')
2325 (defvar vhdl-imenu-generic-expression
2328 "^\\s-*\\(\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\)\\s-+\\(\"?\\(\\w\\|\\s_\\)+\"?\\)"
2331 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\s-*:\\(\\s-\\|\n\\)*\\(\\w\\|\\s_\\)+\\)\\(\\s-\\|\n\\)+\\(generic\\|port\\)\\s-+map\\>"
2334 "^\\s-*\\(component\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
2337 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(procedural\\)"
2340 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(\\(postponed\\s-+\\|\\)process\\)"
2343 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(block\\)"
2346 "^\\s-*\\(package\\( body\\|\\)\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
2349 "^\\s-*\\(configuration\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)"
2352 "^\\s-*\\(architecture\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)"
2355 "^\\s-*\\(entity\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
2358 "Imenu generic expression for VHDL Mode. See `imenu-generic-expression'.")
2360 (defun vhdl-index-menu-init ()
2361 "Initialize index menu."
2362 (set (make-local-variable 'imenu-case-fold-search) t)
2363 (set (make-local-variable 'imenu-generic-expression)
2364 vhdl-imenu-generic-expression)
2365 (when (and vhdl-index-menu (not (string-match "XEmacs" emacs-version)))
2366 (if (or (not (boundp 'font-lock-maximum-size))
2367 (> font-lock-maximum-size (buffer-size)))
2368 (imenu-add-to-menubar "Index")
2369 (message "Scanning buffer for index...buffer too big"))))
2371 ;; ############################################################################
2372 ;; Source file menu (using `easy-menu.el')
2374 (defvar vhdl-sources-menu nil)
2376 (defun vhdl-directory-files (directory &optional full match)
2377 "Call `directory-files' if DIRECTORY exists, otherwise generate error
2379 (if (file-directory-p directory)
2380 (directory-files directory full match)
2381 (message "No such directory: \"%s\"" directory)
2384 (defun vhdl-get-source-files (&optional full directory)
2385 "Get list of VHDL source files in DIRECTORY or current directory."
2386 (let ((mode-alist auto-mode-alist)
2388 ;; create regular expressions for matching file names
2389 (setq filename-regexp ".*\\(")
2391 (when (eq (cdr (car mode-alist)) 'vhdl-mode)
2392 (setq filename-regexp
2393 (concat filename-regexp (car (car mode-alist)) "\\|")))
2394 (setq mode-alist (cdr mode-alist)))
2395 (setq filename-regexp
2396 (concat (substring filename-regexp 0
2397 (string-match "\\\\|$" filename-regexp)) "\\)"))
2399 (nreverse (vhdl-directory-files
2400 (or directory default-directory) full filename-regexp))))
2402 (defun vhdl-add-source-files-menu ()
2403 "Scan directory for all VHDL source files and generate menu.
2404 The directory of the current source file is scanned."
2406 (message "Scanning directory for source files ...")
2407 (let ((newmap (current-local-map))
2408 (mode-alist auto-mode-alist)
2409 (file-list (vhdl-get-source-files))
2411 ;; Create list for menu
2415 (setq menu-list (cons (vector (car file-list)
2416 (list 'find-file (car file-list)) t)
2418 (setq file-list (cdr file-list)))
2419 (setq menu-list (vhdl-menu-split menu-list 25))
2420 (when found (setq menu-list (cons "--" menu-list)))
2421 (setq menu-list (cons ["*Rescan*" vhdl-add-source-files-menu t] menu-list))
2422 (setq menu-list (cons "Sources" menu-list))
2424 (easy-menu-add menu-list)
2425 (easy-menu-define vhdl-sources-menu newmap
2426 "VHDL source files menu" menu-list))
2429 (defun vhdl-menu-split (list n)
2430 "Split menu LIST into several submenues, if number of elements > N."
2431 (if (> (length list) n)
2438 (setq sublist (cons (car remain) sublist))
2439 (setq remain (cdr remain))
2443 (setq result (cons (cons (format "Sources %s" menuno)
2444 (nreverse sublist)) result))
2446 (setq menuno (+ menuno 1))
2447 (setq sublist '()))))
2449 (setq result (cons (cons (format "Sources %s" menuno)
2450 (nreverse sublist)) result)))
2455 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2456 ;;; VHDL Mode definition
2457 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2458 ;; performs all buffer local initializations
2462 "Major mode for editing VHDL code.
2467 - TEMPLATE INSERTION (electrification): After typing a VHDL keyword and
2468 entering `\\[vhdl-electric-space]', you are prompted for arguments while a template is generated
2469 for that VHDL construct. Typing `\\[vhdl-electric-return]' or `\\[keyboard-quit]' at the first (mandatory)
2470 prompt aborts the current template generation. Optional arguments are
2471 indicated by square brackets and removed if the queried string is left empty.
2472 Prompts for mandatory arguments remain in the code if the queried string is
2473 left empty. They can be queried again by `\\[vhdl-template-search-prompt]'.
2474 Typing `\\[just-one-space]' after a keyword inserts a space without calling the template
2475 generator. Automatic template generation (i.e. electrification) can be
2476 disabled (enabled) by typing `\\[vhdl-electric-mode]' or by setting custom variable
2477 `vhdl-electric-mode' (see CUSTOMIZATION).
2478 Enabled electrification is indicated by `/e' in the modeline.
2479 Template generators can be invoked from the VHDL menu, by key bindings, by
2480 typing `C-c C-i C-c' and choosing a construct, or by typing the keyword (i.e.
2481 first word of menu entry not in parenthesis) and `\\[vhdl-electric-space]'.
2482 The following abbreviations can also be used:
2483 arch, attr, cond, conf, comp, cons, func, inst, pack, sig, var.
2484 Template styles can be customized in customization group `vhdl-electric'
2485 \(see CUSTOMIZATION).
2487 - HEADER INSERTION: A file header can be inserted by `\\[vhdl-template-header]'. A
2488 file footer (template at the end of the file) can be inserted by
2489 `\\[vhdl-template-footer]'. See customization group `vhdl-header'.
2491 - STUTTERING: Double striking of some keys inserts cumbersome VHDL syntax
2492 elements. Stuttering can be disabled (enabled) by typing `\\[vhdl-stutter-mode]' or by
2493 variable `vhdl-stutter-mode'. Enabled stuttering is indicated by `/s' in
2494 the modeline. The stuttering keys and their effects are:
2495 ;; --> \" : \" [ --> ( -- --> comment
2496 ;;; --> \" := \" [[ --> [ --CR --> comment-out code
2497 .. --> \" => \" ] --> ) --- --> horizontal line
2498 ,, --> \" <= \" ]] --> ] ---- --> display comment
2499 == --> \" == \" '' --> \\\"
2501 - WORD COMPLETION: Typing `\\[vhdl-electric-tab]' after a (not completed) word looks for a VHDL
2502 keyword or a word in the buffer that starts alike, inserts it and adjusts
2503 case. Re-typing `\\[vhdl-electric-tab]' toggles through alternative word completions.
2504 This also works in the minibuffer (i.e. in template generator prompts).
2505 Typing `\\[vhdl-electric-tab]' after `(' looks for and inserts complete parenthesized
2506 expressions (e.g. for array index ranges). All keywords as well as standard
2507 types and subprograms of VHDL have predefined abbreviations (e.g. type \"std\"
2508 and `\\[vhdl-electric-tab]' will toggle through all standard types beginning with \"std\").
2510 Typing `\\[vhdl-electric-tab]' after a non-word character indents the line if at the beginning
2511 of a line (i.e. no preceding non-blank characters),and inserts a tabulator
2512 stop otherwise. `\\[tab-to-tab-stop]' always inserts a tabulator stop.
2515 `--' puts a single comment.
2516 `---' draws a horizontal line for separating code segments.
2517 `----' inserts a display comment, i.e. two horizontal lines with a
2519 `--CR' comments out code on that line. Re-hitting CR comments out
2521 `\\[vhdl-comment-uncomment-region]' comments out a region if not commented out,
2522 uncomments a region if already commented out.
2524 You are prompted for comments after object definitions (i.e. signals,
2525 variables, constants, ports) and after subprogram and process specifications
2526 if variable `vhdl-prompt-for-comments' is non-nil. Comments are
2527 automatically inserted as additional labels (e.g. after begin statements) and
2528 as help comments if `vhdl-self-insert-comments' is non-nil.
2529 Inline comments (i.e. comments after a piece of code on the same line) are
2530 indented at least to `vhdl-inline-comment-column'. Comments go at maximum to
2531 `vhdl-end-comment-column'. `\\[vhdl-electric-return]' after a space in a comment will open a
2532 new comment line. Typing beyond `vhdl-end-comment-column' in a comment
2533 automatically opens a new comment line. `\\[fill-paragraph]' re-fills
2534 multi-line comments.
2536 - INDENTATION: `\\[vhdl-electric-tab]' indents a line if at the beginning of the line.
2537 The amount of indentation is specified by variable `vhdl-basic-offset'.
2538 `\\[vhdl-indent-line]' always indents the current line (is bound to `TAB' if variable
2539 `vhdl-intelligent-tab' is nil). Indentation can be done for an entire region
2540 \(`\\[vhdl-indent-region]') or buffer (menu). Argument and port lists are indented normally
2541 \(nil) or relative to the opening parenthesis (non-nil) according to variable
2542 `vhdl-argument-list-indent'. If variable `vhdl-indent-tabs-mode' is nil,
2543 spaces are used instead of tabs. `\\[tabify]' and `\\[untabify]' allow
2544 to convert spaces to tabs and vice versa.
2546 - ALIGNMENT: The alignment functions align operators, keywords, and inline
2547 comment to beautify argument lists, port maps, etc. `\\[vhdl-align-group]' aligns a group
2548 of consecutive lines separated by blank lines. `\\[vhdl-align-noindent-region]' aligns an
2549 entire region. If variable `vhdl-align-groups' is non-nil, groups of code
2550 lines separated by empty lines are aligned individually. `\\[vhdl-align-inline-comment-group]' aligns
2551 inline comments for a group of lines, and `\\[vhdl-align-inline-comment-region]' for a region.
2552 Some templates are automatically aligned after generation if custom variable
2553 `vhdl-auto-align' is non-nil.
2554 `\\[vhdl-fixup-whitespace-region]' fixes up whitespace in a region. That is, operator symbols
2555 are surrounded by one space, and multiple spaces are eliminated.
2557 - PORT TRANSLATION: Generic and port clauses from entity or component
2558 declarations can be copied (`\\[vhdl-port-copy]') and pasted as entity and
2559 component declarations, as component instantiations and corresponding
2560 internal constants and signals, as a generic map with constants as actual
2561 parameters, and as a test bench (menu).
2562 A clause with several generic/port names on the same line can be flattened
2563 (`\\[vhdl-port-flatten]') so that only one name per line exists. Names for actual
2564 ports, instances, test benches, and design-under-test instances can be
2565 derived from existing names according to variables `vhdl-...-name'.
2566 Variables `vhdl-testbench-...' allow the insertion of additional templates
2567 into a test bench. New files are created for the test bench entity and
2568 architecture according to variable `vhdl-testbench-create-files'.
2569 See customization group `vhdl-port'.
2571 - TEST BENCH GENERATION: See PORT TRANSLATION.
2573 - KEY BINDINGS: Key bindings (`C-c ...') exist for most commands (see in
2576 - VHDL MENU: All commands can be invoked from the VHDL menu.
2578 - FILE BROWSER: The speedbar allows browsing of directories and file contents.
2579 It can be accessed from the VHDL menu and is automatically opened if
2580 variable `vhdl-speedbar' is non-nil.
2581 In speedbar, open files and directories with `mouse-2' on the name and
2582 browse/rescan their contents with `mouse-2'/`S-mouse-2' on the `+'.
2584 - DESIGN HIERARCHY BROWSER: The speedbar can also be used for browsing the
2585 hierarchy of design units contained in the source files of the current
2586 directory or in the source files/directories specified for a project (see
2587 variable `vhdl-project-alist').
2588 The speedbar can be switched between file and hierarchy browsing mode in the
2589 VHDL menu or by typing `f' and `h' in speedbar.
2590 In speedbar, open design units with `mouse-2' on the name and browse their
2591 hierarchy with `mouse-2' on the `+'. The hierarchy can be rescanned and
2592 ports directly be copied from entities by using the speedbar menu.
2594 - PROJECTS: Projects can be defined in variable `vhdl-project-alist' and a
2595 current project be selected using variable `vhdl-project' (permanently) or
2596 from the menu (temporarily). For each project, a title string (for the file
2597 headers) and source files/directories (for the hierarchy browser) can be
2600 - SPECIAL MENUES: As an alternative to the speedbar, an index menu can
2601 be added (set variable `vhdl-index-menu' to non-nil) or made accessible
2602 as a mouse menu (e.g. add \"(global-set-key '[S-down-mouse-3] 'imenu)\" to
2603 your start-up file) for browsing the file contents. Also, a source file menu
2604 can be added (set variable `vhdl-source-file-menu' to non-nil) for browsing
2605 the current directory for VHDL source files.
2607 - SOURCE FILE COMPILATION: The syntax of the current buffer can be analyzed
2608 by calling a VHDL compiler (menu, `\\[vhdl-compile]'). The compiler to be used is
2609 specified by variable `vhdl-compiler'. The available compilers are listed
2610 in variable `vhdl-compiler-alist' including all required compilation command,
2611 destination directory, and error message syntax information. New compilers
2612 can be added. Additional compile command options can be set in variable
2613 `vhdl-compiler-options'.
2614 An entire hierarchy of source files can be compiled by the `make' command
2615 \(menu, `\\[vhdl-make]'). This only works if an appropriate Makefile exists.
2616 The make command itself as well as a command to generate a Makefile can also
2617 be specified in variable `vhdl-compiler-alist'.
2619 - VHDL STANDARDS: The VHDL standards to be used are specified in variable
2620 `vhdl-standard'. Available standards are: VHDL'87/'93, VHDL-AMS,
2623 - KEYWORD CASE: Lower and upper case for keywords and standardized types,
2624 attributes, and enumeration values is supported. If the variable
2625 `vhdl-upper-case-keywords' is set to non-nil, keywords can be typed in lower
2626 case and are converted into upper case automatically (not for types,
2627 attributes, and enumeration values). The case of keywords, types,
2628 attributes,and enumeration values can be fixed for an entire region (menu)
2629 or buffer (`\\[vhdl-fix-case-buffer]') according to the variables
2630 `vhdl-upper-case-{keywords,types,attributes,enum-values}'.
2632 - HIGHLIGHTING (fontification): Keywords and standardized types, attributes,
2633 enumeration values, and function names (controlled by variable
2634 `vhdl-highlight-keywords'), as well as comments, strings, and template
2635 prompts are highlighted using different colors. Unit, subprogram, signal,
2636 variable, constant, parameter and generic/port names in declarations as well
2637 as labels are highlighted if variable `vhdl-highlight-names' is non-nil.
2639 Additional reserved words or words with a forbidden syntax (e.g. words that
2640 should be avoided) can be specified in variable `vhdl-forbidden-words' or
2641 `vhdl-forbidden-syntax' and be highlighted in a warning color (variable
2642 `vhdl-highlight-forbidden-words'). Verilog keywords are highlighted as
2643 forbidden words if variable `vhdl-highlight-verilog-keywords' is non-nil.
2645 Words with special syntax can be highlighted by specifying their syntax and
2646 color in variable `vhdl-special-syntax-alist' and by setting variable
2647 `vhdl-highlight-special-words' to non-nil. This allows to establish some
2648 naming conventions (e.g. to distinguish different kinds of signals or other
2649 objects by using name suffices) and to support them visually.
2651 Variable `vhdl-highlight-case-sensitive' can be set to non-nil in order to
2652 support case-sensitive highlighting. However, keywords are then only
2653 highlighted if written in lower case.
2655 Code between \"translate_off\" and \"translate_on\" pragmas is highlighted
2656 using a different background color if variable `vhdl-highlight-translate-off'
2659 All colors can be customized by command `\\[customize-face]'.
2660 For highlighting of matching parenthesis, see customization group
2661 `paren-showing' (`\\[customize-group]').
2663 - USER MODELS: VHDL models (templates) can be specified by the user and made
2664 accessible in the menu, through key bindings (`C-c C-m ...'), or by keyword
2665 electrification. See custom variable `vhdl-model-alist'.
2667 - HIDE/SHOW: The code of entire VHDL design units can be hidden using the
2668 `Hide/Show' menu or by pressing `S-mouse-2' within the code (variable
2669 `vhdl-hideshow-menu').
2671 - PRINTING: Postscript printing with different faces (an optimized set of
2672 faces is used if `vhdl-print-customize-faces' is non-nil) or colors
2673 \(if `ps-print-color-p' is non-nil) is possible using the standard Emacs
2674 postscript printing commands. Variable `vhdl-print-two-column' defines
2675 appropriate default settings for nice landscape two-column printing. The
2676 paper format can be set by variable `ps-paper-type'. Do not forget to
2677 switch `ps-print-color-p' to nil for printing on black-and-white printers.
2679 - CUSTOMIZATION: All variables can easily be customized using the `Customize'
2680 menu entry or `\\[customize-option]' (`\\[customize-group]' for groups).
2681 Some customizations only take effect after some action (read the NOTE in
2682 the variable documentation). Customization can also be done globally (i.e.
2683 site-wide, read the INSTALL file).
2685 - FILE EXTENSIONS: As default, files with extensions \".vhd\" and \".vhdl\" are
2686 automatically recognized as VHDL source files. To add an extension \".xxx\",
2687 add the following line to your Emacs start-up file (`.emacs'):
2688 \(setq auto-mode-alist (cons '(\"\\\\.xxx\\\\'\" . vhdl-mode) auto-mode-alist))
2691 - Type `\\[keyboard-quit] \\[keyboard-quit]' to interrupt long operations or if Emacs hangs.
2697 To submit a bug report, enter `\\[vhdl-submit-bug-report]' within VHDL Mode.
2698 Add a description of the problem and include a reproducible test case.
2700 Questions and enhancement requests can be sent to <vhdl-mode@geocities.com>.
2702 The `vhdl-mode-announce' mailing list informs about new VHDL Mode releases.
2703 The `vhdl-mode-victims' mailing list informs about new VHDL Mode beta releases.
2704 You are kindly invited to participate in beta testing. Subscribe to above
2705 mailing lists by sending an email to <vhdl-mode@geocities.com>.
2707 VHDL Mode is officially distributed on the Emacs VHDL Mode Home Page
2708 <http://www.geocities.com/SiliconValley/Peaks/8287>, where the latest
2709 version and release notes can be found.
2712 Bugs and Limitations:
2713 ---------------------
2715 - Re-indenting large regions or expressions can be slow.
2716 - Indentation bug in simultaneous if- and case-statements (VHDL-AMS).
2717 - Hideshow does not work under XEmacs.
2718 - Index menu and file tagging in speedbar do not work under XEmacs.
2719 - Parsing compilation error messages for Ikos and Viewlogic VHDL compilers
2720 does not work under XEmacs.
2723 The VHDL Mode Maintainers
2724 Reto Zimmermann and Rod Whitby
2731 (kill-all-local-variables)
2732 (setq major-mode 'vhdl-mode)
2733 (setq mode-name "VHDL")
2735 ;; set maps and tables
2736 (use-local-map vhdl-mode-map)
2737 (set-syntax-table vhdl-mode-syntax-table)
2738 (setq local-abbrev-table vhdl-mode-abbrev-table)
2740 ;; set local variable values
2741 (set (make-local-variable 'paragraph-start)
2742 "\\s-*\\(--+\\s-*$\\|[^ -]\\|$\\)")
2743 (set (make-local-variable 'paragraph-separate) paragraph-start)
2744 (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
2745 (set (make-local-variable 'require-final-newline) t)
2746 (set (make-local-variable 'parse-sexp-ignore-comments) t)
2747 (set (make-local-variable 'indent-line-function) 'vhdl-indent-line)
2748 (set (make-local-variable 'comment-start) "--")
2749 (set (make-local-variable 'comment-end) "")
2750 (set (make-local-variable 'comment-column) vhdl-inline-comment-column)
2751 (set (make-local-variable 'end-comment-column) vhdl-end-comment-column)
2752 (set (make-local-variable 'comment-start-skip) "--+\\s-*")
2753 (set (make-local-variable 'comment-multi-line) nil)
2754 (set (make-local-variable 'indent-tabs-mode) vhdl-indent-tabs-mode)
2755 (set (make-local-variable 'hippie-expand-only-buffers) '(vhdl-mode))
2756 (set (make-local-variable 'hippie-expand-verbose) nil)
2758 ;; setup the comment indent variable in a Emacs version portable way
2759 ;; ignore any byte compiler warnings you might get here
2760 (when (boundp 'comment-indent-function)
2761 (make-local-variable 'comment-indent-function)
2762 (setq comment-indent-function 'vhdl-comment-indent))
2764 ;; initialize font locking
2765 (require 'font-lock)
2766 (set (make-local-variable 'font-lock-defaults)
2768 'vhdl-font-lock-keywords nil
2769 (not vhdl-highlight-case-sensitive) '((?\_ . "w")) 'beginning-of-line
2770 '(font-lock-syntactic-keywords . vhdl-font-lock-syntactic-keywords)))
2771 (set (make-local-variable 'font-lock-support-mode) 'lazy-lock-mode)
2772 (set (make-local-variable 'lazy-lock-defer-contextually) nil)
2773 (set (make-local-variable 'lazy-lock-defer-on-the-fly) t)
2774 ; (set (make-local-variable 'lazy-lock-defer-time) 0.1)
2775 (set (make-local-variable 'lazy-lock-defer-on-scrolling) t)
2778 ;; variables for source file compilation
2780 (set (make-local-variable 'compilation-error-regexp-alist) nil)
2781 (set (make-local-variable 'compilation-file-regexp-alist) nil)
2784 (vhdl-index-menu-init)
2785 ;; add source file menu
2786 (if vhdl-source-file-menu (vhdl-add-source-files-menu))
2788 (easy-menu-add vhdl-mode-menu-list) ; for XEmacs
2789 (easy-menu-define vhdl-mode-menu vhdl-mode-map
2790 "Menu keymap for VHDL Mode." vhdl-mode-menu-list)
2791 ;; initialize hideshow and add menu
2792 (make-local-variable 'hs-minor-mode-hook)
2793 (vhdl-hideshow-init)
2794 (run-hooks 'menu-bar-update-hook)
2797 (when (fboundp 'speedbar)
2798 (condition-case () ; due to bug in `speedbar-el' v0.7.2a
2800 (when (and vhdl-speedbar (not (and (boundp 'speedbar-frame)
2801 (frame-live-p speedbar-frame))))
2802 (speedbar-frame-mode 1)
2803 (select-frame speedbar-attached-frame)))
2804 (error (vhdl-add-warning "Before using Speedbar, install included `speedbar.el' patch"))))
2807 (vhdl-ps-print-init)
2808 (vhdl-modify-date-init)
2809 (vhdl-mode-line-update)
2810 (message "VHDL Mode %s. Type C-c C-h for documentation."
2812 (vhdl-print-warnings)
2815 (run-hooks 'vhdl-mode-hook))
2817 (defun vhdl-activate-customizations ()
2818 "Activate all customizations on local variables."
2820 (vhdl-mode-map-init)
2821 (use-local-map vhdl-mode-map)
2822 (set-syntax-table vhdl-mode-syntax-table)
2823 (setq comment-column vhdl-inline-comment-column)
2824 (setq end-comment-column vhdl-end-comment-column)
2825 (vhdl-modify-date-init)
2826 (vhdl-update-mode-menu)
2827 (vhdl-hideshow-init)
2828 (run-hooks 'menu-bar-update-hook)
2829 (vhdl-mode-line-update))
2831 (defun vhdl-modify-date-init ()
2832 "Add/remove hook for modifying date when buffer is saved."
2833 (if vhdl-modify-date-on-saving
2834 (add-hook 'local-write-file-hooks 'vhdl-template-modify-noerror)
2835 (remove-hook 'local-write-file-hooks 'vhdl-template-modify-noerror)))
2838 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2840 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2842 (defvar vhdl-doc-keywords nil
2843 "Reserved words in VHDL:
2845 VHDL'93 (IEEE Std 1076-1993):
2846 `vhdl-93-keywords' : keywords
2847 `vhdl-93-types' : standardized types
2848 `vhdl-93-attributes' : standardized attributes
2849 `vhdl-93-enum-values' : standardized enumeration values
2850 `vhdl-93-functions' : standardized functions
2851 `vhdl-93-packages' : standardized packages and libraries
2853 VHDL-AMS (IEEE Std 1076.1):
2854 `vhdl-ams-keywords' : keywords
2855 `vhdl-ams-types' : standardized types
2856 `vhdl-ams-attributes' : standardized attributes
2857 `vhdl-ams-enum-values' : standardized enumeration values
2858 `vhdl-ams-functions' : standardized functions
2860 Math Packages (IEEE Std 1076.2):
2861 `vhdl-math-types' : standardized types
2862 `vhdl-math-constants' : standardized constants
2863 `vhdl-math-functions' : standardized functions
2864 `vhdl-math-packages' : standardized packages
2867 `vhdl-verilog-keywords' : Verilog reserved words
2869 NOTE: click `mouse-2' on variable names above (not in XEmacs).")
2871 (defvar vhdl-doc-coding-style nil
2872 "For VHDL coding style and naming convention guidelines, see the following
2876 \"VHDL Coding Styles and Methodologies\".
2877 Kluwer Academic Publishers, 1999.
2878 http://members.aol.com/vhdlcohen/vhdl/
2880 \[2] Michael Keating and Pierre Bricaud.
2881 \"Reuse Methodology Manual\".
2882 Kluwer Academic Publishers, 1998.
2883 http://www.synopsys.com/products/reuse/rmm.html
2885 \[3] European Space Agency.
2886 \"VHDL Modelling Guidelines\".
2887 ftp://ftp.estec.esa.nl/pub/vhdl/doc/ModelGuide.{pdf,ps}
2889 Use variables `vhdl-highlight-special-words' and `vhdl-special-syntax-alist'
2890 to visually support naming conventions.")
2892 (defun vhdl-doc-variable (variable)
2893 "Display VARIABLE's documentation in *Help* buffer."
2895 (with-output-to-temp-buffer "*Help*"
2896 (princ (documentation-property variable 'variable-documentation))
2897 (unless (string-match "XEmacs" emacs-version)
2898 (help-setup-xref (list #'vhdl-doc-variable variable) (interactive-p)))
2900 (set-buffer standard-output)
2902 (print-help-return-message)))
2904 (defun vhdl-doc-mode ()
2905 "Display VHDL mode documentation in *Help* buffer."
2907 (with-output-to-temp-buffer "*Help*"
2910 (princ (documentation 'vhdl-mode))
2911 (unless (string-match "XEmacs" emacs-version)
2912 (help-setup-xref (list #'vhdl-doc-mode) (interactive-p)))
2914 (set-buffer standard-output)
2916 (print-help-return-message)))
2919 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2920 ;;; Keywords and standardized words
2921 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2923 (defconst vhdl-93-keywords
2925 "abs" "access" "after" "alias" "all" "and" "architecture" "array"
2926 "assert" "attribute"
2927 "begin" "block" "body" "buffer" "bus"
2928 "case" "component" "configuration" "constant"
2929 "disconnect" "downto"
2930 "else" "elsif" "end" "entity" "exit"
2931 "file" "for" "function"
2932 "generate" "generic" "group" "guarded"
2933 "if" "impure" "in" "inertial" "inout" "is"
2934 "label" "library" "linkage" "literal" "loop"
2936 "nand" "new" "next" "nor" "not" "null"
2937 "of" "on" "open" "or" "others" "out"
2938 "package" "port" "postponed" "procedure" "process" "pure"
2939 "range" "record" "register" "reject" "rem" "report" "return"
2941 "select" "severity" "shared" "signal" "sla" "sll" "sra" "srl" "subtype"
2942 "then" "to" "transport" "type"
2943 "unaffected" "units" "until" "use"
2945 "wait" "when" "while" "with"
2948 "List of VHDL'93 keywords.")
2950 (defconst vhdl-ams-keywords
2952 "across" "break" "limit" "nature" "noise" "procedural" "quantity"
2953 "reference" "spectrum" "subnature" "terminal" "through"
2956 "List of VHDL-AMS keywords.")
2958 (defconst vhdl-verilog-keywords
2960 "`define" "`else" "`endif" "`ifdef" "`include" "`timescale" "`undef"
2961 "always" "and" "assign" "begin" "buf" "bufif0" "bufif1"
2962 "case" "casex" "casez" "cmos" "deassign" "default" "defparam" "disable"
2963 "edge" "else" "end" "endattribute" "endcase" "endfunction" "endmodule"
2964 "endprimitive" "endspecify" "endtable" "endtask" "event"
2965 "for" "force" "forever" "fork" "function"
2966 "highz0" "highz1" "if" "initial" "inout" "input" "integer" "join" "large"
2967 "macromodule" "makefile" "medium" "module"
2968 "nand" "negedge" "nmos" "nor" "not" "notif0" "notif1" "or" "output"
2969 "parameter" "pmos" "posedge" "primitive" "pull0" "pull1" "pulldown"
2971 "rcmos" "real" "realtime" "reg" "release" "repeat" "rnmos" "rpmos" "rtran"
2972 "rtranif0" "rtranif1"
2973 "scalared" "signed" "small" "specify" "specparam" "strength" "strong0"
2974 "strong1" "supply" "supply0" "supply1"
2975 "table" "task" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1"
2976 "triand" "trior" "trireg"
2977 "vectored" "wait" "wand" "weak0" "weak1" "while" "wire" "wor" "xnor" "xor"
2979 "List of Verilog keywords as candidate for additional reserved words.")
2981 (defconst vhdl-93-types
2983 "boolean" "bit" "bit_vector" "character" "severity_level" "integer"
2984 "real" "time" "natural" "positive" "string" "line" "text" "side"
2985 "unsigned" "signed" "delay_length" "file_open_kind" "file_open_status"
2986 "std_logic" "std_logic_vector"
2987 "std_ulogic" "std_ulogic_vector"
2989 "List of VHDL'93 standardized types.")
2991 (defconst vhdl-ams-types
2993 "domain_type" "real_vector"
2995 "List of VHDL-AMS standardized types.")
2997 (defconst vhdl-math-types
2999 "complex" "complex_polar"
3001 "List of Math Packages standardized types.")
3003 (defconst vhdl-93-attributes
3005 "base" "left" "right" "high" "low" "pos" "val" "succ"
3006 "pred" "leftof" "rightof" "range" "reverse_range"
3007 "length" "delayed" "stable" "quiet" "transaction"
3008 "event" "active" "last_event" "last_active" "last_value"
3009 "driving" "driving_value" "ascending" "value" "image"
3010 "simple_name" "instance_name" "path_name"
3013 "List of VHDL'93 standardized attributes.")
3015 (defconst vhdl-ams-attributes
3018 "reference" "contribution" "tolerance"
3019 "dot" "integ" "delayed" "above" "zoh" "ltf" "ztf"
3022 "List of VHDL-AMS standardized attributes.")
3024 (defconst vhdl-93-enum-values
3027 "note" "warning" "error" "failure"
3028 "read_mode" "write_mode" "append_mode"
3029 "open_ok" "status_error" "name_error" "mode_error"
3030 "fs" "ps" "ns" "us" "ms" "sec" "min" "hr"
3033 "List of VHDL'93 standardized enumeration values.")
3035 (defconst vhdl-ams-enum-values
3037 "quiescent_domain" "time_domain" "frequency_domain"
3039 "List of VHDL-AMS standardized enumeration values.")
3041 (defconst vhdl-math-constants
3043 "math_e" "math_1_over_e"
3044 "math_pi" "math_two_pi" "math_1_over_pi"
3045 "math_half_pi" "math_q_pi" "math_3_half_pi"
3046 "math_log_of_2" "math_log_of_10" "math_log2_of_e" "math_log10_of_e"
3047 "math_sqrt2" "math_sqrt1_2" "math_sqrt_pi"
3048 "math_deg_to_rad" "math_rad_to_deg"
3049 "cbase_1" "cbase_j" "czero"
3051 "List of Math Packages standardized constants.")
3053 (defconst vhdl-93-functions
3055 "now" "resolved" "rising_edge" "falling_edge"
3056 "read" "readline" "write" "writeline" "endfile"
3057 "resize" "is_X" "std_match"
3058 "shift_left" "shift_right" "rotate_left" "rotate_right"
3059 "to_unsigned" "to_signed" "to_integer"
3060 "to_stdLogicVector" "to_stdULogic" "to_stdULogicVector"
3061 "to_bit" "to_bitVector" "to_X01" "to_X01Z" "to_UX01" "to_01"
3062 "conv_unsigned" "conv_signed" "conv_integer" "conv_std_logic_vector"
3063 "shl" "shr" "ext" "sxt"
3065 "List of VHDL'93 standardized functions.")
3067 (defconst vhdl-ams-functions
3071 "List of VHDL-AMS standardized functions.")
3073 (defconst vhdl-math-functions
3075 "sign" "ceil" "floor" "round" "trunc" "fmax" "fmin" "uniform"
3076 "sqrt" "cbrt" "exp" "log"
3077 "sin" "cos" "tan" "arcsin" "arccos" "arctan"
3078 "sinh" "cosh" "tanh" "arcsinh" "arccosh" "arctanh"
3079 "cmplx" "complex_to_polar" "polar_to_complex" "arg" "conj"
3081 "List of Math Packages standardized functions.")
3083 (defconst vhdl-93-packages
3085 "std_logic_1164" "numeric_std" "numeric_bit"
3087 "std_logic_arith" "std_logic_signed" "std_logic_unsigned"
3088 "std_logic_misc" "std_logic_textio"
3091 "List of VHDL'93 standardized packages and libraries.")
3093 (defconst vhdl-math-packages
3095 "math_real" "math_complex"
3097 "List of Math Packages standardized packages and libraries.")
3099 (defvar vhdl-keywords nil
3100 "List of VHDL keywords.")
3102 (defvar vhdl-types nil
3103 "List of VHDL standardized types.")
3105 (defvar vhdl-attributes nil
3106 "List of VHDL standardized attributes.")
3108 (defvar vhdl-enum-values nil
3109 "List of VHDL standardized enumeration values.")
3111 (defvar vhdl-constants nil
3112 "List of VHDL standardized constants.")
3114 (defvar vhdl-functions nil
3115 "List of VHDL standardized functions.")
3117 (defvar vhdl-packages nil
3118 "List of VHDL standardized packages and libraries.")
3120 (defvar vhdl-reserved-words nil
3121 "List of additional reserved words.")
3123 (defvar vhdl-keywords-regexp nil
3124 "Regexp for VHDL keywords.")
3126 (defvar vhdl-types-regexp nil
3127 "Regexp for VHDL standardized types.")
3129 (defvar vhdl-attributes-regexp nil
3130 "Regexp for VHDL standardized attributes.")
3132 (defvar vhdl-enum-values-regexp nil
3133 "Regexp for VHDL standardized enumeration values.")
3135 (defvar vhdl-functions-regexp nil
3136 "Regexp for VHDL standardized functions.")
3138 (defvar vhdl-packages-regexp nil
3139 "Regexp for VHDL standardized packages and libraries.")
3141 (defvar vhdl-reserved-words-regexp nil
3142 "Regexp for additional reserved words.")
3144 (defun vhdl-words-init ()
3145 "Initialize reserved words."
3147 (append vhdl-93-keywords
3148 (when (vhdl-standard-p 'ams) vhdl-ams-keywords)))
3150 (append vhdl-93-types
3151 (when (vhdl-standard-p 'ams) vhdl-ams-types)
3152 (when (vhdl-standard-p 'math) vhdl-math-types)))
3153 (setq vhdl-attributes
3154 (append vhdl-93-attributes
3155 (when (vhdl-standard-p 'ams) vhdl-ams-attributes)))
3156 (setq vhdl-enum-values
3157 (append vhdl-93-enum-values
3158 (when (vhdl-standard-p 'ams) vhdl-ams-enum-values)))
3159 (setq vhdl-constants
3160 (append (when (vhdl-standard-p 'math) vhdl-math-constants)))
3161 (setq vhdl-functions
3162 (append vhdl-93-functions
3163 (when (vhdl-standard-p 'ams) vhdl-ams-functions)
3164 (when (vhdl-standard-p 'math) vhdl-math-functions)))
3166 (append vhdl-93-packages
3167 (when (vhdl-standard-p 'math) vhdl-math-packages)))
3168 (setq vhdl-reserved-words
3169 (append (when vhdl-highlight-forbidden-words vhdl-forbidden-words)
3170 (when vhdl-highlight-verilog-keywords vhdl-verilog-keywords)
3172 (setq vhdl-keywords-regexp
3173 (concat "\\<\\(" (regexp-opt vhdl-keywords) "\\)\\>"))
3174 (setq vhdl-types-regexp
3175 (concat "\\<\\(" (regexp-opt vhdl-types) "\\)\\>"))
3176 (setq vhdl-attributes-regexp
3177 (concat "\\<\\(" (regexp-opt vhdl-attributes) "\\)\\>"))
3178 (setq vhdl-enum-values-regexp
3179 (concat "\\<\\(" (regexp-opt vhdl-enum-values) "\\)\\>"))
3180 (setq vhdl-functions-regexp
3181 (concat "\\<\\(" (regexp-opt vhdl-functions) "\\)\\>"))
3182 (setq vhdl-packages-regexp
3183 (concat "\\<\\(" (regexp-opt vhdl-packages) "\\)\\>"))
3184 (setq vhdl-reserved-words-regexp
3186 (unless (equal vhdl-forbidden-syntax "")
3187 (concat vhdl-forbidden-syntax "\\|"))
3188 (regexp-opt vhdl-reserved-words)
3190 (vhdl-abbrev-list-init))
3192 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3195 (defvar vhdl-abbrev-list nil
3196 "Predefined abbreviations for VHDL.")
3198 (defun vhdl-abbrev-list-init ()
3199 (setq vhdl-abbrev-list
3201 (list vhdl-upper-case-keywords) vhdl-keywords
3202 (list vhdl-upper-case-types) vhdl-types
3203 (list vhdl-upper-case-attributes) vhdl-attributes
3204 (list vhdl-upper-case-enum-values) vhdl-enum-values
3205 (list vhdl-upper-case-constants) vhdl-constants
3206 (list nil) vhdl-functions
3207 (list nil) vhdl-packages)))
3209 ;; initialize reserved words for VHDL Mode
3213 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3214 ;;; Syntax analysis and indentation
3215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3217 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3220 ;; constant regular expressions for looking at various constructs
3222 (defconst vhdl-symbol-key "\\(\\w\\|\\s_\\)+"
3223 "Regexp describing a VHDL symbol.
3224 We cannot use just `word' syntax class since `_' cannot be in word
3225 class. Putting underscore in word class breaks forward word movement
3226 behavior that users are familiar with.")
3228 (defconst vhdl-case-header-key "case[( \t\n][^;=>]+[) \t\n]is"
3229 "Regexp describing a case statement header key.")
3231 (defconst vhdl-label-key
3232 (concat "\\(" vhdl-symbol-key "\\s-*:\\)[^=]")
3233 "Regexp describing a VHDL label.")
3235 ;; Macro definitions:
3237 (defmacro vhdl-point (position)
3238 "Return the value of point at certain commonly referenced POSITIONs.
3239 POSITION can be one of the following symbols:
3241 bol -- beginning of line
3243 bod -- beginning of defun
3244 boi -- back to indentation
3245 eoi -- last whitespace on line
3246 ionl -- indentation of next line
3247 iopl -- indentation of previous line
3248 bonl -- beginning of next line
3249 bopl -- beginning of previous line
3251 This function does not modify point or mark."
3252 (or (and (eq 'quote (car-safe position))
3253 (null (cdr (cdr position))))
3254 (error "Bad buffer position requested: %s" position))
3255 (setq position (nth 1 position))
3256 `(let ((here (point)))
3258 ((eq position 'bol) '((beginning-of-line)))
3259 ((eq position 'eol) '((end-of-line)))
3260 ((eq position 'bod) '((save-match-data
3261 (vhdl-beginning-of-defun))))
3262 ((eq position 'boi) '((back-to-indentation)))
3263 ((eq position 'eoi) '((end-of-line)(skip-chars-backward " \t")))
3264 ((eq position 'bonl) '((forward-line 1)))
3265 ((eq position 'bopl) '((forward-line -1)))
3266 ((eq position 'iopl)
3268 (back-to-indentation)))
3269 ((eq position 'ionl)
3271 (back-to-indentation)))
3272 (t (error "Unknown buffer position requested: %s" position))
3277 ;; workaround for an Emacs18 bug -- blech! Well, at least it
3278 ;; doesn't hurt for v19
3282 (defmacro vhdl-safe (&rest body)
3283 "Safely execute BODY, return nil if an error occurred."
3284 `(condition-case nil
3288 (defmacro vhdl-add-syntax (symbol &optional relpos)
3289 "A simple macro to append the syntax in SYMBOL to the syntax list.
3290 Try to increase performance by using this macro."
3291 `(setq vhdl-syntactic-context
3292 (cons (cons ,symbol ,relpos) vhdl-syntactic-context)))
3294 (defmacro vhdl-has-syntax (symbol)
3295 "A simple macro to return check the syntax list.
3296 Try to increase performance by using this macro."
3297 `(assoc ,symbol vhdl-syntactic-context))
3299 ;; Syntactic element offset manipulation:
3301 (defun vhdl-read-offset (langelem)
3302 "Read new offset value for LANGELEM from minibuffer.
3303 Return a legal value only."
3304 (let ((oldoff (format "%s" (cdr-safe (assq langelem vhdl-offsets-alist))))
3305 (errmsg "Offset must be int, func, var, or one of +, -, ++, --: ")
3307 offset input interned)
3309 (setq input (read-string prompt oldoff)
3310 offset (cond ((string-equal "+" input) '+)
3311 ((string-equal "-" input) '-)
3312 ((string-equal "++" input) '++)
3313 ((string-equal "--" input) '--)
3314 ((string-match "^-?[0-9]+$" input)
3315 (string-to-int input))
3316 ((fboundp (setq interned (intern input)))
3318 ((boundp interned) interned)
3319 ;; error, but don't signal one, keep trying
3320 ;; to read an input value
3322 (setq prompt errmsg)
3326 (defun vhdl-set-offset (symbol offset &optional add-p)
3327 "Change the value of a syntactic element symbol in `vhdl-offsets-alist'.
3328 SYMBOL is the syntactic element symbol to change and OFFSET is the new
3329 offset for that syntactic element. Optional ADD says to add SYMBOL to
3330 `vhdl-offsets-alist' if it doesn't already appear there."
3333 (intern (completing-read
3334 (concat "Syntactic symbol to change"
3335 (if current-prefix-arg " or add" "")
3340 (cons (format "%s" (car langelem)) nil)))
3342 nil (not current-prefix-arg)
3343 ;; initial contents tries to be the last element
3344 ;; on the syntactic analysis list for the current
3346 (let* ((syntax (vhdl-get-syntactic-context))
3347 (len (length syntax))
3348 (ic (format "%s" (car (nth (1- len) syntax)))))
3351 (offset (vhdl-read-offset langelem)))
3352 (list langelem offset current-prefix-arg)))
3353 ;; sanity check offset
3361 (error "Offset must be int, func, var, or one of +, -, ++, --: %s"
3363 (let ((entry (assq symbol vhdl-offsets-alist)))
3365 (setcdr entry offset)
3367 (setq vhdl-offsets-alist
3368 (cons (cons symbol offset) vhdl-offsets-alist))
3369 (error "%s is not a valid syntactic symbol" symbol))))
3370 (vhdl-keep-region-active))
3372 (defun vhdl-set-style (style &optional local)
3373 "Set `vhdl-mode' variables to use one of several different indentation styles.
3374 STYLE is a string representing the desired style and optional LOCAL is
3375 a flag which, if non-nil, means to make the style variables being
3376 changed buffer local, instead of the default, which is to set the
3377 global variables. Interactively, the flag comes from the prefix
3378 argument. The styles are chosen from the `vhdl-style-alist' variable."
3379 (interactive (list (completing-read "Use which VHDL indentation style? "
3380 vhdl-style-alist nil t)
3381 current-prefix-arg))
3382 (let ((vars (cdr (assoc style vhdl-style-alist))))
3384 (error "Invalid VHDL indentation style `%s'" style))
3385 ;; set all the variables
3389 (let ((var (car varentry))
3390 (val (cdr varentry)))
3392 (make-local-variable var))
3393 ;; special case for vhdl-offsets-alist
3394 (if (not (eq var 'vhdl-offsets-alist))
3396 ;; reset vhdl-offsets-alist to the default value first
3397 (setq vhdl-offsets-alist (copy-alist vhdl-offsets-alist-default))
3398 ;; now set the langelems that are different
3402 (let ((langelem (car langentry))
3403 (offset (cdr langentry)))
3404 (vhdl-set-offset langelem offset)
3409 (vhdl-keep-region-active))
3411 (defun vhdl-get-offset (langelem)
3412 "Get offset from LANGELEM which is a cons cell of the form:
3413 \(SYMBOL . RELPOS). The symbol is matched against
3414 vhdl-offsets-alist and the offset found there is either returned,
3415 or added to the indentation at RELPOS. If RELPOS is nil, then
3416 the offset is simply returned."
3417 (let* ((symbol (car langelem))
3418 (relpos (cdr langelem))
3419 (match (assq symbol vhdl-offsets-alist))
3420 (offset (cdr-safe match)))
3421 ;; offset can be a number, a function, a variable, or one of the
3425 (if vhdl-strict-syntax-p
3426 (error "Don't know how to indent a %s" symbol)
3429 ((eq offset '+) (setq offset vhdl-basic-offset))
3430 ((eq offset '-) (setq offset (- vhdl-basic-offset)))
3431 ((eq offset '++) (setq offset (* 2 vhdl-basic-offset)))
3432 ((eq offset '--) (setq offset (* 2 (- vhdl-basic-offset))))
3433 ((and (not (numberp offset))
3435 (setq offset (funcall offset langelem)))
3436 ((not (numberp offset))
3437 (setq offset (eval offset)))
3440 (< relpos (vhdl-point 'bol)))
3447 ;; Syntactic support functions:
3449 ;; Returns `comment' if in a comment, `string' if in a string literal,
3450 ;; or nil if not in a literal at all. Optional LIM is used as the
3451 ;; backward limit of the search. If omitted, or nil, (point-min) is
3454 (defun vhdl-in-literal (&optional lim)
3455 "Determine if point is in a VHDL literal."
3457 (let ((state (parse-partial-sexp (vhdl-point 'bol) (point))))
3459 ((nth 3 state) 'string)
3460 ((nth 4 state) 'comment)
3463 ;; This is the best we can do in Win-Emacs.
3464 (defun vhdl-win-il (&optional lim)
3465 "Determine if point is in a VHDL literal."
3467 (let* ((here (point))
3470 (lim (or lim (vhdl-point 'bod))))
3472 (while (< (point) here)
3474 (and (re-search-forward "--\\|[\"']"
3476 (buffer-substring (match-beginning 0) (match-end 0))))
3481 ;; looking at the opening of a VHDL style comment
3482 ((string= "--" match)
3483 (if (<= here (progn (end-of-line) (point))) 'comment))
3484 ;; looking at the opening of a double quote string
3485 ((string= "\"" match)
3486 (if (not (save-restriction
3487 ;; this seems to be necessary since the
3488 ;; re-search-forward will not work without it
3489 (narrow-to-region (point) here)
3491 ;; this regexp matches a double quote
3492 ;; which is preceded by an even number
3493 ;; of backslashes, including zero
3494 "\\([^\\]\\|^\\)\\(\\\\\\\\\\)*\"" here 'move)))
3496 ;; looking at the opening of a single quote string
3497 ((string= "'" match)
3498 (if (not (save-restriction
3499 ;; see comments from above
3500 (narrow-to-region (point) here)
3502 ;; this matches a single quote which is
3503 ;; preceded by zero or two backslashes.
3504 "\\([^\\]\\|^\\)\\(\\\\\\\\\\)?'"
3511 (and (string-match "Win-Emacs" emacs-version)
3512 (fset 'vhdl-in-literal 'vhdl-win-il))
3514 ;; Skipping of "syntactic whitespace". Syntactic whitespace is
3515 ;; defined as lexical whitespace or comments. Search no farther back
3516 ;; or forward than optional LIM. If LIM is omitted, (point-min) is
3517 ;; used for backward skipping, (point-max) is used for forward
3520 (defun vhdl-forward-syntactic-ws (&optional lim)
3521 "Forward skip of syntactic whitespace."
3523 (let* ((lim (or lim (point-max)))
3525 (hugenum (point-max)))
3526 (narrow-to-region lim (point))
3527 (while (/= here (point))
3529 (forward-comment hugenum))
3532 ;; This is the best we can do in Win-Emacs.
3533 (defun vhdl-win-fsws (&optional lim)
3534 "Forward skip syntactic whitespace for Win-Emacs."
3535 (let ((lim (or lim (point-max)))
3538 (skip-chars-forward " \t\n\r\f" lim)
3541 ((looking-at "--") (end-of-line))
3542 ;; none of the above
3546 (and (string-match "Win-Emacs" emacs-version)
3547 (fset 'vhdl-forward-syntactic-ws 'vhdl-win-fsws))
3549 (defun vhdl-backward-syntactic-ws (&optional lim)
3550 "Backward skip over syntactic whitespace."
3552 (let* ((lim (or lim (point-min)))
3554 (hugenum (- (point-max))))
3557 (narrow-to-region lim (point))
3558 (while (/= here (point))
3560 (forward-comment hugenum)
3564 ;; This is the best we can do in Win-Emacs.
3565 (defun vhdl-win-bsws (&optional lim)
3566 "Backward skip syntactic whitespace for Win-Emacs."
3567 (let ((lim (or lim (vhdl-point 'bod)))
3570 (skip-chars-backward " \t\n\r\f" lim)
3573 ((eq (vhdl-in-literal lim) 'comment)
3574 (skip-chars-backward "^-" lim)
3575 (skip-chars-backward "-" lim)
3576 (while (not (or (and (= (following-char) ?-)
3577 (= (char-after (1+ (point))) ?-))
3579 (skip-chars-backward "^-" lim)
3580 (skip-chars-backward "-" lim)))
3581 ;; none of the above
3585 (and (string-match "Win-Emacs" emacs-version)
3586 (fset 'vhdl-backward-syntactic-ws 'vhdl-win-bsws))
3588 ;; Functions to help finding the correct indentation column:
3590 (defun vhdl-first-word (point)
3591 "If the keyword at POINT is at boi, then return (current-column) at
3592 that point, else nil."
3594 (and (goto-char point)
3595 (eq (point) (vhdl-point 'boi))
3598 (defun vhdl-last-word (point)
3599 "If the keyword at POINT is at eoi, then return (current-column) at
3600 that point, else nil."
3602 (and (goto-char point)
3603 (save-excursion (or (eq (progn (forward-sexp) (point))
3605 (looking-at "\\s-*\\(--\\)?")))
3608 ;; Core syntactic evaluation functions:
3610 (defconst vhdl-libunit-re
3611 "\\b\\(architecture\\|configuration\\|entity\\|package\\)\\b[^_]")
3613 (defun vhdl-libunit-p ()
3617 (skip-chars-forward " \t\n")
3618 (not (looking-at "is\\b[^_]")))
3621 (and (not (looking-at "use\\b[^_]"))
3624 (vhdl-forward-syntactic-ws)
3625 (/= (following-char) ?:))))
3628 (defconst vhdl-defun-re
3629 "\\b\\(architecture\\|block\\|configuration\\|entity\\|package\\|process\\|procedural\\|procedure\\|function\\)\\b[^_]")
3631 (defun vhdl-defun-p ()
3633 (if (looking-at "block\\|process\\|procedural")
3634 ;; "block", "process", "procedural":
3637 (not (looking-at "end\\s-+\\w")))
3638 ;; "architecture", "configuration", "entity",
3639 ;; "package", "procedure", "function":
3642 (defun vhdl-corresponding-defun ()
3643 "If the word at the current position corresponds to a \"defun\"
3644 keyword, then return a string that can be used to find the
3645 corresponding \"begin\" keyword, else return nil."
3647 (and (looking-at vhdl-defun-re)
3649 (if (looking-at "block\\|process\\|procedural")
3650 ;; "block", "process". "procedural:
3651 (buffer-substring (match-beginning 0) (match-end 0))
3652 ;; "architecture", "configuration", "entity", "package",
3653 ;; "procedure", "function":
3656 (defconst vhdl-begin-fwd-re
3657 "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\|units\\|record\\|for\\)\\b\\([^_]\\|\\'\\)"
3658 "A regular expression for searching forward that matches all known
3659 \"begin\" keywords.")
3661 (defconst vhdl-begin-bwd-re
3662 "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\|units\\|record\\|for\\)\\b[^_]"
3663 "A regular expression for searching backward that matches all known
3664 \"begin\" keywords.")
3666 (defun vhdl-begin-p (&optional lim)
3667 "Return t if we are looking at a real \"begin\" keyword.
3668 Assumes that the caller will make sure that we are looking at
3669 vhdl-begin-fwd-re, and are not inside a literal, and that we are not in
3670 the middle of an identifier that just happens to contain a \"begin\"
3673 ;; "[architecture|case|configuration|entity|package|
3674 ;; procedure|function] ... is":
3675 ((and (looking-at "i")
3677 ;; Skip backward over first sexp (needed to skip over a
3678 ;; procedure interface list, and is harmless in other
3679 ;; situations). Note that we need "return" in the
3680 ;; following search list so that we don't run into
3681 ;; semicolons in the function interface list.
3684 (while (and (not foundp)
3686 ";\\|\\b\\(architecture\\|case\\|configuration\\|entity\\|package\\|procedure\\|return\\|is\\|begin\\|process\\|procedural\\|block\\)\\b[^_]"
3688 (if (or (= (preceding-char) ?_)
3689 (vhdl-in-literal lim))
3692 (and (/= (following-char) ?\;)
3693 (not (looking-at "is\\|begin\\|process\\|procedural\\|block")))))
3696 ((looking-at "be\\|t")
3699 ((and (looking-at "e")
3700 ;; make sure that the "else" isn't inside a
3701 ;; conditional signal assignment.
3703 (re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move)
3704 (or (eq (following-char) ?\;)
3707 ;; "block", "generate", "loop", "process", "procedural",
3708 ;; "units", "record":
3709 ((and (looking-at "bl\\|[glpur]")
3712 (not (looking-at "end\\s-+\\w"))))
3715 ((and (looking-at "c")
3718 (not (looking-at "end\\s-+\\w")))
3719 ;; look out for the dreaded entity class in an attribute
3721 (vhdl-backward-syntactic-ws lim)
3722 (/= (preceding-char) ?:)))
3724 ;; "for" (inside configuration declaration):
3725 ((and (looking-at "f")
3728 (not (looking-at "end\\s-+\\w")))
3729 (vhdl-has-syntax 'configuration))
3733 (defun vhdl-corresponding-mid (&optional lim)
3735 ((looking-at "is\\|block\\|generate\\|process\\|procedural")
3737 ((looking-at "then")
3742 (defun vhdl-corresponding-end (&optional lim)
3743 "If the word at the current position corresponds to a \"begin\"
3744 keyword, then return a vector containing enough information to find
3745 the corresponding \"end\" keyword, else return nil. The keyword to
3746 search forward for is aref 0. The column in which the keyword must
3747 appear is aref 1 or nil if any column is suitable.
3748 Assumes that the caller will make sure that we are not in the middle
3749 of an identifier that just happens to contain a \"begin\" keyword."
3751 (and (looking-at vhdl-begin-fwd-re)
3752 (/= (preceding-char) ?_)
3753 (not (vhdl-in-literal lim))
3756 ;; "is", "generate", "loop":
3757 ((looking-at "[igl]")
3759 (and (vhdl-last-word (point))
3760 (or (vhdl-first-word (point))
3762 (vhdl-beginning-of-statement-1 lim)
3763 (vhdl-backward-skip-label lim)
3764 (vhdl-first-word (point)))))))
3765 ;; "begin", "else", "for":
3766 ((looking-at "be\\|[ef]")
3768 (and (vhdl-last-word (point))
3769 (or (vhdl-first-word (point))
3771 (vhdl-beginning-of-statement-1 lim)
3772 (vhdl-backward-skip-label lim)
3773 (vhdl-first-word (point)))))))
3774 ;; "component", "units", "record":
3775 ((looking-at "[cur]")
3776 ;; The first end found will close the block
3778 ;; "block", "process", "procedural":
3779 ((looking-at "bl\\|p")
3781 (or (vhdl-first-word (point))
3783 (vhdl-beginning-of-statement-1 lim)
3784 (vhdl-backward-skip-label lim)
3785 (vhdl-first-word (point))))))
3788 (vector "elsif\\|else\\|end\\s-+if"
3789 (and (vhdl-last-word (point))
3790 (or (vhdl-first-word (point))
3792 (vhdl-beginning-of-statement-1 lim)
3793 (vhdl-backward-skip-label lim)
3794 (vhdl-first-word (point)))))))
3797 (defconst vhdl-end-fwd-re "\\b\\(end\\|else\\|elsif\\)\\b\\([^_]\\|\\'\\)")
3799 (defconst vhdl-end-bwd-re "\\b\\(end\\|else\\|elsif\\)\\b[^_]")
3801 (defun vhdl-end-p (&optional lim)
3802 "Return t if we are looking at a real \"end\" keyword.
3803 Assumes that the caller will make sure that we are looking at
3804 vhdl-end-fwd-re, and are not inside a literal, and that we are not in
3805 the middle of an identifier that just happens to contain an \"end\"
3807 (or (not (looking-at "else"))
3808 ;; make sure that the "else" isn't inside a conditional signal
3811 (re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move)
3812 (or (eq (following-char) ?\;)
3813 (eq (point) lim)))))
3815 (defun vhdl-corresponding-begin (&optional lim)
3816 "If the word at the current position corresponds to an \"end\"
3817 keyword, then return a vector containing enough information to find
3818 the corresponding \"begin\" keyword, else return nil. The keyword to
3819 search backward for is aref 0. The column in which the keyword must
3820 appear is aref 1 or nil if any column is suitable. The supplementary
3821 keyword to search forward for is aref 2 or nil if this is not
3822 required. If aref 3 is t, then the \"begin\" keyword may be found in
3823 the middle of a statement.
3824 Assumes that the caller will make sure that we are not in the middle
3825 of an identifier that just happens to contain an \"end\" keyword."
3828 (if (and (looking-at vhdl-end-fwd-re)
3829 (not (vhdl-in-literal lim))
3831 (if (looking-at "el")
3833 (vector "if\\|elsif" (vhdl-first-word (point)) "then" nil)
3837 (skip-chars-forward " \t\n")
3840 ((looking-at "if\\b[^_]")
3841 (vector "else\\|elsif\\|if"
3842 (vhdl-first-word pos)
3845 ((looking-at "component\\b[^_]")
3846 (vector (buffer-substring (match-beginning 1)
3848 (vhdl-first-word pos)
3850 ;; "end units", "end record":
3851 ((looking-at "\\(units\\|record\\)\\b[^_]")
3852 (vector (buffer-substring (match-beginning 1)
3854 (vhdl-first-word pos)
3856 ;; "end block", "end process", "end procedural":
3857 ((looking-at "\\(block\\|process\\|procedural\\)\\b[^_]")
3858 (vector "begin" (vhdl-first-word pos) nil nil))
3860 ((looking-at "case\\b[^_]")
3861 (vector "case" (vhdl-first-word pos) "is" nil))
3863 ((looking-at "generate\\b[^_]")
3864 (vector "generate\\|for\\|if"
3865 (vhdl-first-word pos)
3868 ((looking-at "loop\\b[^_]")
3869 (vector "loop\\|while\\|for"
3870 (vhdl-first-word pos)
3872 ;; "end for" (inside configuration declaration):
3873 ((looking-at "for\\b[^_]")
3874 (vector "for" (vhdl-first-word pos) nil nil))
3877 (vector "begin\\|architecture\\|configuration\\|entity\\|package\\|procedure\\|function"
3878 (vhdl-first-word pos)
3879 ;; return an alist of (statement . keyword) mappings
3881 ;; "begin ... end [id]":
3883 ;; "architecture ... is ... begin ... end [id]":
3884 ("architecture" . "is")
3885 ;; "configuration ... is ... end [id]":
3886 ("configuration" . "is")
3887 ;; "entity ... is ... end [id]":
3889 ;; "package ... is ... end [id]":
3891 ;; "procedure ... is ... begin ... end [id]":
3892 ("procedure" . "is")
3893 ;; "function ... is ... begin ... end [id]":
3900 (defconst vhdl-leader-re
3901 "\\b\\(block\\|component\\|process\\|procedural\\|for\\)\\b[^_]")
3903 (defun vhdl-end-of-leader ()
3905 (cond ((looking-at "block\\|process\\|procedural")
3908 (skip-chars-forward " \t\n")
3909 (= (following-char) ?\())
3913 ((looking-at "component")
3918 (skip-chars-forward " \t\n")
3919 (while (looking-at "[,:(]")
3921 (skip-chars-forward " \t\n"))
3926 (defconst vhdl-trailer-re
3927 "\\b\\(is\\|then\\|generate\\|loop\\)\\b[^_]")
3929 (defconst vhdl-statement-fwd-re
3930 "\\b\\(if\\|for\\|while\\)\\b\\([^_]\\|\\'\\)"
3931 "A regular expression for searching forward that matches all known
3932 \"statement\" keywords.")
3934 (defconst vhdl-statement-bwd-re
3935 "\\b\\(if\\|for\\|while\\)\\b[^_]"
3936 "A regular expression for searching backward that matches all known
3937 \"statement\" keywords.")
3939 (defun vhdl-statement-p (&optional lim)
3940 "Return t if we are looking at a real \"statement\" keyword.
3941 Assumes that the caller will make sure that we are looking at
3942 vhdl-statement-fwd-re, and are not inside a literal, and that we are not
3943 in the middle of an identifier that just happens to contain a
3944 \"statement\" keyword."
3946 ;; "for" ... "generate":
3947 ((and (looking-at "f")
3948 ;; Make sure it's the start of a parameter specification.
3951 (skip-chars-forward " \t\n")
3952 (looking-at "in\\b[^_]"))
3953 ;; Make sure it's not an "end for".
3956 (not (looking-at "end\\s-+\\w"))))
3958 ;; "if" ... "then", "if" ... "generate", "if" ... "loop":
3959 ((and (looking-at "i")
3960 ;; Make sure it's not an "end if".
3963 (not (looking-at "end\\s-+\\w"))))
3965 ;; "while" ... "loop":
3970 (defconst vhdl-case-alternative-re "when[( \t\n][^;=>]+=>"
3971 "Regexp describing a case statement alternative key.")
3973 (defun vhdl-case-alternative-p (&optional lim)
3974 "Return t if we are looking at a real case alternative.
3975 Assumes that the caller will make sure that we are looking at
3976 vhdl-case-alternative-re, and are not inside a literal, and that
3977 we are not in the middle of an identifier that just happens to
3978 contain a \"when\" keyword."
3981 (while (and (not foundp)
3982 (re-search-backward ";\\|<=" lim 'move))
3983 (if (or (= (preceding-char) ?_)
3984 (vhdl-in-literal lim))
3987 (or (eq (following-char) ?\;)
3991 ;; Core syntactic movement functions:
3993 (defconst vhdl-b-t-b-re
3994 (concat vhdl-begin-bwd-re "\\|" vhdl-end-bwd-re))
3996 (defun vhdl-backward-to-block (&optional lim)
3997 "Move backward to the previous \"begin\" or \"end\" keyword."
3999 (while (and (not foundp)
4000 (re-search-backward vhdl-b-t-b-re lim 'move))
4001 (if (or (= (preceding-char) ?_)
4002 (vhdl-in-literal lim))
4006 ((and (looking-at vhdl-begin-fwd-re)
4007 (/= (preceding-char) ?_)
4009 (setq foundp 'begin))
4011 ((and (looking-at vhdl-end-fwd-re)
4012 (/= (preceding-char) ?_)
4020 (defun vhdl-forward-sexp (&optional count lim)
4021 "Move forward across one balanced expression (sexp).
4022 With COUNT, do it that many times."
4024 (let ((count (or count 1))
4025 (case-fold-search t)
4030 (skip-chars-forward " \t\n")
4031 ;; Check for an unbalanced "end" keyword
4032 (if (and (looking-at vhdl-end-fwd-re)
4033 (/= (preceding-char) ?_)
4034 (not (vhdl-in-literal lim))
4036 (not (looking-at "else")))
4038 "Containing expression ends prematurely in vhdl-forward-sexp"))
4039 ;; If the current keyword is a "begin" keyword, then find the
4040 ;; corresponding "end" keyword.
4041 (if (setq end-vec (vhdl-corresponding-end lim))
4043 ;; end-re is the statement keyword to search for
4045 (concat "\\b\\(" (aref end-vec 0) "\\)\\b\\([^_]\\|\\'\\)"))
4046 ;; column is either the statement keyword target column
4048 (column (aref end-vec 1))
4049 (eol (vhdl-point 'eol))
4050 foundp literal placeholder)
4051 ;; Look for the statement keyword.
4052 (while (and (not foundp)
4053 (re-search-forward end-re nil t)
4054 (setq placeholder (match-end 1))
4055 (goto-char (match-beginning 0)))
4056 ;; If we are in a literal, or not in the right target
4057 ;; column and not on the same line as the begin, then
4060 (/= (current-indentation) column)
4062 (= (preceding-char) ?_)
4063 (setq literal (vhdl-in-literal lim)))
4064 (if (eq literal 'comment)
4067 ;; An "else" keyword corresponds to both the opening brace
4068 ;; of the following sexp and the closing brace of the
4070 (if (not (looking-at "else"))
4071 (goto-char placeholder))
4075 (error "Unbalanced keywords in vhdl-forward-sexp"))
4077 ;; If the current keyword is not a "begin" keyword, then just
4078 ;; perform the normal forward-sexp.
4081 (setq count (1- count))
4083 (setq target (point)))
4087 (defun vhdl-backward-sexp (&optional count lim)
4088 "Move backward across one balanced expression (sexp).
4089 With COUNT, do it that many times. LIM bounds any required backward
4092 (let ((count (or count 1))
4093 (case-fold-search t)
4097 ;; Perform the normal backward-sexp, unless we are looking at
4098 ;; "else" - an "else" keyword corresponds to both the opening brace
4099 ;; of the following sexp and the closing brace of the previous sexp.
4100 (if (and (looking-at "else\\b\\([^_]\\|\\'\\)")
4101 (/= (preceding-char) ?_)
4102 (not (vhdl-in-literal lim)))
4105 (if (and (looking-at vhdl-begin-fwd-re)
4106 (/= (preceding-char) ?_)
4107 (not (vhdl-in-literal lim))
4109 (error "Containing expression ends prematurely in vhdl-backward-sexp")))
4110 ;; If the current keyword is an "end" keyword, then find the
4111 ;; corresponding "begin" keyword.
4112 (if (and (setq begin-vec (vhdl-corresponding-begin lim))
4113 (/= (preceding-char) ?_))
4115 ;; begin-re is the statement keyword to search for
4117 (concat "\\b\\(" (aref begin-vec 0) "\\)\\b[^_]"))
4118 ;; column is either the statement keyword target column
4120 (column (aref begin-vec 1))
4121 ;; internal-p controls where the statement keyword can
4123 (internal-p (aref begin-vec 3))
4124 (last-backward (point)) last-forward
4125 foundp literal keyword)
4126 ;; Look for the statement keyword.
4127 (while (and (not foundp)
4128 (re-search-backward begin-re lim t)
4130 (buffer-substring (match-beginning 1)
4132 ;; If we are in a literal or in the wrong column,
4135 (and (/= (current-indentation) column)
4136 ;; possibly accept current-column as
4137 ;; well as current-indentation.
4138 (or (not internal-p)
4139 (/= (current-column) column))))
4140 (= (preceding-char) ?_)
4141 (vhdl-in-literal lim))
4143 ;; If there is a supplementary keyword, then
4144 ;; search forward for it.
4145 (if (and (setq begin-re (aref begin-vec 2))
4146 (or (not (listp begin-re))
4147 ;; If begin-re is an alist, then find the
4148 ;; element corresponding to the actual
4149 ;; keyword that we found.
4152 (assoc keyword begin-re))
4154 (setq begin-re (cdr begin-re))))))
4157 (concat "\\b\\(" begin-re "\\)\\b[^_]"))
4159 (setq last-forward (point))
4160 ;; Look for the supplementary keyword
4161 ;; (bounded by the backward search start
4163 (while (and (not foundp)
4164 (re-search-forward begin-re
4166 (goto-char (match-beginning 1)))
4167 ;; If we are in a literal, then try again.
4168 (if (or (= (preceding-char) ?_)
4170 (vhdl-in-literal last-forward)))
4171 (if (eq literal 'comment)
4173 (min (vhdl-point 'eol) last-backward))
4175 ;; We have found the supplementary keyword.
4176 ;; Save the position of the keyword in foundp.
4177 (setq foundp (point)))
4180 ;; If the supplementary keyword was found, then
4181 ;; move point to the supplementary keyword.
4183 ;; If there was no supplementary keyword, then
4184 ;; point is already at the statement keyword.
4186 ) ; end of the search for the statement keyword
4188 (error "Unbalanced keywords in vhdl-backward-sexp"))
4190 (setq count (1- count))
4192 (setq target (point)))
4196 (defun vhdl-backward-up-list (&optional count limit)
4197 "Move backward out of one level of blocks.
4198 With argument, do this that many times."
4200 (let ((count (or count 1))
4204 (if (looking-at vhdl-defun-re)
4205 (error "Unbalanced blocks"))
4206 (vhdl-backward-to-block limit)
4207 (setq count (1- count)))
4208 (setq target (point)))
4209 (goto-char target)))
4211 (defun vhdl-end-of-defun (&optional count)
4212 "Move forward to the end of a VHDL defun."
4214 (let ((case-fold-search t))
4215 (vhdl-beginning-of-defun)
4216 (if (not (looking-at "block\\|process\\|procedural"))
4217 (re-search-forward "\\bis\\b"))
4218 (vhdl-forward-sexp)))
4220 (defun vhdl-mark-defun ()
4221 "Put mark at end of this \"defun\", point at beginning."
4223 (let ((case-fold-search t))
4225 (vhdl-beginning-of-defun)
4227 (if (not (looking-at "block\\|process\\|procedural"))
4228 (re-search-forward "\\bis\\b"))
4230 (exchange-point-and-mark)))
4232 (defun vhdl-beginning-of-libunit ()
4233 "Move backward to the beginning of a VHDL library unit.
4234 Returns the location of the corresponding begin keyword, unless search
4235 stops due to beginning or end of buffer.
4236 Note that if point is between the \"libunit\" keyword and the
4237 corresponding \"begin\" keyword, then that libunit will not be
4238 recognised, and the search will continue backwards. If point is
4239 at the \"begin\" keyword, then the defun will be recognised. The
4240 returned point is at the first character of the \"libunit\" keyword."
4241 (let ((last-forward (point))
4243 ;; Just in case we are actually sitting on the "begin"
4244 ;; keyword, allow for the keyword and an extra character,
4245 ;; as this will be used when looking forward for the
4247 (save-excursion (forward-word 1) (1+ (point))))
4248 foundp literal placeholder)
4249 ;; Find the "libunit" keyword.
4250 (while (and (not foundp)
4251 (re-search-backward vhdl-libunit-re nil 'move))
4252 ;; If we are in a literal, or not at a real libunit, then try again.
4253 (if (or (= (preceding-char) ?_)
4254 (vhdl-in-literal (point-min))
4255 (not (vhdl-libunit-p)))
4257 ;; Find the corresponding "begin" keyword.
4258 (setq last-forward (point))
4259 (while (and (not foundp)
4260 (re-search-forward "\\bis\\b[^_]" last-backward t)
4261 (setq placeholder (match-beginning 0)))
4262 (if (or (= (preceding-char) ?_)
4263 (setq literal (vhdl-in-literal last-forward)))
4264 ;; It wasn't a real keyword, so keep searching.
4265 (if (eq literal 'comment)
4267 (min (vhdl-point 'eol) last-backward))
4269 ;; We have found the begin keyword, loop will exit.
4270 (setq foundp placeholder)))
4271 ;; Go back to the libunit keyword
4272 (goto-char last-forward)))
4275 (defun vhdl-beginning-of-defun (&optional count)
4276 "Move backward to the beginning of a VHDL defun.
4277 With argument, do it that many times.
4278 Returns the location of the corresponding begin keyword, unless search
4279 stops due to beginning or end of buffer."
4280 ;; Note that if point is between the "defun" keyword and the
4281 ;; corresponding "begin" keyword, then that defun will not be
4282 ;; recognised, and the search will continue backwards. If point is
4283 ;; at the "begin" keyword, then the defun will be recognised. The
4284 ;; returned point is at the first character of the "defun" keyword.
4286 (let ((count (or count 1))
4287 (case-fold-search t)
4288 (last-forward (point))
4292 (goto-char last-forward)
4293 (let ((last-backward
4294 ;; Just in case we are actually sitting on the "begin"
4295 ;; keyword, allow for the keyword and an extra character,
4296 ;; as this will be used when looking forward for the
4298 (save-excursion (forward-word 1) (1+ (point))))
4299 begin-string literal)
4300 (while (and (not foundp)
4301 (re-search-backward vhdl-defun-re nil 'move))
4302 ;; If we are in a literal, then try again.
4303 (if (or (= (preceding-char) ?_)
4304 (vhdl-in-literal (point-min)))
4306 (if (setq begin-string (vhdl-corresponding-defun))
4307 ;; This is a real defun keyword.
4308 ;; Find the corresponding "begin" keyword.
4309 ;; Look for the begin keyword.
4311 ;; Save the search start point.
4312 (setq last-forward (point))
4313 (while (and (not foundp)
4314 (search-forward begin-string last-backward t))
4315 (if (or (= (preceding-char) ?_)
4317 (setq literal (vhdl-in-literal last-forward))))
4318 ;; It wasn't a real keyword, so keep searching.
4319 (if (eq literal 'comment)
4321 (min (vhdl-point 'eol) last-backward))
4323 ;; We have found the begin keyword, loop will exit.
4324 (setq foundp (match-beginning 0)))
4326 ;; Go back to the defun keyword
4327 (goto-char last-forward)) ; end search for begin keyword
4329 ) ; end of the search for the defun keyword
4331 (setq count (1- count))
4333 (vhdl-keep-region-active)
4336 (defun vhdl-beginning-of-statement (&optional count lim)
4337 "Go to the beginning of the innermost VHDL statement.
4338 With prefix arg, go back N - 1 statements. If already at the
4339 beginning of a statement then go to the beginning of the preceding
4340 one. If within a string or comment, or next to a comment (only
4341 whitespace between), move by sentences instead of statements.
4343 When called from a program, this function takes 2 optional args: the
4344 prefix arg, and a buffer position limit which is the farthest back to
4347 (let ((count (or count 1))
4348 (case-fold-search t)
4349 (lim (or lim (point-min)))
4354 (setq state (parse-partial-sexp (point) here nil nil)))
4355 (if (and (interactive-p)
4358 (looking-at (concat "[ \t]*" comment-start-skip))))
4359 (forward-sentence (- count))
4361 (vhdl-beginning-of-statement-1 lim)
4362 (setq count (1- count))))
4363 ;; its possible we've been left up-buf of lim
4364 (goto-char (max (point) lim))
4366 (vhdl-keep-region-active))
4368 (defconst vhdl-e-o-s-re
4369 (concat ";\\|" vhdl-begin-fwd-re "\\|" vhdl-statement-fwd-re))
4371 (defun vhdl-end-of-statement ()
4372 "Very simple implementation."
4374 (re-search-forward vhdl-e-o-s-re))
4376 (defconst vhdl-b-o-s-re
4377 (concat ";\\|\(\\|\)\\|\\bwhen\\b[^_]\\|"
4378 vhdl-begin-bwd-re "\\|" vhdl-statement-bwd-re))
4380 (defun vhdl-beginning-of-statement-1 (&optional lim)
4381 "Move to the start of the current statement, or the previous
4382 statement if already at the beginning of one."
4383 (let ((lim (or lim (point-min)))
4387 ;; go backwards one balanced expression, but be careful of
4388 ;; unbalanced paren being reached
4389 (if (not (vhdl-safe (progn (backward-sexp) t)))
4391 (backward-up-list 1)
4393 (vhdl-forward-syntactic-ws here)
4395 (while (and (not donep)
4397 ;; look backwards for a statement boundary
4398 (re-search-backward vhdl-b-o-s-re lim 'move))
4399 (if (or (= (preceding-char) ?_)
4400 (vhdl-in-literal lim))
4403 ;; If we are looking at an open paren, then stop after it
4404 ((eq (following-char) ?\()
4406 (vhdl-forward-syntactic-ws here)
4408 ;; If we are looking at a close paren, then skip it
4409 ((eq (following-char) ?\))
4414 (progn (goto-char pos)
4415 (vhdl-forward-syntactic-ws here)
4417 ;; If we are looking at a semicolon, then stop
4418 ((eq (following-char) ?\;)
4421 (vhdl-forward-syntactic-ws here)
4423 ;; If we are looking at a "begin", then stop
4424 ((and (looking-at vhdl-begin-fwd-re)
4425 (/= (preceding-char) ?_)
4427 ;; If it's a leader "begin", then find the
4429 (if (looking-at vhdl-leader-re)
4431 ;; set a default stop point at the begin
4433 ;; is the start point inside the leader area ?
4434 (goto-char (vhdl-end-of-leader))
4435 (vhdl-forward-syntactic-ws here)
4436 (if (< (point) here)
4437 ;; start point was not inside leader area
4438 ;; set stop point at word after leader
4439 (setq pos (point))))
4441 (vhdl-forward-syntactic-ws here)
4445 ;; If we are looking at a "statement", then stop
4446 ((and (looking-at vhdl-statement-fwd-re)
4447 (/= (preceding-char) ?_)
4448 (vhdl-statement-p nil))
4450 ;; If we are looking at a case alternative key, then stop
4451 ((and (looking-at vhdl-case-alternative-re)
4452 (vhdl-case-alternative-p lim))
4454 ;; set a default stop point at the when
4456 ;; is the start point inside the case alternative key ?
4457 (looking-at vhdl-case-alternative-re)
4458 (goto-char (match-end 0))
4459 (vhdl-forward-syntactic-ws here)
4460 (if (< (point) here)
4461 ;; start point was not inside the case alternative key
4462 ;; set stop point at word after case alternative keyleader
4463 (setq pos (point))))
4466 ;; Bogus find, continue
4471 ;; Defuns for calculating the current syntactic state:
4473 (defun vhdl-get-library-unit (bod placeholder)
4474 "If there is an enclosing library unit at bod, with it's \"begin\"
4475 keyword at placeholder, then return the library unit type."
4476 (let ((here (vhdl-point 'bol)))
4478 (goto-char placeholder)
4479 (vhdl-safe (vhdl-forward-sexp 1 bod))
4484 ((looking-at "e") 'entity)
4485 ((looking-at "a") 'architecture)
4486 ((looking-at "c") 'configuration)
4491 (vhdl-forward-syntactic-ws here)
4492 (if (looking-at "body\\b[^_]")
4493 'package-body 'package))))))
4496 (defun vhdl-get-block-state (&optional lim)
4497 "Finds and records all the closest opens.
4498 lim is the furthest back we need to search (it should be the
4499 previous libunit keyword)."
4500 (let ((here (point))
4501 (lim (or lim (point-min)))
4502 keyword sexp-start sexp-mid sexp-end
4503 preceding-sexp containing-sexp
4504 containing-begin containing-mid containing-paren)
4506 ;; Find the containing-paren, and use that as the limit
4507 (if (setq containing-paren
4509 (narrow-to-region lim (point))
4510 (vhdl-safe (scan-lists (point) -1 1))))
4511 (setq lim containing-paren))
4512 ;; Look backwards for "begin" and "end" keywords.
4513 (while (and (> (point) lim)
4514 (not containing-sexp))
4515 (setq keyword (vhdl-backward-to-block lim))
4517 ((eq keyword 'begin)
4518 ;; Found a "begin" keyword
4519 (setq sexp-start (point))
4520 (setq sexp-mid (vhdl-corresponding-mid lim))
4521 (setq sexp-end (vhdl-safe
4523 (vhdl-forward-sexp 1 lim) (point))))
4524 (if (and sexp-end (<= sexp-end here))
4525 ;; we want to record this sexp, but we only want to
4526 ;; record the last-most of any of them before here
4528 (setq preceding-sexp sexp-start))
4529 ;; we're contained in this sexp so put sexp-start on
4531 (setq containing-sexp sexp-start)
4532 (setq containing-mid sexp-mid)
4533 (setq containing-begin t)))
4535 ;; Found an "end" keyword
4537 (setq sexp-end (point))
4540 (or (vhdl-safe (vhdl-backward-sexp 1 lim) (point))
4541 (progn (backward-sexp) (point))))
4542 ;; we want to record this sexp, but we only want to
4543 ;; record the last-most of any of them before here
4545 (setq preceding-sexp sexp-start)))
4547 ;; Check if the containing-paren should be the containing-sexp
4548 (if (and containing-paren
4549 (or (null containing-sexp)
4550 (< containing-sexp containing-paren)))
4551 (setq containing-sexp containing-paren
4553 containing-begin nil
4554 containing-mid nil))
4555 (vector containing-sexp preceding-sexp containing-begin containing-mid)
4559 (defconst vhdl-s-c-a-re
4560 (concat vhdl-case-alternative-re "\\|" vhdl-case-header-key))
4562 (defun vhdl-skip-case-alternative (&optional lim)
4563 "Skip forward over case/when bodies, with optional maximal
4564 limit. If no next case alternative is found, nil is returned and point
4566 (let ((lim (or lim (point-max)))
4569 (while (and (< (point) lim)
4571 (if (and (re-search-forward vhdl-s-c-a-re lim 'move)
4573 (not (vhdl-in-literal)))
4574 (/= (match-beginning 0) here))
4576 (goto-char (match-beginning 0))
4578 ((and (looking-at "case")
4579 (re-search-forward "\\bis[^_]" lim t))
4581 (vhdl-forward-sexp))
4589 (defun vhdl-backward-skip-label (&optional lim)
4590 "Skip backward over a label, with optional maximal
4591 limit. If label is not found, nil is returned and point
4593 (let ((lim (or lim (point-min)))
4596 (vhdl-backward-syntactic-ws lim)
4597 (and (eq (preceding-char) ?:)
4600 (setq placeholder (point))
4601 (looking-at vhdl-label-key))))
4602 (goto-char placeholder))
4605 (defun vhdl-forward-skip-label (&optional lim)
4606 "Skip forward over a label, with optional maximal
4607 limit. If label is not found, nil is returned and point
4609 (let ((lim (or lim (point-max))))
4610 (if (looking-at vhdl-label-key)
4612 (goto-char (match-end 0))
4613 (vhdl-forward-syntactic-ws lim)))
4616 (defun vhdl-get-syntactic-context ()
4617 "Guess the syntactic description of the current line of VHDL code."
4621 (let* ((indent-point (point))
4622 (case-fold-search t)
4623 vec literal containing-sexp preceding-sexp
4624 containing-begin containing-mid containing-leader
4625 char-before-ip char-after-ip begin-after-ip end-after-ip
4626 placeholder lim library-unit
4629 ;; Reset the syntactic context
4630 (setq vhdl-syntactic-context nil)
4633 ;; Move to the start of the previous library unit, and
4634 ;; record the position of the "begin" keyword.
4635 (setq placeholder (vhdl-beginning-of-libunit))
4636 ;; The position of the "libunit" keyword gives us a gross
4641 ;; If there is a previous library unit, and we are enclosed by
4642 ;; it, then set the syntax accordingly.
4644 (setq library-unit (vhdl-get-library-unit lim placeholder))
4645 (vhdl-add-syntax library-unit lim))
4647 ;; Find the surrounding state.
4648 (if (setq vec (vhdl-get-block-state lim))
4650 (setq containing-sexp (aref vec 0))
4651 (setq preceding-sexp (aref vec 1))
4652 (setq containing-begin (aref vec 2))
4653 (setq containing-mid (aref vec 3))
4656 ;; set the limit on the farthest back we need to search
4657 (setq lim (if containing-sexp
4659 (goto-char containing-sexp)
4660 ;; set containing-leader if required
4661 (if (looking-at vhdl-leader-re)
4662 (setq containing-leader (vhdl-end-of-leader)))
4666 ;; cache char before and after indent point, and move point to
4667 ;; the most likely position to perform the majority of tests
4668 (goto-char indent-point)
4669 (skip-chars-forward " \t")
4670 (setq literal (vhdl-in-literal lim))
4671 (setq char-after-ip (following-char))
4672 (setq begin-after-ip (and
4674 (looking-at vhdl-begin-fwd-re)
4676 (setq end-after-ip (and
4678 (looking-at vhdl-end-fwd-re)
4680 (vhdl-backward-syntactic-ws lim)
4681 (setq char-before-ip (preceding-char))
4682 (goto-char indent-point)
4683 (skip-chars-forward " \t")
4685 ;; now figure out syntactic qualities of the current line
4687 ;; CASE 1: in a string or comment.
4688 ((memq literal '(string comment))
4689 (vhdl-add-syntax literal (vhdl-point 'bopl)))
4690 ;; CASE 2: Line is at top level.
4691 ((null containing-sexp)
4692 ;; Find the point to which indentation will be relative
4694 (if (null preceding-sexp)
4696 ;; no preceding-sexp -> use the preceding statement
4697 (vhdl-beginning-of-statement-1 lim)
4699 ;; if there is a preceding-sexp then indent relative to it
4700 (goto-char preceding-sexp)
4701 ;; if not at boi, then the block-opening keyword is
4702 ;; probably following a label, so we need a different
4704 (if (/= (point) (vhdl-point 'boi))
4706 (vhdl-beginning-of-statement-1 lim)))
4707 ;; v-b-o-s could have left us at point-min
4710 (vhdl-forward-syntactic-ws indent-point))
4711 (setq placeholder (point)))
4713 ;; CASE 2A : we are looking at a block-open
4715 (vhdl-add-syntax 'block-open placeholder))
4716 ;; CASE 2B: we are looking at a block-close
4718 (vhdl-add-syntax 'block-close placeholder))
4719 ;; CASE 2C: we are looking at a top-level statement
4721 (vhdl-backward-syntactic-ws lim)
4723 (= (preceding-char) ?\;)))
4724 (vhdl-add-syntax 'statement placeholder))
4725 ;; CASE 2D: we are looking at a top-level statement-cont
4727 (vhdl-beginning-of-statement-1 lim)
4728 ;; v-b-o-s could have left us at point-min
4731 (vhdl-forward-syntactic-ws indent-point))
4732 (vhdl-add-syntax 'statement-cont (point)))
4734 ;; CASE 3: line is inside parentheses. Most likely we are
4735 ;; either in a subprogram argument (interface) list, or a
4736 ;; continued expression containing parentheses.
4737 ((null containing-begin)
4738 (vhdl-backward-syntactic-ws containing-sexp)
4740 ;; CASE 3A: we are looking at the arglist closing paren
4741 ((eq char-after-ip ?\))
4742 (goto-char containing-sexp)
4743 (vhdl-add-syntax 'arglist-close (vhdl-point 'boi)))
4744 ;; CASE 3B: we are looking at the first argument in an empty
4746 ((eq char-before-ip ?\()
4747 (goto-char containing-sexp)
4748 (vhdl-add-syntax 'arglist-intro (vhdl-point 'boi)))
4749 ;; CASE 3C: we are looking at an arglist continuation line,
4750 ;; but the preceding argument is on the same line as the
4751 ;; opening paren. This case includes multi-line
4752 ;; expression paren groupings.
4753 ((and (save-excursion
4754 (goto-char (1+ containing-sexp))
4755 (skip-chars-forward " \t")
4757 (not (looking-at "--")))
4759 (vhdl-beginning-of-statement-1 containing-sexp)
4760 (skip-chars-backward " \t(")
4761 (<= (point) containing-sexp)))
4762 (goto-char containing-sexp)
4763 (vhdl-add-syntax 'arglist-cont-nonempty (vhdl-point 'boi)))
4764 ;; CASE 3D: we are looking at just a normal arglist
4765 ;; continuation line
4766 (t (vhdl-beginning-of-statement-1 containing-sexp)
4767 (vhdl-forward-syntactic-ws indent-point)
4768 (vhdl-add-syntax 'arglist-cont (vhdl-point 'boi)))
4770 ;; CASE 4: A block mid open
4771 ((and begin-after-ip
4772 (looking-at containing-mid))
4773 (goto-char containing-sexp)
4774 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
4775 (if (looking-at vhdl-trailer-re)
4777 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
4778 (vhdl-backward-skip-label (vhdl-point 'boi))
4779 (vhdl-add-syntax 'block-open (point)))
4780 ;; CASE 5: block close brace
4782 (goto-char containing-sexp)
4783 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
4784 (if (looking-at vhdl-trailer-re)
4786 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
4787 (vhdl-backward-skip-label (vhdl-point 'boi))
4788 (vhdl-add-syntax 'block-close (point)))
4789 ;; CASE 6: A continued statement
4790 ((and (/= char-before-ip ?\;)
4791 ;; check it's not a trailer begin keyword, or a begin
4792 ;; keyword immediately following a label.
4793 (not (and begin-after-ip
4794 (or (looking-at vhdl-trailer-re)
4796 (vhdl-backward-skip-label containing-sexp)))))
4797 ;; check it's not a statement keyword
4798 (not (and (looking-at vhdl-statement-fwd-re)
4799 (vhdl-statement-p)))
4800 ;; see if the b-o-s is before the indent point
4803 (vhdl-beginning-of-statement-1 containing-sexp)
4804 ;; If we ended up after a leader, then this will
4805 ;; move us forward to the start of the first
4806 ;; statement. Note that a containing sexp here is
4807 ;; always a keyword, not a paren, so this will
4808 ;; have no effect if we hit the containing-sexp.
4809 (vhdl-forward-syntactic-ws indent-point)
4810 (setq placeholder (point))))
4811 ;; check it's not a block-intro
4812 (/= placeholder containing-sexp)
4813 ;; check it's not a case block-intro
4815 (goto-char placeholder)
4816 (or (not (looking-at vhdl-case-alternative-re))
4817 (> (match-end 0) indent-point))))
4818 ;; Make placeholder skip a label, but only if it puts us
4819 ;; before the indent point at the start of a line.
4820 (let ((new placeholder))
4821 (if (and (> indent-point
4823 (goto-char placeholder)
4824 (vhdl-forward-skip-label indent-point)
4825 (setq new (point))))
4828 (eq new (progn (back-to-indentation) (point)))))
4829 (setq placeholder new)))
4830 (vhdl-add-syntax 'statement-cont placeholder)
4832 (vhdl-add-syntax 'block-open)))
4833 ;; Statement. But what kind?
4834 ;; CASE 7: A case alternative key
4835 ((and (looking-at vhdl-case-alternative-re)
4836 (vhdl-case-alternative-p containing-sexp))
4837 ;; for a case alternative key, we set relpos to the first
4838 ;; non-whitespace char on the line containing the "case"
4840 (goto-char containing-sexp)
4841 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
4842 (if (looking-at vhdl-trailer-re)
4843 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
4844 (vhdl-add-syntax 'case-alternative (vhdl-point 'boi)))
4845 ;; CASE 8: statement catchall
4847 ;; we know its a statement, but we need to find out if it is
4848 ;; the first statement in a block
4849 (if containing-leader
4850 (goto-char containing-leader)
4851 (goto-char containing-sexp)
4852 ;; Note that a containing sexp here is always a keyword,
4853 ;; not a paren, so skip over the keyword.
4855 ;; move to the start of the first statement
4856 (vhdl-forward-syntactic-ws indent-point)
4857 (setq placeholder (point))
4858 ;; we want to ignore case alternatives keys when skipping forward
4860 (while (looking-at vhdl-case-alternative-re)
4861 (setq incase-p (point))
4862 ;; we also want to skip over the body of the
4863 ;; case/when statement if that doesn't put us at
4864 ;; after the indent-point
4865 (while (vhdl-skip-case-alternative indent-point))
4866 ;; set up the match end
4867 (looking-at vhdl-case-alternative-re)
4868 (goto-char (match-end 0))
4869 ;; move to the start of the first case alternative statement
4870 (vhdl-forward-syntactic-ws indent-point)
4871 (setq placeholder (point)))
4873 ;; CASE 8A: we saw a case/when statement so we must be
4874 ;; in a switch statement. find out if we are at the
4875 ;; statement just after a case alternative key
4877 (= (point) indent-point))
4878 ;; relpos is the "when" keyword
4879 (vhdl-add-syntax 'statement-case-intro incase-p))
4880 ;; CASE 8B: any old statement
4881 ((< (point) indent-point)
4882 ;; relpos is the first statement of the block
4883 (vhdl-add-syntax 'statement placeholder)
4885 (vhdl-add-syntax 'block-open)))
4886 ;; CASE 8C: first statement in a block
4888 (goto-char containing-sexp)
4889 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
4890 (if (looking-at vhdl-trailer-re)
4891 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
4892 (vhdl-backward-skip-label (vhdl-point 'boi))
4893 (vhdl-add-syntax 'statement-block-intro (point))
4895 (vhdl-add-syntax 'block-open)))
4899 ;; now we need to look at any modifiers
4900 (goto-char indent-point)
4901 (skip-chars-forward " \t")
4902 (if (looking-at "--")
4903 (vhdl-add-syntax 'comment))
4904 ;; return the syntax
4905 vhdl-syntactic-context))))
4907 ;; Standard indentation line-ups:
4909 (defun vhdl-lineup-arglist (langelem)
4910 "Lineup the current arglist line with the arglist appearing just
4911 after the containing paren which starts the arglist."
4913 (let* ((containing-sexp
4915 ;; arglist-cont-nonempty gives relpos ==
4916 ;; to boi of containing-sexp paren. This
4917 ;; is good when offset is +, but bad
4918 ;; when it is vhdl-lineup-arglist, so we
4919 ;; have to special case a kludge here.
4920 (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
4923 (backward-up-list 1)
4924 (skip-chars-forward " \t" (vhdl-point 'eol)))
4925 (goto-char (cdr langelem)))
4927 (cs-curcol (save-excursion
4928 (goto-char (cdr langelem))
4932 (looking-at "[ \t]*)"))
4933 (progn (goto-char (match-end 0))
4936 (vhdl-forward-syntactic-ws)
4937 (- (current-column) cs-curcol))
4938 (goto-char containing-sexp)
4940 (let ((eol (vhdl-point 'eol))
4943 (skip-chars-forward " \t")
4945 (vhdl-forward-syntactic-ws)
4948 (- (current-column) cs-curcol)
4951 (defun vhdl-lineup-arglist-intro (langelem)
4952 "Lineup an arglist-intro line to just after the open paren."
4954 (let ((cs-curcol (save-excursion
4955 (goto-char (cdr langelem))
4957 (ce-curcol (save-excursion
4959 (backward-up-list 1)
4960 (skip-chars-forward " \t" (vhdl-point 'eol))
4962 (- ce-curcol cs-curcol -1))))
4964 (defun vhdl-lineup-comment (langelem)
4965 "Support old behavior for comment indentation. We look at
4966 vhdl-comment-only-line-offset to decide how to indent comment
4969 (back-to-indentation)
4970 ;; at or to the right of comment-column
4971 (if (>= (current-column) comment-column)
4972 (vhdl-comment-indent)
4973 ;; otherwise, indent as specified by vhdl-comment-only-line-offset
4975 (or (car-safe vhdl-comment-only-line-offset)
4976 vhdl-comment-only-line-offset)
4977 (or (cdr-safe vhdl-comment-only-line-offset)
4978 (car-safe vhdl-comment-only-line-offset)
4979 -1000 ;jam it against the left side
4982 (defun vhdl-lineup-statement-cont (langelem)
4983 "Line up statement-cont after the assignment operator."
4985 (let* ((relpos (cdr langelem))
4986 (assignp (save-excursion
4987 (goto-char (vhdl-point 'boi))
4988 (and (re-search-forward "\\(<\\|:\\)="
4989 (vhdl-point 'eol) t)
4990 (- (point) (vhdl-point 'boi)))))
4995 (while (and (not foundp)
4996 (< (point) (vhdl-point 'eol)))
4997 (re-search-forward "\\(<\\|:\\)=\\|(" (vhdl-point 'eol) 'move)
4998 (if (vhdl-in-literal (cdr langelem))
5000 (if (= (preceding-char) ?\()
5001 ;; skip over any parenthesized expressions
5002 (goto-char (min (vhdl-point 'eol)
5003 (scan-lists (point) 1 1)))
5004 ;; found an assignment operator (not at eol)
5005 (setq foundp (not (looking-at "\\s-*$"))))))
5007 ;; there's no assignment operator on the line
5009 ;; calculate indentation column after assign and ws, unless
5010 ;; our line contains an assignment operator
5014 (skip-chars-forward " \t")
5016 (- (current-column) assignp curcol))
5019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5020 ;; Indentation commands
5022 (defsubst vhdl-in-comment-p ()
5023 "Check if point is to right of beginning comment delimiter."
5024 (let ((position (point)))
5025 (save-excursion ; finds an unquoted comment
5027 (re-search-forward "^\\([^\"]*\"[^\"]*\"\\)*[^\"]*--" position t))))
5029 (defsubst vhdl-in-string-p ()
5030 "Check if point is in a string."
5031 (let ((position (point)))
5032 (save-excursion ; preceeded by odd number of string delimiters?
5034 (eq position (re-search-forward "^\\([^\"]*\"[^\"]*\"\\)*[^\"]*\"[^\"]*"
5037 (defsubst vhdl-in-comment-or-string-p ()
5038 "Check if point is in a comment or a string."
5039 (and (vhdl-in-comment-p)
5040 (vhdl-in-string-p)))
5042 (defun vhdl-electric-tab (&optional prefix-arg)
5043 "If preceeding character is part of a word or a paren then hippie-expand,
5044 else if right of non whitespace on line then tab-to-tab-stop,
5045 else if last command was a tab or return then dedent one step,
5046 else indent `correctly'."
5048 (vhdl-ext-syntax-table
5049 (cond ((= (char-syntax (preceding-char)) ?w)
5050 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
5052 (vhdl-expand-abbrev prefix-arg)))
5053 ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
5054 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
5056 (vhdl-expand-paren prefix-arg)))
5057 ((> (current-column) (current-indentation))
5059 ((and (or (eq last-command 'vhdl-electric-tab)
5060 (eq last-command 'vhdl-electric-return))
5061 (/= 0 (current-indentation)))
5062 (backward-delete-char-untabify vhdl-basic-offset nil))
5063 (t (vhdl-indent-line)))
5064 (setq this-command 'vhdl-electric-tab)))
5066 (defun vhdl-electric-return ()
5067 "newline-and-indent or indent-new-comment-line if in comment and preceding
5068 character is a space."
5070 (if (and (= (preceding-char) ? ) (vhdl-in-comment-p))
5071 (indent-new-comment-line)
5072 (newline-and-indent)))
5074 (defvar vhdl-progress-info nil
5075 "Array variable for progress information: 0 begin, 1 end, 2 time.")
5077 (defun vhdl-indent-line ()
5078 "Indent the current line as VHDL code. Returns the amount of
5079 indentation change."
5081 (let* ((syntax (vhdl-get-syntactic-context))
5082 (pos (- (point-max) (point)))
5083 ;; special case: comments at or right of comment-column
5084 (indent (if (and (eq (car (car syntax)) 'comment)
5085 (>= (vhdl-get-offset (car syntax)) comment-column))
5086 (vhdl-get-offset (car syntax))
5087 (apply '+ (mapcar 'vhdl-get-offset syntax))))
5088 ; (indent (apply '+ (mapcar 'vhdl-get-offset syntax)))
5089 (shift-amt (- indent (current-indentation))))
5090 (and vhdl-echo-syntactic-information-p
5091 (message "syntax: %s, indent= %d" syntax indent))
5092 (unless (zerop shift-amt)
5093 (delete-region (vhdl-point 'bol) (vhdl-point 'boi))
5096 (if (< (point) (vhdl-point 'boi))
5097 (back-to-indentation)
5098 ;; If initial point was within line's indentation, position after
5099 ;; the indentation. Else stay at same point in text.
5100 (when (> (- (point-max) pos) (point))
5101 (goto-char (- (point-max) pos))))
5102 (run-hooks 'vhdl-special-indent-hook)
5103 ;; update progress status
5104 (when vhdl-progress-info
5105 (aset vhdl-progress-info 1 (+ (aref vhdl-progress-info 1)
5106 (if (> -500 shift-amt) 0 shift-amt)))
5107 (when (< vhdl-progress-interval
5108 (- (nth 1 (current-time)) (aref vhdl-progress-info 2)))
5109 (message "Indenting... (%2d%s)"
5110 (/ (* 100 (- (point) (aref vhdl-progress-info 0)))
5111 (- (aref vhdl-progress-info 1)
5112 (aref vhdl-progress-info 0))) "%")
5113 (aset vhdl-progress-info 2 (nth 1 (current-time)))))
5116 (defun vhdl-indent-buffer ()
5117 "Indent whole buffer as VHDL code.
5118 Calls `indent-region' for whole buffer and adds progress reporting."
5120 (when vhdl-progress-interval
5121 (setq vhdl-progress-info (vector (point-min) (point-max) 0)))
5122 (indent-region (point-min) (point-max) nil)
5123 (when vhdl-progress-interval (message "Indenting...done"))
5124 (setq vhdl-progress-info nil))
5126 (defun vhdl-indent-region (start end column)
5127 "Indent region as VHDL code.
5128 Adds progress reporting to `indent-region'."
5129 (interactive "r\nP")
5130 (when vhdl-progress-interval (setq vhdl-progress-info (vector start end 0)))
5131 (indent-region start end column)
5132 (when vhdl-progress-interval (message "Indenting...done"))
5133 (setq vhdl-progress-info nil))
5135 (defun vhdl-indent-sexp (&optional endpos)
5136 "Indent each line of the list starting just after point.
5137 If optional arg ENDPOS is given, indent each line, stopping when
5138 ENDPOS is encountered."
5142 (end (progn (vhdl-forward-sexp nil endpos) (point))))
5143 (indent-region beg end nil))))
5145 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5146 ;; Miscellaneous commands
5148 (defun vhdl-show-syntactic-information ()
5149 "Show syntactic information for current line."
5151 (message "syntactic analysis: %s" (vhdl-get-syntactic-context))
5152 (vhdl-keep-region-active))
5154 ;; Verification and regression functions:
5156 (defun vhdl-regress-line (&optional arg)
5157 "Check syntactic information for current line."
5159 (let ((expected (save-excursion
5161 (when (search-backward " -- ((" (vhdl-point 'bol) t)
5163 (read (current-buffer)))))
5164 (actual (vhdl-get-syntactic-context))
5166 ;; remove the library unit symbols
5170 (if (memq (car elt) '(entity configuration package
5171 package-body architecture))
5173 (setq expurgated (append expurgated (list elt))))))
5175 (if (and (not arg) expected (listp expected))
5176 (if (not (equal expected expurgated))
5177 (error "Should be: %s, is: %s" expected expurgated))
5180 (when (not (looking-at "^\\s-*\\(--.*\\)?$"))
5182 (if (search-backward " -- ((" (vhdl-point 'bol) t)
5185 (insert (format "%s" expurgated))))))
5186 (vhdl-keep-region-active))
5189 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5190 ;;; Alignment, whitespace fixup, beautifying
5191 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5193 (defvar vhdl-align-alist
5195 ;; after some keywords
5196 (vhdl-mode "\\<\\(constant\\|quantity\\|signal\\|terminal\\|variable\\)[ \t]"
5197 "\\<\\(constant\\|quantity\\|signal\\|terminal\\|variable\\)\\([ \t]+\\)" 2)
5199 (vhdl-mode ":[^=]" "\\([ \t]*\\):[^=]")
5200 ;; after direction specifications
5201 (vhdl-mode ":[ \t]*\\(in\\|out\\|inout\\|buffer\\|\\)\\>"
5202 ":[ \t]*\\(in\\|out\\|inout\\|buffer\\|\\)\\([ \t]+\\)" 2)
5203 ;; before "==", ":=", "=>", and "<="
5204 (vhdl-mode "==" "\\([ \t]*\\)==" 1)
5205 (vhdl-mode ":=" "\\([ \t]*\\):=" 1) ; since ":= ... =>" can occur
5206 (vhdl-mode "<=" "\\([ \t]*\\)<=" 1) ; since "<= ... =>" can occur
5207 (vhdl-mode "=>" "\\([ \t]*\\)=>" 1)
5208 (vhdl-mode ":=" "\\([ \t]*\\):=" 1) ; since "=> ... :=" can occur
5209 (vhdl-mode "<=" "\\([ \t]*\\)<=" 1) ; since "=> ... <=" can occur
5210 ;; before some keywords
5211 (vhdl-mode "[ \t]after\\>" "[^ \t]\\([ \t]+\\)after\\>" 1)
5212 (vhdl-mode "[ \t]when\\>" "[^ \t]\\([ \t]+\\)when\\>" 1)
5213 (vhdl-mode "[ \t]else\\>" "[^ \t]\\([ \t]+\\)else\\>" 1)
5215 "The format of this alist is (MODES [or MODE] REGEXP ALIGN-PATTERN SUBEXP).
5216 It is searched in order. If REGEXP is found anywhere in the first
5217 line of a region to be aligned, ALIGN-PATTERN will be used for that
5218 region. ALIGN-PATTERN must include the whitespace to be expanded or
5219 contracted. It may also provide regexps for the text surrounding the
5220 whitespace. SUBEXP specifies which sub-expression of
5221 ALIGN-PATTERN matches the white space to be expanded/contracted.")
5223 (defvar vhdl-align-try-all-clauses t
5224 "If REGEXP is not found on the first line of the region that clause
5225 is ignored. If this variable is non-nil, then the clause is tried anyway.")
5227 (defun vhdl-align-region (begin end &optional spacing alignment-list indent)
5228 "Attempt to align a range of lines based on the content of the
5229 lines. The definition of `alignment-list' determines the matching
5230 order and the manner in which the lines are aligned. If ALIGNMENT-LIST
5231 is not specified `vhdl-align-alist' is used. If INDENT is non-nil,
5232 indentation is done before aligning."
5233 (interactive "r\np")
5234 (setq alignment-list (or alignment-list vhdl-align-alist))
5235 (setq spacing (or spacing 1))
5239 (setq end (point-marker))
5241 (setq bol (setq begin (progn (beginning-of-line) (point))))
5242 ; (untabify bol end)
5244 (indent-region bol end nil))))
5245 (let ((case-fold-search t)
5246 (copy (copy-alist alignment-list)))
5247 (vhdl-ext-syntax-table
5252 (eol (save-excursion (progn (end-of-line) (point)))))
5253 (setq element (nth 0 copy))
5254 (when (and (or (and (listp (car element))
5255 (memq major-mode (car element)))
5256 (eq major-mode (car element)))
5257 (or vhdl-align-try-all-clauses
5258 (re-search-forward (car (cdr element)) eol t)))
5259 (vhdl-align-region-1 begin end (car (cdr (cdr element)))
5260 (car (cdr (cdr (cdr element)))) spacing))
5261 (setq copy (cdr copy))))))))
5263 (defun vhdl-align-region-1 (begin end match &optional substr spacing)
5264 "Align a range of lines from BEGIN to END. The regular expression
5265 MATCH must match exactly one fields: the whitespace to be
5266 contracted/expanded. The alignment column will equal the
5267 rightmost column of the widest whitespace block. SPACING is
5268 the amount of extra spaces to add to the calculated maximum required.
5269 SPACING defaults to 1 so that at least one space is inserted after
5270 the token in MATCH."
5271 (setq spacing (or spacing 1))
5272 (setq substr (or substr 1))
5274 (let (distance (max 0) (lines 0) bol eol width)
5275 ;; Determine the greatest whitespace distance to the alignment
5278 (setq eol (progn (end-of-line) (point))
5279 bol (setq begin (progn (beginning-of-line) (point))))
5282 (when (and (re-search-forward match eol t)
5283 (not (vhdl-in-comment-p)))
5284 (setq distance (- (match-beginning substr) bol))
5285 (when (> distance max)
5286 (setq max distance))))
5289 eol (save-excursion (end-of-line) (point)))
5290 (setq lines (1+ lines)))
5291 ;; Now insert enough maxs to push each assignment operator to
5292 ;; the same column. We need to use 'lines' as a counter, since
5293 ;; the location of the mark may change
5294 (goto-char (setq bol begin))
5295 (setq eol (save-excursion (end-of-line) (point)))
5297 (when (and (re-search-forward match eol t)
5298 (not (vhdl-in-comment-p)))
5299 (setq width (- (match-end substr) (match-beginning substr)))
5300 (setq distance (- (match-beginning substr) bol))
5301 (goto-char (match-beginning substr))
5303 (insert-char ? (+ (- max distance) spacing)))
5307 eol (save-excursion (end-of-line) (point)))
5308 (setq lines (1- lines))))))
5310 (defun vhdl-align-inline-comment-region-1 (beg end &optional spacing)
5311 "Align inline comments in region."
5313 (let ((high-start 0)
5315 (case-fold-search t))
5316 (vhdl-ext-syntax-table
5318 ;; search for longest code line and longest inline comment
5319 (while (< (point) end)
5321 ((and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>"))
5322 (looking-at "^\\(.*[^ \t\n-]+\\)\\s-*\\(--\\s-*.*\\)$"))
5324 (max high-start (- (match-end 1) (match-beginning 1))))
5326 (max high-length (- (match-end 2) (match-beginning 2)))))
5327 ((and (looking-at "^\\(\\s-*\\))\\(--\\s-*.*\\)$")
5328 (>= (- (match-end 1) (match-beginning 1)) comment-column))
5330 (max high-length (- (match-end 2) (match-beginning 2))))))
5331 (beginning-of-line 2))
5333 (setq spacing (or spacing 2))
5334 (setq high-start (+ high-start spacing))
5335 ;; align as nice as possible
5336 (while (< (point) end)
5337 (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>"))
5338 (or (looking-at "^.*[^ \t\n-]+\\(\\s-*\\)--")
5339 (and (looking-at "^\\(\\s-*\\)--")
5340 (>= (- (match-end 1) (match-beginning 1))
5342 (goto-char (match-end 1))
5343 (delete-region (match-beginning 1) (match-end 1))
5344 (insert-char ? spacing)
5345 (cond ((<= high-start comment-column)
5346 (indent-to comment-column))
5347 ((<= (+ high-start high-length) end-comment-column)
5348 (indent-to high-start))
5349 (t (indent-to comment-column))))
5350 (beginning-of-line 2))))))
5352 (defun vhdl-align-noindent-region (beg end &optional spacing no-message)
5353 "Align region without indentation."
5354 (interactive "r\nP")
5361 (setq end (point-marker))
5363 (unless no-message (message "Aligning..."))
5364 (vhdl-fixup-whitespace-region beg end t)
5366 (if (not vhdl-align-groups)
5367 ;; align entire region
5368 (progn (vhdl-align-region beg end spacing)
5369 (vhdl-align-inline-comment-region-1 beg end))
5371 (while (and (< beg end)
5372 (re-search-forward "^\\s-*$" end t))
5373 (setq pos (point-marker))
5374 (vhdl-align-region beg pos spacing)
5375 (vhdl-align-inline-comment-region-1 beg pos)
5380 (vhdl-align-region beg end spacing)
5381 (vhdl-align-inline-comment-region-1 beg end)))))
5382 (unless no-message (message "Aligning...done")))
5384 (defun vhdl-align-group (&optional spacing)
5385 "Align group of lines between empty lines."
5388 (let ((start (point))
5390 (setq end (if (re-search-forward "^\\s-*$" nil t)
5391 (point-marker) (point-max)))
5393 (setq beg (if (re-search-backward "^\\s-*$" nil t) (point) (point-min)))
5395 (message "Aligning...")
5396 (vhdl-fixup-whitespace-region beg end t)
5397 (vhdl-align-region beg end spacing)
5398 (vhdl-align-inline-comment-region-1 beg end)
5399 (message "Aligning...done"))))
5401 (defun vhdl-align-noindent-buffer ()
5402 "Align buffer without indentation."
5404 (vhdl-align-noindent-region (point-min) (point-max)))
5406 (defun vhdl-align-inline-comment-region (beg end &optional spacing no-message)
5407 "Align inline comments within a region. Groups of code lines separated by
5408 empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
5409 (interactive "r\nP")
5416 (setq end (point-marker))
5418 (unless no-message (message "Aligning inline comments..."))
5420 (if (not vhdl-align-groups)
5421 ;; align entire region
5422 (vhdl-align-inline-comment-region-1 beg end spacing)
5424 (while (and (< beg end) (re-search-forward "^\\s-*$" end t))
5425 (setq pos (point-marker))
5426 (vhdl-align-inline-comment-region-1 beg pos spacing)
5431 (vhdl-align-inline-comment-region-1 beg end spacing))))
5432 (unless no-message (message "Aligning inline comments...done"))))
5434 (defun vhdl-align-inline-comment-group (&optional spacing)
5435 "Align inline comments within a group of lines between empty lines."
5438 (let ((start (point))
5440 (setq end (if (re-search-forward "^\\s-*$" nil t)
5441 (point-marker) (point-max)))
5443 (setq beg (if (re-search-backward "^\\s-*$" nil t) (point) (point-min)))
5445 (message "Aligning inline comments...")
5446 (vhdl-align-inline-comment-region-1 beg end)
5447 (message "Aligning inline comments...done"))))
5449 (defun vhdl-align-inline-comment-buffer ()
5450 "Align inline comments within buffer. Groups of code lines separated by
5451 empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
5453 (vhdl-align-inline-comment-region (point-min) (point-max)))
5455 (defun vhdl-fixup-whitespace-region (beg end &optional no-message)
5456 "Fixup whitespace in region. Surround operator symbols by one space,
5457 eliminate multiple spaces (except at beginning of line), eliminate spaces at
5458 end of line, do nothing in comments."
5460 (unless no-message (message "Fixing up whitespace..."))
5463 (setq end (point-marker))
5464 ;; surround operator symbols by one space
5466 (while (re-search-forward "\\([^/:<>=]\\|^\\)\\(--\\|:\\|=\\|<\\|>\\|:=\\|<=\\|>=\\|=>\\)\\([^=>]\\|$\\)"
5468 (if (equal "--" (match-string 2))
5469 (re-search-forward ".*\n" end t)
5470 (replace-match "\\1 \\2 \\3")))
5471 ;; have no space before and one space after `,' and ';'
5473 (while (re-search-forward "\\(--\\|\\s-*\\([,;]\\)\\)" end t)
5474 (if (equal "--" (match-string 1))
5475 (re-search-forward ".*\n" end t)
5476 (replace-match "\\2 " nil nil nil 1)))
5477 ;; eliminate multiple spaces and spaces at end of line
5479 (while (or (and (looking-at "--.*\n") (re-search-forward "--.*\n" end t))
5480 (and (looking-at "\\s-+$") (re-search-forward "\\s-+$" end t)
5481 (progn (replace-match "" nil nil) t))
5482 (and (looking-at "\\s-+;") (re-search-forward "\\s-+;" end t)
5483 (progn (replace-match ";" nil nil) t))
5484 (and (looking-at "^\\s-+") (re-search-forward "^\\s-+" end t))
5485 (and (looking-at "\\s-+--") (re-search-forward "\\s-+" end t)
5486 (progn (replace-match " " nil nil) t ))
5487 (and (looking-at "\\s-+") (re-search-forward "\\s-+" end t)
5488 (progn (replace-match " " nil nil) t ))
5489 (re-search-forward "\\S-+" end t))))
5490 (unless no-message (message "Fixing up whitespace...done")))
5492 (defun vhdl-fixup-whitespace-buffer ()
5493 "Fixup whitespace in buffer. Surround operator symbols by one space,
5494 eliminate multiple spaces (except at beginning of line), eliminate spaces at
5495 end of line, do nothing in comments."
5497 (vhdl-fixup-whitespace-region (point-min) (point-max)))
5499 (defun vhdl-beautify-region (beg end)
5500 "Beautify region by applying indentation, whitespace fixup, alignment, and
5501 case fixing to a resion. Calls functions `vhdl-indent-buffer',
5502 `vhdl-align-noindent-buffer' (variable `vhdl-align-groups' set to non-nil), and
5503 `vhdl-fix-case-buffer'."
5505 (vhdl-indent-region beg end nil)
5506 (let ((vhdl-align-groups t))
5507 (vhdl-align-noindent-region beg end))
5508 (vhdl-fix-case-region beg end))
5510 (defun vhdl-beautify-buffer ()
5511 "Beautify buffer by applying indentation, whitespace fixup, alignment, and
5512 case fixing to entire buffer. Calls `vhdl-beautify-region' for the entire
5515 (vhdl-beautify-region (point-min) (point-max)))
5518 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5520 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5522 (defconst vhdl-template-prompt-syntax "[^ =<>][^<>@.\n]*[^ =<>]"
5523 "Syntax of prompt inserted by template generators.")
5525 (defvar vhdl-template-invoked-by-hook nil
5526 "Indicates whether a template has been invoked by a hook or by key or menu.
5527 Used for undoing after template abortion.")
5529 ;; correct different behavior of function `unread-command-events' in XEmacs
5530 (defalias 'vhdl-character-to-event
5531 (if (string-match "XEmacs" emacs-version) 'character-to-event 'identity))
5533 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5534 ;; Enabling/disabling
5536 (defun vhdl-mode-line-update ()
5537 "Update the modeline string for VHDL major mode."
5538 (setq mode-name (concat "VHDL"
5539 (and (or vhdl-electric-mode vhdl-stutter-mode) "/")
5540 (and vhdl-electric-mode "e")
5541 (and vhdl-stutter-mode "s")))
5542 (force-mode-line-update))
5544 (defun vhdl-electric-mode (arg)
5545 "Toggle VHDL electric mode.
5546 Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil."
5548 (setq vhdl-electric-mode
5549 (cond ((or (not arg) (zerop arg)) (not vhdl-electric-mode))
5550 ((> arg 0) t) (t nil)))
5551 (vhdl-mode-line-update))
5553 (defun vhdl-stutter-mode (arg)
5554 "Toggle VHDL stuttering mode.
5555 Turn on if ARG positive, turn off if ARG negative, toggle if ARG zero or nil."
5557 (setq vhdl-stutter-mode
5558 (cond ((or (not arg) (zerop arg)) (not vhdl-stutter-mode))
5559 ((> arg 0) t) (t nil)))
5560 (vhdl-mode-line-update))
5562 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5565 (defun vhdl-electric-dash (count)
5566 "-- starts a comment, --- draws a horizontal line,
5567 ---- starts a display comment"
5569 (if vhdl-stutter-mode
5571 ((and abbrev-start-location (= abbrev-start-location (point)))
5572 (setq abbrev-start-location nil)
5573 (goto-char last-abbrev-location)
5574 (beginning-of-line nil)
5575 (vhdl-comment-display))
5576 ((/= (preceding-char) ?-) ; standard dash (minus)
5577 (self-insert-command count))
5578 (t (self-insert-command count)
5579 (message "Enter '-' for horiz. line, 'CR' for commenting-out code, else enter comment")
5580 (let ((next-input (read-char)))
5581 (if (= next-input ?-) ; triple dash
5583 (vhdl-comment-display-line)
5585 "Enter '-' for display comment, else continue coding")
5586 (let ((next-input (read-char)))
5587 (if (= next-input ?-) ; four dashes
5588 (vhdl-comment-display t)
5589 (setq unread-command-events ; pushback the char
5590 (list (vhdl-character-to-event next-input))))))
5591 (setq unread-command-events ; pushback the char
5592 (list (vhdl-character-to-event next-input)))
5593 (vhdl-comment-insert)))))
5594 (self-insert-command count)))
5596 (defun vhdl-electric-open-bracket (count) "'[' --> '(', '([' --> '['"
5598 (if (and vhdl-stutter-mode (= count 1))
5599 (if (= (preceding-char) ?\()
5600 (progn (delete-char -1) (insert-char ?\[ 1))
5601 (insert-char ?\( 1))
5602 (self-insert-command count)))
5604 (defun vhdl-electric-close-bracket (count) "']' --> ')', ')]' --> ']'"
5606 (if (and vhdl-stutter-mode (= count 1))
5608 (if (= (preceding-char) ?\))
5609 (progn (delete-char -1) (insert-char ?\] 1))
5610 (insert-char ?\) 1))
5611 (blink-matching-open))
5612 (self-insert-command count)))
5614 (defun vhdl-electric-quote (count) "'' --> \""
5616 (if (and vhdl-stutter-mode (= count 1))
5617 (if (= (preceding-char) last-input-char)
5618 (progn (delete-backward-char 1) (insert-char ?\" 1))
5619 (insert-char ?\' 1))
5620 (self-insert-command count)))
5622 (defun vhdl-electric-semicolon (count) "';;' --> ' : ', ': ;' --> ' := '"
5624 (if (and vhdl-stutter-mode (= count 1))
5625 (cond ((= (preceding-char) last-input-char)
5626 (progn (delete-char -1)
5627 (when (not (eq (preceding-char) ? )) (insert " "))
5629 (setq this-command 'vhdl-electric-colon)))
5631 (eq last-command 'vhdl-electric-colon) (= (preceding-char) ? ))
5632 (progn (delete-char -1) (insert "= ")))
5633 (t (insert-char ?\; 1)))
5634 (self-insert-command count)))
5636 (defun vhdl-electric-comma (count) "',,' --> ' <= '"
5638 (if (and vhdl-stutter-mode (= count 1))
5639 (cond ((= (preceding-char) last-input-char)
5640 (progn (delete-char -1)
5641 (when (not (eq (preceding-char) ? )) (insert " "))
5643 (t (insert-char ?\, 1)))
5644 (self-insert-command count)))
5646 (defun vhdl-electric-period (count) "'..' --> ' => '"
5648 (if (and vhdl-stutter-mode (= count 1))
5649 (cond ((= (preceding-char) last-input-char)
5650 (progn (delete-char -1)
5651 (when (not (eq (preceding-char) ? )) (insert " "))
5653 (t (insert-char ?\. 1)))
5654 (self-insert-command count)))
5656 (defun vhdl-electric-equal (count) "'==' --> ' == '"
5658 (if (and vhdl-stutter-mode (= count 1))
5659 (cond ((= (preceding-char) last-input-char)
5660 (progn (delete-char -1)
5661 (when (not (eq (preceding-char) ? )) (insert " "))
5663 (t (insert-char ?\= 1)))
5664 (self-insert-command count)))
5666 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5669 (defun vhdl-template-paired-parens ()
5670 "Insert a pair of round parentheses, placing point between them."
5675 (defun vhdl-template-alias ()
5676 "Insert alias declaration."
5678 (let ((start (point)))
5679 (vhdl-insert-keyword "ALIAS ")
5680 (when (vhdl-template-field "name" nil t start (point))
5682 (unless (vhdl-template-field
5683 (concat "[type" (and (vhdl-standard-p 'ams) " or nature") "]")
5685 (backward-delete-char 3))
5686 (vhdl-insert-keyword " IS ")
5687 (vhdl-template-field "name" ";")
5688 (vhdl-comment-insert-inline))))
5690 (defun vhdl-template-architecture ()
5691 "Insert architecture."
5693 (let ((margin (current-indentation))
5695 arch-name entity-exists string
5696 (case-fold-search t))
5697 (vhdl-insert-keyword "ARCHITECTURE ")
5698 (when (setq arch-name
5699 (vhdl-template-field "name" nil t start (point)))
5700 (vhdl-insert-keyword " OF ")
5702 (vhdl-ext-syntax-table
5703 (setq entity-exists (re-search-backward
5704 "\\<entity \\(\\w+\\) is\\>" nil t))
5705 (setq string (match-string 1))))
5706 (if (and entity-exists (not (equal string "")))
5708 (vhdl-template-field "entity name"))
5709 (vhdl-insert-keyword " IS")
5710 (vhdl-template-begin-end
5711 (unless (vhdl-standard-p '87) "ARCHITECTURE") arch-name margin
5712 (memq vhdl-insert-empty-lines '(unit all))))))
5714 (defun vhdl-template-array (kind &optional secondary)
5715 "Insert array type definition."
5717 (let ((start (point)))
5718 (vhdl-insert-keyword "ARRAY (")
5719 (when (or (vhdl-template-field "range" nil (not secondary) start (point))
5721 (vhdl-insert-keyword ") OF ")
5722 (vhdl-template-field (if (eq kind 'type) "type" "nature"))
5723 (vhdl-insert-keyword ";"))))
5725 (defun vhdl-template-assert ()
5726 "Insert an assertion statement."
5728 (let ((start (point)))
5729 (vhdl-insert-keyword "ASSERT ")
5730 (when vhdl-conditions-in-parenthesis (insert "("))
5731 (when (vhdl-template-field "condition (negated)" nil t start (point))
5732 (when vhdl-conditions-in-parenthesis (insert ")"))
5733 (setq start (point))
5734 (vhdl-insert-keyword " REPORT ")
5735 (unless (vhdl-template-field "string expression" nil nil nil nil t)
5736 (delete-region start (point)))
5737 (setq start (point))
5738 (vhdl-insert-keyword " SEVERITY ")
5739 (unless (vhdl-template-field "[NOTE | WARNING | ERROR | FAILURE]" nil t)
5740 (delete-region start (point)))
5743 (defun vhdl-template-attribute ()
5744 "Insert an attribute declaration or specification."
5746 (if (eq (vhdl-decision-query
5747 "attribute" "(d)eclaration or (s)pecification?" t) ?s)
5748 (vhdl-template-attribute-spec)
5749 (vhdl-template-attribute-decl)))
5751 (defun vhdl-template-attribute-decl ()
5752 "Insert an attribute declaration."
5754 (let ((start (point)))
5755 (vhdl-insert-keyword "ATTRIBUTE ")
5756 (when (vhdl-template-field "name" " : " t start (point))
5757 (vhdl-template-field "type" ";")
5758 (vhdl-comment-insert-inline))))
5760 (defun vhdl-template-attribute-spec ()
5761 "Insert an attribute specification."
5763 (let ((start (point)))
5764 (vhdl-insert-keyword "ATTRIBUTE ")
5765 (when (vhdl-template-field "name" nil t start (point))
5766 (vhdl-insert-keyword " OF ")
5767 (vhdl-template-field "entity names | OTHERS | ALL" " : ")
5768 (vhdl-template-field "entity class")
5769 (vhdl-insert-keyword " IS ")
5770 (vhdl-template-field "expression" ";"))))
5772 (defun vhdl-template-block ()
5775 (let ((margin (current-indentation))
5778 (vhdl-insert-keyword ": BLOCK ")
5780 (when (setq label (vhdl-template-field "label" nil t start (+ (point) 8)))
5784 (if (vhdl-template-field "[guard expression]" nil t)
5787 (unless (vhdl-standard-p '87) (vhdl-insert-keyword " IS"))
5788 (vhdl-template-begin-end "BLOCK" label margin)
5789 (vhdl-comment-block))))
5791 (defun vhdl-template-block-configuration ()
5792 "Insert a block configuration statement."
5794 (let ((margin (current-indentation))
5796 (vhdl-insert-keyword "FOR ")
5797 (when (vhdl-template-field "block name" nil t start (point))
5798 (vhdl-insert-keyword "\n\n")
5800 (vhdl-insert-keyword "END FOR;")
5802 (indent-to (+ margin vhdl-basic-offset)))))
5804 (defun vhdl-template-break ()
5805 "Insert a break statement."
5808 (vhdl-insert-keyword "BREAK")
5809 (setq position (point))
5812 (progn (vhdl-insert-keyword "FOR ")
5813 (if (vhdl-template-field "[quantity name]" " USE " t)
5814 (progn (vhdl-template-field "quantity name" " => ") t)
5815 (kill-word -1) nil))
5816 (vhdl-template-field "[quantity name]" " => " t))
5817 (vhdl-template-field "expression")
5818 (setq position (point))
5820 (delete-region position (point))
5821 (unless (vhdl-sequential-statement-p)
5822 (vhdl-insert-keyword " ON ")
5823 (if (vhdl-template-field "[sensitivity list]" nil t)
5824 (setq position (point))
5825 (delete-region position (point))))
5826 (vhdl-insert-keyword " WHEN ")
5827 (when vhdl-conditions-in-parenthesis (insert "("))
5828 (if (vhdl-template-field "[condition]" nil t)
5829 (when vhdl-conditions-in-parenthesis (insert ")"))
5830 (delete-region position (point)))
5833 (defun vhdl-template-case (&optional kind)
5834 "Insert a case statement."
5836 (let ((margin (current-indentation))
5839 (unless kind (setq kind (if (vhdl-sequential-statement-p) 'is 'use)))
5840 (if (or (not (eq vhdl-optional-labels 'all)) (vhdl-standard-p '87))
5841 (vhdl-insert-keyword "CASE ")
5842 (vhdl-insert-keyword ": CASE ")
5844 (setq label (vhdl-template-field "[label]" nil t))
5845 (unless label (delete-char 2))
5848 (when (vhdl-template-field "expression" nil t start (point))
5849 (vhdl-insert-keyword (concat " " (if (eq kind 'is) "IS" "USE") "\n\n"))
5851 (vhdl-insert-keyword "END CASE")
5852 (when label (insert " " label))
5855 (indent-to (+ margin vhdl-basic-offset))
5856 (vhdl-insert-keyword "WHEN ")
5857 (let ((position (point)))
5859 (indent-to (+ margin vhdl-basic-offset))
5860 (vhdl-insert-keyword "WHEN OTHERS => null;")
5861 (goto-char position)))))
5863 (defun vhdl-template-case-is ()
5864 "Insert a sequential case statement."
5866 (vhdl-template-case 'is))
5868 (defun vhdl-template-case-use ()
5869 "Insert a simultaneous case statement."
5871 (vhdl-template-case 'use))
5873 (defun vhdl-template-component ()
5874 "Insert a component declaration."
5876 (vhdl-template-component-decl))
5878 (defun vhdl-template-component-conf ()
5879 "Insert a component configuration (uses `vhdl-template-configuration-spec'
5880 since these are almost equivalent)."
5882 (let ((margin (current-indentation))
5883 (result (vhdl-template-configuration-spec t)))
5887 (vhdl-insert-keyword "END FOR;")
5888 (when (eq result 'no-use)
5889 (end-of-line -0)))))
5891 (defun vhdl-template-component-decl ()
5892 "Insert a component declaration."
5894 (let ((margin (current-indentation))
5897 (vhdl-insert-keyword "COMPONENT ")
5898 (when (setq name (vhdl-template-field "name" nil t start (point)))
5901 (vhdl-insert-keyword "END COMPONENT")
5902 (unless (vhdl-standard-p '87) (insert " " name))
5904 (setq end-column (current-column))
5906 (indent-to (+ margin vhdl-basic-offset))
5907 (vhdl-template-generic-list t t)
5909 (indent-to (+ margin vhdl-basic-offset))
5910 (vhdl-template-port-list t)
5911 (beginning-of-line 2)
5912 (forward-char end-column))))
5914 (defun vhdl-template-component-inst ()
5915 "Insert a component instantiation statement."
5917 (let ((margin (current-indentation))
5920 (when (vhdl-template-field "instance label" nil t start (point))
5922 (if (vhdl-standard-p '87)
5923 (vhdl-template-field "component name")
5924 ;; direct instantiation
5925 (setq unit (vhdl-template-field
5926 "[COMPONENT | ENTITY | CONFIGURATION]" " " t))
5927 (setq unit (upcase (or unit "")))
5928 (cond ((equal unit "ENTITY")
5929 (vhdl-template-field "library name" "." nil nil nil nil "work")
5930 (vhdl-template-field "entity name" "(")
5931 (if (vhdl-template-field "[architecture name]" nil t)
5934 ((equal unit "CONFIGURATION")
5935 (vhdl-template-field "library name" "." nil nil nil nil "work")
5936 (vhdl-template-field "configuration name"))
5937 (t (vhdl-template-field "component name"))))
5939 (indent-to (+ margin vhdl-basic-offset))
5940 (setq position (point))
5941 (vhdl-insert-keyword "GENERIC ")
5942 (when (vhdl-template-map position t t)
5944 (indent-to (+ margin vhdl-basic-offset)))
5945 (setq position (point))
5946 (vhdl-insert-keyword "PORT ")
5947 (unless (vhdl-template-map position t t)
5952 (defun vhdl-template-conditional-signal-asst ()
5953 "Insert a conditional signal assignment."
5955 (when (vhdl-template-field "target signal")
5957 ; (if (not (equal (vhdl-template-field "[GUARDED] [TRANSPORT]") ""))
5959 (let ((margin (current-column))
5962 (vhdl-template-field "waveform")
5963 (setq position (point))
5964 (vhdl-insert-keyword " WHEN ")
5965 (when vhdl-conditions-in-parenthesis (insert "("))
5966 (while (and (vhdl-template-field "[condition]" nil t)
5968 (when vhdl-conditions-in-parenthesis (insert ")"))
5969 (setq position (point))
5970 (vhdl-insert-keyword " ELSE")
5973 (vhdl-template-field "[waveform]" nil t)))
5974 (setq position (point))
5975 (vhdl-insert-keyword " WHEN ")
5976 (when vhdl-conditions-in-parenthesis (insert "(")))
5977 (delete-region position (point))
5979 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)))))
5981 (defun vhdl-template-configuration ()
5982 "Insert a configuration specification if within an architecture,
5983 a block or component configuration if within a configuration declaration,
5984 a configuration declaration if not within a design unit."
5986 (let ((case-fold-search t))
5987 (vhdl-ext-syntax-table
5989 ((and (save-excursion ; architecture body
5990 (re-search-backward "^\\(architecture\\|end\\)\\>" nil t))
5991 (equal "ARCHITECTURE" (upcase (match-string 1))))
5992 (vhdl-template-configuration-spec))
5993 ((and (save-excursion ; configuration declaration
5994 (re-search-backward "^\\(configuration\\|end\\)\\>" nil t))
5995 (equal "CONFIGURATION" (upcase (match-string 1))))
5996 (if (eq (vhdl-decision-query
5997 "configuration" "(b)lock or (c)omponent configuration?" t) ?c)
5998 (vhdl-template-component-conf)
5999 (vhdl-template-block-configuration)))
6000 (t (vhdl-template-configuration-decl)))))) ; otherwise
6002 (defun vhdl-template-configuration-spec (&optional optional-use)
6003 "Insert a configuration specification."
6005 (let ((margin (current-indentation))
6008 (vhdl-insert-keyword "FOR ")
6009 (when (vhdl-template-field "component names | OTHERS | ALL" " : "
6011 (vhdl-template-field "component type" "\n")
6012 (indent-to (+ margin vhdl-basic-offset))
6013 (setq start (point))
6014 (vhdl-insert-keyword "USE ")
6015 (if (and optional-use
6016 (not (setq aspect (vhdl-template-field
6017 "[ENTITY | CONFIGURATION | OPEN]" " " t))))
6018 (progn (delete-region start (point)) 'no-use)
6019 (unless optional-use
6020 (setq aspect (vhdl-template-field
6021 "ENTITY | CONFIGURATION | OPEN" " ")))
6022 (setq aspect (upcase (or aspect "")))
6023 (cond ((equal aspect "ENTITY")
6024 (vhdl-template-field "library name" "." nil nil nil nil "work")
6025 (vhdl-template-field "entity name" "(")
6026 (if (vhdl-template-field "[architecture name]" nil t)
6030 (indent-to (+ margin (* 2 vhdl-basic-offset)))
6031 (setq position (point))
6032 (vhdl-insert-keyword "GENERIC ")
6033 (when (vhdl-template-map position t t)
6035 (indent-to (+ margin (* 2 vhdl-basic-offset))))
6036 (setq position (point))
6037 (vhdl-insert-keyword "PORT ")
6038 (unless (vhdl-template-map position t t)
6043 ((equal aspect "CONFIGURATION")
6044 (vhdl-template-field "library name" "." nil nil nil nil "work")
6045 (vhdl-template-field "configuration name" ";"))
6046 (t (backward-delete-char 1) (insert ";") t))))))
6049 (defun vhdl-template-configuration-decl ()
6050 "Insert a configuration declaration."
6052 (let ((margin (current-indentation))
6054 (case-fold-search t)
6055 entity-exists string name position)
6056 (vhdl-insert-keyword "CONFIGURATION ")
6057 (when (setq name (vhdl-template-field "name" nil t start (point)))
6058 (vhdl-insert-keyword " OF ")
6060 (vhdl-ext-syntax-table
6061 (setq entity-exists (re-search-backward
6062 "\\<entity \\(\\w*\\) is\\>" nil t))
6063 (setq string (match-string 1))))
6064 (if (and entity-exists (not (equal string "")))
6066 (vhdl-template-field "entity name"))
6067 (vhdl-insert-keyword " IS\n")
6068 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
6069 (indent-to (+ margin vhdl-basic-offset))
6070 (setq position (point))
6072 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
6074 (vhdl-insert-keyword "END ")
6075 (unless (vhdl-standard-p '87)
6076 (vhdl-insert-keyword "CONFIGURATION "))
6078 (goto-char position))))
6080 (defun vhdl-template-constant ()
6081 "Insert a constant declaration."
6083 (let ((start (point))
6084 (in-arglist (vhdl-in-argument-list-p)))
6085 (vhdl-insert-keyword "CONSTANT ")
6086 (when (vhdl-template-field "name" nil t start (point))
6088 (when in-arglist (vhdl-insert-keyword "IN "))
6089 (vhdl-template-field "type")
6092 (vhdl-comment-insert-inline))
6093 (let ((position (point)))
6095 (unless (vhdl-template-field "[initialization]" nil t)
6096 (delete-region position (point)))
6098 (vhdl-comment-insert-inline))))))
6100 (defun vhdl-template-default ()
6109 (defun vhdl-template-default-indent ()
6110 "Insert nothing and indent."
6119 (defun vhdl-template-disconnect ()
6120 "Insert a disconnect statement."
6122 (let ((start (point)))
6123 (vhdl-insert-keyword "DISCONNECT ")
6124 (when (vhdl-template-field "signal names | OTHERS | ALL"
6125 " : " t start (point))
6126 (vhdl-template-field "type")
6127 (vhdl-insert-keyword " AFTER ")
6128 (vhdl-template-field "time expression" ";"))))
6130 (defun vhdl-template-else ()
6131 "Insert an else statement."
6133 (let ((case-fold-search t)
6135 (vhdl-ext-syntax-table
6136 (vhdl-insert-keyword "ELSE")
6138 (re-search-backward "\\(\\<when\\>\\|;\\)" nil t)
6139 (equal "WHEN" (upcase (match-string 1))))
6142 (setq margin (current-indentation))
6144 (indent-to (+ margin vhdl-basic-offset))))))
6146 (defun vhdl-template-elsif ()
6147 "Insert an elsif statement."
6149 (let ((start (point))
6151 (vhdl-insert-keyword "ELSIF ")
6152 (when vhdl-conditions-in-parenthesis (insert "("))
6153 (when (vhdl-template-field "condition" nil t start (point))
6154 (when vhdl-conditions-in-parenthesis (insert ")"))
6156 (setq margin (current-indentation))
6157 (vhdl-insert-keyword
6158 (concat " " (if (vhdl-sequential-statement-p) "THEN" "USE") "\n"))
6159 (indent-to (+ margin vhdl-basic-offset)))))
6161 (defun vhdl-template-entity ()
6164 (let ((margin (current-indentation))
6167 (vhdl-insert-keyword "ENTITY ")
6168 (when (setq name (vhdl-template-field "name" nil t start (point)))
6169 (vhdl-insert-keyword " IS\n\n")
6171 (vhdl-insert-keyword "END ")
6172 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ENTITY "))
6174 (setq end-column (current-column))
6176 (indent-to (+ margin vhdl-basic-offset))
6177 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
6178 (indent-to (+ margin vhdl-basic-offset))
6179 (when (vhdl-template-generic-list t)
6180 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")))
6182 (indent-to (+ margin vhdl-basic-offset))
6183 (when (vhdl-template-port-list t)
6184 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")))
6185 (beginning-of-line 2)
6186 (forward-char end-column))))
6188 (defun vhdl-template-exit ()
6189 "Insert an exit statement."
6191 (let ((start (point)))
6192 (vhdl-insert-keyword "EXIT ")
6193 (unless (vhdl-template-field "[loop label]" nil t)
6195 (let ((position (point)))
6196 (vhdl-insert-keyword " WHEN ")
6197 (when vhdl-conditions-in-parenthesis (insert "("))
6198 (if (vhdl-template-field "[condition]" nil t)
6199 (when vhdl-conditions-in-parenthesis (insert ")"))
6200 (delete-region position (point))))
6203 (defun vhdl-template-file ()
6204 "Insert a file declaration."
6206 (let ((start (point)))
6207 (vhdl-insert-keyword "FILE ")
6208 (when (vhdl-template-field "name" nil t start (point))
6210 (vhdl-template-field "type")
6211 (unless (vhdl-standard-p '87)
6212 (vhdl-insert-keyword " OPEN ")
6213 (unless (vhdl-template-field "[READ_MODE | WRITE_MODE | APPEND_MODE]"
6215 (backward-delete-char 6)))
6216 (vhdl-insert-keyword " IS ")
6217 (when (vhdl-standard-p '87)
6218 (vhdl-template-field "[IN | OUT]" " " t))
6219 (vhdl-template-field "filename-string" nil nil nil nil t)
6221 (vhdl-comment-insert-inline))))
6223 (defun vhdl-template-for ()
6224 "Insert a block or component configuration if within a configuration
6225 declaration, a configuration specification if within an architecture
6226 declarative part (and not within a subprogram), and a for-loop otherwise."
6228 (let ((case-fold-search t))
6229 (vhdl-ext-syntax-table
6231 ((and (save-excursion ; configuration declaration
6232 (re-search-backward "^\\(configuration\\|end\\)\\>" nil t))
6233 (equal "CONFIGURATION" (upcase (match-string 1))))
6234 (if (eq (vhdl-decision-query
6235 "for" "(b)lock or (c)omponent configuration?" t) ?c)
6236 (vhdl-template-component-conf)
6237 (vhdl-template-block-configuration)))
6238 ((and (save-excursion
6239 (re-search-backward ; architecture declarative part
6240 "^\\(architecture\\|entity\\|begin\\|end\\)\\>" nil t))
6241 (equal "ARCHITECTURE" (upcase (match-string 1)))
6242 (not (and (save-excursion ; not subprogram
6244 "^\\s-*\\(architecture\\|begin\\|end\\)\\>" nil t))
6245 (equal "BEGIN" (upcase (match-string 1)))
6248 "^\\s-*\\(function\\|procedure\\)\\>" nil t)))))
6249 (vhdl-template-configuration-spec))
6250 ((vhdl-sequential-statement-p) ; sequential statement
6251 (vhdl-template-for-loop))
6252 (t (vhdl-template-for-generate)))))) ; concurrent statement
6254 (defun vhdl-template-for-generate ()
6255 "Insert a for-generate."
6257 (let ((margin (current-indentation))
6259 label string position)
6260 (vhdl-insert-keyword ": FOR ")
6261 (setq position (point-marker))
6263 (when (setq label (vhdl-template-field "label" nil t start position))
6264 (goto-char position)
6265 (vhdl-template-field "loop variable")
6266 (vhdl-insert-keyword " IN ")
6267 (vhdl-template-field "range")
6268 (vhdl-template-generate-body margin label))))
6270 (defun vhdl-template-for-loop ()
6271 "Insert a for loop."
6273 (let ((margin (current-indentation))
6276 (if (not (eq vhdl-optional-labels 'all))
6277 (vhdl-insert-keyword "FOR ")
6278 (vhdl-insert-keyword ": FOR ")
6280 (setq label (vhdl-template-field "[label]" nil t))
6281 (unless label (delete-char 2))
6284 (when (setq index (vhdl-template-field "loop variable"
6285 nil t start (point)))
6286 (vhdl-insert-keyword " IN ")
6287 (vhdl-template-field "range")
6288 (vhdl-insert-keyword " LOOP\n\n")
6290 (vhdl-insert-keyword "END LOOP")
6292 (insert " " label ";")
6294 (when vhdl-self-insert-comments (insert " -- " index)))
6296 (indent-to (+ margin vhdl-basic-offset)))))
6298 (defun vhdl-template-footer ()
6299 "Insert a VHDL file footer."
6301 (unless (equal vhdl-file-footer "")
6303 (goto-char (point-max))
6305 (vhdl-insert-string-or-file vhdl-file-footer))))
6307 (defun vhdl-template-function (&optional kind)
6308 "Insert a function declaration or body."
6310 (let ((margin (current-indentation))
6313 (vhdl-insert-keyword "FUNCTION ")
6314 (when (setq name (vhdl-template-field "name" nil t start (point)))
6315 (vhdl-template-argument-list t)
6316 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))
6319 (indent-to (+ margin vhdl-basic-offset))
6320 (vhdl-insert-keyword "RETURN ")
6321 (vhdl-template-field "type")
6322 (if (if kind (eq kind 'body)
6323 (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b))
6324 (progn (vhdl-insert-keyword " IS")
6325 (vhdl-template-begin-end
6326 (unless (vhdl-standard-p '87) "FUNCTION") name margin)
6327 (vhdl-comment-block))
6330 (defun vhdl-template-function-decl ()
6331 "Insert a function declaration."
6333 (vhdl-template-function 'decl))
6335 (defun vhdl-template-function-body ()
6336 "Insert a function declaration."
6338 (vhdl-template-function 'body))
6340 (defun vhdl-template-generate ()
6341 "Insert a generation scheme."
6343 (if (eq (vhdl-decision-query nil "(f)or or (i)f?" t) ?i)
6344 (vhdl-template-if-generate)
6345 (vhdl-template-for-generate)))
6347 (defun vhdl-template-generic ()
6348 "Insert generic declaration, or generic map in instantiation statements."
6350 (let ((start (point))
6351 (case-fold-search t))
6352 (vhdl-ext-syntax-table
6354 ((and (save-excursion ; entity declaration
6355 (re-search-backward "^\\(entity\\|end\\)\\>" nil t))
6356 (equal "ENTITY" (upcase (match-string 1))))
6357 (vhdl-template-generic-list nil))
6358 ((or (save-excursion
6359 (or (beginning-of-line)
6360 (looking-at "^\\s-*\\w+\\s-*:\\s-*\\w+")))
6361 (equal 'statement-cont (car (car (vhdl-get-syntactic-context)))))
6362 (vhdl-insert-keyword "GENERIC ")
6363 (vhdl-template-map start))
6364 (t (vhdl-template-generic-list nil t))))))
6366 (defun vhdl-template-group ()
6367 "Insert group or group template declaration."
6369 (let ((start (point)))
6370 (if (eq (vhdl-decision-query
6371 "group" "(d)eclaration or (t)emplate declaration?" t) ?t)
6372 (vhdl-template-group-template)
6373 (vhdl-template-group-decl))))
6375 (defun vhdl-template-group-decl ()
6376 "Insert group declaration."
6378 (let ((start (point)))
6379 (vhdl-insert-keyword "GROUP ")
6380 (when (vhdl-template-field "name" " : " t start (point))
6381 (vhdl-template-field "template name" " (")
6382 (vhdl-template-field "constituent list" ");")
6383 (vhdl-comment-insert-inline))))
6385 (defun vhdl-template-group-template ()
6386 "Insert group template declaration."
6388 (let ((start (point)))
6389 (vhdl-insert-keyword "GROUP ")
6390 (when (vhdl-template-field "template name" nil t start (point))
6391 (vhdl-insert-keyword " IS (")
6392 (vhdl-template-field "entity class list" ");")
6393 (vhdl-comment-insert-inline))))
6395 (defun vhdl-template-header ()
6396 "Insert a VHDL file header."
6398 (unless (equal vhdl-file-header "")
6399 (let ((case-fold-search t)
6400 (project-name (or (nth 0 (aget vhdl-project-alist vhdl-project)) ""))
6401 (project-desc (or (nth 2 (aget vhdl-project-alist vhdl-project)) ""))
6403 (vhdl-ext-syntax-table
6407 (goto-char (point-min))
6408 (vhdl-insert-string-or-file vhdl-file-header)
6410 (narrow-to-region (point-min) eot)
6411 (goto-char (point-min))
6412 (while (search-forward "<projectdesc>" nil t)
6413 (replace-match project-desc t t))
6414 (goto-char (point-min))
6415 (while (search-forward "<filename>" nil t)
6416 (replace-match (buffer-name) t t))
6417 (goto-char (point-min))
6418 (while (search-forward "<author>" nil t)
6419 (replace-match "" t t)
6420 (insert (user-full-name))
6421 (when user-mail-address (insert " <" user-mail-address ">")))
6422 (goto-char (point-min))
6423 (while (search-forward "<login>" nil t)
6424 (replace-match (user-login-name) t t))
6425 (goto-char (point-min))
6426 (while (search-forward "<project>" nil t)
6427 (replace-match project-name t t))
6428 (goto-char (point-min))
6429 (while (search-forward "<company>" nil t)
6430 (replace-match vhdl-company-name t t))
6431 (goto-char (point-min))
6432 (while (search-forward "<platform>" nil t)
6433 (replace-match vhdl-platform-spec t t))
6434 (goto-char (point-min))
6435 ;; Replace <RCS> with $, so that RCS for the source is
6436 ;; not over-enthusiastic with replacements
6437 (while (search-forward "<RCS>" nil t)
6438 (replace-match "$" nil t))
6439 (goto-char (point-min))
6440 (while (search-forward "<date>" nil t)
6441 (replace-match "" t t)
6442 (vhdl-template-insert-date))
6443 (goto-char (point-min))
6446 (re-search-forward "<\\(\\(\\w\\|\\s_\\)*\\) string>" nil t)
6447 (setq string (read-string (concat (match-string 1) ": ")))
6448 (replace-match string t t)))))
6449 (goto-char (point-min))
6450 (when (search-forward "<cursor>" nil t)
6451 (replace-match "" t t))
6452 (when (or (not project-name) (equal project-name ""))
6453 (message "You can specify a project title in custom variable `vhdl-project-alist'"))
6454 (when (or (not project-desc) (equal project-desc ""))
6455 (message "You can specify a project description in custom variable `vhdl-project-alist'"))
6456 (when (equal vhdl-company-name "")
6457 (message "You can specify a company name in custom variable `vhdl-company-name'"))
6458 (when (equal vhdl-platform-spec "")
6459 (message "You can specify a platform in custom variable `vhdl-platform-spec'"))))))
6461 (defun vhdl-template-if ()
6462 "Insert a sequential if statement or an if-generate statement."
6464 (if (vhdl-sequential-statement-p)
6465 (vhdl-template-if-then)
6466 (if (and (vhdl-standard-p 'ams)
6467 (eq (vhdl-decision-query "if" "(g)enerate or (u)se?" t) ?u))
6468 (vhdl-template-if-use)
6469 (vhdl-template-if-generate))))
6471 (defun vhdl-template-if-generate ()
6472 "Insert an if-generate."
6474 (let ((margin (current-indentation))
6476 label string position)
6477 (vhdl-insert-keyword ": IF ")
6478 (setq position (point-marker))
6480 (when (setq label (vhdl-template-field "label" nil t start position))
6481 (goto-char position)
6482 (when vhdl-conditions-in-parenthesis (insert "("))
6483 (vhdl-template-field "condition")
6484 (when vhdl-conditions-in-parenthesis (insert ")"))
6485 (vhdl-template-generate-body margin label))))
6487 (defun vhdl-template-if-then-use (kind)
6488 "Insert a sequential if statement."
6490 (let ((margin (current-indentation))
6493 (if (or (not (eq vhdl-optional-labels 'all)) (vhdl-standard-p '87))
6494 (vhdl-insert-keyword "IF ")
6495 (vhdl-insert-keyword ": IF ")
6497 (setq label (vhdl-template-field "[label]" nil t))
6498 (unless label (delete-char 2))
6501 (when vhdl-conditions-in-parenthesis (insert "("))
6502 (when (vhdl-template-field "condition" nil t start (point))
6503 (when vhdl-conditions-in-parenthesis (insert ")"))
6504 (vhdl-insert-keyword
6505 (concat " " (if (eq kind 'then) "THEN" "USE") "\n\n"))
6507 (vhdl-insert-keyword "END IF")
6508 (when label (insert " " label))
6511 (indent-to (+ margin vhdl-basic-offset)))))
6513 (defun vhdl-template-if-then ()
6514 "Insert a sequential if statement."
6516 (vhdl-template-if-then-use 'then))
6518 (defun vhdl-template-if-use ()
6519 "Insert a simultaneous if statement."
6521 (vhdl-template-if-then-use 'use))
6523 (defun vhdl-template-instance ()
6524 "Insert a component instantiation statement."
6526 (vhdl-template-component-inst))
6528 (defun vhdl-template-library ()
6529 "Insert a library specification."
6531 (let ((margin (current-indentation))
6534 (vhdl-insert-keyword "LIBRARY ")
6535 (when (setq name (vhdl-template-field "names" nil t start (point)))
6537 (unless (string-match "," name)
6538 (setq end-pos (point))
6541 (vhdl-insert-keyword "USE ")
6543 (vhdl-insert-keyword "..ALL;")
6545 (if (vhdl-template-field "package name")
6547 (delete-region end-pos (+ (point) 5)))))))
6549 (defun vhdl-template-limit ()
6552 (let ((start (point)))
6553 (vhdl-insert-keyword "LIMIT ")
6554 (when (vhdl-template-field "quantity names | OTHERS | ALL" " : "
6556 (vhdl-template-field "type")
6557 (vhdl-insert-keyword " WITH ")
6558 (vhdl-template-field "real expression" ";"))))
6560 (defun vhdl-template-loop ()
6563 (let ((char (vhdl-decision-query nil "(w)hile, (f)or, or (b)are?" t)))
6565 (vhdl-template-while-loop))
6567 (vhdl-template-for-loop))
6568 (t (vhdl-template-bare-loop)))))
6570 (defun vhdl-template-bare-loop ()
6573 (let ((margin (current-indentation))
6576 (if (not (eq vhdl-optional-labels 'all))
6577 (vhdl-insert-keyword "LOOP ")
6578 (vhdl-insert-keyword ": LOOP ")
6580 (setq label (vhdl-template-field "[label]" nil t))
6581 (unless label (delete-char 2))
6586 (vhdl-insert-keyword "END LOOP")
6587 (insert (if label (concat " " label ";") ";"))
6589 (indent-to (+ margin vhdl-basic-offset))))
6591 (defun vhdl-template-map (&optional start optional secondary)
6592 "Insert a map specification with association list."
6594 (let ((start (or start (point)))
6596 (vhdl-insert-keyword "MAP (")
6597 (if (not vhdl-association-list-with-formals)
6598 (if (vhdl-template-field
6599 (concat (and optional "[") "association list" (and optional "]"))
6600 ")" (or (not secondary) optional)
6601 (and (not secondary) start) (point))
6603 (if (and optional secondary) (delete-region start (point)))
6605 (if vhdl-argument-list-indent
6606 (setq margin (current-column))
6607 (setq margin (+ (current-indentation) vhdl-basic-offset))
6610 (if (vhdl-template-field
6611 (concat (and optional "[") "formal" (and optional "]"))
6612 " => " (or (not secondary) optional)
6613 (and (not secondary) start) (point))
6615 (vhdl-template-field "actual" ",")
6616 (setq end-pos (point))
6619 (while (vhdl-template-field "[formal]" " => " t)
6620 (vhdl-template-field "actual" ",")
6621 (setq end-pos (point))
6624 (delete-region end-pos (point))
6625 (backward-delete-char 1)
6627 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))
6629 (when (and optional secondary) (delete-region start (point)))
6632 (defun vhdl-template-modify (&optional noerror)
6633 "Actualize modification date."
6635 (let ((case-fold-search t))
6636 (vhdl-ext-syntax-table
6638 (goto-char (point-min))
6639 (if (re-search-forward vhdl-modify-date-prefix-string nil t)
6641 (vhdl-template-insert-date))
6643 (error (concat "Modification date prefix string \""
6644 vhdl-modify-date-prefix-string "\" not found"))))))))
6646 (defun vhdl-template-modify-noerror ()
6647 "Call `vhdl-template-modify' with NOERROR non-nil."
6648 (vhdl-template-modify t))
6650 (defun vhdl-template-nature ()
6651 "Insert a nature declaration."
6653 (let ((start (point))
6654 name mid-pos end-pos)
6655 (vhdl-insert-keyword "NATURE ")
6656 (when (setq name (vhdl-template-field "name" nil t start (point)))
6657 (vhdl-insert-keyword " IS ")
6660 (or (vhdl-template-field
6661 "across type | ARRAY | RECORD")
6663 (cond ((equal definition "")
6665 ((equal definition "ARRAY")
6667 (vhdl-template-array 'nature t))
6668 ((equal definition "RECORD")
6669 (setq mid-pos (point-marker))
6671 (vhdl-template-record 'nature name t))
6673 (vhdl-insert-keyword " ACROSS ")
6674 (vhdl-template-field "through type")
6675 (vhdl-insert-keyword " THROUGH ")
6676 (vhdl-template-field "reference name")
6677 (vhdl-insert-keyword " REFERENCE;")))
6679 (setq end-pos (point-marker))
6682 (vhdl-comment-insert-inline)
6683 (when end-pos (goto-char end-pos))))))
6685 (defun vhdl-template-next ()
6686 "Insert a next statement."
6688 (vhdl-insert-keyword "NEXT ")
6689 (unless (vhdl-template-field "[loop label]" nil t)
6691 (let ((position (point)))
6692 (vhdl-insert-keyword " WHEN ")
6693 (when vhdl-conditions-in-parenthesis (insert "("))
6694 (if (vhdl-template-field "[condition]" nil t)
6695 (when vhdl-conditions-in-parenthesis (insert ")"))
6696 (delete-region position (point)))
6699 (defun vhdl-template-others ()
6700 "Insert an others aggregate."
6702 (vhdl-insert-keyword "(OTHERS => '')")
6705 (defun vhdl-template-package (&optional kind)
6706 "Insert a package specification or body."
6708 (let ((margin (current-indentation))
6711 (vhdl-insert-keyword "PACKAGE ")
6712 (setq body (if kind (eq kind 'body)
6713 (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b)))
6714 (when body (vhdl-insert-keyword "BODY "))
6715 (when (setq name (vhdl-template-field "name" nil t start (point)))
6716 (vhdl-insert-keyword " IS\n")
6717 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
6718 (indent-to (+ margin vhdl-basic-offset))
6719 (setq position (point))
6721 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
6723 (vhdl-insert-keyword "END ")
6724 (unless (vhdl-standard-p '87)
6725 (vhdl-insert-keyword (concat "PACKAGE " (and body "BODY "))))
6726 (insert (or name "") ";")
6727 (goto-char position))))
6729 (defun vhdl-template-package-decl ()
6730 "Insert a package specification."
6732 (vhdl-template-package 'decl))
6734 (defun vhdl-template-package-body ()
6735 "Insert a package body."
6737 (vhdl-template-package 'body))
6739 (defun vhdl-template-port ()
6740 "Insert a port declaration, or port map in instantiation statements."
6742 (let ((start (point))
6743 (case-fold-search t))
6744 (vhdl-ext-syntax-table
6746 ((and (save-excursion ; entity declaration
6747 (re-search-backward "^\\(entity\\|end\\)\\>" nil t))
6748 (equal "ENTITY" (upcase (match-string 1))))
6749 (vhdl-template-port-list nil))
6750 ((or (save-excursion
6751 (or (beginning-of-line)
6752 (looking-at "^\\s-*\\w+\\s-*:\\s-*\\w+")))
6753 (equal 'statement-cont (car (car (vhdl-get-syntactic-context)))))
6754 (vhdl-insert-keyword "PORT ")
6755 (vhdl-template-map start))
6756 (t (vhdl-template-port-list nil))))))
6758 (defun vhdl-template-procedural ()
6759 "Insert a procedural."
6761 (let ((margin (current-indentation))
6763 (case-fold-search t)
6765 (vhdl-insert-keyword "PROCEDURAL ")
6766 (when (memq vhdl-optional-labels '(process all))
6770 (setq label (vhdl-template-field "[label]" nil t))
6771 (unless label (delete-char 2))
6774 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "IS"))
6775 (vhdl-template-begin-end "PROCEDURAL" label margin)
6776 (vhdl-comment-block)))
6778 (defun vhdl-template-procedure (&optional kind)
6779 "Insert a procedure declaration or body."
6781 (let ((margin (current-indentation))
6784 (vhdl-insert-keyword "PROCEDURE ")
6785 (when (setq name (vhdl-template-field "name" nil t start (point)))
6786 (vhdl-template-argument-list)
6787 (if (if kind (eq kind 'body)
6788 (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b))
6789 (progn (vhdl-insert-keyword " IS")
6790 (when vhdl-auto-align
6791 (vhdl-align-noindent-region start (point) 1))
6793 (vhdl-template-begin-end
6794 (unless (vhdl-standard-p '87) "PROCEDURE")
6796 (vhdl-comment-block))
6798 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))
6801 (defun vhdl-template-procedure-decl ()
6802 "Insert a procedure declaration."
6804 (vhdl-template-procedure 'decl))
6806 (defun vhdl-template-procedure-body ()
6807 "Insert a procedure body."
6809 (vhdl-template-procedure 'body))
6811 (defun vhdl-template-process (&optional kind)
6814 (let ((margin (current-indentation))
6816 (case-fold-search t)
6817 label seq input-signals clock reset final-pos)
6818 (setq seq (if kind (eq kind 'seq)
6819 (eq (vhdl-decision-query
6820 "process" "(c)ombinational or (s)equential?" t) ?s)))
6821 (vhdl-insert-keyword "PROCESS ")
6822 (when (memq vhdl-optional-labels '(process all))
6826 (setq label (vhdl-template-field "[label]" nil t))
6827 (unless label (delete-char 2))
6832 (unless (setq input-signals
6833 (vhdl-template-field "[sensitivity list]" ")" t))
6834 (setq input-signals "")
6836 (setq clock (or (and (not (equal "" vhdl-clock-name))
6837 (progn (insert vhdl-clock-name) vhdl-clock-name))
6838 (vhdl-template-field "clock name") "<clock>"))
6839 (when (eq vhdl-reset-kind 'async)
6841 (setq reset (or (and (not (equal "" vhdl-reset-name))
6842 (progn (insert vhdl-reset-name) vhdl-reset-name))
6843 (vhdl-template-field "reset name") "<reset>")))
6845 (unless (vhdl-standard-p '87) (vhdl-insert-keyword " IS"))
6846 (vhdl-template-begin-end "PROCESS" label margin)
6847 (when seq (setq reset (vhdl-template-seq-process clock reset)))
6848 (when vhdl-prompt-for-comments
6849 (setq final-pos (point-marker))
6850 (vhdl-ext-syntax-table
6851 (when (and (re-search-backward "\\<begin\\>" nil t)
6852 (re-search-backward "\\<process\\>" nil t))
6855 (progn (insert "\n") (forward-line -1))
6858 (insert "-- purpose: ")
6859 (if (not (vhdl-template-field "[description]" nil t))
6860 (vhdl-line-kill-entire)
6863 (insert "-- type : ")
6864 (insert (if seq "sequential" "combinational") "\n")
6866 (insert "-- inputs : ")
6868 (insert input-signals)
6870 (when reset (insert reset ", "))
6871 (unless (vhdl-template-field "[signal names]" nil t)
6875 (insert "-- outputs: ")
6876 (vhdl-template-field "[signal names]" nil t))))
6877 (goto-char final-pos))))
6879 (defun vhdl-template-process-comb ()
6880 "Insert a combinational process."
6882 (vhdl-template-process 'comb))
6884 (defun vhdl-template-process-seq ()
6885 "Insert a sequential process."
6887 (vhdl-template-process 'seq))
6889 (defun vhdl-template-quantity ()
6890 "Insert a quantity declaration."
6892 (if (vhdl-in-argument-list-p)
6893 (let ((start (point)))
6894 (vhdl-insert-keyword "QUANTITY ")
6895 (when (vhdl-template-field "names" nil t start (point))
6897 (vhdl-template-field "[IN | OUT]" " " t)
6898 (vhdl-template-field "type")
6900 (vhdl-comment-insert-inline)))
6901 (let ((char (vhdl-decision-query
6902 "quantity" "(f)ree, (b)ranch, or (s)ource quantity?" t)))
6903 (cond ((eq char ?f) (vhdl-template-quantity-free))
6904 ((eq char ?b) (vhdl-template-quantity-branch))
6905 ((eq char ?s) (vhdl-template-quantity-source))
6906 (t (vhdl-template-undo (point) (point)))))))
6908 (defun vhdl-template-quantity-free ()
6909 "Insert a free quantity declaration."
6911 (vhdl-insert-keyword "QUANTITY ")
6912 (vhdl-template-field "names")
6914 (vhdl-template-field "type")
6915 (let ((position (point)))
6917 (unless (vhdl-template-field "[initialization]" nil t)
6918 (delete-region position (point)))
6920 (vhdl-comment-insert-inline)))
6922 (defun vhdl-template-quantity-branch ()
6923 "Insert a branch quantity declaration."
6926 (vhdl-insert-keyword "QUANTITY ")
6927 (when (vhdl-template-field "[across names]" " " t)
6928 (vhdl-insert-keyword "ACROSS "))
6929 (when (vhdl-template-field "[through names]" " " t)
6930 (vhdl-insert-keyword "THROUGH "))
6931 (vhdl-template-field "plus terminal name")
6932 (setq position (point))
6933 (vhdl-insert-keyword " TO ")
6934 (unless (vhdl-template-field "[minus terminal name]" nil t)
6935 (delete-region position (point)))
6937 (vhdl-comment-insert-inline)))
6939 (defun vhdl-template-quantity-source ()
6940 "Insert a source quantity declaration."
6942 (vhdl-insert-keyword "QUANTITY ")
6943 (vhdl-template-field "names")
6945 (vhdl-template-field "type" " ")
6946 (if (eq (vhdl-decision-query nil "(s)pectrum or (n)oise?") ?n)
6947 (progn (vhdl-insert-keyword "NOISE ")
6948 (vhdl-template-field "power expression"))
6949 (vhdl-insert-keyword "SPECTRUM ")
6950 (vhdl-template-field "magnitude expression" ", ")
6951 (vhdl-template-field "phase expression"))
6953 (vhdl-comment-insert-inline))
6955 (defun vhdl-template-record (kind &optional name secondary)
6956 "Insert a record type declaration."
6958 (let ((margin (current-column))
6961 (vhdl-insert-keyword "RECORD\n")
6962 (indent-to (+ margin vhdl-basic-offset))
6963 (when (or (vhdl-template-field "element names"
6964 nil (not secondary) start (point))
6966 (while (or first (vhdl-template-field "[element names]" nil t))
6968 (vhdl-template-field (if (eq kind 'type) "type" "nature") ";")
6969 (vhdl-comment-insert-inline)
6971 (indent-to (+ margin vhdl-basic-offset))
6975 (vhdl-insert-keyword "END RECORD")
6976 (unless (vhdl-standard-p '87) (and name (insert " " name)))
6978 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)))))
6980 (defun vhdl-template-report ()
6981 "Insert a report statement."
6983 (let ((start (point)))
6984 (vhdl-insert-keyword "REPORT ")
6985 (if (equal "\"\"" (vhdl-template-field
6986 "string expression" nil t start (point) t))
6987 (backward-delete-char 2)
6988 (setq start (point))
6989 (vhdl-insert-keyword " SEVERITY ")
6990 (unless (vhdl-template-field "[NOTE | WARNING | ERROR | FAILURE]" nil t)
6991 (delete-region start (point)))
6994 (defun vhdl-template-return ()
6995 "Insert a return statement."
6997 (vhdl-insert-keyword "RETURN ")
6998 (unless (vhdl-template-field "[expression]" nil t)
7002 (defun vhdl-template-selected-signal-asst ()
7003 "Insert a selected signal assignment."
7005 (let ((margin (current-indentation))
7008 (let ((position (point)))
7009 (vhdl-insert-keyword " SELECT ")
7010 (goto-char position))
7011 (vhdl-insert-keyword "WITH ")
7012 (when (vhdl-template-field "selector expression"
7013 nil t start (+ (point) 7))
7017 (indent-to (+ margin vhdl-basic-offset))
7018 (vhdl-template-field "target signal" " <= ")
7019 ; (vhdl-template-field "[GUARDED] [TRANSPORT]")
7021 (indent-to (+ margin vhdl-basic-offset))
7022 (vhdl-template-field "waveform")
7023 (vhdl-insert-keyword " WHEN ")
7024 (vhdl-template-field "choices" ",")
7026 (indent-to (+ margin vhdl-basic-offset))
7027 (while (and choices (vhdl-template-field "[waveform]" nil t))
7028 (vhdl-insert-keyword " WHEN ")
7029 (if (setq choices (vhdl-template-field "[choices]" "," t))
7030 (progn (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
7031 (vhdl-insert-keyword "OTHERS")))
7036 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)))))
7038 (defun vhdl-template-signal ()
7039 "Insert a signal declaration."
7041 (let ((start (point))
7042 (in-arglist (vhdl-in-argument-list-p)))
7043 (vhdl-insert-keyword "SIGNAL ")
7044 (when (vhdl-template-field "names" nil t start (point))
7046 (when in-arglist (vhdl-template-field "[IN | OUT | INOUT]" " " t))
7047 (vhdl-template-field "type")
7050 (vhdl-comment-insert-inline))
7051 (let ((position (point)))
7053 (unless (vhdl-template-field "[initialization]" nil t)
7054 (delete-region position (point)))
7056 (vhdl-comment-insert-inline))))))
7058 (defun vhdl-template-subnature ()
7059 "Insert a subnature declaration."
7061 (let ((start (point))
7063 (vhdl-insert-keyword "SUBNATURE ")
7064 (when (vhdl-template-field "name" nil t start (point))
7065 (vhdl-insert-keyword " IS ")
7066 (vhdl-template-field "nature" " (")
7067 (if (vhdl-template-field "[index range]" nil t)
7070 (setq position (point))
7071 (vhdl-insert-keyword " TOLERANCE ")
7072 (if (equal "\"\"" (vhdl-template-field "[string expression]"
7074 (delete-region position (point))
7075 (vhdl-insert-keyword " ACROSS ")
7076 (vhdl-template-field "string expression" nil nil nil nil t)
7077 (vhdl-insert-keyword " THROUGH"))
7079 (vhdl-comment-insert-inline))))
7081 (defun vhdl-template-subprogram-body ()
7082 "Insert a subprogram body."
7084 (if (eq (vhdl-decision-query nil "(p)rocedure or (f)unction?" t) ?f)
7085 (vhdl-template-function-body)
7086 (vhdl-template-procedure-body)))
7088 (defun vhdl-template-subprogram-decl ()
7089 "Insert a subprogram declaration."
7091 (if (eq (vhdl-decision-query nil "(p)rocedure or (f)unction?" t) ?f)
7092 (vhdl-template-function-decl)
7093 (vhdl-template-procedure-decl)))
7095 (defun vhdl-template-subtype ()
7096 "Insert a subtype declaration."
7098 (let ((start (point)))
7099 (vhdl-insert-keyword "SUBTYPE ")
7100 (when (vhdl-template-field "name" nil t start (point))
7101 (vhdl-insert-keyword " IS ")
7102 (vhdl-template-field "type" " ")
7104 (vhdl-template-field "[RANGE value range | ( index range )]" nil t)
7107 (vhdl-comment-insert-inline))))
7109 (defun vhdl-template-terminal ()
7110 "Insert a terminal declaration."
7112 (let ((start (point)))
7113 (vhdl-insert-keyword "TERMINAL ")
7114 (when (vhdl-template-field "names" nil t start (point))
7116 (vhdl-template-field "nature")
7118 (vhdl-comment-insert-inline))))
7120 (defun vhdl-template-type ()
7121 "Insert a type declaration."
7123 (let ((start (point))
7124 name mid-pos end-pos)
7125 (vhdl-insert-keyword "TYPE ")
7126 (when (setq name (vhdl-template-field "name" nil t start (point)))
7127 (vhdl-insert-keyword " IS ")
7130 (or (vhdl-template-field
7131 "[scalar type | ARRAY | RECORD | ACCESS | FILE]" nil t)
7133 (cond ((equal definition "")
7134 (backward-delete-char 4)
7136 ((equal definition "ARRAY")
7138 (vhdl-template-array 'type t))
7139 ((equal definition "RECORD")
7140 (setq mid-pos (point-marker))
7142 (vhdl-template-record 'type name t))
7143 ((equal definition "ACCESS")
7145 (vhdl-template-field "type" ";"))
7146 ((equal definition "FILE")
7147 (vhdl-insert-keyword " OF ")
7148 (vhdl-template-field "type" ";"))
7151 (setq end-pos (point-marker))
7154 (vhdl-comment-insert-inline)
7155 (when end-pos (goto-char end-pos))))))
7157 (defun vhdl-template-use ()
7158 "Insert a use clause."
7160 (let ((start (point))
7161 (case-fold-search t))
7162 (vhdl-ext-syntax-table
7163 (vhdl-insert-keyword "USE ")
7164 (when (save-excursion (beginning-of-line) (looking-at "^\\s-*use\\>"))
7165 (vhdl-insert-keyword "..ALL;")
7167 (when (vhdl-template-field "library name" nil t start (+ (point) 6))
7169 (vhdl-template-field "package name")
7170 (forward-char 5))))))
7172 (defun vhdl-template-variable ()
7173 "Insert a variable declaration."
7175 (let ((start (point))
7176 (case-fold-search t)
7177 (in-arglist (vhdl-in-argument-list-p)))
7178 (vhdl-ext-syntax-table
7179 (if (or (save-excursion
7180 (and (re-search-backward
7181 "\\<function\\|procedure\\|process\\|procedural\\|end\\>"
7183 (not (progn (backward-word 1) (looking-at "\\<end\\>")))))
7184 (save-excursion (backward-word 1) (looking-at "\\<shared\\>")))
7185 (vhdl-insert-keyword "VARIABLE ")
7186 (vhdl-insert-keyword "SHARED VARIABLE ")))
7187 (when (vhdl-template-field "names" nil t start (point))
7189 (when in-arglist (vhdl-template-field "[IN | OUT | INOUT]" " " t))
7190 (vhdl-template-field "type")
7193 (vhdl-comment-insert-inline))
7194 (let ((position (point)))
7196 (unless (vhdl-template-field "[initialization]" nil t)
7197 (delete-region position (point)))
7199 (vhdl-comment-insert-inline))))))
7201 (defun vhdl-template-wait ()
7202 "Insert a wait statement."
7204 (vhdl-insert-keyword "WAIT ")
7205 (unless (vhdl-template-field
7206 "[ON sensitivity list] [UNTIL condition] [FOR time expression]"
7211 (defun vhdl-template-when ()
7212 "Indent correctly if within a case statement."
7214 (let ((position (point))
7215 (case-fold-search t)
7217 (vhdl-ext-syntax-table
7218 (if (and (= (current-column) (current-indentation))
7219 (re-search-forward "\\<end\\>" nil t)
7220 (looking-at "\\s-*\\<case\\>"))
7222 (setq margin (current-indentation))
7223 (goto-char position)
7224 (delete-horizontal-space)
7225 (indent-to (+ margin vhdl-basic-offset)))
7226 (goto-char position)))
7227 (vhdl-insert-keyword "WHEN ")))
7229 (defun vhdl-template-while-loop ()
7230 "Insert a while loop."
7232 (let* ((margin (current-indentation))
7235 (if (not (eq vhdl-optional-labels 'all))
7236 (vhdl-insert-keyword "WHILE ")
7237 (vhdl-insert-keyword ": WHILE ")
7239 (setq label (vhdl-template-field "[label]" nil t))
7240 (unless label (delete-char 2))
7243 (when vhdl-conditions-in-parenthesis (insert "("))
7244 (when (vhdl-template-field "condition" nil t start (point))
7245 (when vhdl-conditions-in-parenthesis (insert ")"))
7246 (vhdl-insert-keyword " LOOP\n\n")
7248 (vhdl-insert-keyword "END LOOP")
7249 (insert (if label (concat " " label ";") ";"))
7251 (indent-to (+ margin vhdl-basic-offset)))))
7253 (defun vhdl-template-with ()
7254 "Insert a with statement (i.e. selected signal assignment)."
7256 (let ((case-fold-search t))
7257 (vhdl-ext-syntax-table
7259 (re-search-backward "\\(\\<limit\\>\\|;\\)")
7260 (equal ";" (match-string 1)))
7261 (vhdl-template-selected-signal-asst)
7262 (vhdl-insert-keyword "WITH ")))))
7264 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7265 ;; Special templates
7267 (defun vhdl-template-clocked-wait ()
7268 "Insert a wait statement for rising/falling clock edge."
7270 (let ((start (point))
7272 (vhdl-insert-keyword "WAIT UNTIL ")
7274 (or (and (not (equal "" vhdl-clock-name))
7275 (progn (insert vhdl-clock-name) vhdl-clock-name))
7276 (vhdl-template-field "clock name" nil t start (point))))
7278 (vhdl-insert-keyword " AND ")
7281 " = " (if vhdl-clock-rising-edge vhdl-one-string vhdl-zero-string) ";")
7282 (vhdl-comment-insert-inline
7283 (concat (if vhdl-clock-rising-edge "rising" "falling")
7286 (defun vhdl-template-seq-process (clock reset)
7287 "Insert a template for the body of a sequential process."
7288 (let ((margin (current-indentation))
7290 (vhdl-insert-keyword "IF ")
7291 (when (eq vhdl-reset-kind 'async)
7293 (if vhdl-reset-active-high vhdl-one-string vhdl-zero-string))
7294 (vhdl-insert-keyword " THEN")
7295 (vhdl-comment-insert-inline
7296 (concat "asynchronous reset (active "
7297 (if vhdl-reset-active-high "high" "low") ")"))
7298 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
7299 (setq position (point))
7300 (insert "\n") (indent-to margin)
7301 (vhdl-insert-keyword "ELSIF "))
7302 (if (eq vhdl-clock-edge-condition 'function)
7303 (insert (if vhdl-clock-rising-edge "rising" "falling")
7305 (insert clock "'event")
7306 (vhdl-insert-keyword " AND ")
7308 (if vhdl-clock-rising-edge vhdl-one-string vhdl-zero-string)))
7309 (vhdl-insert-keyword " THEN")
7310 (vhdl-comment-insert-inline
7311 (concat (if vhdl-clock-rising-edge "rising" "falling") " clock edge"))
7312 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
7313 (when (eq vhdl-reset-kind 'sync)
7314 (vhdl-insert-keyword "IF ")
7315 (setq reset (or (and (not (equal "" vhdl-reset-name))
7316 (progn (insert vhdl-reset-name) vhdl-reset-name))
7317 (vhdl-template-field "reset name") "<reset>"))
7319 (if vhdl-reset-active-high vhdl-one-string vhdl-zero-string))
7320 (vhdl-insert-keyword " THEN")
7321 (vhdl-comment-insert-inline
7322 (concat "synchronous reset (active "
7323 (if vhdl-reset-active-high "high" "low") ")"))
7324 (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset)))
7325 (setq position (point))
7326 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
7327 (vhdl-insert-keyword "ELSE")
7328 (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset)))
7329 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
7330 (vhdl-insert-keyword "END IF;"))
7331 (when (eq vhdl-reset-kind 'none)
7332 (setq position (point)))
7333 (insert "\n") (indent-to margin)
7334 (vhdl-insert-keyword "END IF;")
7335 (goto-char position)
7338 (defun vhdl-template-standard-package (library package)
7339 "Insert specification of a standard package. Include a library
7340 specification, if not already there."
7341 (let ((margin (current-indentation))
7342 (case-fold-search t))
7344 (vhdl-ext-syntax-table
7347 (concat "^\\s-*\\(library\\s-+\\(\\(\\w\\|\\s_\\)+,\\s-+\\)*"
7348 library "\\|end\\)\\>") nil t))))
7349 (unless (and (match-string 1) (string-match "library" (match-string 1)))
7350 (vhdl-insert-keyword "LIBRARY ")
7351 (insert library ";\n")
7353 (vhdl-insert-keyword "USE ")
7354 (insert library "." package)
7355 (vhdl-insert-keyword ".ALL;")))
7357 (defun vhdl-template-package-math-complex ()
7358 "Insert specification of `math_complex' package."
7360 (vhdl-template-standard-package "ieee" "math_complex"))
7362 (defun vhdl-template-package-math-real ()
7363 "Insert specification of `math_real' package."
7365 (vhdl-template-standard-package "ieee" "math_real"))
7367 (defun vhdl-template-package-numeric-bit ()
7368 "Insert specification of `numeric_bit' package."
7370 (vhdl-template-standard-package "ieee" "numeric_bit"))
7372 (defun vhdl-template-package-numeric-std ()
7373 "Insert specification of `numeric_std' package."
7375 (vhdl-template-standard-package "ieee" "numeric_std"))
7377 (defun vhdl-template-package-std-logic-1164 ()
7378 "Insert specification of `std_logic_1164' package."
7380 (vhdl-template-standard-package "ieee" "std_logic_1164"))
7382 (defun vhdl-template-package-std-logic-arith ()
7383 "Insert specification of `std_logic_arith' package."
7385 (vhdl-template-standard-package "ieee" "std_logic_arith"))
7387 (defun vhdl-template-package-std-logic-misc ()
7388 "Insert specification of `std_logic_misc' package."
7390 (vhdl-template-standard-package "ieee" "std_logic_misc"))
7392 (defun vhdl-template-package-std-logic-signed ()
7393 "Insert specification of `std_logic_signed' package."
7395 (vhdl-template-standard-package "ieee" "std_logic_signed"))
7397 (defun vhdl-template-package-std-logic-textio ()
7398 "Insert specification of `std_logic_textio' package."
7400 (vhdl-template-standard-package "ieee" "std_logic_textio"))
7402 (defun vhdl-template-package-std-logic-unsigned ()
7403 "Insert specification of `std_logic_unsigned' package."
7405 (vhdl-template-standard-package "ieee" "std_logic_unsigned"))
7407 (defun vhdl-template-package-textio ()
7408 "Insert specification of `textio' package."
7410 (vhdl-template-standard-package "std" "textio"))
7412 (defun vhdl-template-directive (directive)
7414 (unless (= (current-indentation) (current-column))
7415 (delete-horizontal-space)
7417 (insert "-- pragma " directive))
7419 (defun vhdl-template-directive-translate-on ()
7420 "Insert directive 'translate_on'."
7422 (vhdl-template-directive "translate_on"))
7424 (defun vhdl-template-directive-translate-off ()
7425 "Insert directive 'translate_off'."
7427 (vhdl-template-directive "translate_off"))
7429 (defun vhdl-template-directive-synthesis-on ()
7430 "Insert directive 'synthesis_on'."
7432 (vhdl-template-directive "synthesis_on"))
7434 (defun vhdl-template-directive-synthesis-off ()
7435 "Insert directive 'synthesis_off'."
7437 (vhdl-template-directive "synthesis_off"))
7439 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7440 ;; Comment templates and functions
7442 (defun vhdl-comment-indent ()
7444 (let* ((position (point))
7448 (if (re-search-forward "--" position t)
7449 (- (current-column) 2) ; existing comment at bol stays there
7450 (goto-char position)
7451 (skip-chars-backward " \t")
7452 (max comment-column ; else indent to comment column
7453 (1+ (current-column))))))) ; except leave at least one space
7454 (goto-char position)
7457 (defun vhdl-comment-insert ()
7458 "Start a comment at the end of the line.
7459 If on line with code, indent at least `comment-column'.
7460 If starting after end-comment-column, start a new line."
7462 (when (> (current-column) end-comment-column) (newline-and-indent))
7463 (if (or (looking-at "\\s-*$") ; end of line
7464 (and (not unread-command-events) ; called with key binding or menu
7465 (not (end-of-line))))
7467 (while (= (preceding-char) ?-) (delete-char -1))
7468 (setq margin (current-column))
7469 (delete-horizontal-space)
7471 (progn (indent-to margin) (insert "--"))
7473 (indent-to comment-column)
7475 (if (not unread-command-events) (insert " ")))
7476 ;; else code following current point implies commenting out code
7477 (let (next-input code)
7478 (while (= (preceding-char) ?-) (delete-char -2))
7479 (while (= (setq next-input (read-char)) 13) ; CR
7480 (insert "--") ; or have a space after it?
7483 (message "Enter CR if commenting out a line of code.")
7486 (insert "--")) ; hardwire to 1 space or use vhdl-basic-offset?
7487 (setq unread-command-events
7488 (list (vhdl-character-to-event next-input)))))) ; pushback the char
7490 (defun vhdl-comment-display (&optional line-exists)
7491 "Add 2 comment lines at the current indent, making a display comment."
7493 (let ((margin (current-indentation)))
7494 (when (not line-exists) (vhdl-comment-display-line))
7495 (insert "\n") (indent-to margin)
7496 (insert "\n") (indent-to margin)
7497 (vhdl-comment-display-line)
7501 (defun vhdl-comment-display-line ()
7502 "Displays one line of dashes."
7504 (while (= (preceding-char) ?-) (delete-char -2))
7505 (let* ((col (current-column))
7506 (len (- end-comment-column col)))
7507 (insert-char ?- len)))
7509 (defun vhdl-comment-append-inline ()
7510 "Append empty inline comment to current line."
7513 (delete-horizontal-space)
7515 (indent-to comment-column)
7518 (defun vhdl-comment-insert-inline (&optional string always-insert)
7519 "Insert inline comment."
7520 (when (or (and string (or vhdl-self-insert-comments always-insert))
7521 (and (not string) vhdl-prompt-for-comments))
7522 (let ((position (point)))
7524 (indent-to comment-column)
7526 (if (or (and string (progn (insert string) t))
7527 (vhdl-template-field "[comment]" nil t))
7528 (when (> (current-column) end-comment-column)
7529 (setq position (point-marker))
7530 (re-search-backward "-- ")
7532 (indent-to comment-column)
7533 (goto-char position))
7534 (delete-region position (point))))))
7536 (defun vhdl-comment-block ()
7537 "Insert comment for code block."
7538 (when vhdl-prompt-for-comments
7539 (let ((final-pos (point-marker))
7540 (case-fold-search t))
7541 (vhdl-ext-syntax-table
7542 (when (and (re-search-backward "^\\s-*begin\\>" nil t)
7544 "\\<\\(architecture\\|block\\|function\\|procedure\\|process\\|procedural\\)\\>"
7547 (back-to-indentation)
7548 (setq margin (current-column))
7551 (progn (insert "\n") (forward-line -1))
7554 (insert "-- purpose: ")
7555 (unless (vhdl-template-field "[description]" nil t)
7556 (vhdl-line-kill-entire)))))
7557 (goto-char final-pos))))
7559 (defun vhdl-comment-uncomment-region (beg end &optional arg)
7560 "Comment out region if not commented out, uncomment otherwise."
7561 (interactive "r\nP")
7563 (goto-char (1- end))
7565 (setq end (point-marker))
7569 (if (looking-at comment-start)
7570 (comment-region beg end -1)
7571 (comment-region beg end))))
7573 (defun vhdl-comment-uncomment-line (&optional arg)
7574 "Comment out line if not commented out, uncomment otherwise."
7578 (let ((position (point)))
7579 (forward-line (or arg 1))
7580 (vhdl-comment-uncomment-region position (point)))))
7582 (defun vhdl-comment-kill-region (beg end)
7583 "Kill comments in region."
7587 (setq end (point-marker))
7590 (while (< (point) end)
7591 (if (looking-at "^\\(\\s-*--.*\n\\)")
7592 (progn (delete-region (match-beginning 1) (match-end 1)))
7593 (beginning-of-line 2)))))
7595 (defun vhdl-comment-kill-inline-region (beg end)
7596 "Kill inline comments in region."
7600 (setq end (point-marker))
7603 (while (< (point) end)
7604 (when (looking-at "^.*[^ \t\n-]+\\(\\s-*--.*\\)$")
7605 (delete-region (match-beginning 1) (match-end 1)))
7606 (beginning-of-line 2))))
7608 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7611 (defun vhdl-template-begin-end (construct name margin &optional empty-lines)
7612 "Insert a begin ... end pair with optional name after the end.
7613 Point is left between them."
7616 (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n"))
7618 (vhdl-insert-keyword "BEGIN")
7619 (when (and (or construct name) vhdl-self-insert-comments)
7621 (when construct (insert " ") (vhdl-insert-keyword construct))
7622 (when name (insert " " name)))
7624 (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n"))
7625 (indent-to (+ margin vhdl-basic-offset))
7626 (setq position (point))
7628 (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n"))
7630 (vhdl-insert-keyword "END")
7631 (when construct (insert " ") (vhdl-insert-keyword construct))
7632 (insert (if name (concat " " name) "") ";")
7633 (goto-char position)))
7635 (defun vhdl-template-argument-list (&optional is-function)
7636 "Read from user a procedure or function argument list."
7638 (let ((margin (current-column))
7641 not-empty interface semicolon-pos)
7642 (when (not vhdl-argument-list-indent)
7643 (setq margin (+ (current-indentation) vhdl-basic-offset))
7646 (setq interface (vhdl-template-field
7647 (concat "[CONSTANT | SIGNAL"
7648 (unless is-function " | VARIABLE") "]") " " t))
7649 (while (vhdl-template-field "[names]" nil t)
7652 (when (not is-function)
7653 (if (and interface (equal (upcase interface) "CONSTANT"))
7654 (vhdl-insert-keyword "IN ")
7655 (vhdl-template-field "[IN | OUT | INOUT]" " " t)))
7656 (vhdl-template-field "type")
7657 (setq semicolon-pos (point))
7659 (vhdl-comment-insert-inline)
7660 (setq end-pos (point))
7663 (setq interface (vhdl-template-field
7664 (concat "[CONSTANT | SIGNAL"
7665 (unless is-function " | VARIABLE") "]") " " t)))
7666 (delete-region end-pos (point))
7667 (when semicolon-pos (goto-char semicolon-pos))
7669 (progn (delete-char 1) (insert ")"))
7670 (backward-delete-char 2))))
7672 (defun vhdl-template-generic-list (optional &optional no-value)
7673 "Read from user a generic spec argument list."
7676 (vhdl-insert-keyword "GENERIC (")
7677 (setq margin (current-column))
7678 (when (not vhdl-argument-list-indent)
7679 (let ((position (point)))
7680 (back-to-indentation)
7681 (setq margin (+ (current-column) vhdl-basic-offset))
7682 (goto-char position)
7684 (indent-to margin)))
7685 (let ((vhdl-generics (vhdl-template-field
7686 (concat (and optional "[") "name"
7687 (and no-value "s") (and optional "]"))
7689 (if (not vhdl-generics)
7691 (progn (vhdl-line-kill-entire) (end-of-line -0)
7692 (when (not vhdl-argument-list-indent)
7693 (vhdl-line-kill-entire) (end-of-line -0)))
7694 (vhdl-template-undo start (point))
7697 (let (semicolon-pos end-pos)
7698 (while vhdl-generics
7699 (vhdl-template-field "type")
7701 (progn (setq semicolon-pos (point))
7704 (unless (vhdl-template-field "[value]" nil t)
7706 (setq semicolon-pos (point))
7708 (vhdl-comment-insert-inline)
7709 (setq end-pos (point))
7712 (setq vhdl-generics (vhdl-template-field
7713 (concat "[name" (and no-value "s") "]")
7715 (delete-region end-pos (point))
7716 (goto-char semicolon-pos)
7719 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))
7722 (defun vhdl-template-port-list (optional)
7723 "Read from user a port spec argument list."
7724 (let ((start (point))
7725 margin vhdl-ports object)
7726 (vhdl-insert-keyword "PORT (")
7727 (setq margin (current-column))
7728 (when (not vhdl-argument-list-indent)
7729 (let ((position (point)))
7730 (back-to-indentation)
7731 (setq margin (+ (current-column) vhdl-basic-offset))
7732 (goto-char position)
7734 (indent-to margin)))
7735 (when (vhdl-standard-p 'ams)
7736 (setq object (vhdl-template-field "[SIGNAL | TERMINAL | QUANTITY]"
7738 (setq vhdl-ports (vhdl-template-field
7739 (concat (and optional "[") "names" (and optional "]"))
7741 (if (not vhdl-ports)
7743 (progn (vhdl-line-kill-entire) (end-of-line -0)
7744 (when (not vhdl-argument-list-indent)
7745 (vhdl-line-kill-entire) (end-of-line -0)))
7746 (vhdl-template-undo start (point))
7749 (let (semicolon-pos end-pos)
7751 (cond ((or (null object) (equal "SIGNAL" (upcase object)))
7752 (vhdl-template-field "IN | OUT | INOUT" " "))
7753 ((equal "QUANTITY" (upcase object))
7754 (vhdl-template-field "[IN | OUT]" " " t)))
7755 (vhdl-template-field
7756 (if (and object (equal "TERMINAL" (upcase object)))
7758 (setq semicolon-pos (point))
7760 (vhdl-comment-insert-inline)
7761 (setq end-pos (point))
7764 (when (vhdl-standard-p 'ams)
7765 (setq object (vhdl-template-field "[SIGNAL | TERMINAL | QUANTITY]"
7767 (setq vhdl-ports (vhdl-template-field "[names]" " : " t)))
7768 (delete-region end-pos (point))
7769 (goto-char semicolon-pos)
7772 (when vhdl-auto-align (vhdl-align-noindent-region start end-pos 1))
7775 (defun vhdl-template-generate-body (margin label)
7776 "Insert body for generate template."
7777 (vhdl-insert-keyword " GENERATE")
7778 (if (not (vhdl-standard-p '87))
7779 (vhdl-template-begin-end "GENERATE" label margin)
7782 (vhdl-insert-keyword "END GENERATE ")
7785 (indent-to (+ margin vhdl-basic-offset))))
7787 (defun vhdl-template-insert-date ()
7788 "Insert date in appropriate format."
7792 ;; 'american, 'european', 'scientific kept for backward compatibility
7793 ((eq vhdl-date-format 'american) (format-time-string "%m/%d/%Y" nil))
7794 ((eq vhdl-date-format 'european) (format-time-string "%d.%m.%Y" nil))
7795 ((eq vhdl-date-format 'scientific) (format-time-string "%Y/%m/%d" nil))
7796 (t (format-time-string vhdl-date-format nil)))))
7798 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7801 (defun vhdl-electric-space (count)
7802 "Expand abbreviations and self-insert space(s), do indent-new-comment-line
7803 if in comment and past end-comment-column."
7805 (cond ((vhdl-in-comment-p)
7806 (self-insert-command count)
7807 (cond ((>= (current-column) (+ 2 end-comment-column))
7809 (indent-new-comment-line)
7812 ((>= (current-column) end-comment-column)
7813 (indent-new-comment-line))
7815 ((or (and (>= (preceding-char) ?a) (<= (preceding-char) ?z))
7816 (and (>= (preceding-char) ?A) (<= (preceding-char) ?Z)))
7817 (vhdl-ext-syntax-table
7818 (let ((case-fold-search t))
7820 (self-insert-command count))
7821 (t (self-insert-command count))))
7823 (defun vhdl-template-field (prompt &optional follow-string optional
7824 begin end is-string default)
7825 "Prompt for string and insert it in buffer with optional FOLLOW-STRING.
7826 If OPTIONAL is nil, the prompt is left if an empty string is inserted. If
7827 an empty string is inserted, return nil and call `vhdl-template-undo' for
7828 the region between BEGIN and END. IS-STRING indicates whether a string
7829 with double-quotes is to be inserted. DEFAULT specifies a default string."
7830 (let ((position (point))
7832 (insert "<" prompt ">")
7835 (read-from-minibuffer (concat prompt ": ")
7836 (or (and is-string '("\"\"" . 2)) default)
7837 vhdl-minibuffer-local-map)
7838 (quit (if (and optional begin end)
7841 (when (or (not (equal string "")) optional)
7842 (delete-region position (point)))
7843 (when (and (equal string "") optional begin end)
7844 (vhdl-template-undo begin end)
7845 (message "Template aborted"))
7846 (when (not (equal string ""))
7848 (vhdl-fix-case-region-1 position (point) vhdl-upper-case-keywords
7849 vhdl-keywords-regexp))
7850 (when (or (not (equal string "")) (not optional))
7851 (insert (or follow-string "")))
7852 (if (equal string "") nil string)))
7854 (defun vhdl-decision-query (string prompt &optional optional)
7855 "Query a decision from the user."
7856 (let ((start (point)))
7857 (when string (vhdl-insert-keyword (concat string " ")))
7859 (let ((char (read-char)))
7860 (delete-region start (point))
7861 (if (and optional (eq char ?\r))
7864 (throw 'abort "Template aborted"))
7867 (defun vhdl-insert-keyword (keyword)
7868 "Insert KEYWORD and adjust case."
7869 (insert (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword))))
7871 (defun vhdl-case-keyword (keyword)
7872 "Adjust case of KEYWORD."
7873 (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword)))
7875 (defun vhdl-case-word (num)
7876 "Adjust case or following NUM words."
7877 (if vhdl-upper-case-keywords (upcase-word num) (downcase-word num)))
7879 (defun vhdl-minibuffer-tab (&optional prefix-arg)
7880 "If preceeding character is part of a word or a paren then hippie-expand,
7881 else if right of non whitespace on line then tab-to-tab-stop,
7882 else indent line in proper way for current major mode (used for word
7883 completion in VHDL minibuffer)."
7885 (cond ((= (char-syntax (preceding-char)) ?w)
7886 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
7888 (vhdl-expand-abbrev prefix-arg)))
7889 ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
7890 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
7892 (vhdl-expand-paren prefix-arg)))
7893 ((> (current-column) (current-indentation))
7895 (t (if (eq indent-line-function 'indent-to-left-margin)
7896 (insert-tab prefix-arg)
7898 (funcall indent-line-function prefix-arg)
7899 (funcall indent-line-function))))))
7901 (defun vhdl-template-search-prompt ()
7902 "Search for left out template prompts and query again."
7904 (let ((case-fold-search t))
7905 (vhdl-ext-syntax-table
7906 (when (or (re-search-forward
7907 (concat "<\\(" vhdl-template-prompt-syntax "\\)>") nil t)
7909 (concat "<\\(" vhdl-template-prompt-syntax "\\)>") nil t))
7910 (let ((string (match-string 1)))
7912 (vhdl-template-field string))))))
7914 (defun vhdl-template-undo (begin end)
7915 "Undo aborted template by deleting region and unexpanding the keyword."
7916 (cond (vhdl-template-invoked-by-hook
7919 (delete-region begin end)
7921 (t (delete-region begin end))))
7923 (defun vhdl-insert-string-or-file (string)
7924 "Insert STRING or file contents if STRING is an existing file name."
7925 (unless (equal string "")
7926 (cond ((file-exists-p string)
7927 (forward-char (cadr (insert-file-contents string))))
7928 (t (insert string)))))
7930 (defun vhdl-sequential-statement-p ()
7931 "Check if point is within sequential statement part."
7933 (let ((case-fold-search t)
7935 (vhdl-ext-syntax-table
7936 (set-match-data nil)
7937 (while (and (re-search-backward "^\\s-*\\(begin\\|end\\(\\s-*\\(case\\|if\\|loop\\)\\)?\\)\\>"
7941 (equal "BEGIN" (upcase (match-string 1)))
7942 (re-search-backward "^\\s-*\\(\\w+\\s-*:\\s-*\\)?\\(\\w+\\s-+\\)?\\(function\\|procedure\\|process\\|procedural\\|end\\)\\>"
7944 (not (equal "END" (upcase (match-string 3)))))))))
7946 (defun vhdl-in-argument-list-p ()
7947 "Check if within an argument list."
7949 (let ((case-fold-search t))
7950 (vhdl-ext-syntax-table
7951 (or (string-match "arglist"
7952 (format "%s" (car (car (vhdl-get-syntactic-context)))))
7953 (progn (beginning-of-line)
7954 (looking-at "^\\s-*\\(generic\\|port\\|\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\)\\>\\s-*\\(\\w+\\s-*\\)?(")
7957 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7960 (defun vhdl-hooked-abbrev (func)
7961 "Do function, if syntax says abbrev is a keyword, invoked by hooked abbrev,
7962 but not if inside a comment or quote)."
7963 (if (or (vhdl-in-comment-p)
7967 (and (looking-at "\\<end\\>") (not (looking-at "\\<end;")))))
7972 (if (not vhdl-electric-mode)
7979 (let ((invoke-char last-command-char)
7981 (vhdl-template-invoked-by-hook t))
7982 (let ((caught (catch 'abort
7984 (when (stringp caught) (message caught)))
7985 (when (= invoke-char ?-) (setq abbrev-start-location (point)))
7986 ;; delete CR which is still in event queue
7987 (if (string-match "XEmacs" emacs-version)
7988 (enqueue-eval-event 'delete-char -1)
7989 (setq unread-command-events ; push back a delete char
7990 (list (vhdl-character-to-event ?\177))))))))
7992 (defun vhdl-template-alias-hook ()
7993 (vhdl-hooked-abbrev 'vhdl-template-alias))
7994 (defun vhdl-template-architecture-hook ()
7995 (vhdl-hooked-abbrev 'vhdl-template-architecture))
7996 (defun vhdl-template-assert-hook ()
7997 (vhdl-hooked-abbrev 'vhdl-template-assert))
7998 (defun vhdl-template-attribute-hook ()
7999 (vhdl-hooked-abbrev 'vhdl-template-attribute))
8000 (defun vhdl-template-block-hook ()
8001 (vhdl-hooked-abbrev 'vhdl-template-block))
8002 (defun vhdl-template-break-hook ()
8003 (vhdl-hooked-abbrev 'vhdl-template-break))
8004 (defun vhdl-template-case-hook ()
8005 (vhdl-hooked-abbrev 'vhdl-template-case))
8006 (defun vhdl-template-component-hook ()
8007 (vhdl-hooked-abbrev 'vhdl-template-component))
8008 (defun vhdl-template-instance-hook ()
8009 (vhdl-hooked-abbrev 'vhdl-template-instance))
8010 (defun vhdl-template-conditional-signal-asst-hook ()
8011 (vhdl-hooked-abbrev 'vhdl-template-conditional-signal-asst))
8012 (defun vhdl-template-configuration-hook ()
8013 (vhdl-hooked-abbrev 'vhdl-template-configuration))
8014 (defun vhdl-template-constant-hook ()
8015 (vhdl-hooked-abbrev 'vhdl-template-constant))
8016 (defun vhdl-template-disconnect-hook ()
8017 (vhdl-hooked-abbrev 'vhdl-template-disconnect))
8018 (defun vhdl-template-display-comment-hook ()
8019 (vhdl-hooked-abbrev 'vhdl-comment-display))
8020 (defun vhdl-template-else-hook ()
8021 (vhdl-hooked-abbrev 'vhdl-template-else))
8022 (defun vhdl-template-elsif-hook ()
8023 (vhdl-hooked-abbrev 'vhdl-template-elsif))
8024 (defun vhdl-template-entity-hook ()
8025 (vhdl-hooked-abbrev 'vhdl-template-entity))
8026 (defun vhdl-template-exit-hook ()
8027 (vhdl-hooked-abbrev 'vhdl-template-exit))
8028 (defun vhdl-template-file-hook ()
8029 (vhdl-hooked-abbrev 'vhdl-template-file))
8030 (defun vhdl-template-for-hook ()
8031 (vhdl-hooked-abbrev 'vhdl-template-for))
8032 (defun vhdl-template-function-hook ()
8033 (vhdl-hooked-abbrev 'vhdl-template-function))
8034 (defun vhdl-template-generic-hook ()
8035 (vhdl-hooked-abbrev 'vhdl-template-generic))
8036 (defun vhdl-template-group-hook ()
8037 (vhdl-hooked-abbrev 'vhdl-template-group))
8038 (defun vhdl-template-library-hook ()
8039 (vhdl-hooked-abbrev 'vhdl-template-library))
8040 (defun vhdl-template-limit-hook ()
8041 (vhdl-hooked-abbrev 'vhdl-template-limit))
8042 (defun vhdl-template-if-hook ()
8043 (vhdl-hooked-abbrev 'vhdl-template-if))
8044 (defun vhdl-template-bare-loop-hook ()
8045 (vhdl-hooked-abbrev 'vhdl-template-bare-loop))
8046 (defun vhdl-template-map-hook ()
8047 (vhdl-hooked-abbrev 'vhdl-template-map))
8048 (defun vhdl-template-nature-hook ()
8049 (vhdl-hooked-abbrev 'vhdl-template-nature))
8050 (defun vhdl-template-next-hook ()
8051 (vhdl-hooked-abbrev 'vhdl-template-next))
8052 (defun vhdl-template-package-hook ()
8053 (vhdl-hooked-abbrev 'vhdl-template-package))
8054 (defun vhdl-template-port-hook ()
8055 (vhdl-hooked-abbrev 'vhdl-template-port))
8056 (defun vhdl-template-procedural-hook ()
8057 (vhdl-hooked-abbrev 'vhdl-template-procedural))
8058 (defun vhdl-template-procedure-hook ()
8059 (vhdl-hooked-abbrev 'vhdl-template-procedure))
8060 (defun vhdl-template-process-hook ()
8061 (vhdl-hooked-abbrev 'vhdl-template-process))
8062 (defun vhdl-template-quantity-hook ()
8063 (vhdl-hooked-abbrev 'vhdl-template-quantity))
8064 (defun vhdl-template-report-hook ()
8065 (vhdl-hooked-abbrev 'vhdl-template-report))
8066 (defun vhdl-template-return-hook ()
8067 (vhdl-hooked-abbrev 'vhdl-template-return))
8068 (defun vhdl-template-selected-signal-asst-hook ()
8069 (vhdl-hooked-abbrev 'vhdl-template-selected-signal-asst))
8070 (defun vhdl-template-signal-hook ()
8071 (vhdl-hooked-abbrev 'vhdl-template-signal))
8072 (defun vhdl-template-subnature-hook ()
8073 (vhdl-hooked-abbrev 'vhdl-template-subnature))
8074 (defun vhdl-template-subtype-hook ()
8075 (vhdl-hooked-abbrev 'vhdl-template-subtype))
8076 (defun vhdl-template-terminal-hook ()
8077 (vhdl-hooked-abbrev 'vhdl-template-terminal))
8078 (defun vhdl-template-type-hook ()
8079 (vhdl-hooked-abbrev 'vhdl-template-type))
8080 (defun vhdl-template-use-hook ()
8081 (vhdl-hooked-abbrev 'vhdl-template-use))
8082 (defun vhdl-template-variable-hook ()
8083 (vhdl-hooked-abbrev 'vhdl-template-variable))
8084 (defun vhdl-template-wait-hook ()
8085 (vhdl-hooked-abbrev 'vhdl-template-wait))
8086 (defun vhdl-template-when-hook ()
8087 (vhdl-hooked-abbrev 'vhdl-template-when))
8088 (defun vhdl-template-while-loop-hook ()
8089 (vhdl-hooked-abbrev 'vhdl-template-while-loop))
8090 (defun vhdl-template-with-hook ()
8091 (vhdl-hooked-abbrev 'vhdl-template-with))
8092 (defun vhdl-template-and-hook ()
8093 (vhdl-hooked-abbrev 'vhdl-template-and))
8094 (defun vhdl-template-or-hook ()
8095 (vhdl-hooked-abbrev 'vhdl-template-or))
8096 (defun vhdl-template-nand-hook ()
8097 (vhdl-hooked-abbrev 'vhdl-template-nand))
8098 (defun vhdl-template-nor-hook ()
8099 (vhdl-hooked-abbrev 'vhdl-template-nor))
8100 (defun vhdl-template-xor-hook ()
8101 (vhdl-hooked-abbrev 'vhdl-template-xor))
8102 (defun vhdl-template-xnor-hook ()
8103 (vhdl-hooked-abbrev 'vhdl-template-xnor))
8104 (defun vhdl-template-not-hook ()
8105 (vhdl-hooked-abbrev 'vhdl-template-not))
8107 (defun vhdl-template-default-hook ()
8108 (vhdl-hooked-abbrev 'vhdl-template-default))
8109 (defun vhdl-template-default-indent-hook ()
8110 (vhdl-hooked-abbrev 'vhdl-template-default-indent))
8112 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8113 ;; Template insertion from completion list
8115 (defun vhdl-template-insert-construct (name)
8116 "Insert the built-in construct template with NAME."
8118 (list (let ((completion-ignore-case t))
8119 (completing-read "Construct name: "
8120 vhdl-template-construct-alist nil t))))
8121 (vhdl-template-insert-fun
8122 (car (cdr (assoc name vhdl-template-construct-alist)))))
8124 (defun vhdl-template-insert-package (name)
8125 "Insert the built-in package template with NAME."
8127 (list (let ((completion-ignore-case t))
8128 (completing-read "Package name: "
8129 vhdl-template-package-alist nil t))))
8130 (vhdl-template-insert-fun
8131 (car (cdr (assoc name vhdl-template-package-alist)))))
8133 (defun vhdl-template-insert-directive (name)
8134 "Insert the built-in directive template with NAME."
8136 (list (let ((completion-ignore-case t))
8137 (completing-read "Directive name: "
8138 vhdl-template-directive-alist nil t))))
8139 (vhdl-template-insert-fun
8140 (car (cdr (assoc name vhdl-template-directive-alist)))))
8142 (defun vhdl-template-insert-fun (fun)
8143 "Call FUN to insert a built-in template."
8144 (let ((caught (catch 'abort (when fun (funcall fun)))))
8145 (when (stringp caught) (message caught))))
8148 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8150 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8152 (defun vhdl-model-insert (model-name)
8153 "Insert the user model with name MODEL-NAME."
8155 (let ((completion-ignore-case t))
8156 (list (completing-read "Model name: " vhdl-model-alist))))
8158 (let ((start (point-marker))
8159 (margin (current-indentation))
8160 (case-fold-search t)
8161 model position prompt string end)
8162 (vhdl-ext-syntax-table
8163 (when (setq model (assoc model-name vhdl-model-alist))
8166 (delete-horizontal-space)
8168 (vhdl-insert-string-or-file (nth 1 model))
8169 (setq end (point-marker))
8173 (while (< (point) end)
8174 (unless (looking-at "^$")
8175 (insert-char ? margin))
8176 (beginning-of-line 2))
8179 (unless (equal "" vhdl-clock-name)
8180 (while (re-search-forward "<clock>" end t)
8181 (replace-match vhdl-clock-name)))
8184 (unless (equal "" vhdl-reset-name)
8185 (while (re-search-forward "<reset>" end t)
8186 (replace-match vhdl-reset-name)))
8189 (while (re-search-forward
8190 (concat "<\\(" vhdl-template-prompt-syntax "\\)>") end t)
8191 (unless (equal "cursor" (match-string 1))
8192 (setq position (match-beginning 1))
8193 (setq prompt (match-string 1))
8195 (setq string (vhdl-template-field prompt nil t))
8196 ;; replace occurrences of same prompt
8197 (while (re-search-forward (concat "<\\(" prompt "\\)>") end t)
8198 (replace-match (or string "")))
8199 (goto-char position)))
8201 ;; goto final position
8202 (if (re-search-forward "<cursor>" end t)
8204 (goto-char end))))))
8206 (defun vhdl-model-defun ()
8207 "Define help and hook functions for user models."
8208 (let ((model-alist vhdl-model-alist)
8209 model-name model-keyword)
8211 ;; define functions for user models that can be invoked from menu and key
8212 ;; bindings and which themselves call `vhdl-model-insert' with the model
8214 (setq model-name (nth 0 (car model-alist)))
8215 (eval `(defun ,(vhdl-function-name "vhdl-model" model-name) ()
8216 ,(concat "Insert model for \"" model-name "\".")
8218 (vhdl-model-insert ,model-name)))
8219 ;; define hooks for user models that are invoked from keyword abbrevs
8220 (setq model-keyword (nth 3 (car model-alist)))
8221 (unless (equal model-keyword "")
8223 ,(vhdl-function-name
8224 "vhdl-model" model-name "hook") ()
8226 ',(vhdl-function-name "vhdl-model" model-name)))))
8227 (setq model-alist (cdr model-alist)))))
8232 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8233 ;;; Port translation
8234 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8236 (defvar vhdl-port-list nil
8237 "Variable to hold last PORT map parsed.")
8238 ;; structure: (parenthesised expression means list of such entries)
8239 ;; ((generic-names) generic-type generic-init generic-comment)
8240 ;; ((port-names) port-object port-direct port-type port-comment)
8242 (defun vhdl-parse-string (string &optional optional)
8243 "Check that the text following point matches the regexp in STRING.
8244 END is the point beyond which matching/searching should not go."
8245 (if (looking-at string)
8246 (re-search-forward string nil t)
8248 (throw 'parse (format "Syntax error near line %s" (vhdl-current-line))))
8251 (defun vhdl-replace-string (regexp-cons string)
8252 "Replace STRING from car of REGEXP-CONS to cdr of REGEXP-CONS."
8253 (vhdl-ext-syntax-table
8254 (if (string-match (car regexp-cons) string)
8255 (replace-match (cdr regexp-cons) t nil string)
8258 (defun vhdl-port-flatten ()
8259 "Flatten port list so that only one generic/port exists per line."
8261 (if (not vhdl-port-list)
8262 (error "No port read")
8263 (message "Flattening port...")
8264 (let ((new-vhdl-port-list (list (car vhdl-port-list)))
8265 (old-vhdl-port-list (cdr vhdl-port-list))
8266 old-port-list new-port-list old-port new-port names)
8267 ;; traverse port list and flatten entries
8268 (while old-vhdl-port-list
8269 (setq old-port-list (car old-vhdl-port-list))
8270 (setq new-port-list nil)
8271 (while old-port-list
8272 (setq old-port (car old-port-list))
8273 (setq names (car old-port))
8275 (setq new-port (cons (list (car names)) (cdr old-port)))
8276 (setq new-port-list (append new-port-list (list new-port)))
8277 (setq names (cdr names)))
8278 (setq old-port-list (cdr old-port-list)))
8279 (setq old-vhdl-port-list (cdr old-vhdl-port-list))
8280 (setq new-vhdl-port-list (append new-vhdl-port-list
8281 (list new-port-list))))
8282 (setq vhdl-port-list new-vhdl-port-list)
8283 (message "Flattening port...done"))))
8285 (defun vhdl-port-copy ()
8286 "Get generic and port information from an entity or component declaration."
8288 (message "Reading port...")
8290 (let ((case-fold-search t)
8291 parse-error end-of-list
8293 object names direct type init comment)
8294 (vhdl-ext-syntax-table
8298 ;; check if within entity or component declaration
8299 (when (or (not (re-search-backward
8300 "^\\s-*\\(component\\|entity\\|end\\)\\>" nil t))
8301 (equal "end" (match-string 1)))
8302 (throw 'parse "Not within entity or component declaration"))
8304 (vhdl-parse-string "\\s-*\\(\\w+\\)\\s-*\\(is\\)?\\s-*$")
8305 (setq name (match-string 1))
8306 (vhdl-forward-syntactic-ws)
8307 ;; parse generic clause
8308 (when (vhdl-parse-string "generic[ \t\n]*(" t)
8309 (vhdl-forward-syntactic-ws)
8310 (setq end-of-list (looking-at ")"))
8311 (while (not end-of-list)
8313 (vhdl-parse-string "\\(\\w+\\)[ \t\n]*")
8314 (setq names (list (match-string 1)))
8315 (while (vhdl-parse-string ",[ \t\n]*\\(\\w+\\)[ \t\n]*" t)
8316 (setq names (append names (list (match-string 1)))))
8318 (vhdl-parse-string ":[ \t\n]*\\([^():;\n]+\\)")
8319 (setq type (match-string 1))
8321 (while (looking-at "(")
8325 (point) (progn (forward-sexp) (point)))
8326 (and (vhdl-parse-string "\\([^():;\n]*\\)" t)
8327 (match-string 1)))))
8328 ;; special case: closing parenthesis is on separate line
8329 (when (and type (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" type))
8330 (setq comment (substring type (match-beginning 2)))
8331 (setq type (substring type 0 (match-beginning 1))))
8332 ;; strip of trailing whitespace
8333 (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
8334 (setq type (substring type 0 (match-end 1)))
8335 ;; parse initialization expression
8337 (when (vhdl-parse-string ":=[ \t\n]*" t)
8338 (vhdl-parse-string "\\([^();\n]*\\)")
8339 (setq init (match-string 1))
8340 (while (looking-at "(")
8344 (point) (progn (forward-sexp) (point)))
8345 (and (vhdl-parse-string "\\([^();\n]*\\)" t)
8346 (match-string 1))))))
8347 ;; special case: closing parenthesis is on separate line
8348 (when (and init (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" init))
8349 (setq comment (substring init (match-beginning 2)))
8350 (setq init (substring init 0 (match-beginning 1)))
8351 (vhdl-forward-syntactic-ws))
8352 (skip-chars-forward " \t")
8353 ;; parse inline comment, special case: as above, no initial.
8355 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
8357 (vhdl-forward-syntactic-ws)
8358 (setq end-of-list (vhdl-parse-string ")" t))
8359 (vhdl-parse-string ";\\s-*")
8360 ;; parse inline comment
8362 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
8364 (vhdl-forward-syntactic-ws)
8365 ;; save everything in list
8366 (setq generics (append generics
8367 (list (list names type init comment))))))
8368 ;; parse port clause
8369 (when (vhdl-parse-string "port[ \t\n]*(" t)
8370 (vhdl-forward-syntactic-ws)
8371 (setq end-of-list (looking-at ")"))
8372 (while (not end-of-list)
8375 (and (vhdl-parse-string
8376 "\\(signal\\|quantity\\|terminal\\)[ \t\n]*" t)
8379 (vhdl-parse-string "\\(\\w+\\)[ \t\n]*")
8380 (setq names (list (match-string 1)))
8381 (while (vhdl-parse-string ",[ \t\n]*\\(\\w+\\)[ \t\n]*" t)
8382 (setq names (append names (list (match-string 1)))))
8384 (vhdl-parse-string ":[ \t\n]*")
8386 (and (vhdl-parse-string "\\(IN\\|OUT\\|INOUT\\)[ \t\n]+" t)
8389 (vhdl-parse-string "\\([^();\n]+\\)")
8390 (setq type (match-string 1))
8392 (while (looking-at "(")
8393 (setq type (concat type
8395 (point) (progn (forward-sexp) (point)))
8396 (and (vhdl-parse-string "\\([^();\n]*\\)" t)
8397 (match-string 1)))))
8398 ;; special case: closing parenthesis is on separate line
8399 (when (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" type)
8400 (setq comment (substring type (match-beginning 2)))
8401 (setq type (substring type 0 (match-beginning 1))))
8402 ;; strip of trailing whitespace
8403 (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
8404 (setq type (substring type 0 (match-end 1)))
8405 (vhdl-forward-syntactic-ws)
8406 (setq end-of-list (vhdl-parse-string ")" t))
8407 (vhdl-parse-string ";\\s-*")
8408 ;; parse inline comment
8410 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
8412 (vhdl-forward-syntactic-ws)
8413 ;; save everything in list
8416 (list (list names object direct type comment))))))
8421 (setq vhdl-port-list (list name generics ports))
8422 (message "Reading port...done")))))
8424 (defun vhdl-port-paste-generic (&optional no-init)
8425 "Paste a generic clause."
8426 (let ((margin (current-indentation))
8427 list-margin start names generic
8428 (generics-list (nth 1 vhdl-port-list)))
8429 ;; paste generic clause
8431 (setq start (point))
8432 (vhdl-insert-keyword "GENERIC (")
8433 (unless vhdl-argument-list-indent
8434 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
8435 (setq list-margin (current-column))
8436 (while generics-list
8438 (setq generic (car generics-list))
8439 (setq names (nth 0 generic))
8441 (insert (car names))
8442 (setq names (cdr names))
8443 (when names (insert ", ")))
8445 (insert " : " (nth 1 generic))
8446 ;; paste initialization
8447 (when (and (not no-init) (nth 2 generic))
8448 (insert " := " (nth 2 generic)))
8449 (unless (cdr generics-list) (insert ")"))
8452 (when (and vhdl-include-port-comments (nth 3 generic))
8453 (vhdl-comment-insert-inline (nth 3 generic) t))
8454 (setq generics-list (cdr generics-list))
8455 (when generics-list (insert "\n") (indent-to list-margin)))
8456 ;; align generic clause
8457 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1 t)))))
8459 (defun vhdl-port-paste-port ()
8460 "Paste a port clause."
8461 (let ((margin (current-indentation))
8462 list-margin start names port
8463 (ports-list (nth 2 vhdl-port-list)))
8464 ;; paste port clause
8466 (setq start (point))
8467 (vhdl-insert-keyword "PORT (")
8468 (unless vhdl-argument-list-indent
8469 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
8470 (setq list-margin (current-column))
8472 (setq port (car ports-list))
8474 (when (nth 1 port) (insert (nth 1 port) " "))
8476 (setq names (nth 0 port))
8478 (insert (car names))
8479 (setq names (cdr names))
8480 (when names (insert ", ")))
8483 (when (nth 2 port) (insert (nth 2 port) " "))
8485 (insert (nth 3 port))
8486 (unless (cdr ports-list) (insert ")"))
8489 (when (and vhdl-include-port-comments (nth 4 port))
8490 (vhdl-comment-insert-inline (nth 4 port) t))
8491 (setq ports-list (cdr ports-list))
8492 (when ports-list (insert "\n") (indent-to list-margin)))
8493 ;; align port clause
8494 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1)))))
8496 (defun vhdl-port-paste-declaration (kind)
8497 "Paste as an entity or component declaration."
8499 (let ((margin (current-indentation))
8500 (name (nth 0 vhdl-port-list)))
8501 (vhdl-insert-keyword (if (eq kind 'entity) "ENTITY " "COMPONENT "))
8503 (if (eq kind 'entity) (vhdl-insert-keyword " IS"))
8504 ;; paste generic and port clause
8505 (when (nth 1 vhdl-port-list)
8507 (when (and (memq vhdl-insert-empty-lines '(unit all)) (eq kind 'entity))
8509 (indent-to (+ margin vhdl-basic-offset))
8510 (vhdl-port-paste-generic (eq kind 'component)))
8511 (when (nth 2 vhdl-port-list)
8513 (when (and (memq vhdl-insert-empty-lines '(unit all))
8516 (indent-to (+ margin vhdl-basic-offset)))
8517 (vhdl-port-paste-port)
8519 (when (and (memq vhdl-insert-empty-lines '(unit all)) (eq kind 'entity))
8522 (vhdl-insert-keyword "END")
8523 (if (eq kind 'entity)
8525 (unless (vhdl-standard-p '87) (vhdl-insert-keyword " ENTITY"))
8527 (vhdl-insert-keyword " COMPONENT")
8528 (unless (vhdl-standard-p '87) (insert " " name)))
8531 (defun vhdl-port-paste-entity ()
8532 "Paste as an entity declaration."
8534 (if (not vhdl-port-list)
8535 (error "No port read")
8536 (message "Pasting port as entity...")
8537 (vhdl-port-paste-declaration 'entity)
8538 (message "Pasting port as entity...done")))
8540 (defun vhdl-port-paste-component ()
8541 "Paste as a component declaration."
8543 (if (not vhdl-port-list)
8544 (error "No port read")
8545 (message "Pasting port as component...")
8546 (vhdl-port-paste-declaration 'component)
8547 (message "Pasting port as component...done")))
8549 (defun vhdl-port-paste-generic-map (&optional secondary no-constants)
8550 "Paste as a generic map."
8552 (unless secondary (vhdl-indent-line))
8553 (let ((margin (current-indentation))
8554 list-margin start generic
8555 (generics-list (nth 1 vhdl-port-list)))
8557 (setq start (point))
8558 (vhdl-insert-keyword "GENERIC MAP (")
8559 (if (not vhdl-association-list-with-formals)
8560 ;; paste list of actual generics
8561 (while generics-list
8562 (insert (or (nth 2 (car generics-list)) " "))
8563 (setq generics-list (cdr generics-list))
8564 (insert (if generics-list ", " ")")))
8565 (unless vhdl-argument-list-indent
8566 (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset))))
8567 (setq list-margin (current-column))
8568 (while generics-list
8569 (setq generic (car generics-list))
8570 ;; paste formal and actual generic
8571 (insert (car (nth 0 generic)) " => "
8573 (car (nth 0 generic))
8574 (or (nth 2 generic) "")))
8575 (setq generics-list (cdr generics-list))
8576 (insert (if generics-list "," ")"))
8578 (when (and vhdl-include-port-comments (nth 3 generic))
8579 (vhdl-comment-insert-inline (nth 3 generic) t))
8580 (when generics-list (insert "\n") (indent-to list-margin)))
8581 ;; align generic map
8582 (when vhdl-auto-align
8583 (vhdl-align-noindent-region start (point) 1 t))))))
8585 (defun vhdl-port-paste-port-map ()
8586 "Paste as a port map."
8587 (let ((margin (current-indentation))
8588 list-margin start port
8589 (ports-list (nth 2 vhdl-port-list)))
8591 (setq start (point))
8592 (vhdl-insert-keyword "PORT MAP (")
8593 (if (not vhdl-association-list-with-formals)
8594 ;; paste list of actual ports
8596 (insert (vhdl-replace-string vhdl-actual-port-name
8597 (car (nth 0 (car ports-list)))))
8598 (setq ports-list (cdr ports-list))
8599 (insert (if ports-list ", " ");")))
8600 (unless vhdl-argument-list-indent
8601 (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset))))
8602 (setq list-margin (current-column))
8604 (setq port (car ports-list))
8605 ;; paste formal and actual port
8606 (insert (car (nth 0 port)) " => ")
8607 (insert (vhdl-replace-string vhdl-actual-port-name
8608 (car (nth 0 port))))
8609 (setq ports-list (cdr ports-list))
8610 (insert (if ports-list "," ");"))
8612 (when (or vhdl-include-direction-comments
8613 (and vhdl-include-port-comments (nth 4 port)))
8614 (vhdl-comment-insert-inline
8616 (if vhdl-include-direction-comments
8617 (format "%-4s" (or (concat (nth 2 port) " ") "")) "")
8618 (if vhdl-include-port-comments (nth 4 port) "")) t))
8619 (when ports-list (insert "\n") (indent-to list-margin)))
8620 ;; align port clause
8621 (when vhdl-auto-align
8622 (vhdl-align-noindent-region start (point) 1))))))
8624 (defun vhdl-port-paste-instance (&optional name)
8625 "Paste as an instantiation."
8627 (if (not vhdl-port-list)
8628 (error "No port read")
8629 (let ((orig-vhdl-port-list vhdl-port-list))
8630 ;; flatten local copy of port list (must be flat for port mapping)
8633 (let ((margin (current-indentation))
8634 list-margin start generic port
8635 (generics-list (nth 1 vhdl-port-list))
8636 (ports-list (nth 2 vhdl-port-list)))
8637 ;; paste instantiation
8640 (if (equal (cdr vhdl-instance-name) "")
8641 (vhdl-template-field "instance name" ": ")
8642 (insert (vhdl-replace-string vhdl-instance-name
8643 (nth 0 vhdl-port-list)) ": ")))
8644 (message "Pasting port as instantiation...")
8645 (if (vhdl-standard-p '87)
8646 (insert (nth 0 vhdl-port-list))
8647 (vhdl-insert-keyword "ENTITY ")
8648 (insert "work." (nth 0 vhdl-port-list)))
8649 (when (nth 1 vhdl-port-list)
8650 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
8651 (vhdl-port-paste-generic-map t t))
8652 (when (nth 2 vhdl-port-list)
8653 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
8654 (vhdl-port-paste-port-map))
8655 (message "Pasting port as instantiation...done"))
8656 (setq vhdl-port-list orig-vhdl-port-list))))
8658 (defun vhdl-port-paste-signals (&optional initialize)
8659 "Paste ports as internal signals."
8661 (if (not vhdl-port-list)
8662 (error "No port read")
8663 (message "Pasting port as signals...")
8665 (let ((margin (current-indentation))
8667 (ports-list (nth 2 vhdl-port-list)))
8669 (setq start (point))
8671 (setq port (car ports-list))
8674 (insert (nth 1 port) " ")
8675 (vhdl-insert-keyword "SIGNAL "))
8676 ;; paste actual port signals
8677 (setq names (nth 0 port))
8679 (insert (vhdl-replace-string vhdl-actual-port-name (car names)))
8680 (setq names (cdr names))
8681 (when names (insert ", ")))
8683 (insert " : " (nth 3 port))
8684 ;; paste initialization (inputs only)
8685 (when (and initialize (equal "in" (nth 2 port)))
8688 (if (string-match "(.+)" (nth 3 port)) "(others => '0')" "'0'")))
8691 (when (and vhdl-include-port-comments (nth 4 port))
8692 (vhdl-comment-insert-inline (nth 4 port) t))
8693 (setq ports-list (cdr ports-list))
8694 (when ports-list (insert "\n") (indent-to margin)))
8695 ;; align signal list
8696 (when vhdl-auto-align (vhdl-align-noindent-region start (point) 1))))
8697 (message "Pasting port as signals...done")))
8699 (defun vhdl-port-paste-constants ()
8700 "Paste generics as constants."
8702 (if (not vhdl-port-list)
8703 (error "No port read")
8704 (let ((orig-vhdl-port-list vhdl-port-list))
8705 (message "Pasting port as constants...")
8706 ;; flatten local copy of port list (must be flat for constant initial.)
8709 (let ((margin (current-indentation))
8711 (generics-list (nth 1 vhdl-port-list)))
8713 (setq start (point))
8714 (while generics-list
8715 (setq generic (car generics-list))
8716 (vhdl-insert-keyword "CONSTANT ")
8717 ;; paste generic constants
8718 (setq name (nth 0 generic))
8722 (insert " : " (nth 1 generic))
8723 ;; paste initialization
8724 (when (nth 2 generic)
8725 (insert " := " (nth 2 generic)))
8728 (when (and vhdl-include-port-comments (nth 3 generic))
8729 (vhdl-comment-insert-inline (nth 3 generic) t))
8730 (setq generics-list (cdr generics-list))
8731 (when generics-list (insert "\n") (indent-to margin))))
8732 ;; align signal list
8733 (when vhdl-auto-align
8734 (vhdl-align-noindent-region start (point) 1))))
8735 (message "Pasting port as constants...done")
8736 (setq vhdl-port-list orig-vhdl-port-list))))
8738 (defun vhdl-port-paste-testbench ()
8739 "Paste as a bare-bones test bench."
8741 (if (not vhdl-port-list)
8742 (error "No port read")
8743 (message "Pasting port as test bench...")
8744 (let ((case-fold-search t)
8745 (ent-name (vhdl-replace-string vhdl-testbench-entity-name
8746 (nth 0 vhdl-port-list)))
8747 (source-buffer (current-buffer))
8748 arch-name ent-file-name arch-file-name no-entity position)
8750 (when (not (eq vhdl-testbench-create-files 'none))
8751 (string-match "\\.[^.]*\\'" (buffer-file-name (current-buffer)))
8754 (substring (buffer-file-name (current-buffer))
8755 (match-beginning 0))))
8756 (when (file-exists-p ent-file-name)
8758 (concat "File `" ent-file-name "' exists; overwrite? "))
8759 (progn (delete-file ent-file-name)
8760 (when (get-file-buffer ent-file-name)
8761 (set-buffer ent-file-name)
8762 (set-buffer-modified-p nil)
8763 (kill-buffer ent-file-name)))
8764 (if (eq vhdl-testbench-create-files 'separate)
8766 (error "Pasting port as test bench...aborted"))))
8768 (set-buffer source-buffer)
8769 (find-file ent-file-name)))
8771 (unless (and (eq vhdl-testbench-create-files 'separate) no-entity)
8772 ;; paste entity header
8773 (unless (equal "" vhdl-testbench-entity-header)
8774 (vhdl-insert-string-or-file vhdl-testbench-entity-header))
8775 (vhdl-comment-display-line) (insert "\n\n") (indent-to margin)
8776 ;; paste std_logic_1164 package
8777 (vhdl-insert-keyword "LIBRARY ")
8778 (insert "ieee;\n") (indent-to margin)
8779 (vhdl-insert-keyword "USE ")
8780 (insert "ieee.std_logic_1164.")
8781 (vhdl-insert-keyword "ALL;")
8782 (insert "\n\n") (indent-to margin) (vhdl-comment-display-line)
8783 (insert "\n\n") (indent-to margin)
8784 ;; paste entity declaration
8785 (vhdl-insert-keyword "ENTITY ")
8787 (vhdl-insert-keyword " IS")
8788 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
8789 (insert "\n") (indent-to margin)
8790 (vhdl-insert-keyword "END ")
8791 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ENTITY "))
8792 (insert ent-name ";")
8793 (insert "\n\n") (indent-to margin)
8794 (vhdl-comment-display-line) (insert "\n"))
8795 ;; get architecture name
8797 (if (equal (cdr vhdl-testbench-architecture-name) "")
8798 (read-from-minibuffer "architecture name: "
8799 nil vhdl-minibuffer-local-map)
8800 (vhdl-replace-string vhdl-testbench-architecture-name
8801 (nth 0 vhdl-port-list))))
8802 ;; open architecture file
8803 (when (eq vhdl-testbench-create-files 'separate)
8805 (string-match "\\.[^.]*\\'" (buffer-file-name (current-buffer)))
8806 (setq arch-file-name
8808 (substring (buffer-file-name (current-buffer))
8809 (match-beginning 0))))
8810 (when (file-exists-p arch-file-name)
8812 (concat "File `" ent-file-name "' exists; overwrite? "))
8813 (progn (delete-file arch-file-name)
8814 (when (get-file-buffer arch-file-name)
8815 (set-buffer (get-file-buffer arch-file-name))
8816 (set-buffer-modified-p nil)
8817 (kill-buffer arch-file-name)))
8818 (error "Pasting port as test bench...aborted")))
8819 (set-buffer source-buffer)
8820 (find-file arch-file-name)
8821 ;; paste architecture header
8822 (unless (equal "" vhdl-testbench-architecture-header)
8823 (vhdl-insert-string-or-file vhdl-testbench-architecture-header))
8824 (vhdl-comment-display-line)
8826 (insert "\n") (indent-to margin)
8827 ;; paste architecture body
8828 (vhdl-insert-keyword "ARCHITECTURE ")
8830 (vhdl-insert-keyword " OF ")
8832 (vhdl-insert-keyword " IS")
8833 (insert "\n\n") (indent-to margin)
8834 ;; paste component declaration
8835 (when (vhdl-standard-p '87)
8836 (vhdl-port-paste-component)
8837 (insert "\n\n") (indent-to margin))
8839 (when (nth 1 vhdl-port-list)
8840 (vhdl-port-paste-constants)
8841 (insert "\n\n") (indent-to margin))
8842 ;; paste internal signals
8843 (vhdl-port-paste-signals vhdl-testbench-initialize-signals)
8844 ;; paste custom declarations
8845 (unless (equal "" vhdl-testbench-declarations)
8847 (vhdl-insert-string-or-file vhdl-testbench-declarations)
8848 (delete-indentation))
8849 (setq position (point))
8850 (insert "\n\n") (indent-to margin)
8851 (vhdl-comment-display-line) (insert "\n")
8852 (goto-char position)
8853 (vhdl-template-begin-end
8854 (unless (vhdl-standard-p '87) "ARCHITECTURE")
8856 ;; paste instantiation
8857 (vhdl-port-paste-instance
8858 (vhdl-replace-string vhdl-testbench-dut-name
8859 (nth 0 vhdl-port-list)))
8861 ;; paste custom statements
8862 (unless (equal "" vhdl-testbench-statements)
8864 (vhdl-insert-string-or-file vhdl-testbench-statements))
8866 (indent-to (+ margin vhdl-basic-offset))
8867 (when (not (eq vhdl-testbench-create-files 'none))
8869 (message "Pasting port as test bench...done")))))
8872 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8874 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8876 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8877 ;; Hippie expand customization
8879 (defvar vhdl-expand-upper-case nil)
8881 (defun vhdl-try-expand-abbrev (old)
8882 "Try expanding abbreviations from `vhdl-abbrev-list'."
8884 (he-init-string (he-dabbrev-beg) (point))
8885 (setq he-expand-list
8886 (let ((abbrev-list vhdl-abbrev-list)
8887 (sel-abbrev-list '()))
8889 (when (or (not (stringp (car abbrev-list)))
8891 (concat "^" he-search-string) (car abbrev-list)))
8892 (setq sel-abbrev-list
8893 (cons (car abbrev-list) sel-abbrev-list)))
8894 (setq abbrev-list (cdr abbrev-list)))
8895 (nreverse sel-abbrev-list))))
8896 (while (and he-expand-list
8897 (or (not (stringp (car he-expand-list)))
8898 (he-string-member (car he-expand-list) he-tried-table t)))
8899 ; (equal (car he-expand-list) he-search-string)))
8900 (unless (stringp (car he-expand-list))
8901 (setq vhdl-expand-upper-case (car he-expand-list)))
8902 (setq he-expand-list (cdr he-expand-list)))
8903 (if (null he-expand-list)
8904 (progn (when old (he-reset-string))
8906 (he-substitute-string
8907 (if vhdl-expand-upper-case
8908 (upcase (car he-expand-list))
8909 (car he-expand-list))
8911 (setq he-expand-list (cdr he-expand-list))
8914 (defun vhdl-he-list-beg ()
8915 "Also looks at the word before `(' in order to better match parenthesized
8916 expressions (e.g. for index ranges of types and signals)."
8919 (progn (backward-up-list 1)
8920 (skip-syntax-backward "w_")) ; crashes in `viper-mode'
8924 ;; override `he-list-beg' from `hippie-exp'
8925 (unless (and (boundp 'viper-mode) viper-mode)
8926 (require 'hippie-exp)
8927 (defalias 'he-list-beg 'vhdl-he-list-beg))
8929 ;; function for expanding abbrevs and dabbrevs
8930 (fset 'vhdl-expand-abbrev (make-hippie-expand-function
8931 '(try-expand-dabbrev
8932 try-expand-dabbrev-all-buffers
8933 vhdl-try-expand-abbrev)))
8935 ;; function for expanding parenthesis
8936 (fset 'vhdl-expand-paren (make-hippie-expand-function
8938 try-expand-list-all-buffers)))
8940 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8943 (defun vhdl-fix-case-region-1 (beg end upper-case word-regexp &optional count)
8944 "Convert all words matching word-regexp in region to lower or upper case,
8945 depending on parameter upper-case."
8946 (let ((case-fold-search t)
8949 (vhdl-ext-syntax-table
8952 (setq end (point-marker))
8954 (while (re-search-forward word-regexp end t)
8955 (or (vhdl-in-comment-p)
8959 (downcase-word -1)))
8960 (when (and count vhdl-progress-interval
8961 (< vhdl-progress-interval
8962 (- (nth 1 (current-time)) last-update)))
8963 (message "Fixing case... (%2d%s)"
8964 (+ (* count 25) (/ (* 25 (- (point) beg)) (- end beg)))
8966 (setq last-update (nth 1 (current-time)))))
8968 (and count vhdl-progress-interval (message "Fixing case...done"))))
8970 (defun vhdl-fix-case-region (beg end &optional arg)
8971 "Convert all VHDL words in region to lower or upper case, depending on
8972 variables vhdl-upper-case-{keywords,types,attributes,enum-values}."
8973 (interactive "r\nP")
8974 (vhdl-fix-case-region-1
8975 beg end vhdl-upper-case-keywords vhdl-keywords-regexp 0)
8976 (vhdl-fix-case-region-1
8977 beg end vhdl-upper-case-types vhdl-types-regexp 1)
8978 (vhdl-fix-case-region-1
8979 beg end vhdl-upper-case-attributes (concat "'" vhdl-attributes-regexp) 2)
8980 (vhdl-fix-case-region-1
8981 beg end vhdl-upper-case-enum-values vhdl-enum-values-regexp 3))
8983 (defun vhdl-fix-case-buffer ()
8984 "Convert all VHDL words in buffer to lower or upper case, depending on
8985 variables vhdl-upper-case-{keywords,types,attributes,enum-values}."
8987 (vhdl-fix-case-region (point-min) (point-max)))
8989 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8990 ;; Line handling functions
8992 (defun vhdl-current-line ()
8993 "Return the line number of the line containing point."
8998 (1+ (count-lines 1 (point))))))
9000 (defun vhdl-line-kill-entire (&optional arg)
9001 "Delete entire line."
9004 (kill-line (or arg 1)))
9006 (defun vhdl-line-kill (&optional arg)
9007 "Kill current line."
9009 (vhdl-line-kill-entire arg))
9011 (defun vhdl-line-copy (&optional arg)
9012 "Copy current line."
9016 (let ((position (point)))
9017 (forward-line (or arg 1))
9018 (copy-region-as-kill position (point)))))
9020 (defun vhdl-line-yank ()
9026 (defun vhdl-line-expand (&optional prefix-arg)
9027 "Hippie-expand current line."
9029 (let ((case-fold-search t) (case-replace nil)
9030 (hippie-expand-try-functions-list
9031 '(try-expand-line try-expand-line-all-buffers)))
9032 (hippie-expand prefix-arg)))
9034 (defun vhdl-line-transpose-next (&optional arg)
9035 "Interchange this line with next line."
9038 (transpose-lines (or arg 1))
9041 (defun vhdl-line-transpose-previous (&optional arg)
9042 "Interchange this line with previous line."
9045 (transpose-lines (- 0 (or arg 0)))
9048 (defun vhdl-line-open ()
9049 "Open a new line and indent."
9052 (newline-and-indent))
9055 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9057 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9059 (defun vhdl-project-switch (name)
9060 "Switch to project NAME."
9061 (setq vhdl-project name)
9062 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
9063 (speedbar-refresh)))
9066 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9068 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9069 ;; (using `compile.el')
9071 (defun vhdl-compile-init ()
9072 "Initialize for compilation."
9073 (unless compilation-error-regexp-alist
9074 (setq compilation-error-regexp-alist
9075 (let ((commands-alist vhdl-compiler-alist)
9076 regexp-alist sublist)
9077 (while commands-alist
9078 (setq sublist (nth 5 (car commands-alist)))
9079 (unless (equal "" (car sublist))
9081 (cons (list (nth 0 sublist)
9082 (if (= 0 (nth 1 sublist))
9084 "XEmacs" emacs-version) 9 nil)
9088 (setq commands-alist (cdr commands-alist)))
9090 (unless compilation-file-regexp-alist
9091 (setq compilation-file-regexp-alist
9092 (let ((commands-alist vhdl-compiler-alist)
9094 (while commands-alist
9095 (unless (equal "" (car (nth 6 (car commands-alist))))
9097 (append regexp-alist
9098 (list (nth 6 (car commands-alist))))))
9099 (setq commands-alist (cdr commands-alist)))
9102 (defun vhdl-compile ()
9103 "Compile current buffer using the VHDL compiler specified in
9107 (let* ((command-elem (assoc vhdl-compiler vhdl-compiler-alist))
9108 (command (nth 1 command-elem))
9109 (default-directory (expand-file-name (nth 4 command-elem))))
9111 (compile (concat command " " vhdl-compiler-options
9112 (unless (string-equal vhdl-compiler-options "") " ")
9113 (buffer-file-name))))))
9116 "Call make command for compilation of all updated source files (requires
9120 (let* ((command-elem (assoc vhdl-compiler vhdl-compiler-alist))
9121 (command (nth 2 command-elem))
9122 (default-directory (expand-file-name (nth 4 command-elem))))
9123 (if (equal command "")
9125 (compile command))))
9127 (defun vhdl-generate-makefile ()
9128 "Generate new `Makefile'."
9131 (let* ((command-elem (assoc vhdl-compiler vhdl-compiler-alist))
9132 (command (nth 3 command-elem))
9133 (default-directory (expand-file-name (nth 4 command-elem))))
9134 (if (not (equal command ""))
9136 (error "No such command specified for `%s'" vhdl-compiler))))
9139 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9141 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9142 ;; (using `hideshow.el')
9144 (defun vhdl-forward-unit (&optional count)
9145 "Find begin and end of VHDL design units (for hideshow)."
9147 (let ((case-fold-search t))
9150 "^\\(architecture\\|configuration\\|entity\\|package\\)\\>" nil t)
9151 (re-search-forward "^end\\>" nil t))))
9153 (when (string-match "XEmacs" emacs-version)
9154 (require 'hideshow))
9156 (unless (assq 'vhdl-mode hs-special-modes-alist)
9157 (setq hs-special-modes-alist
9160 "\\(^\\)\\(architecture\\|ARCHITECTURE\\|configuration\\|CONFIGURATION\\|entity\\|ENTITY\\|package\\|PACKAGE\\)\\>"
9161 "\\(^\\)\\(end\\|END\\)\\>"
9164 hs-special-modes-alist)))
9166 (defun vhdl-hideshow-init ()
9167 "Initialize `hideshow'."
9168 (if vhdl-hide-all-init
9169 (add-hook 'hs-minor-mode-hook 'hs-hide-all)
9170 (remove-hook 'hs-minor-mode-hook 'hs-hide-all))
9171 (if vhdl-hideshow-menu
9173 (when (boundp 'hs-minor-mode) (hs-minor-mode 0))))
9176 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9178 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9179 ;; (using `font-lock.el')
9181 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9182 ;; Help functions for translate-off region highlighting
9184 (defun vhdl-within-translate-off ()
9185 "Return point if within translate-off region, else nil."
9186 (and (save-excursion
9188 "^\\s-*--\\s-*pragma\\s-*translate_\\(on\\|off\\)\\s-*\n" nil t))
9189 (equal "off" (match-string 1))
9192 (defun vhdl-start-translate-off (limit)
9193 "Return point before translate-off pragma if before LIMIT, else nil."
9194 (when (re-search-forward
9195 "^\\s-*--\\s-*pragma\\s-*translate_off\\s-*\n" limit t)
9196 (match-beginning 0)))
9198 (defun vhdl-end-translate-off (limit)
9199 "Return point after translate-on pragma if before LIMIT, else nil."
9200 (re-search-forward "^\\s-*--\\s-*pragma\\s-*translate_on\\s-*\n" limit t))
9202 (defun vhdl-match-translate-off (limit)
9203 "Match a translate-off block, setting match-data and returning t, else nil."
9204 (when (< (point) limit)
9205 (let ((start (or (vhdl-within-translate-off)
9206 (vhdl-start-translate-off limit)))
9207 (case-fold-search t))
9209 (let ((end (or (vhdl-end-translate-off limit) limit)))
9210 (set-match-data (list start end))
9211 (goto-char end))))))
9213 (defun vhdl-font-lock-match-item (limit)
9214 "Match, and move over, any declaration item after point. Adapted from
9215 `font-lock-match-c-style-declaration-item-and-skip-to-next'."
9218 (narrow-to-region (point-min) limit)
9220 (when (looking-at "\\s-*\\(\\w+\\)")
9222 (goto-char (match-end 1))
9223 ;; move to next item
9224 (if (looking-at "\\(\\s-*,\\)")
9225 (goto-char (match-end 1))
9229 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9230 ;; Syntax definitions
9232 (defconst vhdl-font-lock-syntactic-keywords
9233 '(("\\(\'\\).\\(\'\\)" (1 (7 . ?\')) (2 (7 . ?\'))))
9234 "Mark single quotes as having string quote syntax in 'c' instances.")
9236 (defvar vhdl-font-lock-keywords nil
9237 "Regular expressions to highlight in VHDL Mode.")
9239 (defconst vhdl-font-lock-keywords-0
9241 ;; highlight template prompts
9242 (list (concat "\\(<" vhdl-template-prompt-syntax ">\\)")
9243 1 'vhdl-font-lock-prompt-face t)
9245 ;; highlight directives
9246 '("--\\s-*pragma\\s-+\\(.*\\)$" 1 vhdl-font-lock-directive-face t)
9248 "For consideration as a value of `vhdl-font-lock-keywords'.
9249 This does highlighting of template prompts and directives (pragmas).")
9251 (defvar vhdl-font-lock-keywords-1 nil
9252 ;; set in `vhdl-font-lock-init' because dependent on custom variables
9253 "For consideration as a value of `vhdl-font-lock-keywords'.
9254 This does highlighting of keywords and standard identifiers.")
9256 (defconst vhdl-font-lock-keywords-2
9258 ;; highlight names of units, subprograms, and components when declared
9262 "architecture\\|configuration\\|entity\\|package\\(\\s-+body\\|\\)\\|"
9263 "\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\|component"
9264 "\\)\\s-+\\(\\w+\\)")
9265 5 'font-lock-function-name-face)
9267 ;; highlight entity names of architectures and configurations
9269 "^\\s-*\\(architecture\\|configuration\\)\\s-+\\w+\\s-+of\\s-+\\(\\w+\\)"
9270 2 'font-lock-function-name-face)
9272 ;; highlight labels of common constructs
9275 "^\\s-*\\(\\w+\\)\\s-*:\\(\\s-\\|\n\\)*\\(\\("
9276 "assert\\|block\\|case\\|component\\|configuration\\|entity\\|exit\\|"
9277 "for\\|if\\|loop\\|next\\|null\\|postponed\\|process\\|"
9278 (when (vhdl-standard-p 'ams) "procedural\\|")
9280 "\\)\\>\\|[^\n]*<=\\)")
9281 1 'font-lock-function-name-face)
9283 ;; highlight label and component name of component instantiations
9286 "^\\s-*\\(\\w+\\)\\s-*:[ \t\n]*\\(component\\s-+\\|\\)\\(\\w+\\)"
9287 "\\(\\s-\\|\n\\)+\\(generic\\|port\\)\\s-+map\\>")
9288 '(1 font-lock-function-name-face) '(3 font-lock-function-name-face))
9290 ;; highlight names and labels at end of constructs
9293 "^\\s-*end\\s-+\\(\\("
9294 "architecture\\|block\\|case\\|component\\|configuration\\|entity\\|"
9295 "for\\|function\\|generate\\|if\\|loop\\|package\\(\\s-+body\\|\\)\\|"
9296 "procedure\\|\\(postponed\\s-+\\|\\)process\\|"
9297 (when (vhdl-standard-p 'ams) "procedural\\|")
9299 "\\)\\>\\|\\)\\s-*\\(\\w*\\)")
9300 5 'font-lock-function-name-face)
9302 ;; highlight labels in exit and next statements
9305 "^\\s-*\\(\\w+\\s-*:\\s-*\\)?\\(exit\\|next\\)\\s-+\\(\\w*\\)")
9306 3 'font-lock-function-name-face)
9308 ;; highlight entity name in attribute specifications
9311 "^\\s-*attribute\\s-+\\w+\\s-+of\\s-+\\(\\w+\\(,\\s-*\\w+\\)*\\)\\s-*:")
9312 1 'font-lock-function-name-face)
9314 ;; highlight labels in component specifications
9317 "^\\s-*for\\s-+\\(\\w+\\(,\\s-*\\w+\\)*\\)\\s-*:"
9318 "\\(\\s-\\|\n\\)*\\(\\w+\\)")
9319 '(1 font-lock-function-name-face) '(4 font-lock-function-name-face))
9321 ;; highlight attribute name in attribute declarations/specifications
9324 "^\\s-*attribute\\s-+\\(\\w+\\)")
9325 1 'vhdl-font-lock-attribute-face)
9327 ;; highlight type/nature name in (sub)type/(sub)nature declarations
9330 "^\\s-*\\(sub\\|\\)\\(nature\\|type\\)\\s-+\\(\\w+\\)")
9331 3 'font-lock-type-face)
9333 ;; highlight signal/variable/constant declaration names
9335 '(vhdl-font-lock-match-item
9336 (progn (goto-char (match-beginning 1))
9337 (skip-syntax-backward " ")
9338 (skip-syntax-backward "w_")
9339 (skip-syntax-backward " ")
9340 (while (= (preceding-char) ?,)
9342 (skip-syntax-backward " ")
9343 (skip-syntax-backward "w_")
9344 (skip-syntax-backward " ")))
9345 ; (skip-chars-backward "^-(\n\";")
9346 (goto-char (match-end 1)) (1 font-lock-variable-name-face)))
9348 ;; highlight alias/group declaration names and for-loop/-generate variables
9349 (list "\\<\\(alias\\|for\\|group\\)\\s-+\\w+\\s-+\\(in\\|is\\)\\>"
9350 '(vhdl-font-lock-match-item
9351 (progn (goto-char (match-end 1)) (match-beginning 2))
9352 nil (1 font-lock-variable-name-face)))
9354 "For consideration as a value of `vhdl-font-lock-keywords'.
9355 This does context sensitive highlighting of names and labels.")
9357 (defvar vhdl-font-lock-keywords-3 nil
9358 ;; set in `vhdl-font-lock-init' because dependent on custom variables
9359 "For consideration as a value of `vhdl-font-lock-keywords'.
9360 This does highlighting of words with special syntax.")
9362 (defvar vhdl-font-lock-keywords-4 nil
9363 ;; set in `vhdl-font-lock-init' because dependent on custom variables
9364 "For consideration as a value of `vhdl-font-lock-keywords'.
9365 This does highlighting of additional reserved words.")
9367 (defconst vhdl-font-lock-keywords-5
9368 ;; background highlight translate-off regions
9369 '((vhdl-match-translate-off (0 vhdl-font-lock-translate-off-face append)))
9370 "For consideration as a value of `vhdl-font-lock-keywords'.
9371 This does background highlighting of translate-off regions.")
9373 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9374 ;; Font and color definitions
9376 (defvar vhdl-font-lock-prompt-face 'vhdl-font-lock-prompt-face
9377 "Face name to use for prompts.")
9379 (defvar vhdl-font-lock-attribute-face 'vhdl-font-lock-attribute-face
9380 "Face name to use for standardized attributes.")
9382 (defvar vhdl-font-lock-enumvalue-face 'vhdl-font-lock-enumvalue-face
9383 "Face name to use for standardized enumeration values.")
9385 (defvar vhdl-font-lock-function-face 'vhdl-font-lock-function-face
9386 "Face name to use for standardized functions and packages.")
9388 (defvar vhdl-font-lock-directive-face 'vhdl-font-lock-directive-face
9389 "Face name to use for directives.")
9391 (defvar vhdl-font-lock-reserved-words-face 'vhdl-font-lock-reserved-words-face
9392 "Face name to use for additional reserved words.")
9394 (defvar vhdl-font-lock-translate-off-face 'vhdl-font-lock-translate-off-face
9395 "Face name to use for translate-off regions.")
9397 ;; face names to use for words with special syntax.
9398 (let ((syntax-alist vhdl-special-syntax-alist)
9401 (setq name (vhdl-function-name
9402 "vhdl-font-lock" (nth 0 (car syntax-alist)) "face"))
9403 (eval `(defvar ,name ',name
9404 ,(concat "Face name to use for "
9405 (nth 0 (car syntax-alist)) ".")))
9406 (setq syntax-alist (cdr syntax-alist))))
9408 (defgroup vhdl-highlight-faces nil
9409 "Faces for highlighting."
9410 :group 'vhdl-highlight)
9412 ;; add faces used from `font-lock'
9413 (custom-add-to-group
9414 'vhdl-highlight-faces 'font-lock-comment-face 'custom-face)
9415 (custom-add-to-group
9416 'vhdl-highlight-faces 'font-lock-string-face 'custom-face)
9417 (custom-add-to-group
9418 'vhdl-highlight-faces 'font-lock-keyword-face 'custom-face)
9419 (custom-add-to-group
9420 'vhdl-highlight-faces 'font-lock-type-face 'custom-face)
9421 (custom-add-to-group
9422 'vhdl-highlight-faces 'font-lock-function-name-face 'custom-face)
9423 (custom-add-to-group
9424 'vhdl-highlight-faces 'font-lock-variable-name-face 'custom-face)
9426 (defface vhdl-font-lock-prompt-face
9427 '((((class color) (background light)) (:foreground "Red" :weight bold))
9428 (((class color) (background dark)) (:foreground "Pink" :weight bold))
9429 (t (:inverse-video t)))
9430 "Font lock mode face used to highlight prompts."
9431 :group 'vhdl-highlight-faces
9432 :group 'font-lock-highlighting-faces)
9434 (defface vhdl-font-lock-attribute-face
9435 '((((class color) (background light)) (:foreground "Orchid"))
9436 (((class color) (background dark)) (:foreground "LightSteelBlue"))
9437 (t (:slant italic :weight bold)))
9438 "Font lock mode face used to highlight standardized attributes."
9439 :group 'vhdl-highlight-faces
9440 :group 'font-lock-highlighting-faces)
9442 (defface vhdl-font-lock-enumvalue-face
9443 '((((class color) (background light)) (:foreground "Gold4"))
9444 (((class color) (background dark)) (:foreground "BurlyWood"))
9445 (t (:slant italic :weight bold)))
9446 "Font lock mode face used to highlight standardized enumeration values."
9447 :group 'vhdl-highlight-faces
9448 :group 'font-lock-highlighting-faces)
9450 (defface vhdl-font-lock-function-face
9451 '((((class color) (background light)) (:foreground "Orchid4"))
9452 (((class color) (background dark)) (:foreground "Orchid1"))
9453 (t (:slant italic :weight bold)))
9454 "Font lock mode face used to highlight standardized functions and packages."
9455 :group 'vhdl-highlight-faces
9456 :group 'font-lock-highlighting-faces)
9458 (defface vhdl-font-lock-directive-face
9459 '((((class color) (background light)) (:foreground "CadetBlue"))
9460 (((class color) (background dark)) (:foreground "Aquamarine"))
9461 (t (:slant italic :weight bold)))
9462 "Font lock mode face used to highlight directives."
9463 :group 'vhdl-highlight-faces
9464 :group 'font-lock-highlighting-faces)
9466 (defface vhdl-font-lock-reserved-words-face
9467 '((((class color) (background light)) (:foreground "Orange" :weight bold))
9468 (((class color) (background dark)) (:foreground "Yellow" :weight bold))
9470 "Font lock mode face used to highlight additional reserved words."
9471 :group 'vhdl-highlight-faces
9472 :group 'font-lock-highlighting-faces)
9474 (defface vhdl-font-lock-translate-off-face
9475 '((((class color) (background light)) (:background "LightGray"))
9476 (((class color) (background dark)) (:background "DimGray"))
9478 "Font lock mode face used to background highlight translate-off regions."
9479 :group 'vhdl-highlight-faces
9480 :group 'font-lock-highlighting-faces)
9482 ;; font lock mode faces used to highlight words with special syntax.
9483 (let ((syntax-alist vhdl-special-syntax-alist))
9485 (eval `(defface ,(vhdl-function-name
9486 "vhdl-font-lock" (car (car syntax-alist)) "face")
9487 '((((class color) (background light))
9488 (:foreground ,(nth 2 (car syntax-alist))))
9489 (((class color) (background dark))
9490 (:foreground ,(nth 3 (car syntax-alist))))
9492 ,(concat "Font lock mode face used to highlight "
9493 (nth 0 (car syntax-alist)) ".")
9494 :group 'vhdl-highlight-faces
9495 :group 'font-lock-highlighting-faces))
9496 (setq syntax-alist (cdr syntax-alist))))
9498 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9499 ;; Font lock initialization
9501 (defun vhdl-font-lock-init ()
9502 "Initialize fontification."
9503 ;; highlight keywords and standardized types, attributes, enumeration
9504 ;; values, and subprograms
9505 (setq vhdl-font-lock-keywords-1
9507 (list (concat "'" vhdl-attributes-regexp)
9508 1 'vhdl-font-lock-attribute-face)
9509 (list vhdl-types-regexp 1 'font-lock-type-face)
9510 (list vhdl-functions-regexp 1 'vhdl-font-lock-function-face)
9511 (list vhdl-packages-regexp 1 'vhdl-font-lock-function-face)
9512 (list vhdl-enum-values-regexp 1 'vhdl-font-lock-enumvalue-face)
9513 (list vhdl-keywords-regexp 1 'font-lock-keyword-face)))
9514 ;; highlight words with special syntax.
9515 (setq vhdl-font-lock-keywords-3
9516 (let ((syntax-alist vhdl-special-syntax-alist)
9521 (cons (concat "\\<\\(" (nth 1 (car syntax-alist)) "\\)\\>")
9523 "vhdl-font-lock" (nth 0 (car syntax-alist)) "face"))
9525 (setq syntax-alist (cdr syntax-alist)))
9527 ;; highlight additional reserved words
9528 (setq vhdl-font-lock-keywords-4
9529 (list (list vhdl-reserved-words-regexp 1
9530 'vhdl-font-lock-reserved-words-face)))
9531 ;; highlight everything together
9532 (setq vhdl-font-lock-keywords
9534 vhdl-font-lock-keywords-0
9535 (when vhdl-highlight-keywords vhdl-font-lock-keywords-1)
9536 (when (or vhdl-highlight-forbidden-words
9537 vhdl-highlight-verilog-keywords) vhdl-font-lock-keywords-4)
9538 (when vhdl-highlight-special-words vhdl-font-lock-keywords-3)
9539 (when vhdl-highlight-names vhdl-font-lock-keywords-2)
9540 (when vhdl-highlight-translate-off vhdl-font-lock-keywords-5))))
9542 ;; initialize fontification for VHDL Mode
9543 (vhdl-font-lock-init)
9545 (defun vhdl-fontify-buffer ()
9546 "Re-initialize fontification and fontify buffer."
9548 (setq font-lock-defaults
9550 'vhdl-font-lock-keywords nil
9551 (not vhdl-highlight-case-sensitive) '((?\_ . "w")) 'beginning-of-line
9552 '(font-lock-syntactic-keywords . vhdl-font-lock-syntactic-keywords)))
9553 (when (fboundp 'font-lock-unset-defaults)
9554 (font-lock-unset-defaults)) ; not implemented in XEmacs
9555 (font-lock-set-defaults)
9556 (font-lock-fontify-buffer))
9558 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9559 ;; Initialization for postscript printing
9561 (defun vhdl-ps-print-settings ()
9562 "Initialize custom face and page settings for postscript printing."
9563 ;; define custom face settings
9564 (unless (or (not vhdl-print-customize-faces)
9566 (set (make-local-variable 'ps-bold-faces)
9567 '(font-lock-keyword-face
9569 vhdl-font-lock-attribute-face
9570 vhdl-font-lock-enumvalue-face
9571 vhdl-font-lock-directive-face))
9572 (set (make-local-variable 'ps-italic-faces)
9573 '(font-lock-comment-face
9574 font-lock-function-name-face
9576 vhdl-font-lock-attribute-face
9577 vhdl-font-lock-enumvalue-face
9578 vhdl-font-lock-directive-face))
9579 (set (make-local-variable 'ps-underlined-faces)
9580 '(font-lock-string-face))
9581 (setq ps-always-build-face-reference t))
9582 ;; define page settings, so that a line containing 79 characters (default)
9583 ;; fits into one column
9584 (when vhdl-print-two-column
9585 (set (make-local-variable 'ps-landscape-mode) t)
9586 (set (make-local-variable 'ps-number-of-columns) 2)
9587 (set (make-local-variable 'ps-font-size) 7.0)
9588 (set (make-local-variable 'ps-header-title-font-size) 10.0)
9589 (set (make-local-variable 'ps-header-font-size) 9.0)
9590 (set (make-local-variable 'ps-header-offset) 12.0)
9591 (when (eq ps-paper-type 'letter)
9592 (set (make-local-variable 'ps-inter-column) 40.0)
9593 (set (make-local-variable 'ps-left-margin) 40.0)
9594 (set (make-local-variable 'ps-right-margin) 40.0))))
9596 (defun vhdl-ps-print-init ()
9597 "Initialize postscript printing."
9598 (if (string-match "XEmacs" emacs-version)
9599 (vhdl-ps-print-settings)
9600 (make-local-variable 'ps-print-hook)
9601 (add-hook 'ps-print-hook 'vhdl-ps-print-settings)))
9604 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9605 ;;; Hierarchy browser (using `speedbar.el')
9606 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9607 ;; Allows displaying the hierarchy of all VHDL design units contained in a
9608 ;; directory by using the speedbar.
9610 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9613 (defvar vhdl-entity-alist nil
9614 "Cache with entities and corresponding architectures and configurations for
9615 each visited directory.")
9616 ;; structure: (parenthesised expression means list of such entries)
9618 ;; (ent-name ent-file ent-line
9619 ;; (arch-name arch-file arch-line
9620 ;; (inst-name inst-file inst-line inst-ent-name inst-arch-name))
9621 ;; (conf-name conf-file conf-line))
9623 (defvar vhdl-package-alist nil
9624 "Cache with packages for each visited directory.")
9625 ;; structure: (parenthesised expression means list of such entries)
9627 ;; (pack-name pack-file pack-line pack-body-file pack-body-line))
9629 (defvar vhdl-ent-inst-alist nil
9630 "Cache with instantiated entities for each visited directory.")
9631 ;; structure: (parenthesised expression means list of such entries)
9632 ;; (directory-name (inst-ent-name))
9634 (defvar vhdl-project-entity-alist nil
9635 "Cache with entities and corresponding architectures and configurations for
9636 each visited project.")
9637 ;; same structure as `vhdl-entity-alist'
9639 (defvar vhdl-project-package-alist nil
9640 "Cache with packages for each visited directory.")
9641 ;; same structure as `vhdl-package-alist'
9643 (defvar vhdl-project-ent-inst-list nil
9644 "Cache with instantiated entities for each visited directory.")
9645 ;; same structure as `vhdl-ent-inst-alist'
9647 (defvar vhdl-speedbar-shown-units-alist nil
9648 "Alist of design units simultaneously open in the current speedbar for each
9649 directory and project.")
9651 (defvar vhdl-speedbar-last-file-name nil
9652 "Last file for which design units were highlighted.")
9654 (defvar vhdl-file-alist nil
9655 "Cache with design units in each file.")
9656 ;; structure (parenthesised expression means list of such entries)
9657 ;; (file-name (ent-list) (arch-list) (conf-list) (pack-list) (inst-list))
9660 (defsubst vhdl-speedbar-project-p ()
9661 "Return non-nil if a project is displayed, i.e. directories or files are
9663 (nth 1 (aget vhdl-project-alist vhdl-project)))
9665 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9668 (defun vhdl-scan-file-contents (name &optional num-string)
9669 "Scan contents of VHDL files in FILE-LIST."
9670 (string-match "\\(.*/\\)\\(.*\\)" name)
9671 ; (unless (file-directory-p (match-string 1 name))
9672 ; (message "No such directory: \"%s\"" (match-string 1 name)))
9673 (let* ((is-directory (= (match-beginning 2) (match-end 2)))
9676 (nreverse (vhdl-get-source-files t name))
9677 (vhdl-directory-files (match-string 1 name) t
9678 (wildcard-to-regexp (match-string 2 name)))))
9679 (case-fold-search t)
9680 (source-buffer (current-buffer))
9681 ent-alist pack-alist ent-inst-list no-files)
9682 (when (and (not is-directory) (null file-list))
9683 (message "No such file: \"%s\"" name))
9686 (setq no-files (length file-list))
9689 (message "Scanning %s %s\"%s\"... (%2d%s)"
9690 (if is-directory "directory" "files")
9691 (or num-string "") name
9692 (/ (* 100 (- no-files (length file-list))) no-files) "%")
9693 (let ((file-name (abbreviate-file-name (car file-list)))
9694 opened arch-name ent-name
9695 ent-list arch-list conf-list pack-list inst-list)
9697 (if (find-buffer-visiting file-name)
9698 (set-buffer (find-buffer-visiting file-name))
9699 (set-buffer (find-file-noselect file-name nil t))
9701 (modify-syntax-entry ?_ "w" (syntax-table))
9702 ;; scan for entities
9703 (goto-char (point-min))
9704 (while (re-search-forward "^\\s-*entity\\s-+\\(\\w+\\)" nil t)
9705 (let* ((ent-entry (aget ent-alist (match-string 1)))
9706 (arch-alist (nth 2 ent-entry))
9707 (conf-alist (nth 3 ent-entry)))
9708 (setq ent-list (cons (match-string 1) ent-list))
9709 (aput 'ent-alist (match-string 1)
9710 (list file-name (vhdl-current-line)
9711 arch-alist conf-alist nil))))
9712 ;; scan for architectures and instantiations
9713 (goto-char (point-min))
9714 (while (re-search-forward
9716 "^\\s-*\\(architecture\\s-+\\(\\w+\\)\\s-+of\\s-+\\(\\w+\\)\\|"
9717 "\\(\\w+\\)\\s-*:\\(\\s-\\|\n\\)*\\(entity\\s-+\\w+\\.\\)?"
9718 "\\(\\w+\\)\\(\\s-*(\\(\\w+\\))\\)?\\(\\s-\\|\n\\|--.*\n\\)*"
9719 "\\(generic\\|port\\)\\s-+map\\>\\)")
9721 (if (match-string 2)
9722 ;; architecture found
9723 (let* ((ent-entry (aget ent-alist (match-string 3)))
9724 (arch-alist (nth 2 ent-entry))
9725 (conf-alist (nth 3 ent-entry)))
9726 (setq arch-name (match-string 2))
9727 (setq ent-name (match-string 3))
9728 (setq arch-list (cons arch-name arch-list))
9729 (vhdl-aappend 'arch-alist arch-name
9730 (list file-name (vhdl-current-line) nil))
9731 (setq ent-entry (list (nth 0 ent-entry) (nth 1 ent-entry)
9732 arch-alist conf-alist nil))
9733 (aput 'ent-alist ent-name ent-entry))
9734 ;; instantiation found
9735 (let* ((ent-entry (aget ent-alist ent-name))
9736 (arch-alist (nth 2 ent-entry))
9737 (arch-entry (aget arch-alist arch-name))
9738 (inst-alist (nth 2 arch-entry))
9739 (inst-name (match-string 4))
9740 (inst-ent-name (match-string 7))
9741 (inst-arch-name (match-string 9))
9742 (conf-alist (nth 3 ent-entry)))
9743 (re-search-backward ":" nil t)
9744 (setq inst-list (cons inst-name inst-list))
9745 (vhdl-aappend 'inst-alist inst-name
9746 (list file-name (vhdl-current-line)
9747 inst-ent-name inst-arch-name))
9749 (list (nth 0 arch-entry) (nth 1 arch-entry)
9751 (vhdl-aappend 'arch-alist arch-name arch-entry)
9752 (setq ent-entry (list (nth 0 ent-entry) (nth 1 ent-entry)
9753 arch-alist conf-alist nil))
9754 (aput 'ent-alist ent-name ent-entry)
9755 (unless (member inst-ent-name ent-inst-list)
9757 (cons inst-ent-name ent-inst-list))))))
9758 ;; scan for configurations
9759 (goto-char (point-min))
9760 (while (re-search-forward
9761 "^\\s-*configuration\\s-+\\(\\w+\\)\\s-+of\\s-+\\(\\w+\\)"
9763 (let* ((ent-entry (aget ent-alist (match-string 2)))
9764 (arch-alist (nth 2 ent-entry))
9765 (conf-alist (nth 3 ent-entry)))
9766 (setq conf-list (cons (match-string 1) conf-list))
9767 (vhdl-aappend 'conf-alist (match-string 1)
9768 (list file-name (vhdl-current-line)))
9769 (setq ent-entry (list (nth 0 ent-entry) (nth 1 ent-entry)
9770 arch-alist conf-alist nil))
9771 (aput 'ent-alist (match-string 2) ent-entry)))
9772 ;; scan for packages
9773 (goto-char (point-min))
9774 (while (re-search-forward
9775 "^\\s-*package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" nil t)
9776 (let ((pack-entry (aget pack-alist (match-string 2))))
9777 (setq pack-list (cons (match-string 2) pack-list))
9778 (aput 'pack-alist (match-string 2)
9779 (if (not (match-string 1))
9780 (list file-name (vhdl-current-line)
9781 (nth 2 pack-entry) (nth 3 pack-entry))
9782 (list (nth 0 pack-entry) (nth 1 pack-entry)
9783 file-name (vhdl-current-line))))))
9784 (setq file-list (cdr file-list))
9785 ;; add design units to variable `vhdl-file-alist'
9786 (aput 'vhdl-file-alist file-name
9787 (list ent-list arch-list conf-list pack-list inst-list))
9790 (kill-buffer (current-buffer))
9791 (when (not vhdl-underscore-is-part-of-word)
9792 (modify-syntax-entry ?_ "_" vhdl-mode-syntax-table)))
9793 (set-buffer source-buffer)))
9794 ;; sort entities and packages
9797 (function (lambda (a b) (string-lessp (car a) (car b))))))
9800 (function (lambda (a b) (string-lessp (car a) (car b))))))
9801 ;; put directory contents into cache
9803 (aput 'vhdl-entity-alist name ent-alist))
9805 (aput 'vhdl-package-alist name pack-alist))
9807 (aput 'vhdl-ent-inst-alist name (list ent-inst-list)))
9808 (message "Scanning %s %s\"%s\"...done"
9809 (if is-directory "directory" "files") (or num-string "") name)
9812 (defun vhdl-scan-project-contents (project &optional rescan)
9813 "Scan the contents of all VHDL files found in the directories and files
9815 (let ((dir-list-tmp (nth 1 (aget vhdl-project-alist project)))
9816 dir-list pro-ent-alist pro-pack-alist pro-ent-inst-list
9817 dir name num-dir act-dir)
9818 ;; resolve environment variables and path wildcards
9819 (setq dir-list-tmp (vhdl-resolve-paths dir-list-tmp))
9820 ;; expand directories
9822 (setq dir (car dir-list-tmp))
9823 ;; get subdirectories
9824 (if (string-match "-r \\(.*/\\)" dir)
9825 (setq dir-list (append dir-list (vhdl-get-subdirs
9826 (match-string 1 dir))))
9827 (setq dir-list (append dir-list (list dir))))
9828 (setq dir-list-tmp (cdr dir-list-tmp)))
9829 ;; get entities and packages of each directory in DIR-LIST
9830 (setq num-dir (length dir-list)
9833 (setq name (abbreviate-file-name (car dir-list)))
9834 (or (and (not rescan)
9835 (or (assoc name vhdl-entity-alist)
9836 (assoc name vhdl-package-alist)))
9837 (vhdl-scan-file-contents name (format "(%s/%s) " act-dir num-dir)))
9838 ;; merge entities and corresponding architectures and configurations
9839 (let ((ent-alist (aget vhdl-entity-alist name)))
9841 (let* ((ent-name (car (car ent-alist)))
9842 (ent-entry (cdr (car ent-alist)))
9843 (pro-ent-entry (aget pro-ent-alist ent-name)))
9844 (aput 'pro-ent-alist ent-name
9845 (list (or (nth 0 pro-ent-entry) (nth 0 ent-entry))
9846 (or (nth 1 pro-ent-entry) (nth 1 ent-entry))
9847 (append (nth 2 pro-ent-entry) (nth 2 ent-entry))
9848 (append (nth 3 pro-ent-entry) (nth 3 ent-entry)))))
9849 (setq ent-alist (cdr ent-alist))))
9850 ;; merge packages and corresponding package bodies
9851 (let ((pack-alist (aget vhdl-package-alist name)))
9853 (let* ((pack-name (car (car pack-alist)))
9854 (pack-entry (cdr (car pack-alist)))
9855 (pro-pack-entry (aget pro-pack-alist pack-name)))
9856 (aput 'pro-pack-alist pack-name
9857 (list (or (nth 0 pro-pack-entry) (nth 0 pack-entry))
9858 (or (nth 1 pro-pack-entry) (nth 1 pack-entry))
9859 (or (nth 2 pro-pack-entry) (nth 2 pack-entry))
9860 (or (nth 3 pro-pack-entry) (nth 3 pack-entry)))))
9861 (setq pack-alist (cdr pack-alist))))
9862 ;; merge list of instantiated entities
9863 (setq pro-ent-inst-list
9864 (append pro-ent-inst-list
9866 (car (aget vhdl-ent-inst-alist name)))))
9867 (setq dir-list (cdr dir-list)
9868 act-dir (1+ act-dir)))
9869 ;; sort lists and put them into the caches
9871 (aput 'vhdl-project-entity-alist project
9873 (function (lambda (a b) (string-lessp (car a) (car b)))))))
9874 (when pro-pack-alist
9875 (aput 'vhdl-project-package-alist project
9876 (sort pro-pack-alist
9877 (function (lambda (a b) (string-lessp (car a) (car b)))))))
9878 (when pro-ent-inst-list
9879 (aput 'vhdl-project-ent-inst-list project pro-ent-inst-list))))
9881 (defun vhdl-get-hierarchy (ent-name arch-name level indent &optional ent-hier)
9882 "Get instantiation hierarchy beginning in architecture ARCH-NAME of
9884 (let* ((ent-alist (if (vhdl-speedbar-project-p)
9885 (aget vhdl-project-entity-alist vhdl-project)
9886 (aget vhdl-entity-alist
9887 (abbreviate-file-name
9888 (file-name-as-directory
9889 (speedbar-line-path (1- indent)))))))
9890 (ent-entry (aget ent-alist ent-name))
9891 (arch-entry (if arch-name (aget (nth 2 ent-entry) arch-name)
9892 (cdr (car (last (nth 2 ent-entry))))))
9893 (inst-list (nth 2 arch-entry))
9894 inst-entry inst-ent-entry inst-arch-entry hier-list)
9895 (when (= level 0) (message "Extract design hierarchy..."))
9896 (when (member ent-name ent-hier)
9897 (error (format "Instantiation loop detected; component \"%s\" instantiates itself"
9900 (setq inst-entry (car inst-list))
9901 (setq inst-ent-entry (aget ent-alist (nth 3 inst-entry)))
9902 (setq inst-arch-entry
9903 (if (nth 4 inst-entry)
9904 (cons (nth 4 inst-entry)
9905 (aget (nth 2 inst-ent-entry) (nth 4 inst-entry)))
9906 (car (last (nth 2 inst-ent-entry)))))
9910 (cons (list (nth 0 inst-entry)
9911 (cons (nth 1 inst-entry) (nth 2 inst-entry))
9913 (cons (nth 0 inst-ent-entry) (nth 1 inst-ent-entry))
9914 (nth 0 inst-arch-entry)
9915 (cons (nth 1 inst-arch-entry) (nth 2 inst-arch-entry))
9917 (vhdl-get-hierarchy (nth 3 inst-entry) (nth 4 inst-entry)
9919 (cons ent-name ent-hier)))))
9920 (setq inst-list (cdr inst-list)))
9921 (when (= level 0) (message "Extract design hierarchy...done"))
9924 (defun vhdl-get-instantiations (ent-name indent)
9925 "Get all instantiations of entity ENT-NAME."
9926 (let ((ent-alist (if (vhdl-speedbar-project-p)
9927 (aget vhdl-project-entity-alist vhdl-project)
9928 (aget vhdl-entity-alist
9929 (abbreviate-file-name
9930 (file-name-as-directory
9931 (speedbar-line-path indent))))))
9932 arch-alist inst-alist ent-inst-list
9933 ent-entry arch-entry inst-entry)
9935 (setq ent-entry (car ent-alist))
9936 (setq arch-alist (nth 3 ent-entry))
9938 (setq arch-entry (car arch-alist))
9939 (setq inst-alist (nth 3 arch-entry))
9941 (setq inst-entry (car inst-alist))
9942 (when (equal ent-name (nth 3 inst-entry))
9944 (cons (list (nth 0 inst-entry)
9945 (cons (nth 1 inst-entry) (nth 2 inst-entry))
9947 (cons (nth 1 ent-entry) (nth 2 ent-entry))
9949 (cons (nth 1 arch-entry) (nth 2 arch-entry)))
9951 (setq inst-alist (cdr inst-alist)))
9952 (setq arch-alist (cdr arch-alist)))
9953 (setq ent-alist (cdr ent-alist)))
9954 (nreverse ent-inst-list)))
9956 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9957 ;; Add hierarchy browser functionality to speedbar.
9959 (defvar vhdl-speedbar-key-map nil
9960 "Keymap used when in the VHDL hierarchy browser mode.")
9962 (defvar vhdl-speedbar-menu-items
9963 '(["Edit Design Unit" speedbar-edit-line t]
9964 ["Expand Hierarchy" speedbar-expand-line
9965 (save-excursion (beginning-of-line) (looking-at "[0-9]+: *.\\+. "))]
9966 ["Contract Hierarchy" speedbar-contract-line
9967 (save-excursion (beginning-of-line) (looking-at "[0-9]+: *.-. "))]
9968 ["Rescan Hierarchy" vhdl-speedbar-rescan-hierarchy t]
9970 ["Copy Port" vhdl-speedbar-port-copy
9972 (beginning-of-line) (looking-at "[0-9]+: *\\[[-+?]\\] "))])
9973 "Additional menu-items to add to speedbar frame.")
9975 (defun vhdl-speedbar-initialize ()
9976 "Initialize speedbar."
9978 ; (set (make-local-variable 'speedbar-tag-hierarchy-method) nil)
9979 ;; VHDL file extensions (extracted from `auto-mode-alist')
9980 (let ((mode-alist auto-mode-alist))
9982 (when (eq (cdr (car mode-alist)) 'vhdl-mode)
9983 (speedbar-add-supported-extension (car (car mode-alist))))
9984 (setq mode-alist (cdr mode-alist))))
9985 ;; hierarchy browser settings
9986 (when (boundp 'speedbar-mode-functions-list)
9987 (speedbar-add-mode-functions-list
9989 (speedbar-item-info . vhdl-speedbar-item-info)
9990 (speedbar-line-path . speedbar-files-line-path)))
9991 (unless vhdl-speedbar-key-map
9992 (setq vhdl-speedbar-key-map (speedbar-make-specialized-keymap))
9993 (define-key vhdl-speedbar-key-map "e" 'speedbar-edit-line)
9994 (define-key vhdl-speedbar-key-map "\C-m" 'speedbar-edit-line)
9995 (define-key vhdl-speedbar-key-map "+" 'speedbar-expand-line)
9996 (define-key vhdl-speedbar-key-map "-" 'speedbar-contract-line)
9997 (define-key vhdl-speedbar-key-map "s" 'vhdl-speedbar-rescan-hierarchy)
9998 (define-key vhdl-speedbar-key-map "c" 'vhdl-speedbar-port-copy))
9999 (define-key speedbar-key-map "h"
10000 (lambda () (interactive)
10001 (speedbar-change-initial-expansion-list "vhdl hierarchy")))
10002 (speedbar-add-expansion-list '("vhdl hierarchy" vhdl-speedbar-menu-items
10003 vhdl-speedbar-key-map
10004 vhdl-speedbar-display-hierarchy))
10005 (setq speedbar-stealthy-function-list
10006 (cons '("vhdl hierarchy" vhdl-speedbar-update-current-unit)
10007 speedbar-stealthy-function-list))
10008 (when vhdl-speedbar-show-hierarchy
10009 (setq speedbar-initial-expansion-list-name "vhdl hierarchy"))))
10011 (defun vhdl-speedbar (&optional arg)
10012 "Open/close speedbar."
10014 (if (not (fboundp 'speedbar))
10015 (error "WARNING: Speedbar is only available in newer Emacs versions")
10016 (condition-case () ; due to bug in `speedbar-el' v0.7.2a
10017 (speedbar-frame-mode arg)
10018 (error (error "WARNING: Install included `speedbar.el' patch first")))))
10020 ;; initialize speedbar for VHDL Mode
10021 (if (not (boundp 'speedbar-frame))
10022 (add-hook 'speedbar-load-hook 'vhdl-speedbar-initialize)
10023 (vhdl-speedbar-initialize)
10024 (when speedbar-frame (speedbar-refresh)))
10026 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10027 ;; Display functions
10029 ;; macros must be defined in the file they are used (copied from `speedbar.el')
10030 (defmacro speedbar-with-writable (&rest forms)
10031 "Allow the buffer to be writable and evaluate FORMS."
10032 (list 'let '((inhibit-read-only t))
10033 (cons 'progn forms)))
10034 (put 'speedbar-with-writable 'lisp-indent-function 0)
10036 (defun vhdl-speedbar-display-hierarchy (directory depth &optional rescan)
10037 "Display directory and hierarchy information in speedbar."
10038 (setq directory (abbreviate-file-name (file-name-as-directory directory)))
10039 (setq speedbar-last-selected-file nil)
10040 (speedbar-with-writable
10042 (if (vhdl-speedbar-project-p)
10044 ;; insert project title
10045 (vhdl-speedbar-make-title-line "Project:" 0)
10046 (let ((start (point)))
10048 (put-text-property start (point) 'invisible t)
10049 (setq start (point))
10050 (insert vhdl-project)
10051 (put-text-property start (point) 'face 'speedbar-directory-face))
10052 (insert-char ?\n 1)
10053 ;; scan and insert hierarchy of project
10054 (vhdl-speedbar-insert-project-hierarchy vhdl-project
10055 speedbar-power-click))
10056 ;; insert directory path
10057 (speedbar-directory-buttons directory depth)
10058 ;; insert subdirectories
10059 (vhdl-speedbar-insert-dirs (speedbar-file-lists directory) depth)
10060 ;; scan and insert hierarchy of current directory
10061 (vhdl-speedbar-insert-dir-hierarchy directory depth
10062 speedbar-power-click)
10063 ;; expand subdirectories
10064 (when (= depth 0) (vhdl-speedbar-expand-dirs directory))))))
10066 (defun vhdl-speedbar-insert-hierarchy (ent-alist pack-alist
10067 ent-inst-list depth)
10068 "Insert hierarchy of ENT-ALIST and PACK-ALIST."
10069 (if (not (or ent-alist pack-alist))
10070 (vhdl-speedbar-make-title-line "No design units!" depth)
10071 (let (ent-entry pack-entry)
10073 (when ent-alist (vhdl-speedbar-make-title-line "Entities:" depth))
10075 (setq ent-entry (car ent-alist))
10076 (speedbar-make-tag-line
10077 'bracket ?+ 'vhdl-speedbar-expand-entity (nth 0 ent-entry)
10078 (nth 0 ent-entry) 'vhdl-speedbar-find-file
10079 (cons (nth 1 ent-entry) (nth 2 ent-entry))
10080 'vhdl-speedbar-entity-face depth)
10081 (when (not (member (nth 0 ent-entry) ent-inst-list))
10082 (end-of-line 0) (insert " (top)") (forward-char 1))
10083 (setq ent-alist (cdr ent-alist)))
10085 (when pack-alist (vhdl-speedbar-make-title-line "Packages:" depth))
10087 (setq pack-entry (car pack-alist))
10088 (vhdl-speedbar-make-pack-line
10090 (cons (nth 1 pack-entry) (nth 2 pack-entry))
10091 (cons (nth 3 pack-entry) (nth 4 pack-entry))
10093 (setq pack-alist (cdr pack-alist))))))
10095 (defun vhdl-speedbar-insert-project-hierarchy (project &optional rescan)
10096 "Insert hierarchy of project. Rescan directories if RESCAN is non-nil,
10097 otherwise use cached data of directories."
10098 (when (or rescan (and (not (assoc project vhdl-project-entity-alist))
10099 (not (assoc project vhdl-project-package-alist))))
10100 (vhdl-scan-project-contents project rescan))
10101 ;; insert design hierarchy in speedbar
10102 (vhdl-speedbar-insert-hierarchy
10103 (aget vhdl-project-entity-alist project)
10104 (aget vhdl-project-package-alist project)
10105 (aget vhdl-project-ent-inst-list project) 0)
10106 ;; expand design units
10107 (vhdl-speedbar-expand-units project))
10109 (defun vhdl-speedbar-insert-dir-hierarchy (directory depth &optional rescan)
10110 "Insert hierarchy of DIRECTORY. Rescan directory if RESCAN is non-nil,
10111 otherwise use cached data."
10112 (when (or rescan (and (not (assoc directory vhdl-entity-alist))
10113 (not (assoc directory vhdl-package-alist))))
10114 (vhdl-scan-file-contents directory))
10115 (vhdl-speedbar-insert-hierarchy
10116 (aget vhdl-entity-alist directory)
10117 (aget vhdl-package-alist directory)
10118 (car (aget vhdl-ent-inst-alist directory))
10120 (vhdl-speedbar-expand-units directory))
10122 (defun vhdl-speedbar-rescan-hierarchy ()
10123 "Rescan hierarchy for the directory under the cursor or the current project."
10126 ;; the current project
10127 ((vhdl-speedbar-project-p)
10128 (vhdl-scan-project-contents vhdl-project t)
10129 (speedbar-refresh))
10130 ;; the top-level directory
10131 ((save-excursion (beginning-of-line) (looking-at "[^0-9]"))
10132 (re-search-forward "[0-9]+:" nil t)
10133 (vhdl-scan-file-contents (abbreviate-file-name (speedbar-line-path)))
10134 (speedbar-refresh))
10135 ;; the current directory
10136 (t (let ((path (speedbar-line-path)))
10137 (string-match "^\\(.+/\\)" path)
10138 (vhdl-scan-file-contents (abbreviate-file-name (match-string 1 path)))
10139 (speedbar-refresh)))))
10141 (defun vhdl-speedbar-expand-dirs (directory)
10142 "Expand subdirectories in DIRECTORY according to
10143 `speedbar-shown-directories'."
10144 ;; (nicked from `speedbar-default-directory-list')
10145 (let ((sf (cdr (reverse speedbar-shown-directories))))
10146 (setq speedbar-shown-directories
10147 (list (expand-file-name default-directory)))
10149 (when (speedbar-goto-this-file (car sf))
10150 (beginning-of-line)
10151 (when (looking-at "[0-9]+:\\s-*<")
10152 (goto-char (match-end 0))
10153 (let* ((position (point))
10154 (directory (abbreviate-file-name
10155 (file-name-as-directory (speedbar-line-file)))))
10156 (speedbar-do-function-pointer))))
10157 (setq sf (cdr sf)))))
10159 (defun vhdl-speedbar-expand-units (directory)
10160 "Expand design units in DIRECTORY according to
10161 `vhdl-speedbar-shown-units-alist'."
10162 (let ((ent-alist (aget vhdl-speedbar-shown-units-alist directory)))
10163 (adelete 'vhdl-speedbar-shown-units-alist directory)
10164 (while ent-alist ; expand entities
10165 (vhdl-speedbar-goto-this-unit directory (car (car ent-alist)))
10166 (beginning-of-line)
10167 (let ((arch-alist (nth 1 (car ent-alist)))
10169 (when (looking-at "[0-9]+:\\s-*\\[")
10170 (goto-char (match-end 0))
10171 (setq position (point))
10172 (speedbar-do-function-pointer)
10173 (while arch-alist ; expand architectures
10174 (goto-char position)
10175 (when (re-search-forward
10176 (concat "[0-9]+:\\s-*\\(\\[\\|{.}\\s-+"
10177 (car arch-alist) "\\>\\)") nil t)
10178 (beginning-of-line)
10179 (when (looking-at "[0-9]+:\\s-*{")
10180 (goto-char (match-end 0))
10181 (speedbar-do-function-pointer)))
10182 (setq arch-alist (cdr arch-alist))))
10183 (setq ent-alist (cdr ent-alist))))))
10185 (defun vhdl-speedbar-expand-entity (text token indent)
10186 "Expand/contract the entity under the cursor."
10188 ((string-match "+" text) ; expand entity
10189 (let* ((ent-alist (if (vhdl-speedbar-project-p)
10190 (aget vhdl-project-entity-alist vhdl-project)
10191 (aget vhdl-entity-alist
10192 (abbreviate-file-name
10193 (file-name-as-directory
10194 (speedbar-line-path indent))))))
10195 (arch-alist (nth 2 (aget ent-alist token)))
10196 (conf-alist (nth 3 (aget ent-alist token)))
10197 (inst-alist (vhdl-get-instantiations token indent))
10198 arch-entry conf-entry inst-entry)
10199 (if (not (or arch-alist conf-alist inst-alist))
10200 (speedbar-change-expand-button-char ??)
10201 (speedbar-change-expand-button-char ?-)
10202 ;; add entity to `vhdl-speedbar-shown-units-alist'
10203 (let* ((directory (if (vhdl-speedbar-project-p)
10205 (abbreviate-file-name
10206 (file-name-as-directory (speedbar-line-path)))))
10207 (ent-alist (aget vhdl-speedbar-shown-units-alist directory)))
10208 (aput 'ent-alist (speedbar-line-text) nil)
10209 (aput 'vhdl-speedbar-shown-units-alist directory ent-alist))
10210 (speedbar-with-writable
10212 (end-of-line) (forward-char 1)
10213 ;; insert architectures
10215 (vhdl-speedbar-make-title-line "Architectures:" (1+ indent)))
10217 (setq arch-entry (car arch-alist))
10218 (speedbar-make-tag-line
10219 'curly ?+ 'vhdl-speedbar-expand-architecture
10220 (cons token (nth 0 arch-entry))
10221 (nth 0 arch-entry) 'vhdl-speedbar-find-file
10222 (cons (nth 1 arch-entry) (nth 2 arch-entry))
10223 'vhdl-speedbar-architecture-face (1+ indent))
10224 (setq arch-alist (cdr arch-alist)))
10225 ;; insert configurations
10227 (vhdl-speedbar-make-title-line "Configurations:" (1+ indent)))
10229 (setq conf-entry (car conf-alist))
10230 (speedbar-make-tag-line
10232 (cons token (nth 0 conf-entry))
10233 (nth 0 conf-entry) 'vhdl-speedbar-find-file
10234 (cons (nth 1 conf-entry) (nth 2 conf-entry))
10235 'vhdl-speedbar-configuration-face (1+ indent))
10236 (setq conf-alist (cdr conf-alist)))
10237 ;; insert instantiations
10239 (vhdl-speedbar-make-title-line "Instantiations:" (1+ indent)))
10241 (setq inst-entry (car inst-alist))
10242 (vhdl-speedbar-make-inst-line
10243 (nth 0 inst-entry) (nth 1 inst-entry)
10244 (nth 2 inst-entry) (nth 3 inst-entry)
10245 (nth 4 inst-entry) (nth 5 inst-entry) (1+ indent) 0)
10246 (setq inst-alist (cdr inst-alist)))))
10247 (setq speedbar-last-selected-file nil)
10248 (save-excursion (speedbar-stealthy-updates)))))
10249 ((string-match "-" text) ; contract entity
10250 (speedbar-change-expand-button-char ?+)
10251 ;; remove entity from `vhdl-speedbar-shown-units-alist'
10252 (let* ((directory (if (vhdl-speedbar-project-p)
10254 (abbreviate-file-name
10255 (file-name-as-directory (speedbar-line-path)))))
10256 (ent-alist (aget vhdl-speedbar-shown-units-alist directory)))
10257 (adelete 'ent-alist (speedbar-line-text))
10259 (aput 'vhdl-speedbar-shown-units-alist directory ent-alist)
10260 (adelete 'vhdl-speedbar-shown-units-alist directory)))
10261 (speedbar-delete-subblock indent))
10262 (t (error "No architectures, configurations, nor instantiations exist for this entity")))
10263 (speedbar-center-buffer-smartly))
10265 (defun vhdl-speedbar-expand-architecture (text token indent)
10266 "Expand/contract the architecture under the cursor."
10268 ((string-match "+" text) ; expand architecture
10269 (let ((hier-alist (vhdl-get-hierarchy (car token) (cdr token) 0 indent)))
10270 (if (not hier-alist)
10271 (speedbar-change-expand-button-char ??)
10272 (speedbar-change-expand-button-char ?-)
10273 ;; add architecture to `vhdl-speedbar-shown-units-alist'
10274 (let* ((path (speedbar-line-path))
10275 (dummy (string-match "^\\(.+/\\)\\([^/ ]+\\)" path))
10276 (ent-name (match-string 2 path))
10277 (directory (if (vhdl-speedbar-project-p)
10279 (abbreviate-file-name (match-string 1 path))))
10280 (ent-alist (aget vhdl-speedbar-shown-units-alist directory))
10281 (arch-alist (nth 0 (aget ent-alist ent-name t))))
10282 (aput 'ent-alist ent-name
10283 (list (cons (speedbar-line-text) arch-alist)))
10284 (aput 'vhdl-speedbar-shown-units-alist directory ent-alist))
10285 (speedbar-with-writable
10287 (end-of-line) (forward-char 1)
10288 ;; insert instance hierarchy
10290 (vhdl-speedbar-make-title-line "Subcomponents:" (1+ indent)))
10292 (let ((entry (car hier-alist)))
10293 (vhdl-speedbar-make-inst-line
10294 (nth 0 entry) (nth 1 entry)
10295 (nth 2 entry) (nth 3 entry)
10296 (nth 4 entry) (nth 5 entry)
10297 (1+ indent) (nth 6 entry))
10298 (setq hier-alist (cdr hier-alist))))))
10299 (setq speedbar-last-selected-file nil)
10300 (save-excursion (speedbar-stealthy-updates)))))
10301 ((string-match "-" text) ; contract architecture
10302 (speedbar-change-expand-button-char ?+)
10303 ;; remove architecture from `vhdl-speedbar-shown-units-alist'
10304 (let* ((path (speedbar-line-path))
10305 (dummy (string-match "^\\(.+/\\)\\([^/ ]+\\)" path))
10306 (ent-name (match-string 2 path))
10307 (directory (if (vhdl-speedbar-project-p)
10309 (abbreviate-file-name (match-string 1 path))))
10310 (ent-alist (aget vhdl-speedbar-shown-units-alist directory))
10311 (arch-alist (nth 0 (aget ent-alist ent-name t))))
10312 (aput 'ent-alist ent-name
10313 (list (delete (speedbar-line-text) arch-alist)))
10314 (aput 'vhdl-speedbar-shown-units-alist directory ent-alist))
10315 (speedbar-delete-subblock indent))
10316 (t (error "No component instantiations contained in this architecture")))
10317 (speedbar-center-buffer-smartly))
10319 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10320 ;; Display help functions
10322 (defun vhdl-speedbar-update-current-unit (&optional no-position)
10323 "Highlight all design units that are contained in the current file.
10324 NO-POSITION non-nil means do not re-position cursor."
10325 (let ((last-frame (selected-frame))
10326 file-name position)
10327 ;; get current file name
10328 (select-frame speedbar-attached-frame)
10329 (setq file-name (abbreviate-file-name (or (buffer-file-name) "")))
10330 (unless (equal file-name speedbar-last-selected-file)
10331 (select-frame speedbar-frame)
10332 (set-buffer speedbar-buffer)
10333 (speedbar-with-writable
10335 ;; unhighlight last units
10337 (aget vhdl-file-alist speedbar-last-selected-file)))
10338 (vhdl-speedbar-update-units
10339 "\\[.\\]" (nth 0 file-entry)
10340 speedbar-last-selected-file 'vhdl-speedbar-entity-face)
10341 (vhdl-speedbar-update-units
10342 "{.}" (nth 1 file-entry)
10343 speedbar-last-selected-file 'vhdl-speedbar-architecture-face)
10344 (vhdl-speedbar-update-units
10345 ">" (nth 2 file-entry)
10346 speedbar-last-selected-file 'vhdl-speedbar-configuration-face)
10347 (vhdl-speedbar-update-units
10348 ">" (nth 3 file-entry)
10349 speedbar-last-selected-file 'vhdl-speedbar-package-face)
10350 (vhdl-speedbar-update-units
10351 ">" (nth 4 file-entry)
10352 speedbar-last-selected-file 'vhdl-speedbar-instantiation-face))
10353 ;; highlight current units
10354 (let* ((file-entry (aget vhdl-file-alist file-name)))
10355 (vhdl-speedbar-update-units
10356 "\\[.\\]" (nth 0 file-entry)
10357 file-name 'vhdl-speedbar-entity-selected-face)
10358 (setq position (or position (point-marker)))
10359 (vhdl-speedbar-update-units
10360 "{.}" (nth 1 file-entry)
10361 file-name 'vhdl-speedbar-architecture-selected-face)
10362 (setq position (or position (point-marker)))
10363 (vhdl-speedbar-update-units
10364 ">" (nth 2 file-entry)
10365 file-name 'vhdl-speedbar-configuration-selected-face)
10366 (setq position (or position (point-marker)))
10367 (vhdl-speedbar-update-units
10368 ">" (nth 3 file-entry)
10369 file-name 'vhdl-speedbar-package-selected-face)
10370 (setq position (or position (point-marker)))
10371 (vhdl-speedbar-update-units
10372 ">" (nth 4 file-entry)
10373 file-name 'vhdl-speedbar-instantiation-selected-face))))
10374 (setq position (or position (point-marker)))
10375 ;; move speedbar so the first highlighted unit is visible
10376 (when (and position (not no-position))
10377 (goto-char position)
10378 (speedbar-center-buffer-smartly)
10379 (speedbar-position-cursor-on-line))
10380 (setq speedbar-last-selected-file file-name))
10381 (select-frame last-frame)
10384 (defun vhdl-speedbar-update-units (text unit-list file-name face)
10385 "Help function to highlight design units."
10388 (goto-char (point-min))
10389 (while (re-search-forward
10390 (concat text " \\(" (car unit-list) "\\)\\>") nil t)
10391 (when (equal file-name (car (get-text-property
10392 (match-beginning 1) 'speedbar-token)))
10393 (setq position (or position (point-marker)))
10394 (put-text-property (match-beginning 1) (match-end 1) 'face face)))
10395 (setq unit-list (cdr unit-list)))
10396 (when position (goto-char position))))
10398 (defun vhdl-speedbar-make-inst-line (inst-name inst-file-marker
10399 ent-name ent-file-marker
10400 arch-name arch-file-marker
10402 "Insert instantiation entry."
10403 (let ((start (point)))
10404 (insert (int-to-string depth) ":")
10405 (put-text-property start (point) 'invisible t)
10406 (setq start (point))
10407 (insert-char ? (+ depth (* offset vhdl-speedbar-hierarchy-indent)))
10409 (put-text-property start (point) 'invisible nil)
10410 (setq start (point))
10412 (speedbar-make-button
10413 start (point) 'vhdl-speedbar-instantiation-face 'speedbar-highlight-face
10414 'vhdl-speedbar-find-file inst-file-marker)
10415 (setq start (point))
10417 (put-text-property start (point) 'invisible nil)
10418 (setq start (point))
10420 (speedbar-make-button
10421 start (point) 'vhdl-speedbar-entity-face 'speedbar-highlight-face
10422 'vhdl-speedbar-find-file ent-file-marker)
10423 (setq start (point))
10426 (put-text-property start (point) 'invisible nil)
10427 (setq start (point))
10429 (speedbar-make-button
10430 start (point) 'vhdl-speedbar-architecture-face 'speedbar-highlight-face
10431 'vhdl-speedbar-find-file arch-file-marker)
10432 (setq start (point))
10434 (put-text-property start (point) 'invisible nil)
10435 (insert-char ?\n 1)
10436 (put-text-property (1- (point)) (point) 'invisible nil)))
10438 (defun vhdl-speedbar-make-pack-line (pack-name pack-file-marker
10439 body-file-marker depth)
10440 "Insert package entry."
10441 (let ((start (point)))
10442 (insert (int-to-string depth) ":")
10443 (put-text-property start (point) 'invisible t)
10444 (setq start (point))
10445 (insert-char ? depth)
10447 (put-text-property start (point) 'invisible nil)
10448 (setq start (point))
10450 (speedbar-make-button
10451 start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face
10452 'vhdl-speedbar-find-file pack-file-marker)
10453 (when (car body-file-marker)
10454 (setq start (point))
10456 (put-text-property start (point) 'invisible nil)
10457 (setq start (point))
10459 (speedbar-make-button
10460 start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face
10461 'vhdl-speedbar-find-file body-file-marker)
10462 (setq start (point))
10464 (put-text-property start (point) 'invisible nil))
10465 (insert-char ?\n 1)
10466 (put-text-property (1- (point)) (point) 'invisible nil)))
10468 (defun vhdl-speedbar-make-title-line (text depth)
10469 "Insert design unit title entry."
10470 (let ((start (point)))
10471 (insert (int-to-string depth) ":")
10472 (put-text-property start (point) 'invisible t)
10473 (setq start (point))
10474 (insert-char ? depth)
10475 (put-text-property start (point) 'invisible nil)
10476 (setq start (point))
10478 (speedbar-make-button start (point) nil nil nil nil)
10479 (insert-char ?\n 1)
10480 (put-text-property start (point) 'invisible nil)))
10482 (defun vhdl-speedbar-insert-dirs (files level)
10483 "Insert subdirectories."
10484 (let ((dirs (car files)))
10486 (speedbar-make-tag-line 'angle ?+ 'vhdl-speedbar-dired (car dirs)
10487 (car dirs) 'speedbar-dir-follow nil
10488 'speedbar-directory-face level)
10489 (setq dirs (cdr dirs)))))
10491 (defun vhdl-speedbar-dired (text token indent)
10492 "Speedbar click handler for directory expand button in hierarchy mode."
10493 (cond ((string-match "+" text) ; we have to expand this dir
10494 (setq speedbar-shown-directories
10495 (cons (expand-file-name
10496 (concat (speedbar-line-path indent) token "/"))
10497 speedbar-shown-directories))
10498 (speedbar-change-expand-button-char ?-)
10499 (speedbar-reset-scanners)
10500 (speedbar-with-writable
10502 (end-of-line) (forward-char 1)
10503 (vhdl-speedbar-insert-dirs
10504 (speedbar-file-lists
10505 (concat (speedbar-line-path indent) token "/"))
10507 (speedbar-reset-scanners)
10508 (vhdl-speedbar-insert-dir-hierarchy
10509 (abbreviate-file-name
10510 (concat (speedbar-line-path indent) token "/"))
10511 (1+ indent) speedbar-power-click)))
10512 (setq speedbar-last-selected-file nil)
10513 (save-excursion (speedbar-stealthy-updates)))
10514 ((string-match "-" text) ; we have to contract this node
10515 (speedbar-reset-scanners)
10516 (let ((oldl speedbar-shown-directories)
10518 (td (expand-file-name
10519 (concat (speedbar-line-path indent) token))))
10521 (if (not (string-match (concat "^" (regexp-quote td)) (car oldl)))
10522 (setq newl (cons (car oldl) newl)))
10523 (setq oldl (cdr oldl)))
10524 (setq speedbar-shown-directories (nreverse newl)))
10525 (speedbar-change-expand-button-char ?+)
10526 (speedbar-delete-subblock indent))
10527 (t (error "Ooops... not sure what to do")))
10528 (speedbar-center-buffer-smartly))
10530 (defun vhdl-speedbar-item-info ()
10531 "Derive and display information about this line item."
10533 (beginning-of-line)
10534 ;; skip invisible number info
10535 (when (looking-at "[0-9]+:") (goto-char (match-end 0)))
10536 (when (looking-at "p:")
10537 (message "Project \"%s\""
10538 (nth 0 (aget vhdl-project-alist vhdl-project))))
10541 ((looking-at "\\s-*<[-+?]> ") (speedbar-files-item-info))
10542 ;; design unit entry
10543 ((looking-at "\\s-*\\([[{][-+?][]}]\\|>\\) ")
10544 (goto-char (match-end 0))
10545 (let ((face (get-text-property (point) 'face)))
10547 "%s \"%s\" in \"%s\""
10548 ;; design unit kind
10549 (cond ((or (eq face 'vhdl-speedbar-entity-face)
10550 (eq face 'vhdl-speedbar-entity-selected-face))
10552 ((or (eq face 'vhdl-speedbar-architecture-face)
10553 (eq face 'vhdl-speedbar-architecture-selected-face))
10555 ((or (eq face 'vhdl-speedbar-configuration-face)
10556 (eq face 'vhdl-speedbar-configuration-selected-face))
10558 ((or (eq face 'vhdl-speedbar-package-face)
10559 (eq face 'vhdl-speedbar-package-selected-face))
10561 ((or (eq face 'vhdl-speedbar-instantiation-face)
10562 (eq face 'vhdl-speedbar-instantiation-selected-face))
10565 ;; design unit name
10566 (buffer-substring-no-properties
10567 (point) (progn (looking-at"\\(\\w\\|_\\)+") (match-end 0)))
10569 (abbreviate-file-name
10570 (or (car (get-text-property (point) 'speedbar-token)) "?"))))))))
10572 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10575 (defun vhdl-get-subdirs (directory)
10576 "Recursively get subdirectories of DIRECTORY."
10577 (let ((dir-list (list (file-name-as-directory directory)))
10578 subdir-list file-list)
10579 (setq file-list (vhdl-directory-files directory t "\\w.*"))
10581 (when (file-directory-p (car file-list))
10582 (setq dir-list (append dir-list (vhdl-get-subdirs (car file-list)))))
10583 (setq file-list (cdr file-list)))
10586 (defun vhdl-resolve-paths (path-list)
10587 "Resolve environment variables and path wildcards in PATH-LIST."
10588 (let (path-list-1 path-list-2 path-list-3 path-beg path-end dir)
10589 ;; resolve environment variables
10591 (setq dir (car path-list))
10592 (while (string-match "\\(.*\\)${?\\(\\(\\w\\|_\\)+\\)}?\\(.*\\)" dir)
10593 (setq dir (concat (match-string 1 dir) (getenv (match-string 2 dir))
10594 (match-string 4 dir))))
10595 (setq path-list-1 (cons dir path-list-1))
10596 (setq path-list (cdr path-list)))
10597 ;; eliminate non-existent directories
10599 (setq dir (car path-list-1))
10600 (string-match "\\(-r \\)?\\(\\([^?*]*/\\)*\\)" dir)
10601 (if (file-directory-p (match-string 2 dir))
10602 (setq path-list-2 (cons dir path-list-2))
10603 (message "No such directory: \"%s\"" (match-string 2 dir)))
10604 (setq path-list-1 (cdr path-list-1)))
10605 ;; resolve path wildcards
10607 (setq dir (car path-list-2))
10609 "\\(-r \\)?\\(\\([^?*]*/\\)*\\)\\([^/]*[?*][^/]*\\)\\(/.*\\)" dir)
10611 (setq path-beg (match-string 1 dir)
10612 path-end (match-string 5 dir))
10617 (lambda (var) (concat path-beg var path-end)))
10618 (let ((all-list (vhdl-directory-files
10619 (match-string 2 dir) t
10620 (concat "\\<" (wildcard-to-regexp
10621 (match-string 4 dir)))))
10624 (when (file-directory-p (car all-list))
10625 (setq dir-list (cons (car all-list) dir-list)))
10626 (setq all-list (cdr all-list)))
10628 (cdr path-list-2))))
10629 (string-match "\\(-r \\)?\\(.*\\)/.*" dir)
10630 (when (file-directory-p (match-string 2 dir))
10631 (setq path-list-3 (cons dir path-list-3)))
10632 (setq path-list-2 (cdr path-list-2))))
10635 (defun vhdl-aappend (alist-symbol key value)
10636 "Append a key-value pair to an alist.
10637 Similar to `aput' but moves the key-value pair to the tail of the alist."
10638 (let ((elem (aelement key value))
10639 (alist (adelete alist-symbol key)))
10640 (set alist-symbol (append alist elem))))
10642 (defun vhdl-speedbar-goto-this-unit (directory unit)
10643 "If UNIT is displayed in DIRECTORY, goto this line and return t, else nil."
10644 (let ((dest (point)))
10645 (if (and (if (vhdl-speedbar-project-p)
10646 (progn (goto-char (point-min)) t)
10647 (speedbar-goto-this-file directory))
10648 (re-search-forward (concat "[]}] " unit "\\>") nil t))
10649 (progn (speedbar-position-cursor-on-line)
10654 (defun vhdl-speedbar-find-file (text token indent)
10655 "When user clicks on TEXT, load file with name and position in TOKEN."
10656 (if (not (car token))
10657 (error "Design unit does not exist")
10658 (speedbar-find-file-in-frame (car token))
10659 (goto-line (cdr token))
10661 (vhdl-speedbar-update-current-unit t)
10662 (speedbar-set-timer speedbar-update-speed)
10663 (speedbar-maybee-jump-to-attached-frame)))
10665 (defun vhdl-speedbar-toggle-hierarchy ()
10666 "Toggle between hierarchy and file browsing mode."
10668 (if (not (boundp 'speedbar-mode-functions-list))
10669 (error "WARNING: Install included `speedbar.el' patch first")
10670 (if (equal speedbar-initial-expansion-list-name "vhdl hierarchy")
10671 (speedbar-change-initial-expansion-list "files")
10672 (speedbar-change-initial-expansion-list "vhdl hierarchy"))))
10674 (defun vhdl-speedbar-port-copy ()
10675 "Copy the port of the entity under the cursor."
10677 (beginning-of-line)
10678 (if (re-search-forward "\\([0-9]\\)+:\\s-*\\[[-+?]\\] \\(\\(\\w\\|\\s_\\)+\\)"
10679 (save-excursion (end-of-line) (point)) t)
10681 (let* ((indent (string-to-number (match-string 1)))
10682 (ent-name (match-string 2))
10683 (ent-alist (if (vhdl-speedbar-project-p)
10684 (aget vhdl-project-entity-alist vhdl-project)
10685 (aget vhdl-entity-alist
10686 (abbreviate-file-name
10687 (file-name-as-directory
10688 (speedbar-line-path indent))))))
10689 (ent-entry (aget ent-alist ent-name))
10690 (file-name (nth 0 ent-entry))
10693 (if (find-buffer-visiting file-name)
10694 (set-buffer (file-name-nondirectory file-name))
10695 (set-buffer (find-file-noselect file-name nil t))
10696 (modify-syntax-entry ?\- ". 12" (syntax-table))
10697 (modify-syntax-entry ?\n ">" (syntax-table))
10698 (modify-syntax-entry ?\^M ">" (syntax-table))
10701 (goto-line (nth 1 ent-entry))
10705 (when opened (kill-buffer (current-buffer))))
10706 (error (error "Port not scanned successfully")))
10707 (error "No entity on current line")))
10709 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10712 (defface vhdl-speedbar-entity-face
10713 '((((class color) (background light)) (:foreground "ForestGreen"))
10714 (((class color) (background dark)) (:foreground "PaleGreen")))
10715 "Face used for displaying entity names."
10716 :group 'speedbar-faces)
10718 (defface vhdl-speedbar-architecture-face
10719 '((((class color) (background light)) (:foreground "Blue"))
10720 (((class color) (background dark)) (:foreground "LightSkyBlue")))
10721 "Face used for displaying architecture names."
10722 :group 'speedbar-faces)
10724 (defface vhdl-speedbar-configuration-face
10725 '((((class color) (background light)) (:foreground "DarkGoldenrod"))
10726 (((class color) (background dark)) (:foreground "Salmon")))
10727 "Face used for displaying configuration names."
10728 :group 'speedbar-faces)
10730 (defface vhdl-speedbar-package-face
10731 '((((class color) (background light)) (:foreground "Grey50"))
10732 (((class color) (background dark)) (:foreground "Grey80")))
10733 "Face used for displaying package names."
10734 :group 'speedbar-faces)
10736 (defface vhdl-speedbar-instantiation-face
10737 '((((class color) (background light)) (:foreground "Brown"))
10738 (((class color) (background dark)) (:foreground "Yellow")))
10739 "Face used for displaying instantiation names."
10740 :group 'speedbar-faces)
10742 (defface vhdl-speedbar-entity-selected-face
10743 '((((class color) (background light)) (:foreground "ForestGreen" :underline t))
10744 (((class color) (background dark)) (:foreground "PaleGreen" :underline t)))
10745 "Face used for displaying entity names."
10746 :group 'speedbar-faces)
10748 (defface vhdl-speedbar-architecture-selected-face
10749 '((((class color) (background light)) (:foreground "Blue" :underline t))
10750 (((class color) (background dark)) (:foreground "LightSkyBlue" :underline t)))
10751 "Face used for displaying architecture names."
10752 :group 'speedbar-faces)
10754 (defface vhdl-speedbar-configuration-selected-face
10755 '((((class color) (background light)) (:foreground "DarkGoldenrod" :underline t))
10756 (((class color) (background dark)) (:foreground "Salmon" :underline t)))
10757 "Face used for displaying configuration names."
10758 :group 'speedbar-faces)
10760 (defface vhdl-speedbar-package-selected-face
10761 '((((class color) (background light)) (:foreground "Grey50" :underline t))
10762 (((class color) (background dark)) (:foreground "Grey80" :underline t)))
10763 "Face used for displaying package names."
10764 :group 'speedbar-faces)
10766 (defface vhdl-speedbar-instantiation-selected-face
10767 '((((class color) (background light)) (:foreground "Brown" :underline t))
10768 (((class color) (background dark)) (:foreground "Yellow" :underline t)))
10769 "Face used for displaying instantiation names."
10770 :group 'speedbar-faces)
10773 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10775 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10776 ;; (using `reporter.el')
10778 (defconst vhdl-mode-help-address "vhdl-mode@geocities.com"
10779 "Address for VHDL Mode bug reports.")
10781 (defun vhdl-version ()
10782 "Echo the current version of VHDL Mode in the minibuffer."
10784 (message "Using VHDL Mode version %s" vhdl-version)
10785 (vhdl-keep-region-active))
10787 ;; get reporter-submit-bug-report when byte-compiling
10789 (require 'reporter))
10791 (defun vhdl-submit-bug-report ()
10792 "Submit via mail a bug report on VHDL Mode."
10794 ;; load in reporter
10796 (y-or-n-p "Do you want to submit a report on VHDL Mode? ")
10797 (require 'reporter)
10798 (reporter-submit-bug-report
10799 vhdl-mode-help-address
10800 (concat "VHDL Mode " vhdl-version)
10802 ;; report all important variables
10803 'vhdl-offsets-alist
10804 'vhdl-comment-only-line-offset
10806 'vhdl-electric-mode
10808 'vhdl-indent-tabs-mode
10809 'vhdl-project-alist
10811 'vhdl-compiler-alist
10813 'vhdl-compiler-options
10816 'vhdl-upper-case-keywords
10817 'vhdl-upper-case-types
10818 'vhdl-upper-case-attributes
10819 'vhdl-upper-case-enum-values
10820 'vhdl-upper-case-constants
10821 'vhdl-electric-keywords
10822 'vhdl-optional-labels
10823 'vhdl-insert-empty-lines
10824 'vhdl-argument-list-indent
10825 'vhdl-association-list-with-formals
10826 'vhdl-conditions-in-parenthesis
10832 'vhdl-platform-spec
10834 'vhdl-modify-date-prefix-string
10835 'vhdl-modify-date-on-saving
10837 'vhdl-reset-active-high
10838 'vhdl-clock-rising-edge
10839 'vhdl-clock-edge-condition
10843 'vhdl-include-port-comments
10844 'vhdl-include-direction-comments
10845 'vhdl-actual-port-name
10846 'vhdl-instance-name
10847 'vhdl-testbench-entity-name
10848 'vhdl-testbench-architecture-name
10849 'vhdl-testbench-dut-name
10850 'vhdl-testbench-entity-header
10851 'vhdl-testbench-architecture-header
10852 'vhdl-testbench-declarations
10853 'vhdl-testbench-statements
10854 'vhdl-testbench-initialize-signals
10855 'vhdl-testbench-create-files
10856 'vhdl-self-insert-comments
10857 'vhdl-prompt-for-comments
10858 'vhdl-inline-comment-column
10859 'vhdl-end-comment-column
10862 'vhdl-highlight-keywords
10863 'vhdl-highlight-names
10864 'vhdl-highlight-special-words
10865 'vhdl-highlight-forbidden-words
10866 'vhdl-highlight-verilog-keywords
10867 'vhdl-highlight-translate-off
10868 'vhdl-highlight-case-sensitive
10869 'vhdl-special-syntax-alist
10870 'vhdl-forbidden-words
10871 'vhdl-forbidden-syntax
10873 'vhdl-speedbar-show-hierarchy
10874 'vhdl-speedbar-hierarchy-indent
10876 'vhdl-source-file-menu
10877 'vhdl-hideshow-menu
10878 'vhdl-hide-all-init
10879 'vhdl-print-two-column
10880 'vhdl-print-customize-faces
10881 'vhdl-intelligent-tab
10882 'vhdl-word-completion-case-sensitive
10883 'vhdl-word-completion-in-minibuffer
10884 'vhdl-underscore-is-part-of-word
10886 'vhdl-startup-warnings)
10890 (if vhdl-special-indent-hook
10891 (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
10892 "vhdl-special-indent-hook is set to '"
10893 (format "%s" vhdl-special-indent-hook)
10894 ".\nPerhaps this is your problem?\n"
10895 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
10898 "Dear VHDL Mode maintainers,")))
10901 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10903 (provide 'vhdl-mode)
10905 ;;; vhdl-mode.el ends here