Merge from emacs-24; up to 2012-12-22T19:09:52Z!rgm@gnu.org
[bpt/emacs.git] / lisp / progmodes / vhdl-mode.el
CommitLineData
d2ddb974
KH
1;;; vhdl-mode.el --- major mode for editing VHDL code
2
ab422c4d 3;; Copyright (C) 1992-2013 Free Software Foundation, Inc.
3dcb36b7
JB
4
5;; Authors: Reto Zimmermann <reto@gnu.org>
6;; Rodney J. Whitby <software.vhdl-mode@rwhitby.net>
0a2e512a 7;; Maintainer: Reto Zimmermann <reto@gnu.org>
5eabfe72 8;; Keywords: languages vhdl
c9c18440 9;; WWW: http://www.iis.ee.ethz.ch/~zimmi/emacs/vhdl-mode.html
3dcb36b7 10
241760a3
SM
11;; Yoni Rabkin <yoni@rabkins.net> contacted the maintainer of this
12;; file on 18/3/2008, and the maintainer agreed that when a bug is
13;; filed in the Emacs bug reporting system against this file, a copy
14;; of the bug report be sent to the maintainer's email address.
15
fda91268 16(defconst vhdl-version "3.33.28"
3dcb36b7
JB
17 "VHDL Mode version number.")
18
fda91268 19(defconst vhdl-time-stamp "2010-09-22"
3dcb36b7 20 "VHDL Mode time stamp for last update.")
d2ddb974
KH
21
22;; This file is part of GNU Emacs.
23
b1fc2b50 24;; GNU Emacs is free software: you can redistribute it and/or modify
d2ddb974 25;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
26;; the Free Software Foundation, either version 3 of the License, or
27;; (at your option) any later version.
d2ddb974
KH
28
29;; GNU Emacs is distributed in the hope that it will be useful,
30;; but WITHOUT ANY WARRANTY; without even the implied warranty of
31;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32;; GNU General Public License for more details.
33
34;; You should have received a copy of the GNU General Public License
b1fc2b50 35;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
d2ddb974 36
5eabfe72 37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974 38;;; Commentary:
5eabfe72 39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
40
41;; This package provides an Emacs major mode for editing VHDL code.
42;; It includes the following features:
43
3dcb36b7
JB
44;; - Syntax highlighting
45;; - Indentation
46;; - Template insertion (electrification)
47;; - Insertion of file headers
5eabfe72 48;; - Insertion of user-specified models
3dcb36b7 49;; - Port translation / testbench generation
0a2e512a
RF
50;; - Structural composition
51;; - Configuration generation
3dcb36b7
JB
52;; - Sensitivity list updating
53;; - File browser
54;; - Design hierarchy browser
d2ddb974 55;; - Source file compilation (syntax analysis)
3dcb36b7
JB
56;; - Makefile generation
57;; - Code hiding
58;; - Word/keyword completion
59;; - Block commenting
60;; - Code fixing/alignment/beautification
7877f373 61;; - PostScript printing
5eabfe72 62;; - VHDL'87/'93 and VHDL-AMS supported
3dcb36b7 63;; - Comprehensive menu
5eabfe72 64;; - Fully customizable
3dcb36b7 65;; - Works under GNU Emacs (recommended) and XEmacs
5eabfe72
KH
66
67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 68;; Documentation
d2ddb974 69
3dcb36b7 70;; See comment string of function `vhdl-mode' or type `C-c C-h' in Emacs.
d2ddb974 71
5eabfe72 72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974 73;; Emacs Versions
3dcb36b7 74
fda91268
RZ
75;; supported: GNU Emacs 20.X/21.X/22.X,23.X, XEmacs 20.X/21.X
76;; tested on: GNU Emacs 20.4/21.3/22.1,23.X, XEmacs 21.1 (marginally)
3dcb36b7 77
5eabfe72 78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7
JB
79;; Installation
80
fda91268 81;; Prerequisites: GNU Emacs 20.X/21.X/22.X/23.X, XEmacs 20.X/21.X.
3dcb36b7
JB
82
83;; Put `vhdl-mode.el' into the `site-lisp' directory of your Emacs installation
84;; or into an arbitrary directory that is added to the load path by the
85;; following line in your Emacs start-up file `.emacs':
86
87;; (setq load-path (cons (expand-file-name "<directory-name>") load-path))
d2ddb974 88
3dcb36b7
JB
89;; If you already have the compiled `vhdl-mode.elc' file, put it in the same
90;; directory. Otherwise, byte-compile the source file:
91;; Emacs: M-x byte-compile-file RET vhdl-mode.el RET
92;; Unix: emacs -batch -q -no-site-file -f batch-byte-compile vhdl-mode.el
93
94;; Add the following lines to the `site-start.el' file in the `site-lisp'
95;; directory of your Emacs installation or to your Emacs start-up file `.emacs'
fda91268 96;; (not required in Emacs 20 and higher):
3dcb36b7
JB
97
98;; (autoload 'vhdl-mode "vhdl-mode" "VHDL Mode" t)
99;; (setq auto-mode-alist (cons '("\\.vhdl?\\'" . vhdl-mode) auto-mode-alist))
100
101;; More detailed installation instructions are included in the official
102;; VHDL Mode distribution.
d2ddb974 103
5eabfe72 104;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
09ae5da1 105;; Acknowledgments
d2ddb974
KH
106
107;; Electrification ideas by Bob Pack <rlpst@cislabs.pitt.edu>
5eabfe72 108;; and Steve Grout.
d2ddb974 109
5eabfe72 110;; Fontification approach suggested by Ken Wood <ken@eda.com.au>.
3dcb36b7 111;; Ideas about alignment from John Wiegley <johnw@gnu.org>.
d2ddb974
KH
112
113;; Many thanks to all the users who sent me bug reports and enhancement
3dcb36b7
JB
114;; requests.
115;; Thanks to Colin Marquardt for his serious beta testing, his innumerable
116;; enhancement suggestions and the fruitful discussions.
5eabfe72
KH
117;; Thanks to Dan Nicolaescu for reviewing the code and for his valuable hints.
118;; Thanks to Ulf Klaperski for the indentation speedup hint.
119
120;; Special thanks go to Wolfgang Fichtner and the crew from the Integrated
121;; Systems Laboratory, Swiss Federal Institute of Technology Zurich, for
122;; giving me the opportunity to develop this code.
123;; This work has been funded in part by MICROSWISS, a Microelectronics Program
124;; of the Swiss Government.
125
3dcb36b7 126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
127
128;;; Code:
129
9e5538bc 130;; Emacs 21+ handling
f8246027 131(defconst vhdl-emacs-21 (and (<= 21 emacs-major-version) (not (featurep 'xemacs)))
0a2e512a 132 "Non-nil if GNU Emacs 21, 22, ... is used.")
f8246027 133(defconst vhdl-emacs-22 (and (<= 22 emacs-major-version) (not (featurep 'xemacs)))
0a2e512a 134 "Non-nil if GNU Emacs 22, ... is used.")
3dcb36b7 135
354617b5 136(defvar compilation-file-regexp-alist)
84c98ace
JB
137(defvar conf-alist)
138(defvar conf-entry)
139(defvar conf-key)
140(defvar ent-alist)
354617b5
JB
141(defvar itimer-version)
142(defvar lazy-lock-defer-contextually)
143(defvar lazy-lock-defer-on-scrolling)
144(defvar lazy-lock-defer-on-the-fly)
7bf42457
JB
145(defvar speedbar-attached-frame)
146
354617b5 147
5eabfe72
KH
148;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
149;;; Variables
150;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974 151
3dcb36b7 152;; help function for user options
5eabfe72
KH
153(defun vhdl-custom-set (variable value &rest functions)
154 "Set variables as in `custom-set-default' and call FUNCTIONS afterwards."
155 (if (fboundp 'custom-set-default)
156 (custom-set-default variable value)
157 (set-default variable value))
158 (while functions
159 (when (fboundp (car functions)) (funcall (car functions)))
160 (setq functions (cdr functions))))
161
3dcb36b7
JB
162(defun vhdl-widget-directory-validate (widget)
163 "Check that the value of WIDGET is a valid directory entry (i.e. ends with
164'/' or is empty)."
165 (let ((val (widget-value widget)))
166 (unless (string-match "^\\(\\|.*/\\)$" val)
167 (widget-put widget :error "Invalid directory entry: must end with '/'")
168 widget)))
169
170;; help string for user options
171(defconst vhdl-name-doc-string "
172
173FROM REGEXP is a regular expression matching the original name:
174 \".*\" matches the entire string
175 \"\\(...\\)\" matches a substring
176TO STRING specifies the string to be inserted as new name:
177 \"\\&\" means substitute entire matched text
178 \"\\N\" means substitute what matched the Nth \"\\(...\\)\"
179Examples:
180 \".*\" \"\\&\" inserts original string
181 \".*\" \"\\&_i\" attaches \"_i\" to original string
182 \"\\(.*\\)_[io]$\" \"\\1\" strips off \"_i\" or \"_o\" from original string
183 \".*\" \"foo\" inserts constant string \"foo\"
184 \".*\" \"\" inserts empty string")
185
5eabfe72 186;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
fda91268 187;; User variables (customization options)
d2ddb974
KH
188
189(defgroup vhdl nil
190 "Customizations for VHDL Mode."
191 :prefix "vhdl-"
42dfe0ad 192 :group 'languages
0a2e512a 193; :version "21.2" ; comment out for XEmacs
5eabfe72 194 )
d2ddb974
KH
195
196(defgroup vhdl-mode nil
197 "Customizations for modes."
198 :group 'vhdl)
199
5eabfe72 200(defcustom vhdl-indent-tabs-mode nil
fb7ada5f 201 "Non-nil means indentation can insert tabs.
d2ddb974
KH
202Overrides local variable `indent-tabs-mode'."
203 :type 'boolean
204 :group 'vhdl-mode)
205
206
207(defgroup vhdl-compile nil
208 "Customizations for compilation."
209 :group 'vhdl)
210
5eabfe72
KH
211(defcustom vhdl-compiler-alist
212 '(
fda91268
RZ
213 ("ADVance MS" "vacom" "-work \\1" "make" "-f \\1"
214 nil "valib \\1; vamap \\2 \\1" "./" "work/" "Makefile" "adms"
215 ("\\s-\\([0-9]+\\):" 0 1 0) ("Compiling file \\(.+\\)" 1)
216 ("ENTI/\\1.vif" "ARCH/\\1-\\2.vif" "CONF/\\1.vif"
217 "PACK/\\1.vif" "BODY/\\1.vif" upcase))
218 ;; Aldec
219 ;; COMP96 ERROR COMP96_0078: "Unknown identifier "Addr_Bits"." "<filename>" 40 30
220 ("Aldec" "vcom" "-93 -work \\1" "make" "-f \\1"
221 nil "vlib \\1; vmap \\2 \\1" "./" "work/" "Makefile" "aldec"
222 (".+?[ \t]+\\(?:ERROR\\)[^:]+:.+?\\(?:.+\"\\(.+?\\)\"[ \t]+\\([0-9]+\\)\\)" 1 2 0) ("" 0)
223 nil)
3dcb36b7 224 ;; Cadence Leapfrog: cv -file test.vhd
5eabfe72 225 ;; duluth: *E,430 (test.vhd,13): identifier (POSITIV) is not declared
3dcb36b7
JB
226 ("Cadence Leapfrog" "cv" "-work \\1 -file" "make" "-f \\1"
227 nil "mkdir \\1" "./" "work/" "Makefile" "leapfrog"
228 ("duluth: \\*E,[0-9]+ (\\(.+\\),\\([0-9]+\\)):" 1 2 0) ("" 0)
229 ("\\1/entity" "\\2/\\1" "\\1/configuration"
230 "\\1/package" "\\1/body" downcase))
231 ;; Cadence Affirma NC vhdl: ncvhdl test.vhd
232 ;; ncvhdl_p: *E,IDENTU (test.vhd,13|25): identifier
233 ;; (PLL_400X_TOP) is not declared [10.3].
234 ("Cadence NC" "ncvhdl" "-work \\1" "make" "-f \\1"
235 nil "mkdir \\1" "./" "work/" "Makefile" "ncvhdl"
236 ("ncvhdl_p: \\*E,\\w+ (\\(.+\\),\\([0-9]+\\)|\\([0-9]+\\)):" 1 2 3) ("" 0)
0a2e512a
RF
237 ("\\1/entity/pc.db" "\\2/\\1/pc.db" "\\1/configuration/pc.db"
238 "\\1/package/pc.db" "\\1/body/pc.db" downcase))
fda91268
RZ
239 ;; ghdl vhdl: ghdl test.vhd
240 ("GHDL" "ghdl" "-i --workdir=\\1 --ieee=synopsys -fexplicit " "make" "-f \\1"
241 nil "mkdir \\1" "./" "work/" "Makefile" "ghdl"
242 ("ghdl_p: \\*E,\\w+ (\\(.+\\),\\([0-9]+\\)|\\([0-9]+\\)):" 1 2 3) ("" 0)
243 ("\\1/entity" "\\2/\\1" "\\1/configuration"
244 "\\1/package" "\\1/body" downcase))
5eabfe72 245 ;; Ikos Voyager: analyze test.vhd
3dcb36b7 246 ;; analyze test.vhd
5eabfe72 247 ;; E L4/C5: this library unit is inaccessible
3dcb36b7
JB
248 ("Ikos" "analyze" "-l \\1" "make" "-f \\1"
249 nil "mkdir \\1" "./" "work/" "Makefile" "ikos"
250 ("E L\\([0-9]+\\)/C\\([0-9]+\\):" 0 1 2)
251 ("^analyze +\\(.+ +\\)*\\(.+\\)$" 2)
252 nil)
5eabfe72
KH
253 ;; ModelSim, Model Technology: vcom test.vhd
254 ;; ERROR: test.vhd(14): Unknown identifier: positiv
255 ;; WARNING[2]: test.vhd(85): Possible infinite loop
fda91268 256 ;; ** Warning: [4] ../src/emacsvsim.vhd(43): An abstract ...
3dcb36b7
JB
257 ;; ** Error: adder.vhd(190): Unknown identifier: ctl_numb
258 ("ModelSim" "vcom" "-93 -work \\1" "make" "-f \\1"
259 nil "vlib \\1; vmap \\2 \\1" "./" "work/" "Makefile" "modelsim"
fda91268 260 ("\\(ERROR\\|WARNING\\|\\*\\* Error\\|\\*\\* Warning\\)[^:]*:\\( *\[[0-9]+\]\\)? \\(.+\\)(\\([0-9]+\\)):" 3 4 0) ("" 0)
3dcb36b7
JB
261 ("\\1/_primary.dat" "\\2/\\1.dat" "\\1/_primary.dat"
262 "\\1/_primary.dat" "\\1/body.dat" downcase))
263 ;; ProVHDL, Synopsys LEDA: provhdl -w work -f test.vhd
264 ;; test.vhd:34: error message
265 ("LEDA ProVHDL" "provhdl" "-w \\1 -f" "make" "-f \\1"
266 nil "mkdir \\1" "./" "work/" "Makefile" "provhdl"
267 ("\\([^ \t\n]+\\):\\([0-9]+\\): " 1 2 0) ("" 0)
268 ("ENTI/\\1.vif" "ARCH/\\1-\\2.vif" "CONF/\\1.vif"
269 "PACK/\\1.vif" "BODY/BODY-\\1.vif" upcase))
5eabfe72
KH
270 ;; QuickHDL, Mentor Graphics: qvhcom test.vhd
271 ;; ERROR: test.vhd(24): near "dnd": expecting: END
272 ;; WARNING[4]: test.vhd(30): A space is required between ...
3dcb36b7
JB
273 ("QuickHDL" "qvhcom" "-work \\1" "make" "-f \\1"
274 nil "mkdir \\1" "./" "work/" "Makefile" "quickhdl"
275 ("\\(ERROR\\|WARNING\\)[^:]*: \\(.+\\)(\\([0-9]+\\)):" 2 3 0) ("" 0)
276 ("\\1/_primary.dat" "\\2/\\1.dat" "\\1/_primary.dat"
277 "\\1/_primary.dat" "\\1/body.dat" downcase))
278 ;; Savant: scram -publish-cc test.vhd
279 ;; test.vhd:87: _set_passed_through_out_port(IIR_Boolean) not defined for
280 ("Savant" "scram" "-publish-cc -design-library-name \\1" "make" "-f \\1"
281 nil "mkdir \\1" "./" "work._savant_lib/" "Makefile" "savant"
282 ("\\([^ \t\n]+\\):\\([0-9]+\\): " 1 2 0) ("" 0)
283 ("\\1_entity.vhdl" "\\2_secondary_units._savant_lib/\\2_\\1.vhdl"
284 "\\1_config.vhdl" "\\1_package.vhdl"
285 "\\1_secondary_units._savant_lib/\\1_package_body.vhdl" downcase))
286 ;; Simili: vhdlp -work test.vhd
287 ;; Error: CSVHDL0002: test.vhd: (line 97): Invalid prefix
288 ("Simili" "vhdlp" "-work \\1" "make" "-f \\1"
289 nil "mkdir \\1" "./" "work/" "Makefile" "simili"
290 ("\\(Error\\|Warning\\): \\w+: \\(.+\\): (line \\([0-9]+\\)): " 2 3 0) ("" 0)
291 ("\\1/prim.var" "\\2/_\\1.var" "\\1/prim.var"
292 "\\1/prim.var" "\\1/_body.var" downcase))
293 ;; Speedwave (Innoveda): analyze -libfile vsslib.ini -src test.vhd
294 ;; ERROR[11]::File test.vhd Line 100: Use of undeclared identifier
295 ("Speedwave" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1"
296 nil "mkdir \\1" "./" "work/" "Makefile" "speedwave"
297 ("^ *ERROR\[[0-9]+\]::File \\(.+\\) Line \\([0-9]+\\):" 1 2 0) ("" 0)
298 nil)
299 ;; Synopsys, VHDL Analyzer (sim): vhdlan -nc test.vhd
5eabfe72 300 ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context.
3dcb36b7
JB
301 ("Synopsys" "vhdlan" "-nc -work \\1" "make" "-f \\1"
302 nil "mkdir \\1" "./" "work/" "Makefile" "synopsys"
303 ("\\*\\*Error: vhdlan,[0-9]+ \\(.+\\)(\\([0-9]+\\)):" 1 2 0) ("" 0)
304 ("\\1.sim" "\\2__\\1.sim" "\\1.sim" "\\1.sim" "\\1__.sim" upcase))
305 ;; Synopsys, VHDL Analyzer (syn): vhdlan -nc -spc test.vhd
306 ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context.
307 ("Synopsys Design Compiler" "vhdlan" "-nc -spc -work \\1" "make" "-f \\1"
308 nil "mkdir \\1" "./" "work/" "Makefile" "synopsys_dc"
309 ("\\*\\*Error: vhdlan,[0-9]+ \\(.+\\)(\\([0-9]+\\)):" 1 2 0) ("" 0)
310 ("\\1.syn" "\\2__\\1.syn" "\\1.syn" "\\1.syn" "\\1__.syn" upcase))
311 ;; Synplify:
312 ;; @W:"test.vhd":57:8:57:9|Optimizing register bit count_x(5) to a constant 0
313 ("Synplify" "n/a" "n/a" "make" "-f \\1"
314 nil "mkdir \\1" "./" "work/" "Makefile" "synplify"
315 ("@[EWN]:\"\\(.+\\)\":\\([0-9]+\\):\\([0-9]+\\):" 1 2 3) ("" 0)
316 nil)
5eabfe72 317 ;; Vantage: analyze -libfile vsslib.ini -src test.vhd
3dcb36b7
JB
318 ;; Compiling "test.vhd" line 1...
319 ;; **Error: LINE 49 *** No aggregate value is valid in this context.
320 ("Vantage" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1"
321 nil "mkdir \\1" "./" "work/" "Makefile" "vantage"
322 ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1 0)
323 ("^ *Compiling \"\\(.+\\)\" " 1)
324 nil)
325 ;; VeriBest: vc vhdl test.vhd
326 ;; (no file name printed out!)
327 ;; 32: Z <= A and BitA ;
328 ;; ^^^^
329 ;; [Error] Name BITA is unknown
330 ("VeriBest" "vc" "vhdl" "make" "-f \\1"
331 nil "mkdir \\1" "./" "work/" "Makefile" "veribest"
332 ("^ +\\([0-9]+\\): +[^ ]" 0 1 0) ("" 0)
333 nil)
5eabfe72 334 ;; Viewlogic: analyze -libfile vsslib.ini -src test.vhd
3dcb36b7
JB
335 ;; Compiling "test.vhd" line 1...
336 ;; **Error: LINE 49 *** No aggregate value is valid in this context.
337 ("Viewlogic" "analyze" "-libfile vsslib.ini -src" "make" "-f \\1"
338 nil "mkdir \\1" "./" "work/" "Makefile" "viewlogic"
339 ("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 0 1 0)
340 ("^ *Compiling \"\\(.+\\)\" " 1)
341 nil)
fda91268
RZ
342 ;; Xilinx XST:
343 ;; ERROR:HDLParsers:164 - "test.vhd" Line 3. parse error
344 ("Xilinx XST" "xflow" "" "make" "-f \\1"
345 nil "mkdir \\1" "./" "work/" "Makefile" "xilinx"
346 ("^ERROR:HDLParsers:[0-9]+ - \"\\(.+\\)\" Line \\([0-9]+\\)\." 1 2 0) ("" 0)
347 nil)
5eabfe72 348 )
fb7ada5f 349 "List of available VHDL compilers and their properties.
5eabfe72
KH
350Each list entry specifies the following items for a compiler:
351Compiler:
3dcb36b7
JB
352 Compiler name : name used in option `vhdl-compiler' to choose compiler
353 Compile command : command used for source file compilation
354 Compile options : compile options (\"\\1\" inserts library name)
355 Make command : command used for compilation using a Makefile
356 Make options : make options (\"\\1\" inserts Makefile name)
357 Generate Makefile: use built-in function or command to generate a Makefile
358 \(\"\\1\" inserts Makefile name, \"\\2\" inserts library name)
359 Library command : command to create library directory \(\"\\1\" inserts
360 library directory, \"\\2\" inserts library name)
361 Compile directory: where compilation is run and the Makefile is placed
362 Library directory: directory of default library
363 Makefile name : name of Makefile (default is \"Makefile\")
364 ID string : compiler identification string (see `vhdl-project-alist')
365Error message:
0a2e512a 366 Regexp : regular expression to match error messages (*)
3dcb36b7
JB
367 File subexp index: index of subexpression that matches the file name
368 Line subexp index: index of subexpression that matches the line number
369 Column subexp idx: index of subexpression that matches the column number
370File message:
5eabfe72 371 Regexp : regular expression to match a file name message
3dcb36b7
JB
372 File subexp index: index of subexpression that matches the file name
373Unit-to-file name mapping: mapping of library unit names to names of files
374 generated by the compiler (used for Makefile generation)
375 To string : string a name is mapped to (\"\\1\" inserts the unit name,
376 \"\\2\" inserts the entity name for architectures)
377 Case adjustment : adjust case of inserted unit names
378
0a2e512a 379\(*) The regular expression must match the error message starting from the
84c98ace 380 beginning of the line (but not necessarily to the end of the line).
0a2e512a 381
3dcb36b7
JB
382Compile options allows insertion of the library name (see `vhdl-project-alist')
383in order to set the compilers library option (e.g. \"vcom -work my_lib\").
384
385For Makefile generation, the built-in function can be used (requires
386specification of the unit-to-file name mapping). Alternatively, an
387external command can be specified. Work directory allows specification of
388an alternative \"work\" library path (e.g. \"WORK/\" instead of \"work/\",
389used for Makefile generation). To use another library name than \"work\",
390customize `vhdl-project-alist'. The library command is inserted in Makefiles
391to automatically create the library directory if not existent.
392
393Compile options, compile directory, library directory, and Makefile name are
394overwritten by the project settings if a project is defined (see
395`vhdl-project-alist'). Directory paths are relative to the source file
396directory.
5eabfe72
KH
397
398Some compilers do not include the file name in the error message, but print
399out a file name message in advance. In this case, set \"File Subexp Index\"
3dcb36b7
JB
400under \"Error Message\" to 0 and fill out the \"File Message\" entries.
401If no file name at all is printed out, set both \"File Message\" entries to 0
402\(a default file name message will be printed out instead, does not work in
403XEmacs).
5eabfe72
KH
404
405A compiler is selected for syntax analysis (`\\[vhdl-compile]') by
3dcb36b7 406assigning its name to option `vhdl-compiler'.
5eabfe72 407
3dcb36b7
JB
408Please send any missing or erroneous compiler properties to the maintainer for
409updating.
410
0a2e512a
RF
411NOTE: Activate new error and file message regexps and reflect the new setting
412 in the choice list of option `vhdl-compiler' by restarting Emacs."
3dcb36b7
JB
413 :type '(repeat
414 (list :tag "Compiler" :indent 2
415 (string :tag "Compiler name ")
416 (string :tag "Compile command ")
417 (string :tag "Compile options " "-work \\1")
418 (string :tag "Make command " "make")
419 (string :tag "Make options " "-f \\1")
420 (choice :tag "Generate Makefile "
421 (const :tag "Built-in function" nil)
422 (string :tag "Command" "vmake \\2 > \\1"))
423 (string :tag "Library command " "mkdir \\1")
424 (directory :tag "Compile directory "
425 :validate vhdl-widget-directory-validate "./")
426 (directory :tag "Library directory "
427 :validate vhdl-widget-directory-validate "work/")
428 (file :tag "Makefile name " "Makefile")
429 (string :tag "ID string ")
430 (list :tag "Error message" :indent 4
431 (regexp :tag "Regexp ")
432 (integer :tag "File subexp index")
433 (integer :tag "Line subexp index")
434 (integer :tag "Column subexp idx"))
435 (list :tag "File message" :indent 4
436 (regexp :tag "Regexp ")
437 (integer :tag "File subexp index"))
438 (choice :tag "Unit-to-file name mapping"
439 :format "%t: %[Value Menu%] %v\n"
440 (const :tag "Not defined" nil)
441 (list :tag "To string" :indent 4
442 (string :tag "Entity " "\\1.vhd")
443 (string :tag "Architecture " "\\2_\\1.vhd")
444 (string :tag "Configuration " "\\1.vhd")
445 (string :tag "Package " "\\1.vhd")
446 (string :tag "Package Body " "\\1_body.vhd")
447 (choice :tag "Case adjustment "
448 (const :tag "None" identity)
449 (const :tag "Upcase" upcase)
450 (const :tag "Downcase" downcase))))))
5eabfe72 451 :set (lambda (variable value)
0a2e512a 452 (vhdl-custom-set variable value 'vhdl-update-mode-menu))
5eabfe72
KH
453 :group 'vhdl-compile)
454
fda91268 455(defcustom vhdl-compiler "GHDL"
fb7ada5f 456 "Specifies the VHDL compiler to be used for syntax analysis.
3dcb36b7
JB
457Select a compiler name from the ones defined in option `vhdl-compiler-alist'."
458 :type (let ((alist vhdl-compiler-alist) list)
459 (while alist
460 (setq list (cons (list 'const (caar alist)) list))
461 (setq alist (cdr alist)))
462 (append '(choice) (nreverse list)))
463 :group 'vhdl-compile)
464
465(defcustom vhdl-compile-use-local-error-regexp t
fb7ada5f 466 "Non-nil means use buffer-local `compilation-error-regexp-alist'.
3dcb36b7
JB
467In this case, only error message regexps for VHDL compilers are active if
468compilation is started from a VHDL buffer. Otherwise, the error message
469regexps are appended to the predefined global regexps, and all regexps are
470active all the time. Note that by doing that, the predefined global regexps
471might result in erroneous parsing of error messages for some VHDL compilers.
472
473NOTE: Activate the new setting by restarting Emacs."
474 :type 'boolean
d2ddb974
KH
475 :group 'vhdl-compile)
476
fda91268
RZ
477(defcustom vhdl-makefile-default-targets '("all" "clean" "library")
478 "List of default target names in Makefiles.
479Automatically generated Makefiles include three default targets to compile
480the entire design, clean the entire design and to create the design library.
481This option allows to change the names of these targets to avoid conflicts
482with other user Makefiles."
483 :type '(list (string :tag "Compile entire design")
484 (string :tag "Clean entire design ")
485 (string :tag "Create design library"))
d1a1c7e6 486 :version "24.3"
fda91268
RZ
487 :group 'vhdl-compile)
488
3dcb36b7 489(defcustom vhdl-makefile-generation-hook nil
fb7ada5f 490 "Functions to run at the end of Makefile generation.
3dcb36b7
JB
491Allows to insert user specific parts into a Makefile.
492
493Example:
494 \(lambda nil
495 \(re-search-backward \"^# Rule for compiling entire design\")
496 \(insert \"# My target\\n\\n.MY_TARGET :\\n\\n\\n\"))"
497 :type 'hook
498 :group 'vhdl-compile)
499
500(defcustom vhdl-default-library "work"
fb7ada5f 501 "Name of default library.
3dcb36b7 502Is overwritten by project settings if a project is active."
d2ddb974
KH
503 :type 'string
504 :group 'vhdl-compile)
505
506
3dcb36b7
JB
507(defgroup vhdl-project nil
508 "Customizations for projects."
d2ddb974
KH
509 :group 'vhdl)
510
3dcb36b7
JB
511(defcustom vhdl-project-alist
512 '(("Example 1" "Source files in two directories, custom library name, VHDL'87"
513 "~/example1/" ("src/system/" "src/components/") ""
514 (("ModelSim" "-87 \\2" "-f \\1 top_level" nil)
515 ("Synopsys" "-vhdl87 \\2" "-f \\1 top_level" ((".*/datapath/.*" . "-optimize \\3") (".*_tb\\.vhd" . nil))))
516 "lib/" "example3_lib" "lib/example3/" "Makefile_\\2" "")
517 ("Example 2" "Individual source files, multiple compilers in different directories"
518 "$EXAMPLE2/" ("vhdl/system.vhd" "vhdl/component_*.vhd") ""
519 nil "\\1/" "work" "\\1/work/" "Makefile" "")
520 ("Example 3" "Source files in a directory tree, multiple compilers in same directory"
521 "/home/me/example3/" ("-r ./*/vhdl/") "/CVS/"
522 nil "./" "work" "work-\\1/" "Makefile-\\1" "\
523-------------------------------------------------------------------------------
524-- This is a multi-line project description
525-- that can be used as a project dependent part of the file header.
526"))
fb7ada5f 527 "List of projects and their properties.
3dcb36b7
JB
528 Name : name used in option `vhdl-project' to choose project
529 Title : title of project (single-line string)
530 Default directory: default project directory (absolute path)
531 Sources : a) source files : path + \"/\" + file name
532 b) directory : path + \"/\"
533 c) directory tree: \"-r \" + path + \"/\"
534 Exclude regexp : matches file/directory names to be excluded as sources
535 Compile options : project-specific options for each compiler
536 Compiler name : name of compiler for which these options are valid
537 Compile options: project-specific compiler options
538 (\"\\1\" inserts library name, \"\\2\" default options)
539 Make options: project-specific make options
540 (\"\\1\" inserts Makefile name, \"\\2\" default options)
541 Exceptions : file-specific exceptions
542 File name regexp: matches file names for which exceptions are valid
543 - Options : file-specific compiler options string
544 (\"\\1\" inserts library name, \"\\2\" default options,
545 \"\\3\" project-specific options)
546 - Do not compile: do not compile this file (in Makefile)
547 Compile directory: where compilation is run and the Makefile is placed
548 \(\"\\1\" inserts compiler ID string)
549 Library name : name of library (default is \"work\")
550 Library directory: path to library (\"\\1\" inserts compiler ID string)
551 Makefile name : name of Makefile
552 (\"\\1\" inserts compiler ID string, \"\\2\" library name)
553 Description : description of project (multi-line string)
554
555Project title and description are used to insert into the file header (see
556option `vhdl-file-header').
557
558The default directory must have an absolute path (use `M-TAB' for completion).
559All other paths can be absolute or relative to the default directory. All
560paths must end with '/'.
561
562The design units found in the sources (files and directories) are shown in the
563hierarchy browser. Path and file name can contain wildcards `*' and `?' as
564well as \"./\" and \"../\" (\"sh\" syntax). Paths can also be absolute.
565Environment variables (e.g. \"$EXAMPLE2\") are resolved. If no sources are
566specified, the default directory is taken as source directory. Otherwise,
567the default directory is only taken as source directory if there is a sources
568entry with the empty string or \"./\". Exclude regexp allows to filter out
569specific file and directory names from the list of sources (e.g. CVS
570directories).
571
572Files are compiled in the compile directory. Makefiles are also placed into
573the compile directory. Library directory specifies which directory the
574compiler compiles into (used to generate the Makefile).
575
576Since different compile/library directories and Makefiles may exist for
577different compilers within one project, these paths and names allow the
578insertion of a compiler-dependent ID string (defined in `vhdl-compiler-alist').
579Compile options, compile directory, library directory, and Makefile name
580overwrite the settings of the current compiler.
581
582File-specific compiler options (highest priority) overwrite project-specific
583options which overwrite default options (lowest priority). Lower priority
584options can be inserted in higher priority options. This allows to reuse
585default options (e.g. \"-file\") in project- or file-specific options (e.g.
586\"-93 -file\").
587
588NOTE: Reflect the new setting in the choice list of option `vhdl-project'
589 by restarting Emacs."
590 :type `(repeat
591 (list :tag "Project" :indent 2
592 (string :tag "Name ")
593 (string :tag "Title ")
594 (directory :tag "Default directory"
595 :validate vhdl-widget-directory-validate
596 ,(abbreviate-file-name default-directory))
597 (repeat :tag "Sources " :indent 4
598 (directory :format " %v" "./"))
599 (regexp :tag "Exclude regexp ")
600 (repeat
601 :tag "Compile options " :indent 4
602 (list :tag "Compiler" :indent 6
603 ,(let ((alist vhdl-compiler-alist) list)
604 (while alist
605 (setq list (cons (list 'const (caar alist)) list))
606 (setq alist (cdr alist)))
607 (append '(choice :tag "Compiler name")
608 (nreverse list)))
609 (string :tag "Compile options" "\\2")
610 (string :tag "Make options " "\\2")
611 (repeat
612 :tag "Exceptions " :indent 8
613 (cons :format "%v"
614 (regexp :tag "File name regexp ")
615 (choice :format "%[Value Menu%] %v"
616 (string :tag "Options" "\\3")
617 (const :tag "Do not compile" nil))))))
618 (directory :tag "Compile directory"
619 :validate vhdl-widget-directory-validate "./")
620 (string :tag "Library name " "work")
621 (directory :tag "Library directory"
622 :validate vhdl-widget-directory-validate "work/")
623 (file :tag "Makefile name " "Makefile")
624 (string :tag "Description: (type `C-j' for newline)"
625 :format "%t\n%v\n")))
626 :set (lambda (variable value)
0a2e512a 627 (vhdl-custom-set variable value
3dcb36b7
JB
628 'vhdl-update-mode-menu
629 'vhdl-speedbar-refresh))
630 :group 'vhdl-project)
631
632(defcustom vhdl-project nil
fb7ada5f 633 "Specifies the default for the current project.
3dcb36b7
JB
634Select a project name from the ones defined in option `vhdl-project-alist'.
635Is used to determine the project title and description to be inserted in file
636headers and the source files/directories to be scanned in the hierarchy
637browser. The current project can also be changed temporarily in the menu."
638 :type (let ((alist vhdl-project-alist) list)
639 (while alist
640 (setq list (cons (list 'const (caar alist)) list))
641 (setq alist (cdr alist)))
642 (append '(choice (const :tag "None" nil) (const :tag "--"))
643 (nreverse list)))
644 :group 'vhdl-project)
645
646(defcustom vhdl-project-file-name '("\\1.prj")
fb7ada5f 647 "List of file names/paths for importing/exporting project setups.
3dcb36b7
JB
648\"\\1\" is replaced by the project name (SPC is replaced by `_'), \"\\2\" is
649replaced by the user name (allows to have user-specific project setups).
650The first entry is used as file name to import/export individual project
651setups. All entries are used to automatically import project setups at
652startup (see option `vhdl-project-auto-load'). Projects loaded from the
653first entry are automatically made current. Hint: specify local project
654setups in first entry, global setups in following entries; loading a local
655project setup will make it current, while loading the global setups
656is done without changing the current project.
657Names can also have an absolute path (i.e. project setups can be stored
658in global directories)."
659 :type '(repeat (string :tag "File name" "\\1.prj"))
660 :group 'vhdl-project)
661
662(defcustom vhdl-project-auto-load '(startup)
fb7ada5f 663 "Automatically load project setups from files.
3dcb36b7
JB
664All project setup files that match the file names specified in option
665`vhdl-project-file-name' are automatically loaded. The project of the
666\(alphabetically) last loaded setup of the first `vhdl-project-file-name'
667entry is activated.
668A project setup file can be obtained by exporting a project (see menu).
669 At startup: project setup file is loaded at Emacs startup"
670 :type '(set (const :tag "At startup" startup))
671 :group 'vhdl-project)
672
673(defcustom vhdl-project-sort t
fb7ada5f 674 "Non-nil means projects are displayed in alphabetical order."
3dcb36b7
JB
675 :type 'boolean
676 :group 'vhdl-project)
677
678
679(defgroup vhdl-style nil
680 "Customizations for coding styles."
681 :group 'vhdl
682 :group 'vhdl-template
683 :group 'vhdl-port
684 :group 'vhdl-compose)
685
fda91268 686(defcustom vhdl-standard '(93 nil)
fb7ada5f 687 "VHDL standards used.
5eabfe72
KH
688Basic standard:
689 VHDL'87 : IEEE Std 1076-1987
fda91268 690 VHDL'93/02 : IEEE Std 1076-1993/2002
5eabfe72
KH
691Additional standards:
692 VHDL-AMS : IEEE Std 1076.1 (analog-mixed-signal)
3dcb36b7 693 Math packages: IEEE Std 1076.2 (`math_real', `math_complex')
5eabfe72 694
3dcb36b7
JB
695NOTE: Activate the new setting in a VHDL buffer by using the menu entry
696 \"Activate Options\"."
5eabfe72
KH
697 :type '(list (choice :tag "Basic standard"
698 (const :tag "VHDL'87" 87)
fda91268 699 (const :tag "VHDL'93/02" 93))
5eabfe72
KH
700 (set :tag "Additional standards" :indent 2
701 (const :tag "VHDL-AMS" ams)
3dcb36b7 702 (const :tag "Math packages" math)))
5eabfe72 703 :set (lambda (variable value)
0a2e512a 704 (vhdl-custom-set variable value
5eabfe72
KH
705 'vhdl-template-map-init
706 'vhdl-mode-abbrev-table-init
707 'vhdl-template-construct-alist-init
708 'vhdl-template-package-alist-init
709 'vhdl-update-mode-menu
710 'vhdl-words-init 'vhdl-font-lock-init))
711 :group 'vhdl-style)
712
713(defcustom vhdl-basic-offset 2
fb7ada5f 714 "Amount of basic offset used for indentation.
d2ddb974
KH
715This value is used by + and - symbols in `vhdl-offsets-alist'."
716 :type 'integer
717 :group 'vhdl-style)
718
d2ddb974 719(defcustom vhdl-upper-case-keywords nil
fb7ada5f 720 "Non-nil means convert keywords to upper case.
5eabfe72 721This is done when typed or expanded or by the fix case functions."
d2ddb974 722 :type 'boolean
5eabfe72 723 :set (lambda (variable value)
0a2e512a 724 (vhdl-custom-set variable value 'vhdl-abbrev-list-init))
5eabfe72 725 :group 'vhdl-style)
d2ddb974
KH
726
727(defcustom vhdl-upper-case-types nil
fb7ada5f 728 "Non-nil means convert standardized types to upper case.
5eabfe72 729This is done when expanded or by the fix case functions."
d2ddb974 730 :type 'boolean
5eabfe72 731 :set (lambda (variable value)
0a2e512a 732 (vhdl-custom-set variable value 'vhdl-abbrev-list-init))
5eabfe72 733 :group 'vhdl-style)
d2ddb974
KH
734
735(defcustom vhdl-upper-case-attributes nil
fb7ada5f 736 "Non-nil means convert standardized attributes to upper case.
5eabfe72 737This is done when expanded or by the fix case functions."
d2ddb974 738 :type 'boolean
5eabfe72 739 :set (lambda (variable value)
0a2e512a 740 (vhdl-custom-set variable value 'vhdl-abbrev-list-init))
5eabfe72 741 :group 'vhdl-style)
d2ddb974
KH
742
743(defcustom vhdl-upper-case-enum-values nil
fb7ada5f 744 "Non-nil means convert standardized enumeration values to upper case.
5eabfe72 745This is done when expanded or by the fix case functions."
d2ddb974 746 :type 'boolean
5eabfe72 747 :set (lambda (variable value)
0a2e512a 748 (vhdl-custom-set variable value 'vhdl-abbrev-list-init))
5eabfe72
KH
749 :group 'vhdl-style)
750
751(defcustom vhdl-upper-case-constants t
fb7ada5f 752 "Non-nil means convert standardized constants to upper case.
5eabfe72
KH
753This is done when expanded."
754 :type 'boolean
755 :set (lambda (variable value)
0a2e512a 756 (vhdl-custom-set variable value 'vhdl-abbrev-list-init))
5eabfe72 757 :group 'vhdl-style)
d2ddb974 758
3dcb36b7 759(defcustom vhdl-use-direct-instantiation 'standard
fb7ada5f 760 "Non-nil means use VHDL'93 direct component instantiation.
3dcb36b7
JB
761 Never : never
762 Standard: only in VHDL standards that allow it (VHDL'93 and higher)
763 Always : always"
764 :type '(choice (const :tag "Never" never)
765 (const :tag "Standard" standard)
766 (const :tag "Always" always))
767 :group 'vhdl-style)
768
fda91268
RZ
769(defcustom vhdl-array-index-record-field-in-sensitivity-list t
770 "Non-nil means include array indices / record fields in sensitivity list.
771If a signal read in a process is a record field or pointed to by an array
772index, the record field or array index is included with the record name in
773the sensitivity list (e.g. \"in1(0)\", \"in2.f0\").
774Otherwise, only the record name is included (e.g. \"in1\", \"in2\")."
775 :type 'boolean
d1a1c7e6 776 :version "24.3"
fda91268 777 :group 'vhdl-style)
3dcb36b7
JB
778
779(defgroup vhdl-naming nil
780 "Customizations for naming conventions."
781 :group 'vhdl)
782
783(defcustom vhdl-entity-file-name '(".*" . "\\&")
784 (concat
fb7ada5f 785 "Specifies how the entity file name is obtained.
3dcb36b7
JB
786The entity file name can be obtained by modifying the entity name (e.g.
787attaching or stripping off a substring). The file extension is automatically
788taken from the file name of the current buffer."
789 vhdl-name-doc-string)
790 :type '(cons (regexp :tag "From regexp")
791 (string :tag "To string "))
792 :group 'vhdl-naming
793 :group 'vhdl-compose)
d2ddb974 794
3dcb36b7
JB
795(defcustom vhdl-architecture-file-name '("\\(.*\\) \\(.*\\)" . "\\1_\\2")
796 (concat
fb7ada5f 797 "Specifies how the architecture file name is obtained.
3dcb36b7
JB
798The architecture file name can be obtained by modifying the entity
799and/or architecture name (e.g. attaching or stripping off a substring). The
0a2e512a
RF
800file extension is automatically taken from the file name of the current
801buffer. The string that is matched against the regexp is the concatenation
802of the entity and the architecture name separated by a space. This gives
803access to both names (see default setting as example)."
804 vhdl-name-doc-string)
805 :type '(cons (regexp :tag "From regexp")
806 (string :tag "To string "))
807 :group 'vhdl-naming
808 :group 'vhdl-compose)
809
810(defcustom vhdl-configuration-file-name '(".*" . "\\&")
811 (concat
fb7ada5f 812 "Specifies how the configuration file name is obtained.
0a2e512a
RF
813The configuration file name can be obtained by modifying the configuration
814name (e.g. attaching or stripping off a substring). The file extension is
815automatically taken from the file name of the current buffer."
3dcb36b7
JB
816 vhdl-name-doc-string)
817 :type '(cons (regexp :tag "From regexp")
818 (string :tag "To string "))
819 :group 'vhdl-naming
820 :group 'vhdl-compose)
821
822(defcustom vhdl-package-file-name '(".*" . "\\&")
823 (concat
fb7ada5f 824 "Specifies how the package file name is obtained.
3dcb36b7
JB
825The package file name can be obtained by modifying the package name (e.g.
826attaching or stripping off a substring). The file extension is automatically
0a2e512a
RF
827taken from the file name of the current buffer. Package files can be created
828in a different directory by prepending a relative or absolute path to the
829file name."
3dcb36b7
JB
830 vhdl-name-doc-string)
831 :type '(cons (regexp :tag "From regexp")
832 (string :tag "To string "))
833 :group 'vhdl-naming
834 :group 'vhdl-compose)
835
836(defcustom vhdl-file-name-case 'identity
fb7ada5f 837 "Specifies how to change case for obtaining file names.
3dcb36b7
JB
838When deriving a file name from a VHDL unit name, case can be changed as
839follows:
840 As Is: case is not changed (taken as is)
841 Lower Case: whole name is changed to lower case
842 Upper Case: whole name is changed to upper case
843 Capitalize: first letter of each word in name is capitalized"
844 :type '(choice (const :tag "As Is" identity)
845 (const :tag "Lower Case" downcase)
846 (const :tag "Upper Case" upcase)
847 (const :tag "Capitalize" capitalize))
848 :group 'vhdl-naming
849 :group 'vhdl-compose)
850
851
852(defgroup vhdl-template nil
5eabfe72 853 "Customizations for electrification."
d2ddb974
KH
854 :group 'vhdl)
855
5eabfe72 856(defcustom vhdl-electric-keywords '(vhdl user)
fb7ada5f 857 "Type of keywords for which electrification is enabled.
5eabfe72 858 VHDL keywords: invoke built-in templates
3dcb36b7 859 User keywords: invoke user models (see option `vhdl-model-alist')"
5eabfe72 860 :type '(set (const :tag "VHDL keywords" vhdl)
3dcb36b7 861 (const :tag "User model keywords" user))
5eabfe72 862 :set (lambda (variable value)
0a2e512a 863 (vhdl-custom-set variable value 'vhdl-mode-abbrev-table-init))
3dcb36b7 864 :group 'vhdl-template)
5eabfe72
KH
865
866(defcustom vhdl-optional-labels 'process
fb7ada5f 867 "Constructs for which labels are to be queried.
5eabfe72
KH
868Template generators prompt for optional labels for:
869 None : no constructs
870 Processes only: processes only (also procedurals in VHDL-AMS)
871 All constructs: all constructs with optional labels and keyword END"
872 :type '(choice (const :tag "None" none)
873 (const :tag "Processes only" process)
874 (const :tag "All constructs" all))
3dcb36b7 875 :group 'vhdl-template)
d2ddb974 876
5eabfe72 877(defcustom vhdl-insert-empty-lines 'unit
fb7ada5f 878 "Specifies whether to insert empty lines in some templates.
5eabfe72
KH
879This improves readability of code. Empty lines are inserted in:
880 None : no constructs
881 Design units only: entities, architectures, configurations, packages only
882 All constructs : also all constructs with BEGIN...END parts
883
3dcb36b7 884Replaces option `vhdl-additional-empty-lines'."
5eabfe72
KH
885 :type '(choice (const :tag "None" none)
886 (const :tag "Design units only" unit)
887 (const :tag "All constructs" all))
3dcb36b7
JB
888 :group 'vhdl-template
889 :group 'vhdl-port
890 :group 'vhdl-compose)
5eabfe72
KH
891
892(defcustom vhdl-argument-list-indent nil
fb7ada5f 893 "Non-nil means indent argument lists relative to opening parenthesis.
5eabfe72
KH
894That is, argument, association, and port lists start on the same line as the
895opening parenthesis and subsequent lines are indented accordingly.
896Otherwise, lists start on a new line and are indented as normal code."
d2ddb974 897 :type 'boolean
3dcb36b7
JB
898 :group 'vhdl-template
899 :group 'vhdl-port
900 :group 'vhdl-compose)
d2ddb974 901
5eabfe72 902(defcustom vhdl-association-list-with-formals t
fb7ada5f 903 "Non-nil means write association lists with formal parameters.
3dcb36b7
JB
904Templates prompt for formal and actual parameters (ports/generics).
905When pasting component instantiations, formals are included.
5eabfe72 906If nil, only a list of actual parameters is entered."
d2ddb974 907 :type 'boolean
3dcb36b7
JB
908 :group 'vhdl-template
909 :group 'vhdl-port
910 :group 'vhdl-compose)
d2ddb974
KH
911
912(defcustom vhdl-conditions-in-parenthesis nil
fb7ada5f 913 "Non-nil means place parenthesis around condition expressions."
d2ddb974 914 :type 'boolean
3dcb36b7 915 :group 'vhdl-template)
d2ddb974 916
5eabfe72 917(defcustom vhdl-zero-string "'0'"
fb7ada5f 918 "String to use for a logic zero."
5eabfe72 919 :type 'string
3dcb36b7 920 :group 'vhdl-template)
5eabfe72
KH
921
922(defcustom vhdl-one-string "'1'"
fb7ada5f 923 "String to use for a logic one."
5eabfe72 924 :type 'string
3dcb36b7 925 :group 'vhdl-template)
5eabfe72
KH
926
927
928(defgroup vhdl-header nil
929 "Customizations for file header."
3dcb36b7
JB
930 :group 'vhdl-template
931 :group 'vhdl-compose)
d2ddb974 932
5eabfe72
KH
933(defcustom vhdl-file-header "\
934-------------------------------------------------------------------------------
935-- Title : <title string>
936-- Project : <project>
937-------------------------------------------------------------------------------
938-- File : <filename>
939-- Author : <author>
940-- Company : <company>
3dcb36b7 941-- Created : <date>
5eabfe72
KH
942-- Last update: <date>
943-- Platform : <platform>
3dcb36b7 944-- Standard : <standard>
5eabfe72
KH
945<projectdesc>-------------------------------------------------------------------------------
946-- Description: <cursor>
3dcb36b7 947<copyright>-------------------------------------------------------------------------------
5eabfe72
KH
948-- Revisions :
949-- Date Version Author Description
950-- <date> 1.0 <login>\tCreated
951-------------------------------------------------------------------------------
952
953"
fb7ada5f 954 "String or file to insert as file header.
5eabfe72
KH
955If the string specifies an existing file name, the contents of the file is
956inserted, otherwise the string itself is inserted as file header.
957Type `C-j' for newlines.
d2ddb974
KH
958If the header contains RCS keywords, they may be written as <RCS>Keyword<RCS>
959if the header needs to be version controlled.
960
961The following keywords for template generation are supported:
3dcb36b7
JB
962 <filename> : replaced by the name of the buffer
963 <author> : replaced by the user name and email address
fda91268
RZ
964 \(`user-full-name',`mail-host-address', `user-mail-address')
965 <authorfull> : replaced by the user full name (`user-full-name')
3dcb36b7
JB
966 <login> : replaced by user login name (`user-login-name')
967 <company> : replaced by contents of option `vhdl-company-name'
968 <date> : replaced by the current date
969 <year> : replaced by the current year
970 <project> : replaced by title of current project (`vhdl-project')
971 <projectdesc> : replaced by description of current project (`vhdl-project')
972 <copyright> : replaced by copyright string (`vhdl-copyright-string')
973 <platform> : replaced by contents of option `vhdl-platform-spec'
974 <standard> : replaced by the VHDL language standard(s) used
975 <... string> : replaced by a queried string (\"...\" is the prompt word)
976 <title string>: replaced by file title in automatically generated files
977 <cursor> : final cursor position
d2ddb974 978
5eabfe72
KH
979The (multi-line) project description <projectdesc> can be used as a project
980dependent part of the file header and can also contain the above keywords."
981 :type 'string
982 :group 'vhdl-header)
983
984(defcustom vhdl-file-footer ""
fb7ada5f 985 "String or file to insert as file footer.
5eabfe72
KH
986If the string specifies an existing file name, the contents of the file is
987inserted, otherwise the string itself is inserted as file footer (i.e. at
988the end of the file).
3dcb36b7
JB
989Type `C-j' for newlines.
990The same keywords as in option `vhdl-file-header' can be used."
5eabfe72
KH
991 :type 'string
992 :group 'vhdl-header)
993
994(defcustom vhdl-company-name ""
fb7ada5f 995 "Name of company to insert in file header.
3dcb36b7
JB
996See option `vhdl-file-header'."
997 :type 'string
998 :group 'vhdl-header)
999
1000(defcustom vhdl-copyright-string "\
1001-------------------------------------------------------------------------------
1002-- Copyright (c) <year> <company>
1003"
fb7ada5f 1004 "Copyright string to insert in file header.
3dcb36b7
JB
1005Can be multi-line string (type `C-j' for newline) and contain other file
1006header keywords (see option `vhdl-file-header')."
5eabfe72
KH
1007 :type 'string
1008 :group 'vhdl-header)
1009
1010(defcustom vhdl-platform-spec ""
fb7ada5f 1011 "Specification of VHDL platform to insert in file header.
5eabfe72 1012The platform specification should contain names and versions of the
3dcb36b7
JB
1013simulation and synthesis tools used.
1014See option `vhdl-file-header'."
5eabfe72
KH
1015 :type 'string
1016 :group 'vhdl-header)
1017
3dcb36b7 1018(defcustom vhdl-date-format "%Y-%m-%d"
fb7ada5f 1019 "Specifies the date format to use in the header.
5eabfe72
KH
1020This string is passed as argument to the command `format-time-string'.
1021For more information on format strings, see the documentation for the
1022`format-time-string' command (C-h f `format-time-string')."
1023 :type 'string
1024 :group 'vhdl-header)
d2ddb974 1025
5eabfe72 1026(defcustom vhdl-modify-date-prefix-string "-- Last update: "
fb7ada5f 1027 "Prefix string of modification date in VHDL file header.
5eabfe72
KH
1028If actualization of the modification date is called (menu,
1029`\\[vhdl-template-modify]'), this string is searched and the rest
1030of the line replaced by the current date."
d2ddb974 1031 :type 'string
5eabfe72
KH
1032 :group 'vhdl-header)
1033
1034(defcustom vhdl-modify-date-on-saving t
fb7ada5f 1035 "Non-nil means update the modification date when the buffer is saved.
5eabfe72
KH
1036Calls function `\\[vhdl-template-modify]').
1037
3dcb36b7
JB
1038NOTE: Activate the new setting in a VHDL buffer by using the menu entry
1039 \"Activate Options\"."
5eabfe72
KH
1040 :type 'boolean
1041 :group 'vhdl-header)
1042
1043
1044(defgroup vhdl-sequential-process nil
1045 "Customizations for sequential processes."
3dcb36b7 1046 :group 'vhdl-template)
d2ddb974 1047
fda91268 1048(defcustom vhdl-reset-kind 'async
fb7ada5f 1049 "Specifies which kind of reset to use in sequential processes."
5eabfe72
KH
1050 :type '(choice (const :tag "None" none)
1051 (const :tag "Synchronous" sync)
fda91268
RZ
1052 (const :tag "Asynchronous" async)
1053 (const :tag "Query" query))
5eabfe72
KH
1054 :group 'vhdl-sequential-process)
1055
1056(defcustom vhdl-reset-active-high nil
fb7ada5f 1057 "Non-nil means reset in sequential processes is active high.
0404f77e 1058Otherwise, reset is active low."
5eabfe72
KH
1059 :type 'boolean
1060 :group 'vhdl-sequential-process)
1061
1062(defcustom vhdl-clock-rising-edge t
fb7ada5f 1063 "Non-nil means rising edge of clock triggers sequential processes.
0404f77e 1064Otherwise, falling edge triggers."
5eabfe72
KH
1065 :type 'boolean
1066 :group 'vhdl-sequential-process)
1067
1068(defcustom vhdl-clock-edge-condition 'standard
fb7ada5f 1069 "Syntax of the clock edge condition.
5eabfe72
KH
1070 Standard: \"clk'event and clk = '1'\"
1071 Function: \"rising_edge(clk)\""
1072 :type '(choice (const :tag "Standard" standard)
1073 (const :tag "Function" function))
1074 :group 'vhdl-sequential-process)
1075
1076(defcustom vhdl-clock-name ""
fb7ada5f 1077 "Name of clock signal to use in templates."
d2ddb974 1078 :type 'string
5eabfe72 1079 :group 'vhdl-sequential-process)
d2ddb974 1080
5eabfe72 1081(defcustom vhdl-reset-name ""
fb7ada5f 1082 "Name of reset signal to use in templates."
d2ddb974 1083 :type 'string
5eabfe72
KH
1084 :group 'vhdl-sequential-process)
1085
1086
1087(defgroup vhdl-model nil
1088 "Customizations for user models."
1089 :group 'vhdl)
1090
1091(defcustom vhdl-model-alist
3dcb36b7 1092 '(("Example Model"
5eabfe72
KH
1093 "<label> : process (<clock>, <reset>)
1094begin -- process <label>
1095 if <reset> = '0' then -- asynchronous reset (active low)
1096 <cursor>
1097 elsif <clock>'event and <clock> = '1' then -- rising clock edge
1098 if <enable> = '1' then -- synchronous load
84c98ace 1099
5eabfe72
KH
1100 end if;
1101 end if;
1102end process <label>;"
1103 "e" ""))
fb7ada5f 1104 "List of user models.
5eabfe72
KH
1105VHDL models (templates) can be specified by the user in this list. They can be
1106invoked from the menu, through key bindings (`C-c C-m ...'), or by keyword
1107electrification (i.e. overriding existing or creating new keywords, see
3dcb36b7 1108option `vhdl-electric-keywords').
5eabfe72
KH
1109 Name : name of model (string of words and spaces)
1110 String : string or name of file to be inserted as model (newline: `C-j')
1111 Key Binding: key binding to invoke model, added to prefix `C-c C-m'
1112 (must be in double-quotes, examples: \"i\", \"\\C-p\", \"\\M-s\")
1113 Keyword : keyword to invoke model
1114
1115The models can contain prompts to be queried. A prompt is of the form \"<...>\".
1116A prompt that appears several times is queried once and replaced throughout
1117the model. Special prompts are:
1118 <clock> : name specified in `vhdl-clock-name' (if not empty)
1119 <reset> : name specified in `vhdl-reset-name' (if not empty)
1120 <cursor>: final cursor position
3dcb36b7
JB
1121File header prompts (see variable `vhdl-file-header') are automatically
1122replaced, so that user models can also be used to insert different types of
1123headers.
5eabfe72
KH
1124
1125If the string specifies an existing file name, the contents of the file is
1126inserted, otherwise the string itself is inserted.
1127The code within the models should be correctly indented.
1128Type `C-j' for newlines.
1129
3dcb36b7
JB
1130NOTE: Activate the new setting in a VHDL buffer by using the menu entry
1131 \"Activate Options\"."
5eabfe72
KH
1132 :type '(repeat (list :tag "Model" :indent 2
1133 (string :tag "Name ")
1134 (string :tag "String : (type `C-j' for newline)"
1135 :format "%t\n%v")
3dcb36b7
JB
1136 (sexp :tag "Key binding" x)
1137 (string :tag "Keyword " :format "%t: %v\n")))
5eabfe72 1138 :set (lambda (variable value)
0a2e512a 1139 (vhdl-custom-set variable value
5eabfe72
KH
1140 'vhdl-model-map-init
1141 'vhdl-model-defun
1142 'vhdl-mode-abbrev-table-init
1143 'vhdl-update-mode-menu))
1144 :group 'vhdl-model)
1145
3dcb36b7 1146
0a2e512a
RF
1147(defgroup vhdl-compose nil
1148 "Customizations for structural composition."
1149 :group 'vhdl)
1150
1151(defcustom vhdl-compose-architecture-name '(".*" . "str")
1152 (concat
fb7ada5f 1153 "Specifies how the component architecture name is obtained.
0a2e512a
RF
1154The component architecture name can be obtained by modifying the entity name
1155\(e.g. attaching or stripping off a substring).
1156If TO STRING is empty, the architecture name is queried."
1157 vhdl-name-doc-string)
1158 :type '(cons (regexp :tag "From regexp")
1159 (string :tag "To string "))
1160 :group 'vhdl-compose)
1161
1162(defcustom vhdl-compose-configuration-name
1163 '("\\(.*\\) \\(.*\\)" . "\\1_\\2_cfg")
1164 (concat
fb7ada5f 1165 "Specifies how the configuration name is obtained.
0a2e512a
RF
1166The configuration name can be obtained by modifying the entity and/or
1167architecture name (e.g. attaching or stripping off a substring). The string
1168that is matched against the regexp is the concatenation of the entity and the
1169architecture name separated by a space. This gives access to both names (see
1170default setting as example)."
1171 vhdl-name-doc-string)
1172 :type '(cons (regexp :tag "From regexp")
1173 (string :tag "To string "))
1174 :group 'vhdl-compose)
1175
1176(defcustom vhdl-components-package-name
1177 '((".*" . "\\&_components") . "components")
1178 (concat
fb7ada5f 1179 "Specifies how the name for the components package is obtained.
0a2e512a 1180The components package is a package containing all component declarations for
a4c6cfad 1181the current design. Its name can be obtained by modifying the project name
0a2e512a
RF
1182\(e.g. attaching or stripping off a substring). If no project is defined, the
1183DIRECTORY entry is chosen."
1184 vhdl-name-doc-string)
1185 :type '(cons (cons :tag "Project" :indent 2
1186 (regexp :tag "From regexp")
1187 (string :tag "To string "))
1188 (string :tag "Directory:\n String "))
1189 :group 'vhdl-compose)
1190
1191(defcustom vhdl-use-components-package nil
fb7ada5f 1192 "Non-nil means use a separate components package for component declarations.
0a2e512a
RF
1193Otherwise, component declarations are inserted and searched for in the
1194architecture declarative parts."
1195 :type 'boolean
1196 :group 'vhdl-compose)
1197
1198(defcustom vhdl-compose-include-header t
fb7ada5f 1199 "Non-nil means include a header in automatically generated files."
0a2e512a
RF
1200 :type 'boolean
1201 :group 'vhdl-compose)
1202
1203(defcustom vhdl-compose-create-files 'single
fb7ada5f 1204 "Specifies whether new files should be created for the new component.
0a2e512a
RF
1205The component's entity and architecture are inserted:
1206 None : in current buffer
1207 Single file : in new single file
1208 Separate files: in two separate files
1209The file names are obtained from variables `vhdl-entity-file-name' and
1210`vhdl-architecture-file-name'."
1211 :type '(choice (const :tag "None" none)
1212 (const :tag "Single file" single)
1213 (const :tag "Separate files" separate))
1214 :group 'vhdl-compose)
1215
1216(defcustom vhdl-compose-configuration-create-file nil
fb7ada5f 1217 "Specifies whether a new file should be created for the configuration.
0a2e512a
RF
1218If non-nil, a new file is created for the configuration.
1219The file name is obtained from variable `vhdl-configuration-file-name'."
1220 :type 'boolean
1221 :group 'vhdl-compose)
1222
1223(defcustom vhdl-compose-configuration-hierarchical t
fb7ada5f 1224 "Specifies whether hierarchical configurations should be created.
0a2e512a
RF
1225If non-nil, automatically created configurations are hierarchical and include
1226the whole hierarchy of subcomponents. Otherwise the configuration only
1227includes one level of subcomponents."
1228 :type 'boolean
1229 :group 'vhdl-compose)
1230
1231(defcustom vhdl-compose-configuration-use-subconfiguration t
fb7ada5f 1232 "Specifies whether subconfigurations should be used inside configurations.
0a2e512a
RF
1233If non-nil, automatically created configurations use configurations in binding
1234indications for subcomponents, if such configurations exist. Otherwise,
1235entities are used in binding indications for subcomponents."
1236 :type 'boolean
1237 :group 'vhdl-compose)
1238
1239
5eabfe72 1240(defgroup vhdl-port nil
3dcb36b7
JB
1241 "Customizations for port translation functions."
1242 :group 'vhdl
1243 :group 'vhdl-compose)
5eabfe72
KH
1244
1245(defcustom vhdl-include-port-comments nil
fb7ada5f 1246 "Non-nil means include port comments when a port is pasted."
5eabfe72
KH
1247 :type 'boolean
1248 :group 'vhdl-port)
1249
1250(defcustom vhdl-include-direction-comments nil
fb7ada5f 1251 "Non-nil means include port direction in instantiations as comments."
5eabfe72
KH
1252 :type 'boolean
1253 :group 'vhdl-port)
1254
3dcb36b7 1255(defcustom vhdl-include-type-comments nil
fb7ada5f 1256 "Non-nil means include generic/port type in instantiations as comments."
3dcb36b7
JB
1257 :type 'boolean
1258 :group 'vhdl-port)
5eabfe72 1259
3dcb36b7 1260(defcustom vhdl-include-group-comments 'never
fb7ada5f 1261 "Specifies whether to include group comments and spacings.
3dcb36b7
JB
1262The comments and empty lines between groups of ports are pasted:
1263 Never : never
1264 Declarations: in entity/component/constant/signal declarations only
1265 Always : also in generic/port maps"
1266 :type '(choice (const :tag "Never" never)
1267 (const :tag "Declarations" decl)
1268 (const :tag "Always" always))
1269 :group 'vhdl-port)
5eabfe72 1270
3dcb36b7 1271(defcustom vhdl-actual-port-name '(".*" . "\\&")
5eabfe72 1272 (concat
fb7ada5f 1273 "Specifies how actual port names are obtained from formal port names.
5eabfe72
KH
1274In a component instantiation, an actual port name can be obtained by
1275modifying the formal port name (e.g. attaching or stripping off a substring)."
1276 vhdl-name-doc-string)
3dcb36b7
JB
1277 :type '(cons (regexp :tag "From regexp")
1278 (string :tag "To string "))
5eabfe72
KH
1279 :group 'vhdl-port)
1280
3dcb36b7 1281(defcustom vhdl-instance-name '(".*" . "\\&_%d")
5eabfe72 1282 (concat
fb7ada5f 1283 "Specifies how an instance name is obtained.
5eabfe72 1284The instance name can be obtained by modifying the name of the component to be
3dcb36b7
JB
1285instantiated (e.g. attaching or stripping off a substring). \"%d\" is replaced
1286by a unique number (starting with 1).
5eabfe72
KH
1287If TO STRING is empty, the instance name is queried."
1288 vhdl-name-doc-string)
3dcb36b7
JB
1289 :type '(cons (regexp :tag "From regexp")
1290 (string :tag "To string "))
1291 :group 'vhdl-port)
1292
1293
1294(defgroup vhdl-testbench nil
bc25429a 1295 "Customizations for testbench generation."
5eabfe72
KH
1296 :group 'vhdl-port)
1297
1298(defcustom vhdl-testbench-entity-name '(".*" . "\\&_tb")
1299 (concat
fb7ada5f 1300 "Specifies how the testbench entity name is obtained.
3dcb36b7 1301The entity name of a testbench can be obtained by modifying the name of
5eabfe72
KH
1302the component to be tested (e.g. attaching or stripping off a substring)."
1303 vhdl-name-doc-string)
3dcb36b7
JB
1304 :type '(cons (regexp :tag "From regexp")
1305 (string :tag "To string "))
1306 :group 'vhdl-testbench)
5eabfe72
KH
1307
1308(defcustom vhdl-testbench-architecture-name '(".*" . "")
1309 (concat
fb7ada5f 1310 "Specifies how the testbench architecture name is obtained.
3dcb36b7 1311The testbench architecture name can be obtained by modifying the name of
5eabfe72
KH
1312the component to be tested (e.g. attaching or stripping off a substring).
1313If TO STRING is empty, the architecture name is queried."
1314 vhdl-name-doc-string)
3dcb36b7
JB
1315 :type '(cons (regexp :tag "From regexp")
1316 (string :tag "To string "))
1317 :group 'vhdl-testbench)
1318
0a2e512a 1319(defcustom vhdl-testbench-configuration-name vhdl-compose-configuration-name
3dcb36b7 1320 (concat
fb7ada5f 1321 "Specifies how the testbench configuration name is obtained.
3dcb36b7
JB
1322The configuration name of a testbench can be obtained by modifying the entity
1323and/or architecture name (e.g. attaching or stripping off a substring). The
1324string that is matched against the regexp is the concatenation of the entity
1325and the architecture name separated by a space. This gives access to both
1326names (see default setting as example)."
1327 vhdl-name-doc-string)
1328 :type '(cons (regexp :tag "From regexp")
1329 (string :tag "To string "))
1330 :group 'vhdl-testbench)
5eabfe72
KH
1331
1332(defcustom vhdl-testbench-dut-name '(".*" . "DUT")
1333 (concat
fb7ada5f 1334 "Specifies how a DUT instance name is obtained.
5eabfe72 1335The design-under-test instance name (i.e. the component instantiated in the
3dcb36b7 1336testbench) can be obtained by modifying the component name (e.g. attaching
5eabfe72
KH
1337or stripping off a substring)."
1338 vhdl-name-doc-string)
3dcb36b7
JB
1339 :type '(cons (regexp :tag "From regexp")
1340 (string :tag "To string "))
1341 :group 'vhdl-testbench)
5eabfe72 1342
3dcb36b7 1343(defcustom vhdl-testbench-include-header t
fb7ada5f 1344 "Non-nil means include a header in automatically generated files."
3dcb36b7
JB
1345 :type 'boolean
1346 :group 'vhdl-testbench)
5eabfe72 1347
3dcb36b7
JB
1348(defcustom vhdl-testbench-declarations "\
1349 -- clock
1350 signal Clk : std_logic := '1';
1351"
fb7ada5f 1352 "String or file to be inserted in the testbench declarative part.
5eabfe72 1353If the string specifies an existing file name, the contents of the file is
3dcb36b7 1354inserted, otherwise the string itself is inserted in the testbench
5eabfe72
KH
1355architecture before the BEGIN keyword.
1356Type `C-j' for newlines."
1357 :type 'string
3dcb36b7
JB
1358 :group 'vhdl-testbench)
1359
1360(defcustom vhdl-testbench-statements "\
1361 -- clock generation
1362 Clk <= not Clk after 10 ns;
5eabfe72 1363
3dcb36b7
JB
1364 -- waveform generation
1365 WaveGen_Proc: process
1366 begin
1367 -- insert signal assignments here
84c98ace 1368
3dcb36b7
JB
1369 wait until Clk = '1';
1370 end process WaveGen_Proc;
1371"
fb7ada5f 1372 "String or file to be inserted in the testbench statement part.
5eabfe72 1373If the string specifies an existing file name, the contents of the file is
3dcb36b7 1374inserted, otherwise the string itself is inserted in the testbench
5eabfe72
KH
1375architecture before the END keyword.
1376Type `C-j' for newlines."
1377 :type 'string
3dcb36b7 1378 :group 'vhdl-testbench)
5eabfe72
KH
1379
1380(defcustom vhdl-testbench-initialize-signals nil
fb7ada5f 1381 "Non-nil means initialize signals with `0' when declared in testbench."
5eabfe72 1382 :type 'boolean
3dcb36b7
JB
1383 :group 'vhdl-testbench)
1384
1385(defcustom vhdl-testbench-include-library t
fb7ada5f 1386 "Non-nil means a library/use clause for std_logic_1164 is included."
3dcb36b7
JB
1387 :type 'boolean
1388 :group 'vhdl-testbench)
1389
1390(defcustom vhdl-testbench-include-configuration t
fb7ada5f 1391 "Non-nil means a testbench configuration is attached at the end."
3dcb36b7
JB
1392 :type 'boolean
1393 :group 'vhdl-testbench)
5eabfe72
KH
1394
1395(defcustom vhdl-testbench-create-files 'single
fb7ada5f 1396 "Specifies whether new files should be created for the testbench.
3dcb36b7 1397testbench entity and architecture are inserted:
5eabfe72
KH
1398 None : in current buffer
1399 Single file : in new single file
1400 Separate files: in two separate files
0a2e512a
RF
1401The file names are obtained from variables `vhdl-testbench-entity-file-name'
1402and `vhdl-testbench-architecture-file-name'."
5eabfe72
KH
1403 :type '(choice (const :tag "None" none)
1404 (const :tag "Single file" single)
1405 (const :tag "Separate files" separate))
3dcb36b7
JB
1406 :group 'vhdl-testbench)
1407
0a2e512a 1408(defcustom vhdl-testbench-entity-file-name vhdl-entity-file-name
3dcb36b7 1409 (concat
fb7ada5f 1410 "Specifies how the testbench entity file name is obtained.
0a2e512a
RF
1411The entity file name can be obtained by modifying the testbench entity name
1412\(e.g. attaching or stripping off a substring). The file extension is
1413automatically taken from the file name of the current buffer. Testbench
1414files can be created in a different directory by prepending a relative or
1415absolute path to the file name."
3dcb36b7
JB
1416 vhdl-name-doc-string)
1417 :type '(cons (regexp :tag "From regexp")
1418 (string :tag "To string "))
0a2e512a 1419 :group 'vhdl-testbench)
3dcb36b7 1420
0a2e512a 1421(defcustom vhdl-testbench-architecture-file-name vhdl-architecture-file-name
3dcb36b7 1422 (concat
fb7ada5f 1423 "Specifies how the testbench architecture file name is obtained.
0a2e512a
RF
1424The architecture file name can be obtained by modifying the testbench entity
1425and/or architecture name (e.g. attaching or stripping off a substring). The
1426string that is matched against the regexp is the concatenation of the entity
1427and the architecture name separated by a space. This gives access to both
1428names (see default setting as example). Testbench files can be created in
1429a different directory by prepending a relative or absolute path to the file
1430name."
3dcb36b7 1431 vhdl-name-doc-string)
0a2e512a
RF
1432 :type '(cons (regexp :tag "From regexp")
1433 (string :tag "To string "))
1434 :group 'vhdl-testbench)
d2ddb974
KH
1435
1436
1437(defgroup vhdl-comment nil
1438 "Customizations for comments."
5eabfe72 1439 :group 'vhdl)
d2ddb974
KH
1440
1441(defcustom vhdl-self-insert-comments t
fb7ada5f 1442 "Non-nil means various templates automatically insert help comments."
d2ddb974
KH
1443 :type 'boolean
1444 :group 'vhdl-comment)
1445
1446(defcustom vhdl-prompt-for-comments t
fb7ada5f 1447 "Non-nil means various templates prompt for user definable comments."
d2ddb974
KH
1448 :type 'boolean
1449 :group 'vhdl-comment)
1450
5eabfe72 1451(defcustom vhdl-inline-comment-column 40
fb7ada5f 1452 "Column to indent and align inline comments to.
3dcb36b7 1453Overrides local option `comment-column'.
5eabfe72 1454
3dcb36b7
JB
1455NOTE: Activate the new setting in a VHDL buffer by using the menu entry
1456 \"Activate Options\"."
d2ddb974
KH
1457 :type 'integer
1458 :group 'vhdl-comment)
1459
1460(defcustom vhdl-end-comment-column 79
fb7ada5f 1461 "End of comment column.
5eabfe72
KH
1462Comments that exceed this column number are wrapped.
1463
3dcb36b7
JB
1464NOTE: Activate the new setting in a VHDL buffer by using the menu entry
1465 \"Activate Options\"."
d2ddb974
KH
1466 :type 'integer
1467 :group 'vhdl-comment)
1468
5eabfe72 1469(defvar end-comment-column)
d2ddb974
KH
1470
1471
5eabfe72
KH
1472(defgroup vhdl-align nil
1473 "Customizations for alignment."
d2ddb974
KH
1474 :group 'vhdl)
1475
5eabfe72 1476(defcustom vhdl-auto-align t
fb7ada5f 1477 "Non-nil means align some templates automatically after generation."
d2ddb974 1478 :type 'boolean
5eabfe72
KH
1479 :group 'vhdl-align)
1480
1481(defcustom vhdl-align-groups t
fb7ada5f 1482 "Non-nil means align groups of code lines separately.
3dcb36b7
JB
1483A group of code lines is a region of consecutive lines between two lines that
1484match the regexp in option `vhdl-align-group-separate'."
1485 :type 'boolean
1486 :group 'vhdl-align)
1487
1488(defcustom vhdl-align-group-separate "^\\s-*$"
fb7ada5f 1489 "Regexp for matching a line that separates groups of lines for alignment.
3dcb36b7
JB
1490Examples:
1491 \"^\\s-*$\": matches an empty line
1492 \"^\\s-*\\(--.*\\)?$\": matches an empty line or a comment-only line"
1493 :type 'regexp
1494 :group 'vhdl-align)
1495
1496(defcustom vhdl-align-same-indent t
fb7ada5f 1497 "Non-nil means align blocks with same indent separately.
3dcb36b7
JB
1498When a region or the entire buffer is aligned, the code is divided into
1499blocks of same indent which are aligned separately (except for argument/port
1500lists). This gives nicer alignment in most cases.
1501Option `vhdl-align-groups' still applies within these blocks."
5eabfe72
KH
1502 :type 'boolean
1503 :group 'vhdl-align)
1504
1505
1506(defgroup vhdl-highlight nil
1507 "Customizations for highlighting."
1508 :group 'vhdl)
d2ddb974
KH
1509
1510(defcustom vhdl-highlight-keywords t
fb7ada5f 1511 "Non-nil means highlight VHDL keywords and other standardized words.
5eabfe72 1512The following faces are used:
0a2e512a
RF
1513 `font-lock-keyword-face' : keywords
1514 `font-lock-type-face' : standardized types
1515 `vhdl-font-lock-attribute-face': standardized attributes
1516 `vhdl-font-lock-enumvalue-face': standardized enumeration values
1517 `vhdl-font-lock-function-face' : standardized function and package names
5eabfe72
KH
1518
1519NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1520 entry \"Fontify Buffer\")."
d2ddb974 1521 :type 'boolean
5eabfe72 1522 :set (lambda (variable value)
0a2e512a 1523 (vhdl-custom-set variable value 'vhdl-font-lock-init))
d2ddb974
KH
1524 :group 'vhdl-highlight)
1525
5eabfe72 1526(defcustom vhdl-highlight-names t
fb7ada5f 1527 "Non-nil means highlight declaration names and construct labels.
5eabfe72 1528The following faces are used:
3dcb36b7 1529 `font-lock-function-name-face' : names in declarations of units,
5eabfe72 1530 subprograms, components, as well as labels of VHDL constructs
3dcb36b7 1531 `font-lock-type-face' : names in type/nature declarations
0a2e512a 1532 `vhdl-font-lock-attribute-face': names in attribute declarations
3dcb36b7 1533 `font-lock-variable-name-face' : names in declarations of signals,
5eabfe72
KH
1534 variables, constants, subprogram parameters, generics, and ports
1535
1536NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1537 entry \"Fontify Buffer\")."
d2ddb974 1538 :type 'boolean
5eabfe72 1539 :set (lambda (variable value)
0a2e512a 1540 (vhdl-custom-set variable value 'vhdl-font-lock-init))
d2ddb974
KH
1541 :group 'vhdl-highlight)
1542
5eabfe72 1543(defcustom vhdl-highlight-special-words nil
fb7ada5f 1544 "Non-nil means highlight words with special syntax.
3dcb36b7
JB
1545The words with syntax and color specified in option `vhdl-special-syntax-alist'
1546are highlighted accordingly.
5eabfe72
KH
1547Can be used for visual support of naming conventions.
1548
1549NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1550 entry \"Fontify Buffer\")."
d2ddb974 1551 :type 'boolean
5eabfe72 1552 :set (lambda (variable value)
0a2e512a 1553 (vhdl-custom-set variable value 'vhdl-font-lock-init))
d2ddb974
KH
1554 :group 'vhdl-highlight)
1555
5eabfe72 1556(defcustom vhdl-highlight-forbidden-words nil
fb7ada5f 1557 "Non-nil means highlight forbidden words.
3dcb36b7
JB
1558The reserved words specified in option `vhdl-forbidden-words' or having the
1559syntax specified in option `vhdl-forbidden-syntax' are highlighted in a
0a2e512a 1560warning color (face `vhdl-font-lock-reserved-words-face') to indicate not to
5eabfe72
KH
1561use them.
1562
1563NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1564 entry \"Fontify Buffer\")."
d2ddb974 1565 :type 'boolean
5eabfe72 1566 :set (lambda (variable value)
0a2e512a 1567 (vhdl-custom-set variable value
5eabfe72 1568 'vhdl-words-init 'vhdl-font-lock-init))
d2ddb974
KH
1569 :group 'vhdl-highlight)
1570
5eabfe72 1571(defcustom vhdl-highlight-verilog-keywords nil
fb7ada5f 1572 "Non-nil means highlight Verilog keywords as reserved words.
5eabfe72 1573Verilog keywords are highlighted in a warning color (face
0a2e512a 1574`vhdl-font-lock-reserved-words-face') to indicate not to use them.
2f402702 1575
5eabfe72 1576NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1577 entry \"Fontify Buffer\")."
d2ddb974 1578 :type 'boolean
5eabfe72 1579 :set (lambda (variable value)
0a2e512a 1580 (vhdl-custom-set variable value
5eabfe72 1581 'vhdl-words-init 'vhdl-font-lock-init))
d2ddb974
KH
1582 :group 'vhdl-highlight)
1583
5eabfe72 1584(defcustom vhdl-highlight-translate-off nil
fb7ada5f 1585 "Non-nil means background-highlight code excluded from translation.
5eabfe72
KH
1586That is, all code between \"-- pragma translate_off\" and
1587\"-- pragma translate_on\" is highlighted using a different background color
0a2e512a 1588\(face `vhdl-font-lock-translate-off-face').
5eabfe72 1589Note: this might slow down on-the-fly fontification (and thus editing).
d2ddb974 1590
5eabfe72 1591NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1592 entry \"Fontify Buffer\")."
5eabfe72
KH
1593 :type 'boolean
1594 :set (lambda (variable value)
0a2e512a 1595 (vhdl-custom-set variable value 'vhdl-font-lock-init))
d2ddb974
KH
1596 :group 'vhdl-highlight)
1597
5eabfe72 1598(defcustom vhdl-highlight-case-sensitive nil
fb7ada5f 1599 "Non-nil means consider case for highlighting.
5eabfe72
KH
1600Possible trade-off:
1601 non-nil also upper-case VHDL words are highlighted, but case of words with
1602 special syntax is not considered
1603 nil only lower-case VHDL words are highlighted, but case of words with
1604 special syntax is considered
3dcb36b7 1605Overrides local option `font-lock-keywords-case-fold-search'.
5eabfe72
KH
1606
1607NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1608 entry \"Fontify Buffer\")."
5eabfe72
KH
1609 :type 'boolean
1610 :group 'vhdl-highlight)
d2ddb974 1611
3dcb36b7 1612(defcustom vhdl-special-syntax-alist
fda91268
RZ
1613 '(("generic/constant" "\\<\\w+_[cg]\\>" "Gold3" "BurlyWood1" nil)
1614 ("type" "\\<\\w+_t\\>" "ForestGreen" "PaleGreen" nil)
1615 ("variable" "\\<\\w+_v\\>" "Grey50" "Grey80" nil))
fb7ada5f 1616 "List of special syntax to be highlighted.
3dcb36b7 1617If option `vhdl-highlight-special-words' is non-nil, words with the specified
5eabfe72
KH
1618syntax (as regular expression) are highlighted in the corresponding color.
1619
1620 Name : string of words and spaces
1621 Regexp : regular expression describing word syntax
fda91268
RZ
1622 (e.g. \"\\\\=\<\\\w+_c\\\\=\>\" matches word with suffix \"_c\")
1623 expression must start with \"\\\\=\<\" and end with \"\\\\=\>\"
1624 if only whole words should be matched (no substrings)
5eabfe72
KH
1625 Color (light): foreground color for light background
1626 (matching color examples: Gold3, Grey50, LimeGreen, Tomato,
1627 LightSeaGreen, DodgerBlue, Gold, PaleVioletRed)
1628 Color (dark) : foreground color for dark background
1629 (matching color examples: BurlyWood1, Grey80, Green, Coral,
1630 AquaMarine2, LightSkyBlue1, Yellow, PaleVioletRed1)
fda91268 1631 In comments : If non-nil, words are also highlighted inside comments
5eabfe72
KH
1632
1633Can be used for visual support of naming conventions, such as highlighting
3dcb36b7 1634different kinds of signals (e.g. \"Clk50\", \"Rst_n\") or objects (e.g.
5eabfe72 1635\"Signal_s\", \"Variable_v\", \"Constant_c\") by distinguishing them using
3dcb36b7 1636common substrings or name suffices.
5eabfe72 1637For each entry, a new face is generated with the specified colors and name
0a2e512a 1638\"vhdl-font-lock-\" + name + \"-face\".
5eabfe72
KH
1639
1640NOTE: Activate a changed regexp in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1641 entry \"Fontify Buffer\"). All other changes require restarting Emacs."
5eabfe72
KH
1642 :type '(repeat (list :tag "Face" :indent 2
1643 (string :tag "Name ")
1644 (regexp :tag "Regexp " "\\w+_")
1645 (string :tag "Color (light)")
fda91268
RZ
1646 (string :tag "Color (dark) ")
1647 (boolean :tag "In comments ")))
5eabfe72 1648 :set (lambda (variable value)
0a2e512a 1649 (vhdl-custom-set variable value 'vhdl-font-lock-init))
5eabfe72 1650 :group 'vhdl-highlight)
d2ddb974 1651
5eabfe72 1652(defcustom vhdl-forbidden-words '()
fb7ada5f 1653 "List of forbidden words to be highlighted.
3dcb36b7 1654If option `vhdl-highlight-forbidden-words' is non-nil, these reserved
5eabfe72
KH
1655words are highlighted in a warning color to indicate not to use them.
1656
1657NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1658 entry \"Fontify Buffer\")."
5eabfe72
KH
1659 :type '(repeat (string :format "%v"))
1660 :set (lambda (variable value)
0a2e512a 1661 (vhdl-custom-set variable value
5eabfe72
KH
1662 'vhdl-words-init 'vhdl-font-lock-init))
1663 :group 'vhdl-highlight)
d2ddb974 1664
5eabfe72 1665(defcustom vhdl-forbidden-syntax ""
fb7ada5f 1666 "Syntax of forbidden words to be highlighted.
3dcb36b7 1667If option `vhdl-highlight-forbidden-words' is non-nil, words with this
5eabfe72
KH
1668syntax are highlighted in a warning color to indicate not to use them.
1669Can be used to highlight too long identifiers (e.g. \"\\w\\w\\w\\w\\w\\w\\w\\w\\w\\w+\"
1670highlights identifiers with 10 or more characters).
d2ddb974 1671
5eabfe72 1672NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
3dcb36b7 1673 entry \"Fontify Buffer\")."
d2ddb974 1674 :type 'regexp
5eabfe72 1675 :set (lambda (variable value)
0a2e512a 1676 (vhdl-custom-set variable value
5eabfe72
KH
1677 'vhdl-words-init 'vhdl-font-lock-init))
1678 :group 'vhdl-highlight)
d2ddb974 1679
3dcb36b7 1680(defcustom vhdl-directive-keywords '("pragma" "synopsys")
fb7ada5f 1681 "List of compiler directive keywords recognized for highlighting.
d2ddb974 1682
3dcb36b7
JB
1683NOTE: Activate the new setting in a VHDL buffer by re-fontifying it (menu
1684 entry \"Fontify Buffer\")."
1685 :type '(repeat (string :format "%v"))
1686 :set (lambda (variable value)
1687 (vhdl-custom-set variable value
1688 'vhdl-words-init 'vhdl-font-lock-init))
1689 :group 'vhdl-highlight)
1690
1691
1692(defgroup vhdl-speedbar nil
1693 "Customizations for speedbar."
d2ddb974
KH
1694 :group 'vhdl)
1695
3dcb36b7 1696(defcustom vhdl-speedbar-auto-open nil
fb7ada5f 1697 "Non-nil means automatically open speedbar at startup.
5eabfe72 1698Alternatively, the speedbar can be opened from the VHDL menu."
d2ddb974 1699 :type 'boolean
3dcb36b7
JB
1700 :group 'vhdl-speedbar)
1701
1702(defcustom vhdl-speedbar-display-mode 'files
fb7ada5f 1703 "Specifies the default displaying mode when opening speedbar.
3dcb36b7
JB
1704Alternatively, the displaying mode can be selected from the speedbar menu or
1705by typing `f' (files), `h' (directory hierarchy) or `H' (project hierarchy)."
1706 :type '(choice (const :tag "Files" files)
1707 (const :tag "Directory hierarchy" directory)
1708 (const :tag "Project hierarchy" project))
1709 :group 'vhdl-speedbar)
1710
1711(defcustom vhdl-speedbar-scan-limit '(10000000 (1000000 50))
fb7ada5f 1712 "Limits scanning of large files and netlists.
3dcb36b7
JB
1713Design units: maximum file size to scan for design units
1714Hierarchy (instances of subcomponents):
1715 File size: maximum file size to scan for instances (in bytes)
1716 Instances per arch: maximum number of instances to scan per architecture
1717
1718\"None\" always means that there is no limit.
1719In case of files not or incompletely scanned, a warning message and the file
1720names are printed out.
1721Background: scanning for instances is considerably slower than scanning for
1722design units, especially when there are many instances. These limits should
1723prevent the scanning of large netlists."
1724 :type '(list (choice :tag "Design units"
1725 :format "%t : %[Value Menu%] %v"
1726 (const :tag "None" nil)
1727 (integer :tag "File size"))
1728 (list :tag "Hierarchy" :indent 2
1729 (choice :tag "File size"
1730 :format "%t : %[Value Menu%] %v"
1731 (const :tag "None" nil)
1732 (integer :tag "Size "))
1733 (choice :tag "Instances per arch"
1734 (const :tag "None" nil)
1735 (integer :tag "Number "))))
1736 :group 'vhdl-speedbar)
1737
1738(defcustom vhdl-speedbar-jump-to-unit t
fb7ada5f 1739 "Non-nil means jump to the design unit code when opened in a buffer.
3dcb36b7
JB
1740The buffer cursor position is left unchanged otherwise."
1741 :type 'boolean
1742 :group 'vhdl-speedbar)
d2ddb974 1743
3dcb36b7 1744(defcustom vhdl-speedbar-update-on-saving t
fb7ada5f 1745 "Automatically update design hierarchy when buffer is saved."
d2ddb974 1746 :type 'boolean
3dcb36b7
JB
1747 :group 'vhdl-speedbar)
1748
1749(defcustom vhdl-speedbar-save-cache '(hierarchy display)
fb7ada5f 1750 "Automatically save modified hierarchy caches when exiting Emacs.
3dcb36b7
JB
1751 Hierarchy: design hierarchy information
1752 Display: displaying information (which design units to expand)"
1753 :type '(set (const :tag "Hierarchy" hierarchy)
1754 (const :tag "Display" display))
1755 :group 'vhdl-speedbar)
1756
1757(defcustom vhdl-speedbar-cache-file-name ".emacs-vhdl-cache-\\1-\\2"
fb7ada5f 1758 "Name of file for saving hierarchy cache.
3dcb36b7
JB
1759\"\\1\" is replaced by the project name if a project is specified,
1760\"directory\" otherwise. \"\\2\" is replaced by the user name (allows for
1761different users to have cache files in the same directory). Can also have
1762an absolute path (i.e. all caches can be stored in one global directory)."
1763 :type 'string
1764 :group 'vhdl-speedbar)
d2ddb974 1765
3dcb36b7
JB
1766
1767(defgroup vhdl-menu nil
c80e3b4a 1768 "Customizations for menus."
3dcb36b7 1769 :group 'vhdl)
5eabfe72
KH
1770
1771(defcustom vhdl-index-menu nil
fb7ada5f 1772 "Non-nil means add an index menu for a source file when loading.
5eabfe72 1773Alternatively, the speedbar can be used. Note that the index menu scans a file
3dcb36b7 1774when it is opened, while speedbar only scans the file upon request."
5eabfe72
KH
1775 :type 'boolean
1776 :group 'vhdl-menu)
1777
1778(defcustom vhdl-source-file-menu nil
fb7ada5f 1779 "Non-nil means add a menu of all source files in current directory.
5eabfe72
KH
1780Alternatively, the speedbar can be used."
1781 :type 'boolean
1782 :group 'vhdl-menu)
1783
1784(defcustom vhdl-hideshow-menu nil
fb7ada5f 1785 "Non-nil means add hideshow menu and functionality at startup.
3dcb36b7
JB
1786Hideshow can also be enabled from the VHDL Mode menu.
1787Hideshow allows hiding code of various VHDL constructs.
5eabfe72 1788
3dcb36b7
JB
1789NOTE: Activate the new setting in a VHDL buffer by using the menu entry
1790 \"Activate Options\"."
5eabfe72
KH
1791 :type 'boolean
1792 :group 'vhdl-menu)
1793
1794(defcustom vhdl-hide-all-init nil
fb7ada5f 1795 "Non-nil means hide all design units initially after a file is loaded."
d2ddb974
KH
1796 :type 'boolean
1797 :group 'vhdl-menu)
1798
1799
1800(defgroup vhdl-print nil
1801 "Customizations for printing."
1802 :group 'vhdl)
1803
1804(defcustom vhdl-print-two-column t
fb7ada5f 1805 "Non-nil means print code in two columns and landscape format.
7877f373 1806Adjusts settings in a way that PostScript printing (\"File\" menu, `ps-print')
3dcb36b7 1807prints VHDL files in a nice two-column landscape style.
5eabfe72
KH
1808
1809NOTE: Activate the new setting by restarting Emacs.
1810 Overrides `ps-print' settings locally."
1811 :type 'boolean
1812 :group 'vhdl-print)
1813
1814(defcustom vhdl-print-customize-faces t
fb7ada5f 1815 "Non-nil means use an optimized set of faces for PostScript printing.
5eabfe72
KH
1816
1817NOTE: Activate the new setting by restarting Emacs.
1818 Overrides `ps-print' settings locally."
d2ddb974
KH
1819 :type 'boolean
1820 :group 'vhdl-print)
1821
1822
1823(defgroup vhdl-misc nil
1824 "Miscellaneous customizations."
1825 :group 'vhdl)
1826
1827(defcustom vhdl-intelligent-tab t
fb7ada5f 1828 "Non-nil means `TAB' does indentation, word completion and tab insertion.
97610156 1829That is, if preceding character is part of a word then complete word,
d2ddb974
KH
1830else if not at beginning of line then insert tab,
1831else if last command was a `TAB' or `RET' then dedent one step,
5eabfe72 1832else indent current line (i.e. `TAB' is bound to `vhdl-electric-tab').
d2ddb974 1833If nil, TAB always indents current line (i.e. `TAB' is bound to
3dcb36b7
JB
1834`indent-according-to-mode').
1835
1836NOTE: Activate the new setting in a VHDL buffer by using the menu entry
1837 \"Activate Options\"."
1838 :type 'boolean
1839 :group 'vhdl-misc)
5eabfe72 1840
3dcb36b7 1841(defcustom vhdl-indent-syntax-based t
fb7ada5f 1842 "Non-nil means indent lines of code based on their syntactic context.
3dcb36b7
JB
1843Otherwise, a line is indented like the previous nonblank line. This can be
1844useful in large files where syntax-based indentation gets very slow."
d2ddb974
KH
1845 :type 'boolean
1846 :group 'vhdl-misc)
1847
fda91268
RZ
1848(defcustom vhdl-indent-comment-like-next-code-line t
1849 "*Non-nil means comment lines are indented like the following code line.
1850Otherwise, comment lines are indented like the preceding code line.
1851Indenting comment lines like the following code line gives nicer indentation
1852when comments precede the code that they refer to."
1853 :type 'boolean
d1a1c7e6 1854 :version "24.3"
fda91268
RZ
1855 :group 'vhdl-misc)
1856
5eabfe72 1857(defcustom vhdl-word-completion-case-sensitive nil
fb7ada5f 1858 "Non-nil means word completion using `TAB' is case sensitive.
5eabfe72
KH
1859That is, `TAB' completes words that start with the same letters and case.
1860Otherwise, case is ignored."
1861 :type 'boolean
d2ddb974
KH
1862 :group 'vhdl-misc)
1863
1864(defcustom vhdl-word-completion-in-minibuffer t
fb7ada5f 1865 "Non-nil enables word completion in minibuffer (for template prompts).
5eabfe72
KH
1866
1867NOTE: Activate the new setting by restarting Emacs."
d2ddb974
KH
1868 :type 'boolean
1869 :group 'vhdl-misc)
1870
1871(defcustom vhdl-underscore-is-part-of-word nil
fb7ada5f 1872 "Non-nil means consider the underscore character `_' as part of word.
d2ddb974 1873An identifier containing underscores is then treated as a single word in
5eabfe72
KH
1874select and move operations. All parts of an identifier separated by underscore
1875are treated as single words otherwise.
1876
3dcb36b7
JB
1877NOTE: Activate the new setting in a VHDL buffer by using the menu entry
1878 \"Activate Options\"."
d2ddb974 1879 :type 'boolean
5eabfe72 1880 :set (lambda (variable value)
0a2e512a 1881 (vhdl-custom-set variable value 'vhdl-mode-syntax-table-init))
d2ddb974
KH
1882 :group 'vhdl-misc)
1883
3dcb36b7
JB
1884
1885(defgroup vhdl-related nil
5eabfe72
KH
1886 "Related general customizations."
1887 :group 'vhdl)
1888
3dcb36b7
JB
1889;; add related general customizations
1890(custom-add-to-group 'vhdl-related 'hideshow 'custom-group)
f8246027 1891(if (featurep 'xemacs)
3dcb36b7
JB
1892 (custom-add-to-group 'vhdl-related 'paren-mode 'custom-variable)
1893 (custom-add-to-group 'vhdl-related 'paren-showing 'custom-group))
1894(custom-add-to-group 'vhdl-related 'ps-print 'custom-group)
1895(custom-add-to-group 'vhdl-related 'speedbar 'custom-group)
fda91268 1896(custom-add-to-group 'vhdl-related 'comment-style 'custom-variable)
3dcb36b7 1897(custom-add-to-group 'vhdl-related 'line-number-mode 'custom-variable)
f8246027 1898(unless (featurep 'xemacs)
3dcb36b7
JB
1899 (custom-add-to-group 'vhdl-related 'transient-mark-mode 'custom-variable))
1900(custom-add-to-group 'vhdl-related 'user-full-name 'custom-variable)
1901(custom-add-to-group 'vhdl-related 'mail-host-address 'custom-variable)
1902(custom-add-to-group 'vhdl-related 'user-mail-address 'custom-variable)
1903
fda91268
RZ
1904;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1905;; Hidden user variables
1906
1907(defvar vhdl-compile-absolute-path nil
1908 "If non-nil, use absolute instead of relative path for compiled files.")
1909
1910(defvar vhdl-comment-display-line-char ?-
1911 "Character to use in comment display line.")
1912
5eabfe72
KH
1913;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1914;; Internal variables
1915
3dcb36b7 1916(defvar vhdl-menu-max-size 20
fb7ada5f 1917 "Specifies the maximum size of a menu before splitting it into submenus.")
5eabfe72
KH
1918
1919(defvar vhdl-progress-interval 1
fb7ada5f 1920 "Interval used to update progress status during long operations.
5eabfe72 1921If a number, percentage complete gets updated after each interval of
3dcb36b7 1922that many seconds. To inhibit all messages, set this option to nil.")
d2ddb974
KH
1923
1924(defvar vhdl-inhibit-startup-warnings-p nil
fb7ada5f 1925 "If non-nil, inhibits start up compatibility warnings.")
d2ddb974
KH
1926
1927(defvar vhdl-strict-syntax-p nil
fb7ada5f 1928 "If non-nil, all syntactic symbols must be found in `vhdl-offsets-alist'.
d2ddb974
KH
1929If the syntactic symbol for a particular line does not match a symbol
1930in the offsets alist, an error is generated, otherwise no error is
1931reported and the syntactic symbol is ignored.")
1932
1933(defvar vhdl-echo-syntactic-information-p nil
fb7ada5f 1934 "If non-nil, syntactic info is echoed when the line is indented.")
d2ddb974
KH
1935
1936(defconst vhdl-offsets-alist-default
0a2e512a
RF
1937 '((string . -1000)
1938 (cpp-macro . -1000)
1939 (block-open . 0)
1940 (block-close . 0)
1941 (statement . 0)
1942 (statement-cont . vhdl-lineup-statement-cont)
d2ddb974
KH
1943 (statement-block-intro . +)
1944 (statement-case-intro . +)
0a2e512a
RF
1945 (case-alternative . +)
1946 (comment . vhdl-lineup-comment)
1947 (arglist-intro . +)
1948 (arglist-cont . 0)
d2ddb974 1949 (arglist-cont-nonempty . vhdl-lineup-arglist)
0a2e512a
RF
1950 (arglist-close . vhdl-lineup-arglist)
1951 (entity . 0)
1952 (configuration . 0)
1953 (package . 0)
1954 (architecture . 0)
1955 (package-body . 0)
d2ddb974
KH
1956 )
1957 "Default settings for offsets of syntactic elements.
1958Do not change this constant! See the variable `vhdl-offsets-alist' for
1959more information.")
1960
1961(defvar vhdl-offsets-alist (copy-alist vhdl-offsets-alist-default)
fb7ada5f 1962 "Association list of syntactic element symbols and indentation offsets.
d2ddb974
KH
1963As described below, each cons cell in this list has the form:
1964
1965 (SYNTACTIC-SYMBOL . OFFSET)
1966
5eabfe72 1967When a line is indented, `vhdl-mode' first determines the syntactic
d2ddb974
KH
1968context of the line by generating a list of symbols called syntactic
1969elements. This list can contain more than one syntactic element and
1970the global variable `vhdl-syntactic-context' contains the context list
1971for the line being indented. Each element in this list is actually a
1972cons cell of the syntactic symbol and a buffer position. This buffer
1973position is call the relative indent point for the line. Some
1974syntactic symbols may not have a relative indent point associated with
1975them.
1976
5eabfe72 1977After the syntactic context list for a line is generated, `vhdl-mode'
d2ddb974
KH
1978calculates the absolute indentation for the line by looking at each
1979syntactic element in the list. First, it compares the syntactic
1980element against the SYNTACTIC-SYMBOL's in `vhdl-offsets-alist'. When it
1981finds a match, it adds the OFFSET to the column of the relative indent
1982point. The sum of this calculation for each element in the syntactic
1983list is the absolute offset for line being indented.
1984
1985If the syntactic element does not match any in the `vhdl-offsets-alist',
1986an error is generated if `vhdl-strict-syntax-p' is non-nil, otherwise
1987the element is ignored.
1988
1989Actually, OFFSET can be an integer, a function, a variable, or one of
1990the following symbols: `+', `-', `++', or `--'. These latter
1991designate positive or negative multiples of `vhdl-basic-offset',
5eabfe72 1992respectively: *1, *-1, *2, and *-2. If OFFSET is a function, it is
d2ddb974
KH
1993called with a single argument containing the cons of the syntactic
1994element symbol and the relative indent point. The function should
1995return an integer offset.
1996
1997Here is the current list of valid syntactic element symbols:
1998
1999 string -- inside multi-line string
2000 block-open -- statement block open
2001 block-close -- statement block close
2002 statement -- a VHDL statement
2003 statement-cont -- a continuation of a VHDL statement
2004 statement-block-intro -- the first line in a new statement block
2005 statement-case-intro -- the first line in a case alternative block
2006 case-alternative -- a case statement alternative clause
2007 comment -- a line containing only a comment
2008 arglist-intro -- the first line in an argument list
2009 arglist-cont -- subsequent argument list lines when no
9b053e76 2010 arguments follow on the same line as
d2ddb974
KH
2011 the arglist opening paren
2012 arglist-cont-nonempty -- subsequent argument list lines when at
2013 least one argument follows on the same
2014 line as the arglist opening paren
2015 arglist-close -- the solo close paren of an argument list
2016 entity -- inside an entity declaration
2017 configuration -- inside a configuration declaration
2018 package -- inside a package declaration
2019 architecture -- inside an architecture body
5eabfe72 2020 package-body -- inside a package body")
d2ddb974
KH
2021
2022(defvar vhdl-comment-only-line-offset 0
fb7ada5f 2023 "Extra offset for line which contains only the start of a comment.
d2ddb974
KH
2024Can contain an integer or a cons cell of the form:
2025
2026 (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
2027
2028Where NON-ANCHORED-OFFSET is the amount of offset given to
2029non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
2030the amount of offset to give column-zero anchored comment-only lines.
2031Just an integer as value is equivalent to (<val> . 0)")
2032
2033(defvar vhdl-special-indent-hook nil
fb7ada5f 2034 "Hook for user defined special indentation adjustments.
d2ddb974
KH
2035This hook gets called after a line is indented by the mode.")
2036
2037(defvar vhdl-style-alist
2038 '(("IEEE"
2039 (vhdl-basic-offset . 4)
3dcb36b7 2040 (vhdl-offsets-alist . ())))
d2ddb974
KH
2041 "Styles of Indentation.
2042Elements of this alist are of the form:
2043
2044 (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
2045
2046where STYLE-STRING is a short descriptive string used to select a
5eabfe72 2047style, VARIABLE is any `vhdl-mode' variable, and VALUE is the intended
d2ddb974
KH
2048value for that variable when using the selected style.
2049
2050There is one special case when VARIABLE is `vhdl-offsets-alist'. In this
2051case, the VALUE is a list containing elements of the form:
2052
2053 (SYNTACTIC-SYMBOL . VALUE)
2054
2055as described in `vhdl-offsets-alist'. These are passed directly to
2056`vhdl-set-offset' so there is no need to set every syntactic symbol in
2057your style, only those that are different from the default.")
2058
2059;; dynamically append the default value of most variables
2060(or (assoc "Default" vhdl-style-alist)
2061 (let* ((varlist '(vhdl-inhibit-startup-warnings-p
2062 vhdl-strict-syntax-p
2063 vhdl-echo-syntactic-information-p
2064 vhdl-basic-offset
2065 vhdl-offsets-alist
2066 vhdl-comment-only-line-offset))
2067 (default (cons "Default"
2068 (mapcar
2069 (function
2070 (lambda (var)
5eabfe72 2071 (cons var (symbol-value var))))
d2ddb974
KH
2072 varlist))))
2073 (setq vhdl-style-alist (cons default vhdl-style-alist))))
2074
2075(defvar vhdl-mode-hook nil
fb7ada5f 2076 "Hook called by `vhdl-mode'.")
d2ddb974
KH
2077
2078
5eabfe72 2079;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 2080;;; Required packages
5eabfe72 2081;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5eabfe72 2082
3dcb36b7 2083;; mandatory
5eabfe72 2084(require 'assoc)
3dcb36b7
JB
2085(require 'compile) ; XEmacs
2086(require 'easymenu)
2087(require 'hippie-exp)
2088
2089;; optional (minimize warning messages during compile)
2090(eval-when-compile
2091 (require 'font-lock)
2092 (require 'ps-print)
2093 (require 'speedbar))
5eabfe72
KH
2094
2095
2096;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 2097;;; Compatibility
5eabfe72 2098;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974 2099
3dcb36b7
JB
2100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2101;; XEmacs compatibility
d2ddb974 2102
3dcb36b7 2103;; active regions
d2ddb974 2104(defun vhdl-keep-region-active ()
5eabfe72
KH
2105 "Do whatever is necessary to keep the region active in XEmacs.
2106Ignore byte-compiler warnings you might see."
a445370f 2107 (and (featurep 'xemacs)
d2ddb974
KH
2108 (setq zmacs-region-stays t)))
2109
3dcb36b7 2110;; `wildcard-to-regexp' is included only in XEmacs 21
5eabfe72
KH
2111(unless (fboundp 'wildcard-to-regexp)
2112 (defun wildcard-to-regexp (wildcard)
44e97401 2113 "Simplified version of `wildcard-to-regexp' from Emacs's `files.el'."
5eabfe72
KH
2114 (let* ((i (string-match "[*?]" wildcard))
2115 (result (substring wildcard 0 i))
2116 (len (length wildcard)))
2117 (when i
2118 (while (< i len)
2119 (let ((ch (aref wildcard i)))
2120 (setq result (concat result
2121 (cond ((eq ch ?*) "[^\000]*")
2122 ((eq ch ??) "[^\000]")
2123 (t (char-to-string ch)))))
2124 (setq i (1+ i)))))
2125 (concat "\\`" result "\\'"))))
2126
3dcb36b7
JB
2127;; `regexp-opt' undefined (`xemacs-devel' not installed)
2128;; `regexp-opt' accelerates fontification by 10-20%
2129(unless (fboundp 'regexp-opt)
2130; (vhdl-warning-when-idle "Please install `xemacs-devel' package.")
2131 (defun regexp-opt (strings &optional paren)
2132 (let ((open (if paren "\\(" "")) (close (if paren "\\)" "")))
2133 (concat open (mapconcat 'regexp-quote strings "\\|") close))))
2134
2135;; `match-string-no-properties' undefined (XEmacs, what else?)
2136(unless (fboundp 'match-string-no-properties)
2137 (defalias 'match-string-no-properties 'match-string))
2138
2139;; `subst-char-in-string' undefined (XEmacs)
2140(unless (fboundp 'subst-char-in-string)
2141 (defun subst-char-in-string (fromchar tochar string &optional inplace)
2142 (let ((i (length string))
2143 (newstr (if inplace string (copy-sequence string))))
2144 (while (> i 0)
2145 (setq i (1- i))
2146 (if (eq (aref newstr i) fromchar) (aset newstr i tochar)))
2147 newstr)))
2148
2149;; `itimer.el': idle timer bug fix in version 1.09 (XEmacs 21.1.9)
f8246027 2150(when (and (featurep 'xemacs) (string< itimer-version "1.09")
3dcb36b7
JB
2151 (not noninteractive))
2152 (load "itimer")
2153 (when (string< itimer-version "1.09")
2154 (message "WARNING: Install included `itimer.el' patch first (see INSTALL file)")
2155 (beep) (sit-for 5)))
2156
2157;; `file-expand-wildcards' undefined (XEmacs)
2158(unless (fboundp 'file-expand-wildcards)
2159 (defun file-expand-wildcards (pattern &optional full)
44e97401 2160 "Taken from Emacs's `files.el'."
3dcb36b7
JB
2161 (let* ((nondir (file-name-nondirectory pattern))
2162 (dirpart (file-name-directory pattern))
2163 (dirs (if (and dirpart (string-match "[[*?]" dirpart))
2164 (mapcar 'file-name-as-directory
2165 (file-expand-wildcards (directory-file-name dirpart)))
2166 (list dirpart)))
2167 contents)
2168 (while dirs
2169 (when (or (null (car dirs)) ; Possible if DIRPART is not wild.
2170 (file-directory-p (directory-file-name (car dirs))))
2171 (let ((this-dir-contents
2172 (delq nil
2173 (mapcar #'(lambda (name)
2174 (unless (string-match "\\`\\.\\.?\\'"
2175 (file-name-nondirectory name))
2176 name))
2177 (directory-files (or (car dirs) ".") full
2178 (wildcard-to-regexp nondir))))))
2179 (setq contents
2180 (nconc
2181 (if (and (car dirs) (not full))
2182 (mapcar (function (lambda (name) (concat (car dirs) name)))
2183 this-dir-contents)
2184 this-dir-contents)
2185 contents))))
2186 (setq dirs (cdr dirs)))
2187 contents)))
5eabfe72 2188
0a2e512a
RF
2189;; `member-ignore-case' undefined (XEmacs)
2190(unless (fboundp 'member-ignore-case)
2191 (defalias 'member-ignore-case 'member))
2192
5eabfe72 2193;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 2194;; Compatibility with older VHDL Mode versions
5eabfe72 2195
3dcb36b7
JB
2196(defvar vhdl-warnings nil
2197 "Warnings to tell the user during start up.")
d2ddb974 2198
3dcb36b7
JB
2199(defun vhdl-run-when-idle (secs repeat function)
2200 "Wait until idle, then run FUNCTION."
4bcb9c95 2201 (if (fboundp 'start-itimer)
3dcb36b7
JB
2202 (start-itimer "vhdl-mode" function secs repeat t)
2203; (run-with-idle-timer secs repeat function)))
c7015153 2204 ;; explicitly activate timer (necessary when Emacs is already idle)
3dcb36b7
JB
2205 (aset (run-with-idle-timer secs repeat function) 0 nil)))
2206
2207(defun vhdl-warning-when-idle (&rest args)
2208 "Wait until idle, then print out warning STRING and beep."
2209 (if noninteractive
2210 (vhdl-warning (apply 'format args) t)
2211 (unless vhdl-warnings
2212 (vhdl-run-when-idle .1 nil 'vhdl-print-warnings))
2213 (setq vhdl-warnings (cons (apply 'format args) vhdl-warnings))))
2214
2215(defun vhdl-warning (string &optional nobeep)
2216 "Print out warning STRING and beep."
29a4e67d 2217 (message "WARNING: %s" string)
3dcb36b7 2218 (unless (or nobeep noninteractive) (beep)))
d2ddb974 2219
3dcb36b7
JB
2220(defun vhdl-print-warnings ()
2221 "Print out messages in variable `vhdl-warnings'."
2222 (let ((no-warnings (length vhdl-warnings)))
2223 (setq vhdl-warnings (nreverse vhdl-warnings))
2224 (while vhdl-warnings
29a4e67d 2225 (message "WARNING: %s" (car vhdl-warnings))
3dcb36b7
JB
2226 (setq vhdl-warnings (cdr vhdl-warnings)))
2227 (beep)
2228 (when (> no-warnings 1)
2229 (message "WARNING: See warnings in message buffer (type `C-c M-m')."))))
2230
2231;; Backward compatibility checks and fixes
2232;; option `vhdl-compiler' changed format
2233(unless (stringp vhdl-compiler)
2234 (setq vhdl-compiler "ModelSim")
2235 (vhdl-warning-when-idle "Option `vhdl-compiler' has changed format; customize again"))
2236
2237;; option `vhdl-standard' changed format
2238(unless (listp vhdl-standard)
2239 (setq vhdl-standard '(87 nil))
2240 (vhdl-warning-when-idle "Option `vhdl-standard' has changed format; customize again"))
2241
2242;; option `vhdl-model-alist' changed format
2243(when (= (length (car vhdl-model-alist)) 3)
2244 (let ((old-alist vhdl-model-alist)
2245 new-alist)
2246 (while old-alist
2247 (setq new-alist (cons (append (car old-alist) '("")) new-alist))
2248 (setq old-alist (cdr old-alist)))
2249 (setq vhdl-model-alist (nreverse new-alist)))
2250 (customize-save-variable 'vhdl-model-alist vhdl-model-alist))
2251
2252;; option `vhdl-project-alist' changed format
2253(when (= (length (car vhdl-project-alist)) 3)
2254 (let ((old-alist vhdl-project-alist)
2255 new-alist)
2256 (while old-alist
2257 (setq new-alist (cons (append (car old-alist) '("")) new-alist))
2258 (setq old-alist (cdr old-alist)))
2259 (setq vhdl-project-alist (nreverse new-alist)))
2260 (customize-save-variable 'vhdl-project-alist vhdl-project-alist))
2261
2262;; option `vhdl-project-alist' changed format (3.31.1)
2263(when (= (length (car vhdl-project-alist)) 4)
2264 (let ((old-alist vhdl-project-alist)
2265 new-alist elem)
2266 (while old-alist
2267 (setq elem (car old-alist))
2268 (setq new-alist
2269 (cons (list (nth 0 elem) (nth 1 elem) "" (nth 2 elem)
2270 nil "./" "work" "work/" "Makefile" (nth 3 elem))
2271 new-alist))
2272 (setq old-alist (cdr old-alist)))
2273 (setq vhdl-project-alist (nreverse new-alist)))
2274 (vhdl-warning-when-idle "Option `vhdl-project-alist' changed format; please re-customize"))
2275
2276;; option `vhdl-project-alist' changed format (3.31.12)
2277(when (= (length (car vhdl-project-alist)) 10)
2278 (let ((tmp-alist vhdl-project-alist))
2279 (while tmp-alist
2280 (setcdr (nthcdr 3 (car tmp-alist))
2281 (cons "" (nthcdr 4 (car tmp-alist))))
2282 (setq tmp-alist (cdr tmp-alist))))
2283 (customize-save-variable 'vhdl-project-alist vhdl-project-alist))
2284
2285;; option `vhdl-compiler-alist' changed format (3.31.1)
2286(when (= (length (car vhdl-compiler-alist)) 7)
2287 (let ((old-alist vhdl-compiler-alist)
2288 new-alist elem)
2289 (while old-alist
2290 (setq elem (car old-alist))
2291 (setq new-alist
2292 (cons (list (nth 0 elem) (nth 1 elem) "" "make -f \\1"
2293 (if (equal (nth 3 elem) "") nil (nth 3 elem))
2294 (nth 4 elem) "work/" "Makefile" (downcase (nth 0 elem))
2295 (nth 5 elem) (nth 6 elem) nil)
2296 new-alist))
2297 (setq old-alist (cdr old-alist)))
2298 (setq vhdl-compiler-alist (nreverse new-alist)))
2299 (vhdl-warning-when-idle "Option `vhdl-compiler-alist' changed; please reset and re-customize"))
2300
2301;; option `vhdl-compiler-alist' changed format (3.31.10)
2302(when (= (length (car vhdl-compiler-alist)) 12)
2303 (let ((tmp-alist vhdl-compiler-alist))
2304 (while tmp-alist
2305 (setcdr (nthcdr 4 (car tmp-alist))
2306 (cons "mkdir \\1" (nthcdr 5 (car tmp-alist))))
2307 (setq tmp-alist (cdr tmp-alist))))
2308 (customize-save-variable 'vhdl-compiler-alist vhdl-compiler-alist))
2309
2310;; option `vhdl-compiler-alist' changed format (3.31.11)
2311(when (= (length (car vhdl-compiler-alist)) 13)
2312 (let ((tmp-alist vhdl-compiler-alist))
2313 (while tmp-alist
2314 (setcdr (nthcdr 3 (car tmp-alist))
2315 (cons "" (nthcdr 4 (car tmp-alist))))
2316 (setq tmp-alist (cdr tmp-alist))))
2317 (customize-save-variable 'vhdl-compiler-alist vhdl-compiler-alist))
2318
2319;; option `vhdl-compiler-alist' changed format (3.32.7)
2320(when (= (length (nth 11 (car vhdl-compiler-alist))) 3)
2321 (let ((tmp-alist vhdl-compiler-alist))
2322 (while tmp-alist
2323 (setcdr (nthcdr 2 (nth 11 (car tmp-alist)))
2324 '(0 . nil))
2325 (setq tmp-alist (cdr tmp-alist))))
2326 (customize-save-variable 'vhdl-compiler-alist vhdl-compiler-alist))
2327
2328;; option `vhdl-project': empty value changed from "" to nil (3.31.1)
2329(when (equal vhdl-project "")
2330 (setq vhdl-project nil)
2331 (customize-save-variable 'vhdl-project vhdl-project))
2332
2333;; option `vhdl-project-file-name': changed format (3.31.17 beta)
2334(when (stringp vhdl-project-file-name)
2335 (setq vhdl-project-file-name (list vhdl-project-file-name))
2336 (customize-save-variable 'vhdl-project-file-name vhdl-project-file-name))
2337
2338;; option `speedbar-indentation-width': introduced in speedbar 0.10
2339(if (not (boundp 'speedbar-indentation-width))
2340 (defvar speedbar-indentation-width 2)
2341 ;; set default to 2 if not already customized
2342 (unless (get 'speedbar-indentation-width 'saved-value)
2343 (setq speedbar-indentation-width 2)))
2344
2345
2346;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2347;;; Help functions / inline substitutions / macros
2348;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2349
2350(defun vhdl-standard-p (standard)
2351 "Check if STANDARD is specified as used standard."
2352 (or (eq standard (car vhdl-standard))
2353 (memq standard (cadr vhdl-standard))))
2354
2355(defun vhdl-project-p (&optional warning)
2356 "Return non-nil if a project is displayed, i.e. directories or files are
2357specified."
2358 (if (assoc vhdl-project vhdl-project-alist)
2359 vhdl-project
2360 (when (and vhdl-project warning)
2361 (vhdl-warning-when-idle "Project does not exist: \"%s\"" vhdl-project))
2362 nil))
2363
2364(defun vhdl-resolve-env-variable (string)
2365 "Resolve environment variables in STRING."
2366 (while (string-match "\\(.*\\)${?\\(\\(\\w\\|_\\)+\\)}?\\(.*\\)" string)
2367 (setq string (concat (match-string 1 string)
2368 (getenv (match-string 2 string))
2369 (match-string 4 string))))
2370 string)
2371
2372(defun vhdl-default-directory ()
2373 "Return the default directory of the current project or the directory of the
2374current buffer if no project is defined."
2375 (if (vhdl-project-p)
2376 (expand-file-name (vhdl-resolve-env-variable
2377 (nth 1 (aget vhdl-project-alist vhdl-project))))
2378 default-directory))
2379
2380(defmacro vhdl-prepare-search-1 (&rest body)
2381 "Enable case insensitive search and switch to syntax table that includes '_',
2382then execute BODY, and finally restore the old environment. Used for
2383consistent searching."
68a47940 2384 `(let ((case-fold-search t)) ; case insensitive search
3dcb36b7 2385 ;; use extended syntax table
68a47940
SM
2386 (with-syntax-table vhdl-mode-ext-syntax-table
2387 ,@body)))
3dcb36b7
JB
2388
2389(defmacro vhdl-prepare-search-2 (&rest body)
2390 "Enable case insensitive search, switch to syntax table that includes '_',
2391and remove `intangible' overlays, then execute BODY, and finally restore the
2392old environment. Used for consistent searching."
68a47940 2393 ;; FIXME: Why not just let-bind `inhibit-point-motion-hooks'? --Stef
3dcb36b7
JB
2394 `(let ((case-fold-search t) ; case insensitive search
2395 (current-syntax-table (syntax-table))
68a47940 2396 overlay-all-list overlay-intangible-list overlay)
3dcb36b7
JB
2397 ;; use extended syntax table
2398 (set-syntax-table vhdl-mode-ext-syntax-table)
2399 ;; remove `intangible' overlays
2400 (when (fboundp 'overlay-lists)
2401 (setq overlay-all-list (overlay-lists))
2402 (setq overlay-all-list
2403 (append (car overlay-all-list) (cdr overlay-all-list)))
2404 (while overlay-all-list
2405 (setq overlay (car overlay-all-list))
2406 (when (memq 'intangible (overlay-properties overlay))
2407 (setq overlay-intangible-list
2408 (cons overlay overlay-intangible-list))
2409 (overlay-put overlay 'intangible nil))
2410 (setq overlay-all-list (cdr overlay-all-list))))
2411 ;; execute BODY safely
68a47940
SM
2412 (unwind-protect
2413 (progn ,@body)
2414 ;; restore syntax table
2415 (set-syntax-table current-syntax-table)
2416 ;; restore `intangible' overlays
2417 (when (fboundp 'overlay-lists)
2418 (while overlay-intangible-list
2419 (overlay-put (car overlay-intangible-list) 'intangible t)
2420 (setq overlay-intangible-list
2421 (cdr overlay-intangible-list)))))))
3dcb36b7
JB
2422
2423(defmacro vhdl-visit-file (file-name issue-error &rest body)
2424 "Visit file FILE-NAME and execute BODY."
2425 `(if (null ,file-name)
2426 (progn ,@body)
2427 (unless (file-directory-p ,file-name)
2428 (let ((source-buffer (current-buffer))
2429 (visiting-buffer (find-buffer-visiting ,file-name))
2430 file-opened)
2431 (when (or (and visiting-buffer (set-buffer visiting-buffer))
2432 (condition-case ()
2433 (progn (set-buffer (create-file-buffer ,file-name))
2434 (setq file-opened t)
2435 (vhdl-insert-file-contents ,file-name)
2436 (modify-syntax-entry ?\- ". 12" (syntax-table))
2437 (modify-syntax-entry ?\n ">" (syntax-table))
2438 (modify-syntax-entry ?\^M ">" (syntax-table))
2439 (modify-syntax-entry ?_ "w" (syntax-table))
2440 t)
2441 (error
2442 (if ,issue-error
2443 (progn
2444 (when file-opened (kill-buffer (current-buffer)))
2445 (set-buffer source-buffer)
ec3ec9cc 2446 (error "ERROR: File cannot be opened: \"%s\"" ,file-name))
3dcb36b7
JB
2447 (vhdl-warning (format "File cannot be opened: \"%s\"" ,file-name) t)
2448 nil))))
2449 (condition-case info
2450 (progn ,@body)
2451 (error
2452 (if ,issue-error
2453 (progn
2454 (when file-opened (kill-buffer (current-buffer)))
2455 (set-buffer source-buffer)
2456 (error (cadr info)))
2457 (vhdl-warning (cadr info))))))
2458 (when file-opened (kill-buffer (current-buffer)))
2459 (set-buffer source-buffer)))))
2460
2461(defun vhdl-insert-file-contents (filename)
2462 "Nicked from `insert-file-contents-literally', but allow coding system
2463conversion."
2464 (let ((format-alist nil)
2465 (after-insert-file-functions nil)
2466 (jka-compr-compression-info-list nil))
2467 (insert-file-contents filename t)))
2468
2469(defun vhdl-sort-alist (alist)
a4c6cfad 2470 "Sort ALIST."
3dcb36b7
JB
2471 (sort alist (function (lambda (a b) (string< (car a) (car b))))))
2472
2473(defun vhdl-get-subdirs (directory)
2474 "Recursively get subdirectories of DIRECTORY."
2475 (let ((dir-list (list (file-name-as-directory directory)))
2476 file-list)
2477 (setq file-list (vhdl-directory-files directory t "\\w.*"))
2478 (while file-list
2479 (when (file-directory-p (car file-list))
2480 (setq dir-list (append dir-list (vhdl-get-subdirs (car file-list)))))
2481 (setq file-list (cdr file-list)))
2482 dir-list))
2483
2484(defun vhdl-aput (alist-symbol key &optional value)
2485 "As `aput', but delete key-value pair if VALUE is nil."
2486 (if value
2487 (aput alist-symbol key value)
2488 (adelete alist-symbol key)))
2489
2490(defun vhdl-delete (elt list)
2491 "Delete by side effect the first occurrence of ELT as a member of LIST."
2492 (setq list (cons nil list))
2493 (let ((list1 list))
2494 (while (and (cdr list1) (not (equal elt (cadr list1))))
2495 (setq list1 (cdr list1)))
2496 (when list
2497 (setcdr list1 (cddr list1))))
2498 (cdr list))
2499
2500(defun vhdl-speedbar-refresh (&optional key)
2501 "Refresh directory or project with name KEY."
2502 (when (and (boundp 'speedbar-frame)
2503 (frame-live-p speedbar-frame))
2504 (let ((pos (point))
2505 (last-frame (selected-frame)))
2506 (if (null key)
2507 (speedbar-refresh)
2508 (select-frame speedbar-frame)
2509 (when (save-excursion
2510 (goto-char (point-min))
2511 (re-search-forward (concat "^\\([0-9]+:\\s-*<\\)->\\s-+" key "$") nil t))
2512 (goto-char (match-end 1))
2513 (speedbar-do-function-pointer)
2514 (backward-char 2)
2515 (speedbar-do-function-pointer)
2516 (message "Refreshing speedbar...done"))
2517 (select-frame last-frame)))))
2518
2519(defun vhdl-show-messages ()
2520 "Get *Messages* buffer to show recent messages."
2521 (interactive)
f8246027 2522 (display-buffer (if (featurep 'xemacs) " *Message-Log*" "*Messages*")))
3dcb36b7
JB
2523
2524(defun vhdl-use-direct-instantiation ()
2525 "Return whether direct instantiation is used."
2526 (or (eq vhdl-use-direct-instantiation 'always)
2527 (and (eq vhdl-use-direct-instantiation 'standard)
2528 (not (vhdl-standard-p '87)))))
2529
2530(defun vhdl-max-marker (marker1 marker2)
2531 "Return larger marker."
2532 (if (> marker1 marker2) marker1 marker2))
2533
2534(defun vhdl-goto-marker (marker)
2535 "Goto marker in appropriate buffer."
2536 (when (markerp marker)
2537 (set-buffer (marker-buffer marker)))
2538 (goto-char marker))
2539
2540(defun vhdl-menu-split (list title)
c80e3b4a 2541 "Split menu LIST into several submenus, if number of
3dcb36b7
JB
2542elements > `vhdl-menu-max-size'."
2543 (if (> (length list) vhdl-menu-max-size)
2544 (let ((remain list)
2545 (result '())
2546 (sublist '())
2547 (menuno 1)
2548 (i 0))
2549 (while remain
2550 (setq sublist (cons (car remain) sublist))
2551 (setq remain (cdr remain))
2552 (setq i (+ i 1))
2553 (if (= i vhdl-menu-max-size)
2554 (progn
2555 (setq result (cons (cons (format "%s %s" title menuno)
2556 (nreverse sublist)) result))
2557 (setq i 0)
2558 (setq menuno (+ menuno 1))
2559 (setq sublist '()))))
2560 (and sublist
2561 (setq result (cons (cons (format "%s %s" title menuno)
2562 (nreverse sublist)) result)))
2563 (nreverse result))
2564 list))
2565
2566
2567;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2568;;; Bindings
2569;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2570
2571;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2572;; Key bindings
2573
2574(defvar vhdl-template-map nil
2575 "Keymap for VHDL templates.")
2576
2577(defun vhdl-template-map-init ()
2578 "Initialize `vhdl-template-map'."
2579 (setq vhdl-template-map (make-sparse-keymap))
2580 ;; key bindings for VHDL templates
2581 (define-key vhdl-template-map "al" 'vhdl-template-alias)
2582 (define-key vhdl-template-map "ar" 'vhdl-template-architecture)
2583 (define-key vhdl-template-map "at" 'vhdl-template-assert)
2584 (define-key vhdl-template-map "ad" 'vhdl-template-attribute-decl)
2585 (define-key vhdl-template-map "as" 'vhdl-template-attribute-spec)
2586 (define-key vhdl-template-map "bl" 'vhdl-template-block)
2587 (define-key vhdl-template-map "ca" 'vhdl-template-case-is)
2588 (define-key vhdl-template-map "cd" 'vhdl-template-component-decl)
2589 (define-key vhdl-template-map "ci" 'vhdl-template-component-inst)
5eabfe72
KH
2590 (define-key vhdl-template-map "cs" 'vhdl-template-conditional-signal-asst)
2591 (define-key vhdl-template-map "Cb" 'vhdl-template-block-configuration)
2592 (define-key vhdl-template-map "Cc" 'vhdl-template-component-conf)
2593 (define-key vhdl-template-map "Cd" 'vhdl-template-configuration-decl)
2594 (define-key vhdl-template-map "Cs" 'vhdl-template-configuration-spec)
2595 (define-key vhdl-template-map "co" 'vhdl-template-constant)
2596 (define-key vhdl-template-map "di" 'vhdl-template-disconnect)
2597 (define-key vhdl-template-map "el" 'vhdl-template-else)
2598 (define-key vhdl-template-map "ei" 'vhdl-template-elsif)
2599 (define-key vhdl-template-map "en" 'vhdl-template-entity)
2600 (define-key vhdl-template-map "ex" 'vhdl-template-exit)
2601 (define-key vhdl-template-map "fi" 'vhdl-template-file)
2602 (define-key vhdl-template-map "fg" 'vhdl-template-for-generate)
2603 (define-key vhdl-template-map "fl" 'vhdl-template-for-loop)
2604 (define-key vhdl-template-map "\C-f" 'vhdl-template-footer)
2605 (define-key vhdl-template-map "fb" 'vhdl-template-function-body)
2606 (define-key vhdl-template-map "fd" 'vhdl-template-function-decl)
2607 (define-key vhdl-template-map "ge" 'vhdl-template-generic)
2608 (define-key vhdl-template-map "gd" 'vhdl-template-group-decl)
2609 (define-key vhdl-template-map "gt" 'vhdl-template-group-template)
2610 (define-key vhdl-template-map "\C-h" 'vhdl-template-header)
2611 (define-key vhdl-template-map "ig" 'vhdl-template-if-generate)
2612 (define-key vhdl-template-map "it" 'vhdl-template-if-then)
2613 (define-key vhdl-template-map "li" 'vhdl-template-library)
2614 (define-key vhdl-template-map "lo" 'vhdl-template-bare-loop)
2615 (define-key vhdl-template-map "\C-m" 'vhdl-template-modify)
2616 (define-key vhdl-template-map "\C-t" 'vhdl-template-insert-date)
2617 (define-key vhdl-template-map "ma" 'vhdl-template-map)
2618 (define-key vhdl-template-map "ne" 'vhdl-template-next)
2619 (define-key vhdl-template-map "ot" 'vhdl-template-others)
2620 (define-key vhdl-template-map "Pd" 'vhdl-template-package-decl)
2621 (define-key vhdl-template-map "Pb" 'vhdl-template-package-body)
2622 (define-key vhdl-template-map "(" 'vhdl-template-paired-parens)
2623 (define-key vhdl-template-map "po" 'vhdl-template-port)
2624 (define-key vhdl-template-map "pb" 'vhdl-template-procedure-body)
2625 (define-key vhdl-template-map "pd" 'vhdl-template-procedure-decl)
2626 (define-key vhdl-template-map "pc" 'vhdl-template-process-comb)
2627 (define-key vhdl-template-map "ps" 'vhdl-template-process-seq)
2628 (define-key vhdl-template-map "rp" 'vhdl-template-report)
2629 (define-key vhdl-template-map "rt" 'vhdl-template-return)
2630 (define-key vhdl-template-map "ss" 'vhdl-template-selected-signal-asst)
2631 (define-key vhdl-template-map "si" 'vhdl-template-signal)
2632 (define-key vhdl-template-map "su" 'vhdl-template-subtype)
2633 (define-key vhdl-template-map "ty" 'vhdl-template-type)
2634 (define-key vhdl-template-map "us" 'vhdl-template-use)
2635 (define-key vhdl-template-map "va" 'vhdl-template-variable)
2636 (define-key vhdl-template-map "wa" 'vhdl-template-wait)
2637 (define-key vhdl-template-map "wl" 'vhdl-template-while-loop)
2638 (define-key vhdl-template-map "wi" 'vhdl-template-with)
2639 (define-key vhdl-template-map "wc" 'vhdl-template-clocked-wait)
2640 (define-key vhdl-template-map "\C-pb" 'vhdl-template-package-numeric-bit)
2641 (define-key vhdl-template-map "\C-pn" 'vhdl-template-package-numeric-std)
2642 (define-key vhdl-template-map "\C-ps" 'vhdl-template-package-std-logic-1164)
2643 (define-key vhdl-template-map "\C-pA" 'vhdl-template-package-std-logic-arith)
2644 (define-key vhdl-template-map "\C-pM" 'vhdl-template-package-std-logic-misc)
2645 (define-key vhdl-template-map "\C-pS" 'vhdl-template-package-std-logic-signed)
2646 (define-key vhdl-template-map "\C-pT" 'vhdl-template-package-std-logic-textio)
2647 (define-key vhdl-template-map "\C-pU" 'vhdl-template-package-std-logic-unsigned)
2648 (define-key vhdl-template-map "\C-pt" 'vhdl-template-package-textio)
2649 (define-key vhdl-template-map "\C-dn" 'vhdl-template-directive-translate-on)
2650 (define-key vhdl-template-map "\C-df" 'vhdl-template-directive-translate-off)
2651 (define-key vhdl-template-map "\C-dN" 'vhdl-template-directive-synthesis-on)
2652 (define-key vhdl-template-map "\C-dF" 'vhdl-template-directive-synthesis-off)
2653 (define-key vhdl-template-map "\C-q" 'vhdl-template-search-prompt)
2654 (when (vhdl-standard-p 'ams)
2655 (define-key vhdl-template-map "br" 'vhdl-template-break)
2656 (define-key vhdl-template-map "cu" 'vhdl-template-case-use)
2657 (define-key vhdl-template-map "iu" 'vhdl-template-if-use)
2658 (define-key vhdl-template-map "lm" 'vhdl-template-limit)
2659 (define-key vhdl-template-map "na" 'vhdl-template-nature)
2660 (define-key vhdl-template-map "pa" 'vhdl-template-procedural)
2661 (define-key vhdl-template-map "qf" 'vhdl-template-quantity-free)
2662 (define-key vhdl-template-map "qb" 'vhdl-template-quantity-branch)
2663 (define-key vhdl-template-map "qs" 'vhdl-template-quantity-source)
2664 (define-key vhdl-template-map "sn" 'vhdl-template-subnature)
2665 (define-key vhdl-template-map "te" 'vhdl-template-terminal)
2666 )
2667 (when (vhdl-standard-p 'math)
2668 (define-key vhdl-template-map "\C-pc" 'vhdl-template-package-math-complex)
2669 (define-key vhdl-template-map "\C-pr" 'vhdl-template-package-math-real)
2670 ))
2671
2672;; initialize template map for VHDL Mode
2673(vhdl-template-map-init)
2674
2675(defun vhdl-function-name (prefix string &optional postfix)
2676 "Generate a Lisp function name.
2677PREFIX, STRING and optional POSTFIX are concatenated by '-' and spaces in
2678STRING are replaced by `-' and substrings are converted to lower case."
2679 (let ((name prefix))
2680 (while (string-match "\\(\\w+\\)\\s-*\\(.*\\)" string)
2681 (setq name
2682 (concat name "-" (downcase (substring string 0 (match-end 1)))))
2683 (setq string (substring string (match-beginning 2))))
2684 (when postfix (setq name (concat name "-" postfix)))
2685 (intern name)))
2686
3dcb36b7 2687(defvar vhdl-model-map nil
5eabfe72
KH
2688 "Keymap for VHDL models.")
2689
2690(defun vhdl-model-map-init ()
2691 "Initialize `vhdl-model-map'."
2692 (setq vhdl-model-map (make-sparse-keymap))
2693 ;; key bindings for VHDL models
2694 (let ((model-alist vhdl-model-alist) model)
2695 (while model-alist
2696 (setq model (car model-alist))
2697 (define-key vhdl-model-map (nth 2 model)
2698 (vhdl-function-name "vhdl-model" (nth 0 model)))
2699 (setq model-alist (cdr model-alist)))))
2700
2701;; initialize user model map for VHDL Mode
2702(vhdl-model-map-init)
d2ddb974 2703
3dcb36b7 2704(defvar vhdl-mode-map nil
d2ddb974
KH
2705 "Keymap for VHDL Mode.")
2706
5eabfe72
KH
2707(defun vhdl-mode-map-init ()
2708 "Initialize `vhdl-mode-map'."
d2ddb974 2709 (setq vhdl-mode-map (make-sparse-keymap))
5eabfe72 2710 ;; template key bindings
0a2e512a 2711 (define-key vhdl-mode-map "\C-c\C-t" vhdl-template-map)
5eabfe72 2712 ;; model key bindings
0a2e512a 2713 (define-key vhdl-mode-map "\C-c\C-m" vhdl-model-map)
d2ddb974 2714 ;; standard key bindings
0a2e512a
RF
2715 (define-key vhdl-mode-map "\M-a" 'vhdl-beginning-of-statement)
2716 (define-key vhdl-mode-map "\M-e" 'vhdl-end-of-statement)
2717 (define-key vhdl-mode-map "\M-\C-f" 'vhdl-forward-sexp)
2718 (define-key vhdl-mode-map "\M-\C-b" 'vhdl-backward-sexp)
2719 (define-key vhdl-mode-map "\M-\C-u" 'vhdl-backward-up-list)
2720 (define-key vhdl-mode-map "\M-\C-a" 'vhdl-backward-same-indent)
2721 (define-key vhdl-mode-map "\M-\C-e" 'vhdl-forward-same-indent)
f8246027 2722 (unless (featurep 'xemacs) ; would override `M-backspace' in XEmacs
0a2e512a
RF
2723 (define-key vhdl-mode-map "\M-\C-h" 'vhdl-mark-defun))
2724 (define-key vhdl-mode-map "\M-\C-q" 'vhdl-indent-sexp)
2725 (define-key vhdl-mode-map "\M-^" 'vhdl-delete-indentation)
5eabfe72 2726 ;; backspace/delete key bindings
0a2e512a 2727 (define-key vhdl-mode-map [backspace] 'backward-delete-char-untabify)
3dcb36b7 2728 (unless (boundp 'delete-key-deletes-forward) ; XEmacs variable
0a2e512a 2729 (define-key vhdl-mode-map [delete] 'delete-char)
3dcb36b7 2730 (define-key vhdl-mode-map [(meta delete)] 'kill-word))
5eabfe72 2731 ;; mode specific key bindings
3dcb36b7
JB
2732 (define-key vhdl-mode-map "\C-c\C-m\C-e" 'vhdl-electric-mode)
2733 (define-key vhdl-mode-map "\C-c\C-m\C-s" 'vhdl-stutter-mode)
2734 (define-key vhdl-mode-map "\C-c\C-s\C-p" 'vhdl-set-project)
2735 (define-key vhdl-mode-map "\C-c\C-p\C-d" 'vhdl-duplicate-project)
2736 (define-key vhdl-mode-map "\C-c\C-p\C-m" 'vhdl-import-project)
2737 (define-key vhdl-mode-map "\C-c\C-p\C-x" 'vhdl-export-project)
2738 (define-key vhdl-mode-map "\C-c\C-s\C-k" 'vhdl-set-compiler)
0a2e512a 2739 (define-key vhdl-mode-map "\C-c\C-k" 'vhdl-compile)
5eabfe72 2740 (define-key vhdl-mode-map "\C-c\M-\C-k" 'vhdl-make)
3dcb36b7 2741 (define-key vhdl-mode-map "\C-c\M-k" 'vhdl-generate-makefile)
5eabfe72
KH
2742 (define-key vhdl-mode-map "\C-c\C-p\C-w" 'vhdl-port-copy)
2743 (define-key vhdl-mode-map "\C-c\C-p\M-w" 'vhdl-port-copy)
2744 (define-key vhdl-mode-map "\C-c\C-p\C-e" 'vhdl-port-paste-entity)
2745 (define-key vhdl-mode-map "\C-c\C-p\C-c" 'vhdl-port-paste-component)
2746 (define-key vhdl-mode-map "\C-c\C-p\C-i" 'vhdl-port-paste-instance)
2747 (define-key vhdl-mode-map "\C-c\C-p\C-s" 'vhdl-port-paste-signals)
2748 (define-key vhdl-mode-map "\C-c\C-p\M-c" 'vhdl-port-paste-constants)
f8246027 2749 (if (featurep 'xemacs) ; `... C-g' not allowed in XEmacs
5eabfe72
KH
2750 (define-key vhdl-mode-map "\C-c\C-p\M-g" 'vhdl-port-paste-generic-map)
2751 (define-key vhdl-mode-map "\C-c\C-p\C-g" 'vhdl-port-paste-generic-map))
3dcb36b7 2752 (define-key vhdl-mode-map "\C-c\C-p\C-z" 'vhdl-port-paste-initializations)
5eabfe72
KH
2753 (define-key vhdl-mode-map "\C-c\C-p\C-t" 'vhdl-port-paste-testbench)
2754 (define-key vhdl-mode-map "\C-c\C-p\C-f" 'vhdl-port-flatten)
3dcb36b7
JB
2755 (define-key vhdl-mode-map "\C-c\C-p\C-r" 'vhdl-port-reverse-direction)
2756 (define-key vhdl-mode-map "\C-c\C-s\C-w" 'vhdl-subprog-copy)
2757 (define-key vhdl-mode-map "\C-c\C-s\M-w" 'vhdl-subprog-copy)
2758 (define-key vhdl-mode-map "\C-c\C-s\C-d" 'vhdl-subprog-paste-declaration)
2759 (define-key vhdl-mode-map "\C-c\C-s\C-b" 'vhdl-subprog-paste-body)
2760 (define-key vhdl-mode-map "\C-c\C-s\C-c" 'vhdl-subprog-paste-call)
2761 (define-key vhdl-mode-map "\C-c\C-s\C-f" 'vhdl-subprog-flatten)
83a38a5a
SM
2762 (define-key vhdl-mode-map "\C-c\C-m\C-n" 'vhdl-compose-new-component)
2763 (define-key vhdl-mode-map "\C-c\C-m\C-p" 'vhdl-compose-place-component)
2764 (define-key vhdl-mode-map "\C-c\C-m\C-w" 'vhdl-compose-wire-components)
2765 (define-key vhdl-mode-map "\C-c\C-m\C-f" 'vhdl-compose-configuration)
2766 (define-key vhdl-mode-map "\C-c\C-m\C-k" 'vhdl-compose-components-package)
2767 (define-key vhdl-mode-map "\C-c\C-c" 'vhdl-comment-uncomment-region)
0a2e512a
RF
2768 (define-key vhdl-mode-map "\C-c-" 'vhdl-comment-append-inline)
2769 (define-key vhdl-mode-map "\C-c\M--" 'vhdl-comment-display-line)
3dcb36b7
JB
2770 (define-key vhdl-mode-map "\C-c\C-i\C-l" 'indent-according-to-mode)
2771 (define-key vhdl-mode-map "\C-c\C-i\C-g" 'vhdl-indent-group)
0a2e512a 2772 (define-key vhdl-mode-map "\M-\C-\\" 'vhdl-indent-region)
3dcb36b7
JB
2773 (define-key vhdl-mode-map "\C-c\C-i\C-b" 'vhdl-indent-buffer)
2774 (define-key vhdl-mode-map "\C-c\C-a\C-g" 'vhdl-align-group)
2775 (define-key vhdl-mode-map "\C-c\C-a\C-a" 'vhdl-align-group)
2776 (define-key vhdl-mode-map "\C-c\C-a\C-i" 'vhdl-align-same-indent)
2777 (define-key vhdl-mode-map "\C-c\C-a\C-l" 'vhdl-align-list)
2778 (define-key vhdl-mode-map "\C-c\C-a\C-d" 'vhdl-align-declarations)
2779 (define-key vhdl-mode-map "\C-c\C-a\M-a" 'vhdl-align-region)
2780 (define-key vhdl-mode-map "\C-c\C-a\C-b" 'vhdl-align-buffer)
2781 (define-key vhdl-mode-map "\C-c\C-a\C-c" 'vhdl-align-inline-comment-group)
2782 (define-key vhdl-mode-map "\C-c\C-a\M-c" 'vhdl-align-inline-comment-region)
2783 (define-key vhdl-mode-map "\C-c\C-f\C-l" 'vhdl-fill-list)
2784 (define-key vhdl-mode-map "\C-c\C-f\C-f" 'vhdl-fill-list)
2785 (define-key vhdl-mode-map "\C-c\C-f\C-g" 'vhdl-fill-group)
2786 (define-key vhdl-mode-map "\C-c\C-f\C-i" 'vhdl-fill-same-indent)
2787 (define-key vhdl-mode-map "\C-c\C-f\M-f" 'vhdl-fill-region)
5eabfe72
KH
2788 (define-key vhdl-mode-map "\C-c\C-l\C-w" 'vhdl-line-kill)
2789 (define-key vhdl-mode-map "\C-c\C-l\M-w" 'vhdl-line-copy)
2790 (define-key vhdl-mode-map "\C-c\C-l\C-y" 'vhdl-line-yank)
2791 (define-key vhdl-mode-map "\C-c\C-l\t" 'vhdl-line-expand)
2792 (define-key vhdl-mode-map "\C-c\C-l\C-n" 'vhdl-line-transpose-next)
2793 (define-key vhdl-mode-map "\C-c\C-l\C-p" 'vhdl-line-transpose-previous)
2794 (define-key vhdl-mode-map "\C-c\C-l\C-o" 'vhdl-line-open)
2795 (define-key vhdl-mode-map "\C-c\C-l\C-g" 'goto-line)
2796 (define-key vhdl-mode-map "\C-c\C-l\C-c" 'vhdl-comment-uncomment-line)
3dcb36b7
JB
2797 (define-key vhdl-mode-map "\C-c\C-x\C-p" 'vhdl-fix-clause)
2798 (define-key vhdl-mode-map "\C-c\C-x\M-c" 'vhdl-fix-case-region)
2799 (define-key vhdl-mode-map "\C-c\C-x\C-c" 'vhdl-fix-case-buffer)
2800 (define-key vhdl-mode-map "\C-c\C-x\M-w" 'vhdl-fixup-whitespace-region)
2801 (define-key vhdl-mode-map "\C-c\C-x\C-w" 'vhdl-fixup-whitespace-buffer)
0a2e512a
RF
2802 (define-key vhdl-mode-map "\C-c\M-b" 'vhdl-beautify-region)
2803 (define-key vhdl-mode-map "\C-c\C-b" 'vhdl-beautify-buffer)
3dcb36b7
JB
2804 (define-key vhdl-mode-map "\C-c\C-u\C-s" 'vhdl-update-sensitivity-list-process)
2805 (define-key vhdl-mode-map "\C-c\C-u\M-s" 'vhdl-update-sensitivity-list-buffer)
83a38a5a
SM
2806 (define-key vhdl-mode-map "\C-c\C-i\C-f" 'vhdl-fontify-buffer)
2807 (define-key vhdl-mode-map "\C-c\C-i\C-s" 'vhdl-statistics-buffer)
0a2e512a
RF
2808 (define-key vhdl-mode-map "\C-c\M-m" 'vhdl-show-messages)
2809 (define-key vhdl-mode-map "\C-c\C-h" 'vhdl-doc-mode)
2810 (define-key vhdl-mode-map "\C-c\C-v" 'vhdl-version)
2811 (define-key vhdl-mode-map "\M-\t" 'insert-tab)
5eabfe72 2812 ;; insert commands bindings
3dcb36b7 2813 (define-key vhdl-mode-map "\C-c\C-i\C-t" 'vhdl-template-insert-construct)
5eabfe72
KH
2814 (define-key vhdl-mode-map "\C-c\C-i\C-p" 'vhdl-template-insert-package)
2815 (define-key vhdl-mode-map "\C-c\C-i\C-d" 'vhdl-template-insert-directive)
2816 (define-key vhdl-mode-map "\C-c\C-i\C-m" 'vhdl-model-insert)
2817 ;; electric key bindings
0a2e512a
RF
2818 (define-key vhdl-mode-map " " 'vhdl-electric-space)
2819 (when vhdl-intelligent-tab
2820 (define-key vhdl-mode-map "\t" 'vhdl-electric-tab))
2821 (define-key vhdl-mode-map "\r" 'vhdl-electric-return)
2822 (define-key vhdl-mode-map "-" 'vhdl-electric-dash)
2823 (define-key vhdl-mode-map "[" 'vhdl-electric-open-bracket)
2824 (define-key vhdl-mode-map "]" 'vhdl-electric-close-bracket)
2825 (define-key vhdl-mode-map "'" 'vhdl-electric-quote)
2826 (define-key vhdl-mode-map ";" 'vhdl-electric-semicolon)
2827 (define-key vhdl-mode-map "," 'vhdl-electric-comma)
2828 (define-key vhdl-mode-map "." 'vhdl-electric-period)
5eabfe72 2829 (when (vhdl-standard-p 'ams)
0a2e512a 2830 (define-key vhdl-mode-map "=" 'vhdl-electric-equal)))
5eabfe72
KH
2831
2832;; initialize mode map for VHDL Mode
2833(vhdl-mode-map-init)
d2ddb974
KH
2834
2835;; define special minibuffer keymap for enabling word completion in minibuffer
2836;; (useful in template generator prompts)
4bcb9c95
SM
2837(defvar vhdl-minibuffer-local-map
2838 (let ((map (make-sparse-keymap)))
2839 (set-keymap-parent map minibuffer-local-map)
2840 (when vhdl-word-completion-in-minibuffer
2841 (define-key map "\t" 'vhdl-minibuffer-tab))
2842 map)
d2ddb974
KH
2843 "Keymap for minibuffer used in VHDL Mode.")
2844
5eabfe72
KH
2845;; set up electric character functions to work with
2846;; `delete-selection-mode' (Emacs) and `pending-delete-mode' (XEmacs)
51b5ad57 2847(mapc
5eabfe72
KH
2848 (function
2849 (lambda (sym)
2850 (put sym 'delete-selection t) ; for `delete-selection-mode' (Emacs)
2851 (put sym 'pending-delete t))) ; for `pending-delete-mode' (XEmacs)
2852 '(vhdl-electric-space
2853 vhdl-electric-tab
2854 vhdl-electric-return
2855 vhdl-electric-dash
2856 vhdl-electric-open-bracket
2857 vhdl-electric-close-bracket
2858 vhdl-electric-quote
2859 vhdl-electric-semicolon
2860 vhdl-electric-comma
2861 vhdl-electric-period
2862 vhdl-electric-equal))
2863
3dcb36b7
JB
2864;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2865;; Syntax table
2866
d2ddb974 2867(defvar vhdl-mode-syntax-table nil
5eabfe72 2868 "Syntax table used in `vhdl-mode' buffers.")
d2ddb974 2869
3dcb36b7
JB
2870(defvar vhdl-mode-ext-syntax-table nil
2871 "Syntax table extended by `_' used in `vhdl-mode' buffers.")
2872
5eabfe72
KH
2873(defun vhdl-mode-syntax-table-init ()
2874 "Initialize `vhdl-mode-syntax-table'."
d2ddb974 2875 (setq vhdl-mode-syntax-table (make-syntax-table))
5eabfe72
KH
2876 ;; define punctuation
2877 (modify-syntax-entry ?\# "." vhdl-mode-syntax-table)
2878 (modify-syntax-entry ?\$ "." vhdl-mode-syntax-table)
2879 (modify-syntax-entry ?\% "." vhdl-mode-syntax-table)
2880 (modify-syntax-entry ?\& "." vhdl-mode-syntax-table)
2881 (modify-syntax-entry ?\' "." vhdl-mode-syntax-table)
2882 (modify-syntax-entry ?\* "." vhdl-mode-syntax-table)
2883 (modify-syntax-entry ?\+ "." vhdl-mode-syntax-table)
2884 (modify-syntax-entry ?\. "." vhdl-mode-syntax-table)
2885 (modify-syntax-entry ?\/ "." vhdl-mode-syntax-table)
2886 (modify-syntax-entry ?\: "." vhdl-mode-syntax-table)
2887 (modify-syntax-entry ?\; "." vhdl-mode-syntax-table)
2888 (modify-syntax-entry ?\< "." vhdl-mode-syntax-table)
2889 (modify-syntax-entry ?\= "." vhdl-mode-syntax-table)
2890 (modify-syntax-entry ?\> "." vhdl-mode-syntax-table)
2891 (modify-syntax-entry ?\\ "." vhdl-mode-syntax-table)
2892 (modify-syntax-entry ?\| "." vhdl-mode-syntax-table)
2893 ;; define string
2894 (modify-syntax-entry ?\" "\"" vhdl-mode-syntax-table)
2895 ;; define underscore
2896 (when vhdl-underscore-is-part-of-word
3dcb36b7 2897 (modify-syntax-entry ?\_ "w" vhdl-mode-syntax-table))
5eabfe72
KH
2898 ;; a single hyphen is punctuation, but a double hyphen starts a comment
2899 (modify-syntax-entry ?\- ". 12" vhdl-mode-syntax-table)
2900 ;; and \n and \^M end a comment
2901 (modify-syntax-entry ?\n ">" vhdl-mode-syntax-table)
2902 (modify-syntax-entry ?\^M ">" vhdl-mode-syntax-table)
2903 ;; define parentheses to match
2904 (modify-syntax-entry ?\( "()" vhdl-mode-syntax-table)
2905 (modify-syntax-entry ?\) ")(" vhdl-mode-syntax-table)
2906 (modify-syntax-entry ?\[ "(]" vhdl-mode-syntax-table)
2907 (modify-syntax-entry ?\] ")[" vhdl-mode-syntax-table)
2908 (modify-syntax-entry ?\{ "(}" vhdl-mode-syntax-table)
3dcb36b7
JB
2909 (modify-syntax-entry ?\} "){" vhdl-mode-syntax-table)
2910 ;; extended syntax table including '_' (for simpler search regexps)
2911 (setq vhdl-mode-ext-syntax-table (copy-syntax-table vhdl-mode-syntax-table))
2912 (modify-syntax-entry ?_ "w" vhdl-mode-ext-syntax-table))
5eabfe72
KH
2913
2914;; initialize syntax table for VHDL Mode
2915(vhdl-mode-syntax-table-init)
2916
d2ddb974
KH
2917(defvar vhdl-syntactic-context nil
2918 "Buffer local variable containing syntactic analysis list.")
2919(make-variable-buffer-local 'vhdl-syntactic-context)
2920
5eabfe72 2921;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 2922;; Abbrev ook bindings
d2ddb974
KH
2923
2924(defvar vhdl-mode-abbrev-table nil
5eabfe72
KH
2925 "Abbrev table to use in `vhdl-mode' buffers.")
2926
2927(defun vhdl-mode-abbrev-table-init ()
2928 "Initialize `vhdl-mode-abbrev-table'."
5eabfe72
KH
2929 (define-abbrev-table 'vhdl-mode-abbrev-table
2930 (append
2931 (when (memq 'vhdl vhdl-electric-keywords)
2932 ;; VHDL'93 keywords
86905e5b
SM
2933 (mapcar (lambda (x) (list (car x) "" (cdr x) 0 'system))
2934 '(
2935 ("--" . vhdl-template-display-comment-hook)
2936 ("abs" . vhdl-template-default-hook)
2937 ("access" . vhdl-template-default-hook)
2938 ("after" . vhdl-template-default-hook)
2939 ("alias" . vhdl-template-alias-hook)
2940 ("all" . vhdl-template-default-hook)
2941 ("and" . vhdl-template-default-hook)
2942 ("arch" . vhdl-template-architecture-hook)
2943 ("architecture" . vhdl-template-architecture-hook)
2944 ("array" . vhdl-template-default-hook)
2945 ("assert" . vhdl-template-assert-hook)
2946 ("attr" . vhdl-template-attribute-hook)
2947 ("attribute" . vhdl-template-attribute-hook)
2948 ("begin" . vhdl-template-default-indent-hook)
2949 ("block" . vhdl-template-block-hook)
2950 ("body" . vhdl-template-default-hook)
2951 ("buffer" . vhdl-template-default-hook)
2952 ("bus" . vhdl-template-default-hook)
2953 ("case" . vhdl-template-case-hook)
2954 ("comp" . vhdl-template-component-hook)
2955 ("component" . vhdl-template-component-hook)
2956 ("cond" . vhdl-template-conditional-signal-asst-hook)
2957 ("conditional" . vhdl-template-conditional-signal-asst-hook)
2958 ("conf" . vhdl-template-configuration-hook)
2959 ("configuration" . vhdl-template-configuration-hook)
2960 ("cons" . vhdl-template-constant-hook)
2961 ("constant" . vhdl-template-constant-hook)
2962 ("disconnect" . vhdl-template-disconnect-hook)
2963 ("downto" . vhdl-template-default-hook)
2964 ("else" . vhdl-template-else-hook)
2965 ("elseif" . vhdl-template-elsif-hook)
2966 ("elsif" . vhdl-template-elsif-hook)
2967 ("end" . vhdl-template-default-indent-hook)
2968 ("entity" . vhdl-template-entity-hook)
2969 ("exit" . vhdl-template-exit-hook)
2970 ("file" . vhdl-template-file-hook)
2971 ("for" . vhdl-template-for-hook)
2972 ("func" . vhdl-template-function-hook)
2973 ("function" . vhdl-template-function-hook)
2974 ("generic" . vhdl-template-generic-hook)
2975 ("group" . vhdl-template-group-hook)
2976 ("guarded" . vhdl-template-default-hook)
2977 ("if" . vhdl-template-if-hook)
2978 ("impure" . vhdl-template-default-hook)
2979 ("in" . vhdl-template-default-hook)
2980 ("inertial" . vhdl-template-default-hook)
2981 ("inout" . vhdl-template-default-hook)
2982 ("inst" . vhdl-template-instance-hook)
2983 ("instance" . vhdl-template-instance-hook)
2984 ("is" . vhdl-template-default-hook)
2985 ("label" . vhdl-template-default-hook)
2986 ("library" . vhdl-template-library-hook)
2987 ("linkage" . vhdl-template-default-hook)
2988 ("literal" . vhdl-template-default-hook)
2989 ("loop" . vhdl-template-bare-loop-hook)
2990 ("map" . vhdl-template-map-hook)
2991 ("mod" . vhdl-template-default-hook)
2992 ("nand" . vhdl-template-default-hook)
2993 ("new" . vhdl-template-default-hook)
2994 ("next" . vhdl-template-next-hook)
2995 ("nor" . vhdl-template-default-hook)
2996 ("not" . vhdl-template-default-hook)
2997 ("null" . vhdl-template-default-hook)
2998 ("of" . vhdl-template-default-hook)
2999 ("on" . vhdl-template-default-hook)
3000 ("open" . vhdl-template-default-hook)
3001 ("or" . vhdl-template-default-hook)
3002 ("others" . vhdl-template-others-hook)
3003 ("out" . vhdl-template-default-hook)
3004 ("pack" . vhdl-template-package-hook)
3005 ("package" . vhdl-template-package-hook)
3006 ("port" . vhdl-template-port-hook)
3007 ("postponed" . vhdl-template-default-hook)
3008 ("procedure" . vhdl-template-procedure-hook)
3009 ("process" . vhdl-template-process-hook)
3010 ("pure" . vhdl-template-default-hook)
3011 ("range" . vhdl-template-default-hook)
3012 ("record" . vhdl-template-default-hook)
3013 ("register" . vhdl-template-default-hook)
3014 ("reject" . vhdl-template-default-hook)
3015 ("rem" . vhdl-template-default-hook)
3016 ("report" . vhdl-template-report-hook)
3017 ("return" . vhdl-template-return-hook)
3018 ("rol" . vhdl-template-default-hook)
3019 ("ror" . vhdl-template-default-hook)
3020 ("select" . vhdl-template-selected-signal-asst-hook)
3021 ("severity" . vhdl-template-default-hook)
3022 ("shared" . vhdl-template-default-hook)
3023 ("sig" . vhdl-template-signal-hook)
3024 ("signal" . vhdl-template-signal-hook)
3025 ("sla" . vhdl-template-default-hook)
3026 ("sll" . vhdl-template-default-hook)
3027 ("sra" . vhdl-template-default-hook)
3028 ("srl" . vhdl-template-default-hook)
3029 ("subtype" . vhdl-template-subtype-hook)
3030 ("then" . vhdl-template-default-hook)
3031 ("to" . vhdl-template-default-hook)
3032 ("transport" . vhdl-template-default-hook)
3033 ("type" . vhdl-template-type-hook)
3034 ("unaffected" . vhdl-template-default-hook)
3035 ("units" . vhdl-template-default-hook)
3036 ("until" . vhdl-template-default-hook)
3037 ("use" . vhdl-template-use-hook)
3038 ("var" . vhdl-template-variable-hook)
3039 ("variable" . vhdl-template-variable-hook)
3040 ("wait" . vhdl-template-wait-hook)
3041 ("when" . vhdl-template-when-hook)
3042 ("while" . vhdl-template-while-loop-hook)
3043 ("with" . vhdl-template-with-hook)
3044 ("xnor" . vhdl-template-default-hook)
3045 ("xor" . vhdl-template-default-hook)
3046 )))
5eabfe72
KH
3047 ;; VHDL-AMS keywords
3048 (when (and (memq 'vhdl vhdl-electric-keywords) (vhdl-standard-p 'ams))
86905e5b
SM
3049 (mapcar (lambda (x) (list (car x) "" (cdr x) 0 'system))
3050 '(
3051 ("across" . vhdl-template-default-hook)
3052 ("break" . vhdl-template-break-hook)
3053 ("limit" . vhdl-template-limit-hook)
3054 ("nature" . vhdl-template-nature-hook)
3055 ("noise" . vhdl-template-default-hook)
3056 ("procedural" . vhdl-template-procedural-hook)
3057 ("quantity" . vhdl-template-quantity-hook)
3058 ("reference" . vhdl-template-default-hook)
3059 ("spectrum" . vhdl-template-default-hook)
3060 ("subnature" . vhdl-template-subnature-hook)
3061 ("terminal" . vhdl-template-terminal-hook)
3062 ("through" . vhdl-template-default-hook)
3063 ("tolerance" . vhdl-template-default-hook)
3064 )))
5eabfe72
KH
3065 ;; user model keywords
3066 (when (memq 'user vhdl-electric-keywords)
86905e5b
SM
3067 (let (abbrev-list keyword)
3068 (dolist (elem vhdl-model-alist)
3069 (setq keyword (nth 3 elem))
5eabfe72 3070 (unless (equal keyword "")
86905e5b
SM
3071 (push (list keyword ""
3072 (vhdl-function-name
3073 "vhdl-model" (nth 0 elem) "hook") 0 'system)
3074 abbrev-list)))
5eabfe72
KH
3075 abbrev-list)))))
3076
3077;; initialize abbrev table for VHDL Mode
3078(vhdl-mode-abbrev-table-init)
3079
3080;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3081;; Template completion lists
3082
3083(defvar vhdl-template-construct-alist nil
3084 "List of built-in construct templates.")
3085
3086(defun vhdl-template-construct-alist-init ()
3087 "Initialize `vhdl-template-construct-alist'."
3088 (setq
3089 vhdl-template-construct-alist
3090 (append
3091 '(
3092 ("alias declaration" vhdl-template-alias)
3093 ("architecture body" vhdl-template-architecture)
3094 ("assertion" vhdl-template-assert)
3095 ("attribute declaration" vhdl-template-attribute-decl)
3096 ("attribute specification" vhdl-template-attribute-spec)
3097 ("block configuration" vhdl-template-block-configuration)
3098 ("block statement" vhdl-template-block)
3099 ("case statement" vhdl-template-case-is)
3100 ("component configuration" vhdl-template-component-conf)
3101 ("component declaration" vhdl-template-component-decl)
3102 ("component instantiation statement" vhdl-template-component-inst)
3103 ("conditional signal assignment" vhdl-template-conditional-signal-asst)
3104 ("configuration declaration" vhdl-template-configuration-decl)
3105 ("configuration specification" vhdl-template-configuration-spec)
3106 ("constant declaration" vhdl-template-constant)
3107 ("disconnection specification" vhdl-template-disconnect)
3108 ("entity declaration" vhdl-template-entity)
3109 ("exit statement" vhdl-template-exit)
3110 ("file declaration" vhdl-template-file)
3111 ("generate statement" vhdl-template-generate)
3112 ("generic clause" vhdl-template-generic)
3113 ("group declaration" vhdl-template-group-decl)
3114 ("group template declaration" vhdl-template-group-template)
3115 ("if statement" vhdl-template-if-then)
3116 ("library clause" vhdl-template-library)
3117 ("loop statement" vhdl-template-loop)
3118 ("next statement" vhdl-template-next)
3119 ("package declaration" vhdl-template-package-decl)
3120 ("package body" vhdl-template-package-body)
3121 ("port clause" vhdl-template-port)
3122 ("process statement" vhdl-template-process)
3123 ("report statement" vhdl-template-report)
3124 ("return statement" vhdl-template-return)
3125 ("selected signal assignment" vhdl-template-selected-signal-asst)
3126 ("signal declaration" vhdl-template-signal)
3127 ("subprogram declaration" vhdl-template-subprogram-decl)
3128 ("subprogram body" vhdl-template-subprogram-body)
3129 ("subtype declaration" vhdl-template-subtype)
3130 ("type declaration" vhdl-template-type)
3131 ("use clause" vhdl-template-use)
3132 ("variable declaration" vhdl-template-variable)
3133 ("wait statement" vhdl-template-wait)
3134 )
3135 (when (vhdl-standard-p 'ams)
3136 '(
3137 ("break statement" vhdl-template-break)
3138 ("nature declaration" vhdl-template-nature)
3139 ("quantity declaration" vhdl-template-quantity)
3140 ("simultaneous case statement" vhdl-template-case-use)
3141 ("simultaneous if statement" vhdl-template-if-use)
3142 ("simultaneous procedural statement" vhdl-template-procedural)
3143 ("step limit specification" vhdl-template-limit)
3144 ("subnature declaration" vhdl-template-subnature)
3145 ("terminal declaration" vhdl-template-terminal)
3146 )))))
d2ddb974 3147
5eabfe72
KH
3148;; initialize for VHDL Mode
3149(vhdl-template-construct-alist-init)
3150
3151(defvar vhdl-template-package-alist nil
3152 "List of built-in package templates.")
3153
3154(defun vhdl-template-package-alist-init ()
3155 "Initialize `vhdl-template-package-alist'."
3156 (setq
3157 vhdl-template-package-alist
3158 (append
3159 '(
3160 ("numeric_bit" vhdl-template-package-numeric-bit)
3161 ("numeric_std" vhdl-template-package-numeric-std)
3162 ("std_logic_1164" vhdl-template-package-std-logic-1164)
3163 ("std_logic_arith" vhdl-template-package-std-logic-arith)
3164 ("std_logic_misc" vhdl-template-package-std-logic-misc)
3165 ("std_logic_signed" vhdl-template-package-std-logic-signed)
3166 ("std_logic_textio" vhdl-template-package-std-logic-textio)
3167 ("std_logic_unsigned" vhdl-template-package-std-logic-unsigned)
3168 ("textio" vhdl-template-package-textio)
3169 )
3170 (when (vhdl-standard-p 'math)
3171 '(
3172 ("math_complex" vhdl-template-package-math-complex)
3173 ("math_real" vhdl-template-package-math-real)
3174 )))))
d2ddb974 3175
5eabfe72
KH
3176;; initialize for VHDL Mode
3177(vhdl-template-package-alist-init)
d2ddb974 3178
5eabfe72 3179(defvar vhdl-template-directive-alist
3dcb36b7
JB
3180 '(
3181 ("translate_on" vhdl-template-directive-translate-on)
3182 ("translate_off" vhdl-template-directive-translate-off)
3183 ("synthesis_on" vhdl-template-directive-synthesis-on)
3184 ("synthesis_off" vhdl-template-directive-synthesis-off)
3185 )
5eabfe72 3186 "List of built-in directive templates.")
d2ddb974 3187
5eabfe72
KH
3188
3189;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
09e80d9f 3190;;; Menus
5eabfe72
KH
3191;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3192
3193;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
3194;; VHDL menu (using `easy-menu.el')
3195
5eabfe72
KH
3196(defun vhdl-customize ()
3197 "Call the customize function with `vhdl' as argument."
3198 (interactive)
3199 (customize-browse 'vhdl))
3200
5eabfe72
KH
3201(defun vhdl-create-mode-menu ()
3202 "Create VHDL Mode menu."
3dcb36b7
JB
3203 `("VHDL"
3204 ,(append
3205 '("Project"
3206 ["None" (vhdl-set-project "")
3207 :style radio :selected (null vhdl-project)]
3208 "--")
3209 ;; add menu entries for defined projects
3210 (let ((project-alist vhdl-project-alist) menu-list name)
3211 (while project-alist
3212 (setq name (caar project-alist))
3213 (setq menu-list
3214 (cons `[,name (vhdl-set-project ,name)
3215 :style radio :selected (equal ,name vhdl-project)]
3216 menu-list))
3217 (setq project-alist (cdr project-alist)))
3218 (setq menu-list
3219 (if vhdl-project-sort
3220 (sort menu-list
3221 (function (lambda (a b) (string< (elt a 0) (elt b 0)))))
3222 (nreverse menu-list)))
3223 (vhdl-menu-split menu-list "Project"))
3224 '("--" "--"
3225 ["Select Project..." vhdl-set-project t]
0a2e512a 3226 ["Set As Default Project" vhdl-set-default-project t]
3dcb36b7
JB
3227 "--"
3228 ["Duplicate Project" vhdl-duplicate-project vhdl-project]
3229 ["Import Project..." vhdl-import-project
3230 :keys "C-c C-p C-m" :active t]
3231 ["Export Project" vhdl-export-project vhdl-project]
3232 "--"
3233 ["Customize Project..." (customize-option 'vhdl-project-alist) t]))
d2ddb974 3234 "--"
3dcb36b7
JB
3235 ("Compile"
3236 ["Compile Buffer" vhdl-compile t]
3237 ["Stop Compilation" kill-compilation t]
3238 "--"
3239 ["Make" vhdl-make t]
3240 ["Generate Makefile" vhdl-generate-makefile t]
3241 "--"
3242 ["Next Error" next-error t]
3243 ["Previous Error" previous-error t]
3244 ["First Error" first-error t]
3245 "--"
3246 ,(append
3247 '("Compiler")
3248 ;; add menu entries for defined compilers
3249 (let ((comp-alist vhdl-compiler-alist) menu-list name)
3250 (while comp-alist
3251 (setq name (caar comp-alist))
3252 (setq menu-list
3253 (cons `[,name (setq vhdl-compiler ,name)
3254 :style radio :selected (equal ,name vhdl-compiler)]
3255 menu-list))
3256 (setq comp-alist (cdr comp-alist)))
3257 (setq menu-list (nreverse menu-list))
3258 (vhdl-menu-split menu-list "Compiler"))
3259 '("--" "--"
3260 ["Select Compiler..." vhdl-set-compiler t]
3261 "--"
3262 ["Customize Compiler..."
3263 (customize-option 'vhdl-compiler-alist) t])))
5eabfe72 3264 "--"
3dcb36b7
JB
3265 ,(append
3266 '("Template"
3267 ("VHDL Construct 1"
3268 ["Alias" vhdl-template-alias t]
3269 ["Architecture" vhdl-template-architecture t]
3270 ["Assert" vhdl-template-assert t]
3271 ["Attribute (Decl)" vhdl-template-attribute-decl t]
3272 ["Attribute (Spec)" vhdl-template-attribute-spec t]
3273 ["Block" vhdl-template-block t]
3274 ["Case" vhdl-template-case-is t]
3275 ["Component (Decl)" vhdl-template-component-decl t]
3276 ["(Component) Instance" vhdl-template-component-inst t]
3277 ["Conditional (Signal Asst)" vhdl-template-conditional-signal-asst t]
3278 ["Configuration (Block)" vhdl-template-block-configuration t]
3279 ["Configuration (Comp)" vhdl-template-component-conf t]
3280 ["Configuration (Decl)" vhdl-template-configuration-decl t]
3281 ["Configuration (Spec)" vhdl-template-configuration-spec t]
3282 ["Constant" vhdl-template-constant t]
3283 ["Disconnect" vhdl-template-disconnect t]
3284 ["Else" vhdl-template-else t]
3285 ["Elsif" vhdl-template-elsif t]
3286 ["Entity" vhdl-template-entity t]
3287 ["Exit" vhdl-template-exit t]
3288 ["File" vhdl-template-file t]
3289 ["For (Generate)" vhdl-template-for-generate t]
3290 ["For (Loop)" vhdl-template-for-loop t]
3291 ["Function (Body)" vhdl-template-function-body t]
3292 ["Function (Decl)" vhdl-template-function-decl t]
3293 ["Generic" vhdl-template-generic t]
3294 ["Group (Decl)" vhdl-template-group-decl t]
3295 ["Group (Template)" vhdl-template-group-template t])
3296 ("VHDL Construct 2"
3297 ["If (Generate)" vhdl-template-if-generate t]
3298 ["If (Then)" vhdl-template-if-then t]
3299 ["Library" vhdl-template-library t]
3300 ["Loop" vhdl-template-bare-loop t]
3301 ["Map" vhdl-template-map t]
3302 ["Next" vhdl-template-next t]
3303 ["Others (Aggregate)" vhdl-template-others t]
3304 ["Package (Decl)" vhdl-template-package-decl t]
3305 ["Package (Body)" vhdl-template-package-body t]
3306 ["Port" vhdl-template-port t]
3307 ["Procedure (Body)" vhdl-template-procedure-body t]
3308 ["Procedure (Decl)" vhdl-template-procedure-decl t]
3309 ["Process (Comb)" vhdl-template-process-comb t]
3310 ["Process (Seq)" vhdl-template-process-seq t]
3311 ["Report" vhdl-template-report t]
3312 ["Return" vhdl-template-return t]
3313 ["Select" vhdl-template-selected-signal-asst t]
3314 ["Signal" vhdl-template-signal t]
3315 ["Subtype" vhdl-template-subtype t]
3316 ["Type" vhdl-template-type t]
3317 ["Use" vhdl-template-use t]
3318 ["Variable" vhdl-template-variable t]
3319 ["Wait" vhdl-template-wait t]
3320 ["(Clocked Wait)" vhdl-template-clocked-wait t]
3321 ["When" vhdl-template-when t]
3322 ["While (Loop)" vhdl-template-while-loop t]
3323 ["With" vhdl-template-with t]))
3324 (when (vhdl-standard-p 'ams)
3325 '(("VHDL-AMS Construct"
3326 ["Break" vhdl-template-break t]
3327 ["Case (Use)" vhdl-template-case-use t]
3328 ["If (Use)" vhdl-template-if-use t]
3329 ["Limit" vhdl-template-limit t]
3330 ["Nature" vhdl-template-nature t]
3331 ["Procedural" vhdl-template-procedural t]
3332 ["Quantity (Free)" vhdl-template-quantity-free t]
3333 ["Quantity (Branch)" vhdl-template-quantity-branch t]
3334 ["Quantity (Source)" vhdl-template-quantity-source t]
3335 ["Subnature" vhdl-template-subnature t]
3336 ["Terminal" vhdl-template-terminal t])))
3337 '(["Insert Construct..." vhdl-template-insert-construct
3338 :keys "C-c C-i C-t"]
3339 "--")
3340 (list
3341 (append
3342 '("Package")
3dcb36b7
JB
3343 '(["numeric_bit" vhdl-template-package-numeric-bit t]
3344 ["numeric_std" vhdl-template-package-numeric-std t]
3345 ["std_logic_1164" vhdl-template-package-std-logic-1164 t]
3346 ["textio" vhdl-template-package-textio t]
3347 "--"
3348 ["std_logic_arith" vhdl-template-package-std-logic-arith t]
3349 ["std_logic_signed" vhdl-template-package-std-logic-signed t]
3350 ["std_logic_unsigned" vhdl-template-package-std-logic-unsigned t]
3351 ["std_logic_misc" vhdl-template-package-std-logic-misc t]
3352 ["std_logic_textio" vhdl-template-package-std-logic-textio t]
fda91268
RZ
3353 "--")
3354 (when (vhdl-standard-p 'ams)
3355 '(["fundamental_constants" vhdl-template-package-fundamental-constants t]
3356 ["material_constants" vhdl-template-package-material-constants t]
3357 ["energy_systems" vhdl-template-package-energy-systems t]
3358 ["electrical_systems" vhdl-template-package-electrical-systems t]
3359 ["mechanical_systems" vhdl-template-package-mechanical-systems t]
3360 ["radiant_systems" vhdl-template-package-radiant-systems t]
3361 ["thermal_systems" vhdl-template-package-thermal-systems t]
3362 ["fluidic_systems" vhdl-template-package-fluidic-systems t]
3363 "--"))
3364 (when (vhdl-standard-p 'math)
3365 '(["math_complex" vhdl-template-package-math-complex t]
3366 ["math_real" vhdl-template-package-math-real t]
3367 "--"))
3368 '(["Insert Package..." vhdl-template-insert-package
3dcb36b7
JB
3369 :keys "C-c C-i C-p"])))
3370 '(("Directive"
3371 ["translate_on" vhdl-template-directive-translate-on t]
3372 ["translate_off" vhdl-template-directive-translate-off t]
3373 ["synthesis_on" vhdl-template-directive-synthesis-on t]
3374 ["synthesis_off" vhdl-template-directive-synthesis-off t]
3375 "--"
3376 ["Insert Directive..." vhdl-template-insert-directive
3377 :keys "C-c C-i C-d"])
5eabfe72 3378 "--"
3dcb36b7
JB
3379 ["Insert Header" vhdl-template-header :keys "C-c C-t C-h"]
3380 ["Insert Footer" vhdl-template-footer t]
3381 ["Insert Date" vhdl-template-insert-date t]
3382 ["Modify Date" vhdl-template-modify :keys "C-c C-t C-m"]
5eabfe72 3383 "--"
3dcb36b7
JB
3384 ["Query Next Prompt" vhdl-template-search-prompt t]))
3385 ,(append
3386 '("Model")
3387 ;; add menu entries for defined models
3388 (let ((model-alist vhdl-model-alist) menu-list model)
3389 (while model-alist
3390 (setq model (car model-alist))
3391 (setq menu-list
3392 (cons
3393 (vector
3394 (nth 0 model)
3395 (vhdl-function-name "vhdl-model" (nth 0 model))
3396 :keys (concat "C-c C-m " (key-description (nth 2 model))))
3397 menu-list))
3398 (setq model-alist (cdr model-alist)))
3399 (setq menu-list (nreverse menu-list))
3400 (vhdl-menu-split menu-list "Model"))
3401 '("--" "--"
3402 ["Insert Model..." vhdl-model-insert :keys "C-c C-i C-m"]
3403 ["Customize Model..." (customize-option 'vhdl-model-alist) t]))
3404 ("Port"
5eabfe72 3405 ["Copy" vhdl-port-copy t]
d2ddb974 3406 "--"
5eabfe72
KH
3407 ["Paste As Entity" vhdl-port-paste-entity vhdl-port-list]
3408 ["Paste As Component" vhdl-port-paste-component vhdl-port-list]
3409 ["Paste As Instance" vhdl-port-paste-instance
3410 :keys "C-c C-p C-i" :active vhdl-port-list]
3411 ["Paste As Signals" vhdl-port-paste-signals vhdl-port-list]
3412 ["Paste As Constants" vhdl-port-paste-constants vhdl-port-list]
3413 ["Paste As Generic Map" vhdl-port-paste-generic-map vhdl-port-list]
3dcb36b7 3414 ["Paste As Initializations" vhdl-port-paste-initializations vhdl-port-list]
d2ddb974 3415 "--"
3dcb36b7
JB
3416 ["Paste As Testbench" vhdl-port-paste-testbench vhdl-port-list]
3417 "--"
3418 ["Flatten" vhdl-port-flatten
3419 :style toggle :selected vhdl-port-flattened :active vhdl-port-list]
3420 ["Reverse Direction" vhdl-port-reverse-direction
3421 :style toggle :selected vhdl-port-reversed-direction :active vhdl-port-list])
3422 ("Compose"
3423 ["New Component" vhdl-compose-new-component t]
0a2e512a 3424 ["Copy Component" vhdl-port-copy t]
3dcb36b7
JB
3425 ["Place Component" vhdl-compose-place-component vhdl-port-list]
3426 ["Wire Components" vhdl-compose-wire-components t]
3427 "--"
0a2e512a 3428 ["Generate Configuration" vhdl-compose-configuration t]
3dcb36b7
JB
3429 ["Generate Components Package" vhdl-compose-components-package t])
3430 ("Subprogram"
3431 ["Copy" vhdl-subprog-copy t]
3432 "--"
3433 ["Paste As Declaration" vhdl-subprog-paste-declaration vhdl-subprog-list]
3434 ["Paste As Body" vhdl-subprog-paste-body vhdl-subprog-list]
3435 ["Paste As Call" vhdl-subprog-paste-call vhdl-subprog-list]
3436 "--"
3437 ["Flatten" vhdl-subprog-flatten
3438 :style toggle :selected vhdl-subprog-flattened :active vhdl-subprog-list])
3439 "--"
3440 ("Comment"
5eabfe72
KH
3441 ["(Un)Comment Out Region" vhdl-comment-uncomment-region (mark)]
3442 "--"
3443 ["Insert Inline Comment" vhdl-comment-append-inline t]
3444 ["Insert Horizontal Line" vhdl-comment-display-line t]
3445 ["Insert Display Comment" vhdl-comment-display t]
3446 "--"
3447 ["Fill Comment" fill-paragraph t]
3448 ["Fill Comment Region" fill-region (mark)]
3449 ["Kill Comment Region" vhdl-comment-kill-region (mark)]
3dcb36b7
JB
3450 ["Kill Inline Comment Region" vhdl-comment-kill-inline-region (mark)])
3451 ("Line"
5eabfe72
KH
3452 ["Kill" vhdl-line-kill t]
3453 ["Copy" vhdl-line-copy t]
3454 ["Yank" vhdl-line-yank t]
3455 ["Expand" vhdl-line-expand t]
3456 "--"
3457 ["Transpose Next" vhdl-line-transpose-next t]
3458 ["Transpose Prev" vhdl-line-transpose-previous t]
3459 ["Open" vhdl-line-open t]
3dcb36b7 3460 ["Join" vhdl-delete-indentation t]
5eabfe72
KH
3461 "--"
3462 ["Goto" goto-line t]
3dcb36b7
JB
3463 ["(Un)Comment Out" vhdl-comment-uncomment-line t])
3464 ("Move"
5eabfe72
KH
3465 ["Forward Statement" vhdl-end-of-statement t]
3466 ["Backward Statement" vhdl-beginning-of-statement t]
3467 ["Forward Expression" vhdl-forward-sexp t]
3468 ["Backward Expression" vhdl-backward-sexp t]
3dcb36b7
JB
3469 ["Forward Same Indent" vhdl-forward-same-indent t]
3470 ["Backward Same Indent" vhdl-backward-same-indent t]
5eabfe72
KH
3471 ["Forward Function" vhdl-end-of-defun t]
3472 ["Backward Function" vhdl-beginning-of-defun t]
3dcb36b7
JB
3473 ["Mark Function" vhdl-mark-defun t])
3474 "--"
3475 ("Indent"
3476 ["Line" indent-according-to-mode :keys "C-c C-i C-l"]
3477 ["Group" vhdl-indent-group :keys "C-c C-i C-g"]
5eabfe72 3478 ["Region" vhdl-indent-region (mark)]
3dcb36b7
JB
3479 ["Buffer" vhdl-indent-buffer :keys "C-c C-i C-b"])
3480 ("Align"
5eabfe72 3481 ["Group" vhdl-align-group t]
3dcb36b7
JB
3482 ["Same Indent" vhdl-align-same-indent :keys "C-c C-a C-i"]
3483 ["List" vhdl-align-list t]
3484 ["Declarations" vhdl-align-declarations t]
3485 ["Region" vhdl-align-region (mark)]
3486 ["Buffer" vhdl-align-buffer t]
5eabfe72
KH
3487 "--"
3488 ["Inline Comment Group" vhdl-align-inline-comment-group t]
3489 ["Inline Comment Region" vhdl-align-inline-comment-region (mark)]
3dcb36b7
JB
3490 ["Inline Comment Buffer" vhdl-align-inline-comment-buffer t])
3491 ("Fill"
3492 ["List" vhdl-fill-list t]
3493 ["Group" vhdl-fill-group t]
3494 ["Same Indent" vhdl-fill-same-indent :keys "C-c C-f C-i"]
3495 ["Region" vhdl-fill-region (mark)])
3496 ("Beautify"
3497 ["Region" vhdl-beautify-region (mark)]
3498 ["Buffer" vhdl-beautify-buffer t])
3499 ("Fix"
3500 ["Generic/Port Clause" vhdl-fix-clause t]
fda91268 3501 ["Generic/Port Clause Buffer" vhdl-fix-clause t]
5eabfe72 3502 "--"
3dcb36b7
JB
3503 ["Case Region" vhdl-fix-case-region (mark)]
3504 ["Case Buffer" vhdl-fix-case-buffer t]
3505 "--"
3506 ["Whitespace Region" vhdl-fixup-whitespace-region (mark)]
3507 ["Whitespace Buffer" vhdl-fixup-whitespace-buffer t]
3508 "--"
3509 ["Trailing Spaces Buffer" vhdl-remove-trailing-spaces t])
3510 ("Update"
3511 ["Sensitivity List" vhdl-update-sensitivity-list-process t]
3512 ["Sensitivity List Buffer" vhdl-update-sensitivity-list-buffer t])
3513 "--"
3514 ["Fontify Buffer" vhdl-fontify-buffer t]
3515 ["Statistics Buffer" vhdl-statistics-buffer t]
3516 ["Show Messages" vhdl-show-messages t]
3517 ["Syntactic Info" vhdl-show-syntactic-information t]
3518 "--"
3519 ["Speedbar" vhdl-speedbar t]
3520 ["Hide/Show" vhdl-hs-minor-mode t]
3521 "--"
3522 ("Documentation"
5eabfe72 3523 ["VHDL Mode" vhdl-doc-mode :keys "C-c C-h"]
3dcb36b7 3524 ["Release Notes" (vhdl-doc-variable 'vhdl-doc-release-notes) t]
5eabfe72 3525 ["Reserved Words" (vhdl-doc-variable 'vhdl-doc-keywords) t]
3dcb36b7
JB
3526 ["Coding Style" (vhdl-doc-variable 'vhdl-doc-coding-style) t])
3527 ["Version" vhdl-version t]
3528 ["Bug Report..." vhdl-submit-bug-report t]
3529 "--"
3530 ("Options"
3531 ("Mode"
3532 ["Electric Mode"
3533 (progn (customize-set-variable 'vhdl-electric-mode
fda91268
RZ
3534 (not vhdl-electric-mode))
3535 (vhdl-mode-line-update))
3dcb36b7
JB
3536 :style toggle :selected vhdl-electric-mode :keys "C-c C-m C-e"]
3537 ["Stutter Mode"
3538 (progn (customize-set-variable 'vhdl-stutter-mode
fda91268
RZ
3539 (not vhdl-stutter-mode))
3540 (vhdl-mode-line-update))
3dcb36b7
JB
3541 :style toggle :selected vhdl-stutter-mode :keys "C-c C-m C-s"]
3542 ["Indent Tabs Mode"
3543 (progn (customize-set-variable 'vhdl-indent-tabs-mode
3544 (not vhdl-indent-tabs-mode))
3545 (setq indent-tabs-mode vhdl-indent-tabs-mode))
3546 :style toggle :selected vhdl-indent-tabs-mode]
3547 "--"
3548 ["Customize Group..." (customize-group 'vhdl-mode) t])
3549 ("Project"
3550 ["Project Setup..." (customize-option 'vhdl-project-alist) t]
3551 ,(append
3552 '("Selected Project at Startup"
3553 ["None" (progn (customize-set-variable 'vhdl-project nil)
3554 (vhdl-set-project ""))
3555 :style radio :selected (null vhdl-project)]
3556 "--")
3557 ;; add menu entries for defined projects
3558 (let ((project-alist vhdl-project-alist) menu-list name)
3559 (while project-alist
3560 (setq name (caar project-alist))
3561 (setq menu-list
3562 (cons `[,name (progn (customize-set-variable
3563 'vhdl-project ,name)
3564 (vhdl-set-project ,name))
3565 :style radio :selected (equal ,name vhdl-project)]
3566 menu-list))
3567 (setq project-alist (cdr project-alist)))
3568 (setq menu-list (nreverse menu-list))
3569 (vhdl-menu-split menu-list "Project")))
3570 ["Setup File Name..." (customize-option 'vhdl-project-file-name) t]
3571 ("Auto Load Setup File"
3572 ["At Startup"
3573 (customize-set-variable 'vhdl-project-auto-load
3574 (if (memq 'startup vhdl-project-auto-load)
3575 (delq 'startup vhdl-project-auto-load)
3576 (cons 'startup vhdl-project-auto-load)))
3577 :style toggle :selected (memq 'startup vhdl-project-auto-load)])
3578 ["Sort Projects"
3579 (customize-set-variable 'vhdl-project-sort (not vhdl-project-sort))
3580 :style toggle :selected vhdl-project-sort]
3581 "--"
3582 ["Customize Group..." (customize-group 'vhdl-project) t])
3583 ("Compiler"
3584 ["Compiler Setup..." (customize-option 'vhdl-compiler-alist) t]
3585 ,(append
3586 '("Selected Compiler at Startup")
3587 ;; add menu entries for defined compilers
3588 (let ((comp-alist vhdl-compiler-alist) menu-list name)
3589 (while comp-alist
3590 (setq name (caar comp-alist))
3591 (setq menu-list
3592 (cons `[,name (customize-set-variable 'vhdl-compiler ,name)
3593 :style radio :selected (equal ,name vhdl-compiler)]
3594 menu-list))
3595 (setq comp-alist (cdr comp-alist)))
3596 (setq menu-list (nreverse menu-list))
fe3c5669 3597 (vhdl-menu-split menu-list "Compiler")))
3dcb36b7
JB
3598 ["Use Local Error Regexp"
3599 (customize-set-variable 'vhdl-compile-use-local-error-regexp
3600 (not vhdl-compile-use-local-error-regexp))
3601 :style toggle :selected vhdl-compile-use-local-error-regexp]
fda91268
RZ
3602 ["Makefile Default Targets..."
3603 (customize-option 'vhdl-makefile-default-targets) t]
3dcb36b7
JB
3604 ["Makefile Generation Hook..."
3605 (customize-option 'vhdl-makefile-generation-hook) t]
3606 ["Default Library Name" (customize-option 'vhdl-default-library) t]
3607 "--"
3608 ["Customize Group..." (customize-group 'vhdl-compiler) t])
3609 ("Style"
3610 ("VHDL Standard"
3611 ["VHDL'87"
3612 (progn (customize-set-variable 'vhdl-standard
3613 (list '87 (cadr vhdl-standard)))
3614 (vhdl-activate-customizations))
3615 :style radio :selected (eq '87 (car vhdl-standard))]
fda91268 3616 ["VHDL'93/02"
3dcb36b7
JB
3617 (progn (customize-set-variable 'vhdl-standard
3618 (list '93 (cadr vhdl-standard)))
3619 (vhdl-activate-customizations))
3620 :style radio :selected (eq '93 (car vhdl-standard))]
3621 "--"
3622 ["VHDL-AMS"
3623 (progn (customize-set-variable
3624 'vhdl-standard (list (car vhdl-standard)
3625 (if (memq 'ams (cadr vhdl-standard))
3626 (delq 'ams (cadr vhdl-standard))
3627 (cons 'ams (cadr vhdl-standard)))))
3628 (vhdl-activate-customizations))
3629 :style toggle :selected (memq 'ams (cadr vhdl-standard))]
3630 ["Math Packages"
3631 (progn (customize-set-variable
3632 'vhdl-standard (list (car vhdl-standard)
3633 (if (memq 'math (cadr vhdl-standard))
3634 (delq 'math (cadr vhdl-standard))
3635 (cons 'math (cadr vhdl-standard)))))
3636 (vhdl-activate-customizations))
3637 :style toggle :selected (memq 'math (cadr vhdl-standard))])
3638 ["Indentation Offset..." (customize-option 'vhdl-basic-offset) t]
3639 ["Upper Case Keywords"
3640 (customize-set-variable 'vhdl-upper-case-keywords
3641 (not vhdl-upper-case-keywords))
3642 :style toggle :selected vhdl-upper-case-keywords]
3643 ["Upper Case Types"
3644 (customize-set-variable 'vhdl-upper-case-types
3645 (not vhdl-upper-case-types))
3646 :style toggle :selected vhdl-upper-case-types]
3647 ["Upper Case Attributes"
3648 (customize-set-variable 'vhdl-upper-case-attributes
3649 (not vhdl-upper-case-attributes))
3650 :style toggle :selected vhdl-upper-case-attributes]
3651 ["Upper Case Enumeration Values"
3652 (customize-set-variable 'vhdl-upper-case-enum-values
3653 (not vhdl-upper-case-enum-values))
3654 :style toggle :selected vhdl-upper-case-enum-values]
3655 ["Upper Case Constants"
3656 (customize-set-variable 'vhdl-upper-case-constants
3657 (not vhdl-upper-case-constants))
3658 :style toggle :selected vhdl-upper-case-constants]
3659 ("Use Direct Instantiation"
3660 ["Never"
3661 (customize-set-variable 'vhdl-use-direct-instantiation 'never)
3662 :style radio :selected (eq 'never vhdl-use-direct-instantiation)]
3663 ["Standard"
3664 (customize-set-variable 'vhdl-use-direct-instantiation 'standard)
3665 :style radio :selected (eq 'standard vhdl-use-direct-instantiation)]
3666 ["Always"
3667 (customize-set-variable 'vhdl-use-direct-instantiation 'always)
3668 :style radio :selected (eq 'always vhdl-use-direct-instantiation)])
fda91268
RZ
3669 ["Include Array Index and Record Field in Sensitivity List"
3670 (customize-set-variable 'vhdl-array-index-record-field-in-sensitivity-list
3671 (not vhdl-array-index-record-field-in-sensitivity-list))
3672 :style toggle :selected vhdl-array-index-record-field-in-sensitivity-list]
3dcb36b7
JB
3673 "--"
3674 ["Customize Group..." (customize-group 'vhdl-style) t])
3675 ("Naming"
3676 ["Entity File Name..." (customize-option 'vhdl-entity-file-name) t]
3677 ["Architecture File Name..."
3678 (customize-option 'vhdl-architecture-file-name) t]
0a2e512a
RF
3679 ["Configuration File Name..."
3680 (customize-option 'vhdl-configuration-file-name) t]
3dcb36b7
JB
3681 ["Package File Name..." (customize-option 'vhdl-package-file-name) t]
3682 ("File Name Case"
3683 ["As Is"
3684 (customize-set-variable 'vhdl-file-name-case 'identity)
3685 :style radio :selected (eq 'identity vhdl-file-name-case)]
3686 ["Lower Case"
3687 (customize-set-variable 'vhdl-file-name-case 'downcase)
3688 :style radio :selected (eq 'downcase vhdl-file-name-case)]
3689 ["Upper Case"
3690 (customize-set-variable 'vhdl-file-name-case 'upcase)
3691 :style radio :selected (eq 'upcase vhdl-file-name-case)]
3692 ["Capitalize"
3693 (customize-set-variable 'vhdl-file-name-case 'capitalize)
3694 :style radio :selected (eq 'capitalize vhdl-file-name-case)])
3695 "--"
3696 ["Customize Group..." (customize-group 'vhdl-naming) t])
3697 ("Template"
3698 ("Electric Keywords"
3699 ["VHDL Keywords"
3700 (customize-set-variable 'vhdl-electric-keywords
3701 (if (memq 'vhdl vhdl-electric-keywords)
3702 (delq 'vhdl vhdl-electric-keywords)
3703 (cons 'vhdl vhdl-electric-keywords)))
3704 :style toggle :selected (memq 'vhdl vhdl-electric-keywords)]
3705 ["User Model Keywords"
3706 (customize-set-variable 'vhdl-electric-keywords
3707 (if (memq 'user vhdl-electric-keywords)
3708 (delq 'user vhdl-electric-keywords)
3709 (cons 'user vhdl-electric-keywords)))
3710 :style toggle :selected (memq 'user vhdl-electric-keywords)])
3711 ("Insert Optional Labels"
3712 ["None"
3713 (customize-set-variable 'vhdl-optional-labels 'none)
3714 :style radio :selected (eq 'none vhdl-optional-labels)]
3715 ["Processes Only"
3716 (customize-set-variable 'vhdl-optional-labels 'process)
3717 :style radio :selected (eq 'process vhdl-optional-labels)]
3718 ["All Constructs"
3719 (customize-set-variable 'vhdl-optional-labels 'all)
3720 :style radio :selected (eq 'all vhdl-optional-labels)])
3721 ("Insert Empty Lines"
3722 ["None"
3723 (customize-set-variable 'vhdl-insert-empty-lines 'none)
3724 :style radio :selected (eq 'none vhdl-insert-empty-lines)]
3725 ["Design Units Only"
3726 (customize-set-variable 'vhdl-insert-empty-lines 'unit)
3727 :style radio :selected (eq 'unit vhdl-insert-empty-lines)]
3728 ["All Constructs"
3729 (customize-set-variable 'vhdl-insert-empty-lines 'all)
3730 :style radio :selected (eq 'all vhdl-insert-empty-lines)])
3731 ["Argument List Indent"
3732 (customize-set-variable 'vhdl-argument-list-indent
3733 (not vhdl-argument-list-indent))
3734 :style toggle :selected vhdl-argument-list-indent]
3735 ["Association List with Formals"
3736 (customize-set-variable 'vhdl-association-list-with-formals
3737 (not vhdl-association-list-with-formals))
3738 :style toggle :selected vhdl-association-list-with-formals]
3739 ["Conditions in Parenthesis"
3740 (customize-set-variable 'vhdl-conditions-in-parenthesis
3741 (not vhdl-conditions-in-parenthesis))
3742 :style toggle :selected vhdl-conditions-in-parenthesis]
3743 ["Zero String..." (customize-option 'vhdl-zero-string) t]
3744 ["One String..." (customize-option 'vhdl-one-string) t]
3745 ("File Header"
3746 ["Header String..." (customize-option 'vhdl-file-header) t]
3747 ["Footer String..." (customize-option 'vhdl-file-footer) t]
3748 ["Company Name..." (customize-option 'vhdl-company-name) t]
3749 ["Copyright String..." (customize-option 'vhdl-copyright-string) t]
3750 ["Platform Specification..." (customize-option 'vhdl-platform-spec) t]
3751 ["Date Format..." (customize-option 'vhdl-date-format) t]
3752 ["Modify Date Prefix String..."
3753 (customize-option 'vhdl-modify-date-prefix-string) t]
3754 ["Modify Date on Saving"
3755 (progn (customize-set-variable 'vhdl-modify-date-on-saving
3756 (not vhdl-modify-date-on-saving))
3757 (vhdl-activate-customizations))
3758 :style toggle :selected vhdl-modify-date-on-saving])
3759 ("Sequential Process"
3760 ("Kind of Reset"
3761 ["None"
3762 (customize-set-variable 'vhdl-reset-kind 'none)
3763 :style radio :selected (eq 'none vhdl-reset-kind)]
3764 ["Synchronous"
3765 (customize-set-variable 'vhdl-reset-kind 'sync)
3766 :style radio :selected (eq 'sync vhdl-reset-kind)]
3767 ["Asynchronous"
3768 (customize-set-variable 'vhdl-reset-kind 'async)
fda91268
RZ
3769 :style radio :selected (eq 'async vhdl-reset-kind)]
3770 ["Query"
3771 (customize-set-variable 'vhdl-reset-kind 'query)
3772 :style radio :selected (eq 'query vhdl-reset-kind)])
3dcb36b7
JB
3773 ["Reset is Active High"
3774 (customize-set-variable 'vhdl-reset-active-high
3775 (not vhdl-reset-active-high))
3776 :style toggle :selected vhdl-reset-active-high]
3777 ["Use Rising Clock Edge"
3778 (customize-set-variable 'vhdl-clock-rising-edge
3779 (not vhdl-clock-rising-edge))
3780 :style toggle :selected vhdl-clock-rising-edge]
3781 ("Clock Edge Condition"
3782 ["Standard"
3783 (customize-set-variable 'vhdl-clock-edge-condition 'standard)
3784 :style radio :selected (eq 'standard vhdl-clock-edge-condition)]
3785 ["Function \"rising_edge\""
3786 (customize-set-variable 'vhdl-clock-edge-condition 'function)
3787 :style radio :selected (eq 'function vhdl-clock-edge-condition)])
3788 ["Clock Name..." (customize-option 'vhdl-clock-name) t]
3789 ["Reset Name..." (customize-option 'vhdl-reset-name) t])
3790 "--"
3791 ["Customize Group..." (customize-group 'vhdl-template) t])
3792 ("Model"
3793 ["Model Definition..." (customize-option 'vhdl-model-alist) t])
3794 ("Port"
3795 ["Include Port Comments"
3796 (customize-set-variable 'vhdl-include-port-comments
3797 (not vhdl-include-port-comments))
3798 :style toggle :selected vhdl-include-port-comments]
3799 ["Include Direction Comments"
3800 (customize-set-variable 'vhdl-include-direction-comments
3801 (not vhdl-include-direction-comments))
3802 :style toggle :selected vhdl-include-direction-comments]
3803 ["Include Type Comments"
3804 (customize-set-variable 'vhdl-include-type-comments
3805 (not vhdl-include-type-comments))
3806 :style toggle :selected vhdl-include-type-comments]
3807 ("Include Group Comments"
3808 ["Never"
3809 (customize-set-variable 'vhdl-include-group-comments 'never)
3810 :style radio :selected (eq 'never vhdl-include-group-comments)]
3811 ["Declarations"
3812 (customize-set-variable 'vhdl-include-group-comments 'decl)
3813 :style radio :selected (eq 'decl vhdl-include-group-comments)]
3814 ["Always"
3815 (customize-set-variable 'vhdl-include-group-comments 'always)
3816 :style radio :selected (eq 'always vhdl-include-group-comments)])
3817 ["Actual Port Name..." (customize-option 'vhdl-actual-port-name) t]
3818 ["Instance Name..." (customize-option 'vhdl-instance-name) t]
3819 ("Testbench"
3820 ["Entity Name..." (customize-option 'vhdl-testbench-entity-name) t]
3821 ["Architecture Name..."
3822 (customize-option 'vhdl-testbench-architecture-name) t]
3823 ["Configuration Name..."
3824 (customize-option 'vhdl-testbench-configuration-name) t]
3825 ["DUT Name..." (customize-option 'vhdl-testbench-dut-name) t]
3826 ["Include Header"
3827 (customize-set-variable 'vhdl-testbench-include-header
3828 (not vhdl-testbench-include-header))
3829 :style toggle :selected vhdl-testbench-include-header]
3830 ["Declarations..." (customize-option 'vhdl-testbench-declarations) t]
3831 ["Statements..." (customize-option 'vhdl-testbench-statements) t]
3832 ["Initialize Signals"
3833 (customize-set-variable 'vhdl-testbench-initialize-signals
3834 (not vhdl-testbench-initialize-signals))
3835 :style toggle :selected vhdl-testbench-initialize-signals]
3836 ["Include Library Clause"
3837 (customize-set-variable 'vhdl-testbench-include-library
3838 (not vhdl-testbench-include-library))
3839 :style toggle :selected vhdl-testbench-include-library]
3840 ["Include Configuration"
3841 (customize-set-variable 'vhdl-testbench-include-configuration
3842 (not vhdl-testbench-include-configuration))
3843 :style toggle :selected vhdl-testbench-include-configuration]
3844 ("Create Files"
3845 ["None"
3846 (customize-set-variable 'vhdl-testbench-create-files 'none)
3847 :style radio :selected (eq 'none vhdl-testbench-create-files)]
3848 ["Single"
3849 (customize-set-variable 'vhdl-testbench-create-files 'single)
3850 :style radio :selected (eq 'single vhdl-testbench-create-files)]
3851 ["Separate"
3852 (customize-set-variable 'vhdl-testbench-create-files 'separate)
0a2e512a
RF
3853 :style radio :selected (eq 'separate vhdl-testbench-create-files)])
3854 ["Testbench Entity File Name..."
3855 (customize-option 'vhdl-testbench-entity-file-name) t]
3856 ["Testbench Architecture File Name..."
3857 (customize-option 'vhdl-testbench-architecture-file-name) t])
3dcb36b7
JB
3858 "--"
3859 ["Customize Group..." (customize-group 'vhdl-port) t])
3860 ("Compose"
0a2e512a
RF
3861 ["Architecture Name..."
3862 (customize-option 'vhdl-compose-architecture-name) t]
3863 ["Configuration Name..."
3864 (customize-option 'vhdl-compose-configuration-name) t]
3865 ["Components Package Name..."
3866 (customize-option 'vhdl-components-package-name) t]
3867 ["Use Components Package"
3868 (customize-set-variable 'vhdl-use-components-package
3869 (not vhdl-use-components-package))
3870 :style toggle :selected vhdl-use-components-package]
3871 ["Include Header"
3872 (customize-set-variable 'vhdl-compose-include-header
3873 (not vhdl-compose-include-header))
3874 :style toggle :selected vhdl-compose-include-header]
3875 ("Create Entity/Architecture Files"
3dcb36b7
JB
3876 ["None"
3877 (customize-set-variable 'vhdl-compose-create-files 'none)
3878 :style radio :selected (eq 'none vhdl-compose-create-files)]
3879 ["Single"
3880 (customize-set-variable 'vhdl-compose-create-files 'single)
3881 :style radio :selected (eq 'single vhdl-compose-create-files)]
3882 ["Separate"
3883 (customize-set-variable 'vhdl-compose-create-files 'separate)
3884 :style radio :selected (eq 'separate vhdl-compose-create-files)])
0a2e512a
RF
3885 ["Create Configuration File"
3886 (customize-set-variable 'vhdl-compose-configuration-create-file
3887 (not vhdl-compose-configuration-create-file))
3888 :style toggle :selected vhdl-compose-configuration-create-file]
3889 ["Hierarchical Configuration"
3890 (customize-set-variable 'vhdl-compose-configuration-hierarchical
3891 (not vhdl-compose-configuration-hierarchical))
3892 :style toggle :selected vhdl-compose-configuration-hierarchical]
3893 ["Use Subconfiguration"
3894 (customize-set-variable 'vhdl-compose-configuration-use-subconfiguration
3895 (not vhdl-compose-configuration-use-subconfiguration))
3896 :style toggle :selected vhdl-compose-configuration-use-subconfiguration]
3dcb36b7
JB
3897 "--"
3898 ["Customize Group..." (customize-group 'vhdl-compose) t])
3899 ("Comment"
3900 ["Self Insert Comments"
3901 (customize-set-variable 'vhdl-self-insert-comments
3902 (not vhdl-self-insert-comments))
3903 :style toggle :selected vhdl-self-insert-comments]
3904 ["Prompt for Comments"
3905 (customize-set-variable 'vhdl-prompt-for-comments
3906 (not vhdl-prompt-for-comments))
3907 :style toggle :selected vhdl-prompt-for-comments]
3908 ["Inline Comment Column..."
3909 (customize-option 'vhdl-inline-comment-column) t]
3910 ["End Comment Column..." (customize-option 'vhdl-end-comment-column) t]
3911 "--"
3912 ["Customize Group..." (customize-group 'vhdl-comment) t])
3913 ("Align"
3914 ["Auto Align Templates"
3915 (customize-set-variable 'vhdl-auto-align (not vhdl-auto-align))
3916 :style toggle :selected vhdl-auto-align]
3917 ["Align Line Groups"
3918 (customize-set-variable 'vhdl-align-groups (not vhdl-align-groups))
3919 :style toggle :selected vhdl-align-groups]
3920 ["Group Separation String..."
3921 (customize-set-variable 'vhdl-align-group-separate) t]
3922 ["Align Lines with Same Indent"
3923 (customize-set-variable 'vhdl-align-same-indent
3924 (not vhdl-align-same-indent))
3925 :style toggle :selected vhdl-align-same-indent]
3926 "--"
3927 ["Customize Group..." (customize-group 'vhdl-align) t])
3928 ("Highlight"
3929 ["Highlighting On/Off..."
3930 (customize-option
4bcb9c95
SM
3931 (if (fboundp 'global-font-lock-mode)
3932 'global-font-lock-mode 'font-lock-auto-fontify)) t]
3dcb36b7
JB
3933 ["Highlight Keywords"
3934 (progn (customize-set-variable 'vhdl-highlight-keywords
3935 (not vhdl-highlight-keywords))
3936 (vhdl-fontify-buffer))
3937 :style toggle :selected vhdl-highlight-keywords]
3938 ["Highlight Names"
3939 (progn (customize-set-variable 'vhdl-highlight-names
3940 (not vhdl-highlight-names))
3941 (vhdl-fontify-buffer))
3942 :style toggle :selected vhdl-highlight-names]
3943 ["Highlight Special Words"
3944 (progn (customize-set-variable 'vhdl-highlight-special-words
3945 (not vhdl-highlight-special-words))
3946 (vhdl-fontify-buffer))
3947 :style toggle :selected vhdl-highlight-special-words]
3948 ["Highlight Forbidden Words"
3949 (progn (customize-set-variable 'vhdl-highlight-forbidden-words
3950 (not vhdl-highlight-forbidden-words))
3951 (vhdl-fontify-buffer))
3952 :style toggle :selected vhdl-highlight-forbidden-words]
3953 ["Highlight Verilog Keywords"
3954 (progn (customize-set-variable 'vhdl-highlight-verilog-keywords
3955 (not vhdl-highlight-verilog-keywords))
3956 (vhdl-fontify-buffer))
3957 :style toggle :selected vhdl-highlight-verilog-keywords]
3958 ["Highlight \"translate_off\""
3959 (progn (customize-set-variable 'vhdl-highlight-translate-off
3960 (not vhdl-highlight-translate-off))
3961 (vhdl-fontify-buffer))
3962 :style toggle :selected vhdl-highlight-translate-off]
3963 ["Case Sensitive Highlighting"
3964 (progn (customize-set-variable 'vhdl-highlight-case-sensitive
3965 (not vhdl-highlight-case-sensitive))
3966 (vhdl-fontify-buffer))
3967 :style toggle :selected vhdl-highlight-case-sensitive]
3968 ["Special Syntax Definition..."
3969 (customize-option 'vhdl-special-syntax-alist) t]
3970 ["Forbidden Words..." (customize-option 'vhdl-forbidden-words) t]
3971 ["Forbidden Syntax..." (customize-option 'vhdl-forbidden-syntax) t]
3972 ["Directive Keywords..." (customize-option 'vhdl-directive-keywords) t]
3973 ["Colors..." (customize-group 'vhdl-highlight-faces) t]
3974 "--"
3975 ["Customize Group..." (customize-group 'vhdl-highlight) t])
3976 ("Speedbar"
3977 ["Auto Open at Startup"
3978 (customize-set-variable 'vhdl-speedbar-auto-open
3979 (not vhdl-speedbar-auto-open))
3980 :style toggle :selected vhdl-speedbar-auto-open]
3981 ("Default Displaying Mode"
3982 ["Files"
3983 (customize-set-variable 'vhdl-speedbar-display-mode 'files)
3984 :style radio :selected (eq 'files vhdl-speedbar-display-mode)]
3985 ["Directory Hierarchy"
3986 (customize-set-variable 'vhdl-speedbar-display-mode 'directory)
3987 :style radio :selected (eq 'directory vhdl-speedbar-display-mode)]
3988 ["Project Hierarchy"
3989 (customize-set-variable 'vhdl-speedbar-display-mode 'project)
3990 :style radio :selected (eq 'project vhdl-speedbar-display-mode)])
3991 ["Indentation Offset..."
3992 (customize-option 'speedbar-indentation-width) t]
3993 ["Scan Size Limits..." (customize-option 'vhdl-speedbar-scan-limit) t]
3994 ["Jump to Unit when Opening"
3995 (customize-set-variable 'vhdl-speedbar-jump-to-unit
3996 (not vhdl-speedbar-jump-to-unit))
3997 :style toggle :selected vhdl-speedbar-jump-to-unit]
3998 ["Update Hierarchy on File Saving"
3999 (customize-set-variable 'vhdl-speedbar-update-on-saving
4000 (not vhdl-speedbar-update-on-saving))
4001 :style toggle :selected vhdl-speedbar-update-on-saving]
4002 ("Save in Cache File"
4003 ["Hierarchy Information"
4004 (customize-set-variable 'vhdl-speedbar-save-cache
4005 (if (memq 'hierarchy vhdl-speedbar-save-cache)
4006 (delq 'hierarchy vhdl-speedbar-save-cache)
4007 (cons 'hierarchy vhdl-speedbar-save-cache)))
4008 :style toggle :selected (memq 'hierarchy vhdl-speedbar-save-cache)]
4009 ["Displaying Status"
4010 (customize-set-variable 'vhdl-speedbar-save-cache
4011 (if (memq 'display vhdl-speedbar-save-cache)
4012 (delq 'display vhdl-speedbar-save-cache)
4013 (cons 'display vhdl-speedbar-save-cache)))
4014 :style toggle :selected (memq 'display vhdl-speedbar-save-cache)])
4015 ["Cache File Name..."
4016 (customize-option 'vhdl-speedbar-cache-file-name) t]
4017 "--"
4018 ["Customize Group..." (customize-group 'vhdl-speedbar) t])
4019 ("Menu"
4020 ["Add Index Menu when Loading File"
4021 (progn (customize-set-variable 'vhdl-index-menu (not vhdl-index-menu))
4022 (vhdl-index-menu-init))
4023 :style toggle :selected vhdl-index-menu]
4024 ["Add Source File Menu when Loading File"
4025 (progn (customize-set-variable 'vhdl-source-file-menu
4026 (not vhdl-source-file-menu))
4027 (vhdl-add-source-files-menu))
4028 :style toggle :selected vhdl-source-file-menu]
4029 ["Add Hideshow Menu at Startup"
4030 (progn (customize-set-variable 'vhdl-hideshow-menu
4031 (not vhdl-hideshow-menu))
4032 (vhdl-activate-customizations))
4033 :style toggle :selected vhdl-hideshow-menu]
4034 ["Hide Everything Initially"
4035 (customize-set-variable 'vhdl-hide-all-init (not vhdl-hide-all-init))
4036 :style toggle :selected vhdl-hide-all-init]
4037 "--"
4038 ["Customize Group..." (customize-group 'vhdl-menu) t])
4039 ("Print"
4040 ["In Two Column Format"
4041 (progn (customize-set-variable 'vhdl-print-two-column
4042 (not vhdl-print-two-column))
4043 (message "Activate new setting by saving options and restarting Emacs"))
4044 :style toggle :selected vhdl-print-two-column]
4045 ["Use Customized Faces"
4046 (progn (customize-set-variable 'vhdl-print-customize-faces
4047 (not vhdl-print-customize-faces))
4048 (message "Activate new setting by saving options and restarting Emacs"))
4049 :style toggle :selected vhdl-print-customize-faces]
4050 "--"
4051 ["Customize Group..." (customize-group 'vhdl-print) t])
4052 ("Miscellaneous"
4053 ["Use Intelligent Tab"
4054 (progn (customize-set-variable 'vhdl-intelligent-tab
4055 (not vhdl-intelligent-tab))
4056 (vhdl-activate-customizations))
4057 :style toggle :selected vhdl-intelligent-tab]
4058 ["Indent Syntax-Based"
4059 (customize-set-variable 'vhdl-indent-syntax-based
4060 (not vhdl-indent-syntax-based))
4061 :style toggle :selected vhdl-indent-syntax-based]
fda91268
RZ
4062 ["Indent Comments Like Next Code Line"
4063 (customize-set-variable 'vhdl-indent-comment-like-next-code-line
4064 (not vhdl-indent-comment-like-next-code-line))
4065 :style toggle :selected vhdl-indent-comment-like-next-code-line]
3dcb36b7
JB
4066 ["Word Completion is Case Sensitive"
4067 (customize-set-variable 'vhdl-word-completion-case-sensitive
4068 (not vhdl-word-completion-case-sensitive))
4069 :style toggle :selected vhdl-word-completion-case-sensitive]
4070 ["Word Completion in Minibuffer"
4071 (progn (customize-set-variable 'vhdl-word-completion-in-minibuffer
4072 (not vhdl-word-completion-in-minibuffer))
4073 (message "Activate new setting by saving options and restarting Emacs"))
4074 :style toggle :selected vhdl-word-completion-in-minibuffer]
4075 ["Underscore is Part of Word"
4076 (progn (customize-set-variable 'vhdl-underscore-is-part-of-word
4077 (not vhdl-underscore-is-part-of-word))
4078 (vhdl-activate-customizations))
4079 :style toggle :selected vhdl-underscore-is-part-of-word]
4080 "--"
4081 ["Customize Group..." (customize-group 'vhdl-misc) t])
4082 ["Related..." (customize-browse 'vhdl-related) t]
d2ddb974 4083 "--"
3dcb36b7
JB
4084 ["Save Options" customize-save-customized t]
4085 ["Activate Options" vhdl-activate-customizations t]
4086 ["Browse Options..." vhdl-customize t])))
5eabfe72
KH
4087
4088(defvar vhdl-mode-menu-list (vhdl-create-mode-menu)
4089 "VHDL Mode menu.")
4090
4091(defun vhdl-update-mode-menu ()
3dcb36b7 4092 "Update VHDL Mode menu."
5eabfe72
KH
4093 (interactive)
4094 (easy-menu-remove vhdl-mode-menu-list) ; for XEmacs
4095 (setq vhdl-mode-menu-list (vhdl-create-mode-menu))
4096 (easy-menu-add vhdl-mode-menu-list) ; for XEmacs
4097 (easy-menu-define vhdl-mode-menu vhdl-mode-map
4098 "Menu keymap for VHDL Mode." vhdl-mode-menu-list))
d2ddb974 4099
5eabfe72
KH
4100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4101;; Index menu (using `imenu.el'), also used for speedbar (using `speedbar.el')
d2ddb974 4102
3dcb36b7 4103(defconst vhdl-imenu-generic-expression
d2ddb974 4104 '(
5eabfe72
KH
4105 ("Subprogram"
4106 "^\\s-*\\(\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\)\\s-+\\(\"?\\(\\w\\|\\s_\\)+\"?\\)"
4107 4)
4108 ("Instance"
fda91268 4109 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\s-*:\\(\\s-\\|\n\\)*\\(entity\\s-+\\(\\w\\|\\s_\\)+\\.\\)?\\(\\w\\|\\s_\\)+\\)\\(\\s-\\|\n\\)+\\(generic\\|port\\)\\s-+map\\>"
5eabfe72
KH
4110 1)
4111 ("Component"
4112 "^\\s-*\\(component\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
d2ddb974 4113 2)
5eabfe72
KH
4114 ("Procedural"
4115 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(procedural\\)"
4116 1)
4117 ("Process"
4118 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(\\(postponed\\s-+\\|\\)process\\)"
4119 1)
4120 ("Block"
4121 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(block\\)"
4122 1)
4123 ("Package"
4124 "^\\s-*\\(package\\( body\\|\\)\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
4125 3)
d2ddb974
KH
4126 ("Configuration"
4127 "^\\s-*\\(configuration\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)"
4128 2)
5eabfe72
KH
4129 ("Architecture"
4130 "^\\s-*\\(architecture\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)"
d2ddb974 4131 2)
5eabfe72
KH
4132 ("Entity"
4133 "^\\s-*\\(entity\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
d2ddb974 4134 2)
d2ddb974
KH
4135 )
4136 "Imenu generic expression for VHDL Mode. See `imenu-generic-expression'.")
4137
5eabfe72
KH
4138(defun vhdl-index-menu-init ()
4139 "Initialize index menu."
4140 (set (make-local-variable 'imenu-case-fold-search) t)
4141 (set (make-local-variable 'imenu-generic-expression)
4142 vhdl-imenu-generic-expression)
3dcb36b7 4143 (when (and vhdl-index-menu (fboundp 'imenu))
20367d28 4144 (imenu-add-to-menubar "Index")))
d2ddb974 4145
3dcb36b7 4146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
4147;; Source file menu (using `easy-menu.el')
4148
5eabfe72
KH
4149(defvar vhdl-sources-menu nil)
4150
4151(defun vhdl-directory-files (directory &optional full match)
4152 "Call `directory-files' if DIRECTORY exists, otherwise generate error
4153message."
3dcb36b7
JB
4154 (if (not (file-directory-p directory))
4155 (vhdl-warning-when-idle "No such directory: \"%s\"" directory)
4156 (let ((dir (directory-files directory full match)))
4157 (setq dir (delete "." dir))
4158 (setq dir (delete ".." dir))
4159 dir)))
5eabfe72
KH
4160
4161(defun vhdl-get-source-files (&optional full directory)
4162 "Get list of VHDL source files in DIRECTORY or current directory."
4163 (let ((mode-alist auto-mode-alist)
4164 filename-regexp)
4165 ;; create regular expressions for matching file names
3dcb36b7 4166 (setq filename-regexp "\\`[^.].*\\(")
5eabfe72 4167 (while mode-alist
3dcb36b7 4168 (when (eq (cdar mode-alist) 'vhdl-mode)
5eabfe72 4169 (setq filename-regexp
3dcb36b7 4170 (concat filename-regexp (caar mode-alist) "\\|")))
5eabfe72
KH
4171 (setq mode-alist (cdr mode-alist)))
4172 (setq filename-regexp
4173 (concat (substring filename-regexp 0
4174 (string-match "\\\\|$" filename-regexp)) "\\)"))
4175 ;; find files
3dcb36b7
JB
4176 (vhdl-directory-files
4177 (or directory default-directory) full filename-regexp)))
d2ddb974
KH
4178
4179(defun vhdl-add-source-files-menu ()
5eabfe72
KH
4180 "Scan directory for all VHDL source files and generate menu.
4181The directory of the current source file is scanned."
d2ddb974
KH
4182 (interactive)
4183 (message "Scanning directory for source files ...")
5eabfe72 4184 (let ((newmap (current-local-map))
5eabfe72
KH
4185 (file-list (vhdl-get-source-files))
4186 menu-list found)
4187 ;; Create list for menu
4188 (setq found nil)
4189 (while file-list
4190 (setq found t)
4191 (setq menu-list (cons (vector (car file-list)
4192 (list 'find-file (car file-list)) t)
4193 menu-list))
4194 (setq file-list (cdr file-list)))
3dcb36b7 4195 (setq menu-list (vhdl-menu-split menu-list "Sources"))
5eabfe72
KH
4196 (when found (setq menu-list (cons "--" menu-list)))
4197 (setq menu-list (cons ["*Rescan*" vhdl-add-source-files-menu t] menu-list))
4198 (setq menu-list (cons "Sources" menu-list))
d2ddb974 4199 ;; Create menu
5eabfe72
KH
4200 (easy-menu-add menu-list)
4201 (easy-menu-define vhdl-sources-menu newmap
4202 "VHDL source files menu" menu-list))
d2ddb974
KH
4203 (message ""))
4204
d2ddb974 4205
5eabfe72 4206;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 4207;;; Mode definition
5eabfe72
KH
4208;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4209;; performs all buffer local initializations
4210
1c36bac6 4211;;;###autoload
175069ef
SM
4212(define-derived-mode vhdl-mode prog-mode
4213 '("VHDL" (vhdl-electric-mode "/" (vhdl-stutter-mode "/"))
4214 (vhdl-electric-mode "e")
4215 (vhdl-stutter-mode "s"))
d2ddb974
KH
4216 "Major mode for editing VHDL code.
4217
4218Usage:
4219------
4220
3dcb36b7
JB
4221 TEMPLATE INSERTION (electrification):
4222 After typing a VHDL keyword and entering `SPC', you are prompted for
4223 arguments while a template is generated for that VHDL construct. Typing
4224 `RET' or `C-g' at the first \(mandatory) prompt aborts the current
4225 template generation. Optional arguments are indicated by square
4226 brackets and removed if the queried string is left empty. Prompts for
4227 mandatory arguments remain in the code if the queried string is left
4228 empty. They can be queried again by `C-c C-t C-q'. Enabled
37269466 4229 electrification is indicated by `/e' in the mode line.
3dcb36b7
JB
4230
4231 Typing `M-SPC' after a keyword inserts a space without calling the
4232 template generator. Automatic template generation (i.e.
4233 electrification) can be disabled (enabled) by typing `C-c C-m C-e' or by
4234 setting option `vhdl-electric-mode' (see OPTIONS).
4235
4236 Template generators can be invoked from the VHDL menu, by key
4237 bindings, by typing `C-c C-i C-c' and choosing a construct, or by typing
4238 the keyword (i.e. first word of menu entry not in parenthesis) and
4239 `SPC'. The following abbreviations can also be used: arch, attr, cond,
4240 conf, comp, cons, func, inst, pack, sig, var.
4241
4242 Template styles can be customized in customization group
4243 `vhdl-template' \(see OPTIONS).
4244
4245
4246 HEADER INSERTION:
4247 A file header can be inserted by `C-c C-t C-h'. A file footer
4248 (template at the end of the file) can be inserted by `C-c C-t C-f'.
4249 See customization group `vhdl-header'.
4250
4251
4252 STUTTERING:
4253 Double striking of some keys inserts cumbersome VHDL syntax elements.
4254 Stuttering can be disabled (enabled) by typing `C-c C-m C-s' or by
4255 option `vhdl-stutter-mode'. Enabled stuttering is indicated by `/s' in
37269466 4256 the mode line. The stuttering keys and their effects are:
3dcb36b7
JB
4257
4258 ;; --> \" : \" [ --> ( -- --> comment
4259 ;;; --> \" := \" [[ --> [ --CR --> comment-out code
4260 .. --> \" => \" ] --> ) --- --> horizontal line
4261 ,, --> \" <= \" ]] --> ] ---- --> display comment
4262 == --> \" == \" '' --> \\\"
4263
4264
4265 WORD COMPLETION:
4266 Typing `TAB' after a (not completed) word looks for a VHDL keyword or a
4267 word in the buffer that starts alike, inserts it and adjusts case.
4268 Re-typing `TAB' toggles through alternative word completions. This also
4269 works in the minibuffer (i.e. in template generator prompts).
4270
4271 Typing `TAB' after `(' looks for and inserts complete parenthesized
4272 expressions (e.g. for array index ranges). All keywords as well as
4273 standard types and subprograms of VHDL have predefined abbreviations
4274 \(e.g. type \"std\" and `TAB' will toggle through all standard types
4275 beginning with \"std\").
4276
4277 Typing `TAB' after a non-word character indents the line if at the
4278 beginning of a line (i.e. no preceding non-blank characters), and
4279 inserts a tabulator stop otherwise. `M-TAB' always inserts a tabulator
4280 stop.
4281
4282
4283 COMMENTS:
4284 `--' puts a single comment.
4285 `---' draws a horizontal line for separating code segments.
4286 `----' inserts a display comment, i.e. two horizontal lines
4287 with a comment in between.
4288 `--CR' comments out code on that line. Re-hitting CR comments
4289 out following lines.
fda91268
RZ
4290 `C-c C-c' comments out a region if not commented out,
4291 uncomments a region if already commented out. Option
4292 `comment-style' defines where the comment characters
4293 should be placed (beginning of line, indent, etc.).
3dcb36b7
JB
4294
4295 You are prompted for comments after object definitions (i.e. signals,
4296 variables, constants, ports) and after subprogram and process
4297 specifications if option `vhdl-prompt-for-comments' is non-nil.
4298 Comments are automatically inserted as additional labels (e.g. after
4299 begin statements) and as help comments if `vhdl-self-insert-comments' is
4300 non-nil.
4301
4302 Inline comments (i.e. comments after a piece of code on the same line)
4303 are indented at least to `vhdl-inline-comment-column'. Comments go at
4304 maximum to `vhdl-end-comment-column'. `RET' after a space in a comment
4305 will open a new comment line. Typing beyond `vhdl-end-comment-column'
4306 in a comment automatically opens a new comment line. `M-q' re-fills
4307 multi-line comments.
4308
4309
4310 INDENTATION:
4311 `TAB' indents a line if at the beginning of the line. The amount of
4312 indentation is specified by option `vhdl-basic-offset'. `C-c C-i C-l'
4313 always indents the current line (is bound to `TAB' if option
fda91268
RZ
4314 `vhdl-intelligent-tab' is nil). If a region is active, `TAB' indents
4315 the entire region.
3dcb36b7
JB
4316
4317 Indentation can be done for a group of lines (`C-c C-i C-g'), a region
4318 \(`M-C-\\') or the entire buffer (menu). Argument and port lists are
4319 indented normally (nil) or relative to the opening parenthesis (non-nil)
4320 according to option `vhdl-argument-list-indent'.
4321
4322 If option `vhdl-indent-tabs-mode' is nil, spaces are used instead of
4323 tabs. `M-x tabify' and `M-x untabify' allow to convert spaces to tabs
4324 and vice versa.
4325
4326 Syntax-based indentation can be very slow in large files. Option
4327 `vhdl-indent-syntax-based' allows to use faster but simpler indentation.
4328
fda91268
RZ
4329 Option `vhdl-indent-comment-like-next-code-line' controls whether
4330 comment lines are indented like the preceding or like the following code
4331 line.
4332
3dcb36b7
JB
4333
4334 ALIGNMENT:
4335 The alignment functions align operators, keywords, and inline comments
4336 to beautify the code. `C-c C-a C-a' aligns a group of consecutive lines
4337 separated by blank lines, `C-c C-a C-i' a block of lines with same
4338 indent. `C-c C-a C-l' aligns all lines belonging to a list enclosed by
4339 a pair of parentheses (e.g. port clause/map, argument list), and `C-c
4340 C-a C-d' all lines within the declarative part of a design unit. `C-c
4341 C-a M-a' aligns an entire region. `C-c C-a C-c' aligns inline comments
4342 for a group of lines, and `C-c C-a M-c' for a region.
4343
4344 If option `vhdl-align-groups' is non-nil, groups of code lines
4345 separated by special lines (see option `vhdl-align-group-separate') are
4346 aligned individually. If option `vhdl-align-same-indent' is non-nil,
4347 blocks of lines with same indent are aligned separately. Some templates
4348 are automatically aligned after generation if option `vhdl-auto-align'
4349 is non-nil.
4350
4351 Alignment tries to align inline comments at
4352 `vhdl-inline-comment-column' and tries inline comment not to exceed
4353 `vhdl-end-comment-column'.
4354
4355 `C-c C-x M-w' fixes up whitespace in a region. That is, operator
4356 symbols are surrounded by one space, and multiple spaces are eliminated.
4357
4358
0a2e512a
RF
4359 CODE FILLING:
4360 Code filling allows to condense code (e.g. sensitivity lists or port
4361 maps) by removing comments and newlines and re-wrapping so that all
4362 lines are maximally filled (block filling). `C-c C-f C-f' fills a list
4363 enclosed by parenthesis, `C-c C-f C-g' a group of lines separated by
4364 blank lines, `C-c C-f C-i' a block of lines with same indent, and
4365 `C-c C-f M-f' an entire region.
3dcb36b7
JB
4366
4367
4368 CODE BEAUTIFICATION:
4369 `C-c M-b' and `C-c C-b' beautify the code of a region or of the entire
fa463103 4370 buffer respectively. This includes indentation, alignment, and case
3dcb36b7
JB
4371 fixing. Code beautification can also be run non-interactively using the
4372 command:
4373
4374 emacs -batch -l ~/.emacs filename.vhd -f vhdl-beautify-buffer
4375
4376
4377 PORT TRANSLATION:
4378 Generic and port clauses from entity or component declarations can be
4379 copied (`C-c C-p C-w') and pasted as entity and component declarations,
4380 as component instantiations and corresponding internal constants and
4381 signals, as a generic map with constants as actual generics, and as
4382 internal signal initializations (menu).
4383
4384 To include formals in component instantiations, see option
4385 `vhdl-association-list-with-formals'. To include comments in pasting,
4386 see options `vhdl-include-...-comments'.
4387
4388 A clause with several generic/port names on the same line can be
4389 flattened (`C-c C-p C-f') so that only one name per line exists. The
0a2e512a
RF
4390 direction of ports can be reversed (`C-c C-p C-r'), i.e., inputs become
4391 outputs and vice versa, which can be useful in testbenches. (This
4392 reversion is done on the internal data structure and is only reflected
4393 in subsequent paste operations.)
3dcb36b7
JB
4394
4395 Names for actual ports, instances, testbenches, and
4396 design-under-test instances can be derived from existing names according
4397 to options `vhdl-...-name'. See customization group `vhdl-port'.
4398
4399
0a2e512a
RF
4400 SUBPROGRAM TRANSLATION:
4401 Similar functionality exists for copying/pasting the interface of
4402 subprograms (function/procedure). A subprogram interface can be copied
4403 and then pasted as a subprogram declaration, body or call (uses
4404 association list with formals).
3dcb36b7
JB
4405
4406
4407 TESTBENCH GENERATION:
4408 A copied port can also be pasted as a testbench. The generated
4409 testbench includes an entity, an architecture, and an optional
4410 configuration. The architecture contains the component declaration and
4411 instantiation of the DUT as well as internal constant and signal
4412 declarations. Additional user-defined templates can be inserted. The
4413 names used for entity/architecture/configuration/DUT as well as the file
4414 structure to be generated can be customized. See customization group
4415 `vhdl-testbench'.
4416
4417
4418 KEY BINDINGS:
4419 Key bindings (`C-c ...') exist for most commands (see in menu).
4420
4421
4422 VHDL MENU:
4423 All commands can be found in the VHDL menu including their key bindings.
4424
4425
4426 FILE BROWSER:
4427 The speedbar allows browsing of directories and file contents. It can
4428 be accessed from the VHDL menu and is automatically opened if option
4429 `vhdl-speedbar-auto-open' is non-nil.
4430
4431 In speedbar, open files and directories with `mouse-2' on the name and
4432 browse/rescan their contents with `mouse-2'/`S-mouse-2' on the `+'.
4433
4434
4435 DESIGN HIERARCHY BROWSER:
4436 The speedbar can also be used for browsing the hierarchy of design units
4437 contained in the source files of the current directory or the specified
4438 projects (see option `vhdl-project-alist').
4439
4440 The speedbar can be switched between file, directory hierarchy and
4441 project hierarchy browsing mode in the speedbar menu or by typing `f',
4442 `h' or `H' in speedbar.
4443
4444 In speedbar, open design units with `mouse-2' on the name and browse
4445 their hierarchy with `mouse-2' on the `+'. Ports can directly be copied
4446 from entities and components (in packages). Individual design units and
4447 complete designs can directly be compiled (\"Make\" menu entry).
4448
4449 The hierarchy is automatically updated upon saving a modified source
4450 file when option `vhdl-speedbar-update-on-saving' is non-nil. The
4451 hierarchy is only updated for projects that have been opened once in the
4452 speedbar. The hierarchy is cached between Emacs sessions in a file (see
4453 options in group `vhdl-speedbar').
4454
4455 Simple design consistency checks are done during scanning, such as
4456 multiple declarations of the same unit or missing primary units that are
4457 required by secondary units.
4458
4459
0a2e512a 4460 STRUCTURAL COMPOSITION:
fda91268 4461 Enables simple structural composition. `C-c C-m C-n' creates a skeleton
0a2e512a
RF
4462 for a new component. Subcomponents (i.e. component declaration and
4463 instantiation) can be automatically placed from a previously read port
fda91268 4464 \(`C-c C-m C-p') or directly from the hierarchy browser (`P'). Finally,
0a2e512a 4465 all subcomponents can be automatically connected using internal signals
fda91268 4466 and ports (`C-c C-m C-w') following these rules:
0a2e512a
RF
4467 - subcomponent actual ports with same name are considered to be
4468 connected by a signal (internal signal or port)
4469 - signals that are only inputs to subcomponents are considered as
4470 inputs to this component -> input port created
4471 - signals that are only outputs from subcomponents are considered as
4472 outputs from this component -> output port created
4473 - signals that are inputs to AND outputs from subcomponents are
4474 considered as internal connections -> internal signal created
84c98ace 4475
0a2e512a
RF
4476 Purpose: With appropriate naming conventions it is possible to
4477 create higher design levels with only a few mouse clicks or key
4478 strokes. A new design level can be created by simply generating a new
4479 component, placing the required subcomponents from the hierarchy
4480 browser, and wiring everything automatically.
84c98ace 4481
0a2e512a
RF
4482 Note: Automatic wiring only works reliably on templates of new
4483 components and component instantiations that were created by VHDL mode.
84c98ace 4484
0a2e512a
RF
4485 Component declarations can be placed in a components package (option
4486 `vhdl-use-components-package') which can be automatically generated for
fda91268 4487 an entire directory or project (`C-c C-m M-p'). The VHDL'93 direct
0a2e512a
RF
4488 component instantiation is also supported (option
4489 `vhdl-use-direct-instantiation').
4490
fda91268
RZ
4491 Configuration declarations can automatically be generated either from
4492 the menu (`C-c C-m C-f') (for the architecture the cursor is in) or from
4493 the speedbar menu (for the architecture under the cursor). The
4494 configurations can optionally be hierarchical (i.e. include all
4495 component levels of a hierarchical design, option
4496 `vhdl-compose-configuration-hierarchical') or include subconfigurations
4497 (option `vhdl-compose-configuration-use-subconfiguration'). For
4498 subcomponents in hierarchical configurations, the most-recently-analyzed
4499 (mra) architecture is selected. If another architecture is desired, it
4500 can be marked as most-recently-analyzed (speedbar menu) before
4501 generating the configuration.
09ae5da1 4502
fda91268
RZ
4503 Note: Configurations of subcomponents (i.e. hierarchical configuration
4504 declarations) are currently not considered when displaying
4505 configurations in speedbar.
84c98ace 4506
0a2e512a 4507 See the options group `vhdl-compose' for all relevant user options.
3dcb36b7
JB
4508
4509
4510 SOURCE FILE COMPILATION:
4511 The syntax of the current buffer can be analyzed by calling a VHDL
4512 compiler (menu, `C-c C-k'). The compiler to be used is specified by
4513 option `vhdl-compiler'. The available compilers are listed in option
4514 `vhdl-compiler-alist' including all required compilation command,
4515 command options, compilation directory, and error message syntax
4516 information. New compilers can be added.
4517
4518 All the source files of an entire design can be compiled by the `make'
4519 command (menu, `C-c M-C-k') if an appropriate Makefile exists.
4520
4521
4522 MAKEFILE GENERATION:
4523 Makefiles can be generated automatically by an internal generation
4524 routine (`C-c M-k'). The library unit dependency information is
4525 obtained from the hierarchy browser. Makefile generation can be
4526 customized for each compiler in option `vhdl-compiler-alist'.
4527
4528 Makefile generation can also be run non-interactively using the
4529 command:
4530
4531 emacs -batch -l ~/.emacs -l vhdl-mode
4532 [-compiler compilername] [-project projectname]
4533 -f vhdl-generate-makefile
4534
4535 The Makefile's default target \"all\" compiles the entire design, the
4536 target \"clean\" removes it and the target \"library\" creates the
fda91268
RZ
4537 library directory if not existent. These target names can be customized
4538 by option `vhdl-makefile-default-targets'. The Makefile also includes a
4539 target for each primary library unit which allows selective compilation
4540 of this unit, its secondary units and its subhierarchy (example:
4541 compilation of a design specified by a configuration). User specific
4542 parts can be inserted into a Makefile with option
4543 `vhdl-makefile-generation-hook'.
3dcb36b7
JB
4544
4545 Limitations:
4546 - Only library units and dependencies within the current library are
4547 considered. Makefiles for designs that span multiple libraries are
4548 not (yet) supported.
4549 - Only one-level configurations are supported (also hierarchical),
4550 but configurations that go down several levels are not.
4551 - The \"others\" keyword in configurations is not supported.
4552
4553
4554 PROJECTS:
4555 Projects can be defined in option `vhdl-project-alist' and a current
4556 project be selected using option `vhdl-project' (permanently) or from
4557 the menu or speedbar (temporarily). For each project, title and
4558 description strings (for the file headers), source files/directories
4559 (for the hierarchy browser and Makefile generation), library name, and
4560 compiler-dependent options, exceptions and compilation directory can be
4561 specified. Compilation settings overwrite the settings of option
4562 `vhdl-compiler-alist'.
4563
4564 Project setups can be exported (i.e. written to a file) and imported.
4565 Imported setups are not automatically saved in `vhdl-project-alist' but
4566 can be saved afterwards in its customization buffer. When starting
4567 Emacs with VHDL Mode (i.e. load a VHDL file or use \"emacs -l
4568 vhdl-mode\") in a directory with an existing project setup file, it is
4569 automatically loaded and its project activated if option
4570 `vhdl-project-auto-load' is non-nil. Names/paths of the project setup
4571 files can be specified in option `vhdl-project-file-name'. Multiple
4572 project setups can be automatically loaded from global directories.
4573 This is an alternative to specifying project setups with option
4574 `vhdl-project-alist'.
4575
4576
4577 SPECIAL MENUES:
4578 As an alternative to the speedbar, an index menu can be added (set
4579 option `vhdl-index-menu' to non-nil) or made accessible as a mouse menu
4580 (e.g. add \"(global-set-key '[S-down-mouse-3] 'imenu)\" to your start-up
4581 file) for browsing the file contents (is not populated if buffer is
4582 larger than `font-lock-maximum-size'). Also, a source file menu can be
4583 added (set option `vhdl-source-file-menu' to non-nil) for browsing the
4584 current directory for VHDL source files.
4585
4586
4587 VHDL STANDARDS:
4588 The VHDL standards to be used are specified in option `vhdl-standard'.
fda91268 4589 Available standards are: VHDL'87/'93(02), VHDL-AMS, and Math Packages.
3dcb36b7
JB
4590
4591
4592 KEYWORD CASE:
4593 Lower and upper case for keywords and standardized types, attributes,
4594 and enumeration values is supported. If the option
4595 `vhdl-upper-case-keywords' is set to non-nil, keywords can be typed in
4596 lower case and are converted into upper case automatically (not for
4597 types, attributes, and enumeration values). The case of keywords,
4598 types, attributes,and enumeration values can be fixed for an entire
4599 region (menu) or buffer (`C-c C-x C-c') according to the options
4600 `vhdl-upper-case-{keywords,types,attributes,enum-values}'.
4601
4602
4603 HIGHLIGHTING (fontification):
4604 Keywords and standardized types, attributes, enumeration values, and
4605 function names (controlled by option `vhdl-highlight-keywords'), as well
4606 as comments, strings, and template prompts are highlighted using
4607 different colors. Unit, subprogram, signal, variable, constant,
4608 parameter and generic/port names in declarations as well as labels are
4609 highlighted if option `vhdl-highlight-names' is non-nil.
4610
4611 Additional reserved words or words with a forbidden syntax (e.g. words
4612 that should be avoided) can be specified in option
4613 `vhdl-forbidden-words' or `vhdl-forbidden-syntax' and be highlighted in
4614 a warning color (option `vhdl-highlight-forbidden-words'). Verilog
4615 keywords are highlighted as forbidden words if option
4616 `vhdl-highlight-verilog-keywords' is non-nil.
4617
4618 Words with special syntax can be highlighted by specifying their
4619 syntax and color in option `vhdl-special-syntax-alist' and by setting
4620 option `vhdl-highlight-special-words' to non-nil. This allows to
4621 establish some naming conventions (e.g. to distinguish different kinds
4622 of signals or other objects by using name suffices) and to support them
4623 visually.
4624
4625 Option `vhdl-highlight-case-sensitive' can be set to non-nil in order
4626 to support case-sensitive highlighting. However, keywords are then only
4627 highlighted if written in lower case.
4628
4629 Code between \"translate_off\" and \"translate_on\" pragmas is
4630 highlighted using a different background color if option
4631 `vhdl-highlight-translate-off' is non-nil.
4632
4633 For documentation and customization of the used colors see
4634 customization group `vhdl-highlight-faces' (`M-x customize-group'). For
4635 highlighting of matching parenthesis, see customization group
4636 `paren-showing'. Automatic buffer highlighting is turned on/off by
4637 option `global-font-lock-mode' (`font-lock-auto-fontify' in XEmacs).
4638
4639
4640 USER MODELS:
4641 VHDL models (templates) can be specified by the user and made accessible
4642 in the menu, through key bindings (`C-c C-m ...'), or by keyword
4643 electrification. See option `vhdl-model-alist'.
4644
4645
4646 HIDE/SHOW:
4647 The code of blocks, processes, subprograms, component declarations and
4648 instantiations, generic/port clauses, and configuration declarations can
4649 be hidden using the `Hide/Show' menu or by pressing `S-mouse-2' within
4650 the code (see customization group `vhdl-menu'). XEmacs: limited
4651 functionality due to old `hideshow.el' package.
4652
4653
4654 CODE UPDATING:
4655 - Sensitivity List: `C-c C-u C-s' updates the sensitivity list of the
4656 current process, `C-c C-u M-s' of all processes in the current buffer.
4657 Limitations:
4658 - Only declared local signals (ports, signals declared in
4659 architecture and blocks) are automatically inserted.
4660 - Global signals declared in packages are not automatically inserted.
4661 Insert them once manually (will be kept afterwards).
4662 - Out parameters of procedures are considered to be read.
4663 Use option `vhdl-entity-file-name' to specify the entity file name
4664 \(used to obtain the port names).
fda91268
RZ
4665 Use option `vhdl-array-index-record-field-in-sensitivity-list' to
4666 specify whether to include array indices and record fields in
4667 sensitivity lists.
3dcb36b7
JB
4668
4669
4670 CODE FIXING:
4671 `C-c C-x C-p' fixes the closing parenthesis of a generic/port clause
4672 \(e.g. if the closing parenthesis is on the wrong line or is missing).
4673
4674
4675 PRINTING:
7877f373 4676 PostScript printing with different faces (an optimized set of faces is
3dcb36b7
JB
4677 used if `vhdl-print-customize-faces' is non-nil) or colors \(if
4678 `ps-print-color-p' is non-nil) is possible using the standard Emacs
7877f373 4679 PostScript printing commands. Option `vhdl-print-two-column' defines
3dcb36b7
JB
4680 appropriate default settings for nice landscape two-column printing.
4681 The paper format can be set by option `ps-paper-type'. Do not forget to
4682 switch `ps-print-color-p' to nil for printing on black-and-white
4683 printers.
4684
4685
4686 OPTIONS:
4687 User options allow customization of VHDL Mode. All options are
4688 accessible from the \"Options\" menu entry. Simple options (switches
4689 and choices) can directly be changed, while for complex options a
4690 customization buffer is opened. Changed options can be saved for future
4691 sessions using the \"Save Options\" menu entry.
4692
4693 Options and their detailed descriptions can also be accessed by using
4694 the \"Customize\" menu entry or the command `M-x customize-option' (`M-x
4695 customize-group' for groups). Some customizations only take effect
4696 after some action (read the NOTE in the option documentation).
4697 Customization can also be done globally (i.e. site-wide, read the
4698 INSTALL file).
4699
4700 Not all options are described in this documentation, so go and see
4701 what other useful user options there are (`M-x vhdl-customize' or menu)!
4702
4703
4704 FILE EXTENSIONS:
4705 As default, files with extensions \".vhd\" and \".vhdl\" are
4706 automatically recognized as VHDL source files. To add an extension
4707 \".xxx\", add the following line to your Emacs start-up file (`.emacs'):
4708
4709 \(setq auto-mode-alist (cons '(\"\\\\.xxx\\\\'\" . vhdl-mode) auto-mode-alist))
4710
4711
4712 HINTS:
4713 - To start Emacs with open VHDL hierarchy browser without having to load
4714 a VHDL file first, use the command:
4715
4716 emacs -l vhdl-mode -f speedbar-frame-mode
4717
4718 - Type `C-g C-g' to interrupt long operations or if Emacs hangs.
4719
4720 - Some features only work on properly indented code.
4721
4722
4723 RELEASE NOTES:
4724 See also the release notes (menu) for added features in new releases.
d2ddb974
KH
4725
4726
4727Maintenance:
4728------------
4729
3dcb36b7 4730To submit a bug report, enter `M-x vhdl-submit-bug-report' within VHDL Mode.
d2ddb974
KH
4731Add a description of the problem and include a reproducible test case.
4732
3dcb36b7 4733Questions and enhancement requests can be sent to <reto@gnu.org>.
d2ddb974
KH
4734
4735The `vhdl-mode-announce' mailing list informs about new VHDL Mode releases.
3dcb36b7
JB
4736The `vhdl-mode-victims' mailing list informs about new VHDL Mode beta
4737releases. You are kindly invited to participate in beta testing. Subscribe
4738to above mailing lists by sending an email to <reto@gnu.org>.
d2ddb974 4739
3dcb36b7 4740VHDL Mode is officially distributed at
fda91268 4741http://www.iis.ee.ethz.ch/~zimmi/emacs/vhdl-mode.html
3dcb36b7 4742where the latest version can be found.
d2ddb974
KH
4743
4744
3dcb36b7
JB
4745Known problems:
4746---------------
d2ddb974 4747
3dcb36b7
JB
4748- XEmacs: Incorrect start-up when automatically opening speedbar.
4749- XEmacs: Indentation in XEmacs 21.4 (and higher).
fda91268
RZ
4750- Indentation incorrect for new 'postponed' VHDL keyword.
4751- Indentation incorrect for 'protected body' construct.
d2ddb974
KH
4752
4753
3dcb36b7
JB
4754 The VHDL Mode Authors
4755 Reto Zimmermann and Rod Whitby
5eabfe72 4756
d2ddb974
KH
4757Key bindings:
4758-------------
4759
4760\\{vhdl-mode-map}"
175069ef 4761 :abbrev-table vhdl-mode-abbrev-table
5eabfe72 4762
3dcb36b7 4763 ;; set local variables
5eabfe72
KH
4764 (set (make-local-variable 'paragraph-start)
4765 "\\s-*\\(--+\\s-*$\\|[^ -]\\|$\\)")
d2ddb974
KH
4766 (set (make-local-variable 'paragraph-separate) paragraph-start)
4767 (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
d2ddb974
KH
4768 (set (make-local-variable 'parse-sexp-ignore-comments) t)
4769 (set (make-local-variable 'indent-line-function) 'vhdl-indent-line)
4770 (set (make-local-variable 'comment-start) "--")
4771 (set (make-local-variable 'comment-end) "")
0a2e512a
RF
4772 (when vhdl-emacs-21
4773 (set (make-local-variable 'comment-padding) ""))
5eabfe72 4774 (set (make-local-variable 'comment-column) vhdl-inline-comment-column)
d2ddb974
KH
4775 (set (make-local-variable 'end-comment-column) vhdl-end-comment-column)
4776 (set (make-local-variable 'comment-start-skip) "--+\\s-*")
5eabfe72 4777 (set (make-local-variable 'comment-multi-line) nil)
d2ddb974 4778 (set (make-local-variable 'indent-tabs-mode) vhdl-indent-tabs-mode)
5eabfe72 4779 (set (make-local-variable 'hippie-expand-verbose) nil)
d2ddb974
KH
4780
4781 ;; setup the comment indent variable in a Emacs version portable way
4782 ;; ignore any byte compiler warnings you might get here
5eabfe72 4783 (when (boundp 'comment-indent-function)
175069ef 4784 (set (make-local-variable 'comment-indent-function) 'vhdl-comment-indent))
d2ddb974
KH
4785
4786 ;; initialize font locking
5eabfe72
KH
4787 (set (make-local-variable 'font-lock-defaults)
4788 (list
3dcb36b7 4789 '(nil vhdl-font-lock-keywords) nil
cf38dd42
SM
4790 (not vhdl-highlight-case-sensitive) '((?\_ . "w")) 'beginning-of-line))
4791 (if (eval-when-compile (fboundp 'syntax-propertize-rules))
4792 (set (make-local-variable 'syntax-propertize-function)
4793 (syntax-propertize-rules
4794 ;; Mark single quotes as having string quote syntax in
4795 ;; 'c' instances.
4796 ("\\(\'\\).\\(\'\\)" (1 "\"'") (2 "\"'"))))
4797 (set (make-local-variable 'font-lock-syntactic-keywords)
4798 vhdl-font-lock-syntactic-keywords))
3dcb36b7
JB
4799 (unless vhdl-emacs-21
4800 (set (make-local-variable 'font-lock-support-mode) 'lazy-lock-mode)
4801 (set (make-local-variable 'lazy-lock-defer-contextually) nil)
4802 (set (make-local-variable 'lazy-lock-defer-on-the-fly) t)
4803; (set (make-local-variable 'lazy-lock-defer-time) 0.1)
4804 (set (make-local-variable 'lazy-lock-defer-on-scrolling) t))
4805; (turn-on-font-lock)
d2ddb974
KH
4806
4807 ;; variables for source file compilation
3dcb36b7
JB
4808 (when vhdl-compile-use-local-error-regexp
4809 (set (make-local-variable 'compilation-error-regexp-alist) nil)
4810 (set (make-local-variable 'compilation-file-regexp-alist) nil))
5eabfe72
KH
4811
4812 ;; add index menu
4813 (vhdl-index-menu-init)
4814 ;; add source file menu
d2ddb974 4815 (if vhdl-source-file-menu (vhdl-add-source-files-menu))
5eabfe72
KH
4816 ;; add VHDL menu
4817 (easy-menu-add vhdl-mode-menu-list) ; for XEmacs
4818 (easy-menu-define vhdl-mode-menu vhdl-mode-map
4819 "Menu keymap for VHDL Mode." vhdl-mode-menu-list)
4820 ;; initialize hideshow and add menu
5eabfe72 4821 (vhdl-hideshow-init)
d2ddb974
KH
4822 (run-hooks 'menu-bar-update-hook)
4823
5eabfe72
KH
4824 ;; miscellaneous
4825 (vhdl-ps-print-init)
3dcb36b7 4826 (vhdl-write-file-hooks-init)
3dcb36b7 4827 (message "VHDL Mode %s.%s" vhdl-version
175069ef 4828 (if noninteractive "" " See menu for documentation and release notes.")))
5eabfe72
KH
4829
4830(defun vhdl-activate-customizations ()
4831 "Activate all customizations on local variables."
4832 (interactive)
4833 (vhdl-mode-map-init)
4834 (use-local-map vhdl-mode-map)
4835 (set-syntax-table vhdl-mode-syntax-table)
4836 (setq comment-column vhdl-inline-comment-column)
4837 (setq end-comment-column vhdl-end-comment-column)
3dcb36b7 4838 (vhdl-write-file-hooks-init)
5eabfe72
KH
4839 (vhdl-update-mode-menu)
4840 (vhdl-hideshow-init)
56eb0904 4841 (run-hooks 'menu-bar-update-hook))
5eabfe72 4842
3dcb36b7
JB
4843(defun vhdl-write-file-hooks-init ()
4844 "Add/remove hooks when buffer is saved."
5eabfe72 4845 (if vhdl-modify-date-on-saving
175069ef
SM
4846 (add-hook 'local-write-file-hooks 'vhdl-template-modify-noerror nil t)
4847 (remove-hook 'local-write-file-hooks 'vhdl-template-modify-noerror t))
4848 (if (featurep 'xemacs) (make-local-hook 'after-save-hook))
4849 (add-hook 'after-save-hook 'vhdl-add-modified-file nil t))
3dcb36b7
JB
4850
4851(defun vhdl-process-command-line-option (option)
4852 "Process command line options for VHDL Mode."
4853 (cond
4854 ;; set compiler
4855 ((equal option "-compiler")
4856 (vhdl-set-compiler (car command-line-args-left))
4857 (setq command-line-args-left (cdr command-line-args-left)))
4858 ;; set project
4859 ((equal option "-project")
4860 (vhdl-set-project (car command-line-args-left))
4861 (setq command-line-args-left (cdr command-line-args-left)))))
4862
4863;; make Emacs process VHDL Mode options
4864(setq command-switch-alist
4865 (append command-switch-alist
4866 '(("-compiler" . vhdl-process-command-line-option)
4867 ("-project" . vhdl-process-command-line-option))))
5eabfe72
KH
4868
4869
4870;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 4871;;; Keywords and standardized words
5eabfe72
KH
4872;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4873
fda91268 4874(defconst vhdl-02-keywords
3dcb36b7
JB
4875 '(
4876 "abs" "access" "after" "alias" "all" "and" "architecture" "array"
4877 "assert" "attribute"
4878 "begin" "block" "body" "buffer" "bus"
4879 "case" "component" "configuration" "constant"
4880 "disconnect" "downto"
4881 "else" "elsif" "end" "entity" "exit"
4882 "file" "for" "function"
4883 "generate" "generic" "group" "guarded"
4884 "if" "impure" "in" "inertial" "inout" "is"
4885 "label" "library" "linkage" "literal" "loop"
4886 "map" "mod"
4887 "nand" "new" "next" "nor" "not" "null"
4888 "of" "on" "open" "or" "others" "out"
fda91268 4889 "package" "port" "postponed" "procedure" "process" "protected" "pure"
3dcb36b7
JB
4890 "range" "record" "register" "reject" "rem" "report" "return"
4891 "rol" "ror"
4892 "select" "severity" "shared" "signal" "sla" "sll" "sra" "srl" "subtype"
4893 "then" "to" "transport" "type"
4894 "unaffected" "units" "until" "use"
4895 "variable"
4896 "wait" "when" "while" "with"
4897 "xnor" "xor"
4898 )
fda91268 4899 "List of VHDL'02 keywords.")
d2ddb974 4900
5eabfe72
KH
4901(defconst vhdl-ams-keywords
4902 '(
4903 "across" "break" "limit" "nature" "noise" "procedural" "quantity"
4904 "reference" "spectrum" "subnature" "terminal" "through"
4905 "tolerance"
4906 )
4907 "List of VHDL-AMS keywords.")
d2ddb974 4908
5eabfe72
KH
4909(defconst vhdl-verilog-keywords
4910 '(
4911 "`define" "`else" "`endif" "`ifdef" "`include" "`timescale" "`undef"
4912 "always" "and" "assign" "begin" "buf" "bufif0" "bufif1"
4913 "case" "casex" "casez" "cmos" "deassign" "default" "defparam" "disable"
4914 "edge" "else" "end" "endattribute" "endcase" "endfunction" "endmodule"
4915 "endprimitive" "endspecify" "endtable" "endtask" "event"
4916 "for" "force" "forever" "fork" "function"
4917 "highz0" "highz1" "if" "initial" "inout" "input" "integer" "join" "large"
4918 "macromodule" "makefile" "medium" "module"
4919 "nand" "negedge" "nmos" "nor" "not" "notif0" "notif1" "or" "output"
4920 "parameter" "pmos" "posedge" "primitive" "pull0" "pull1" "pulldown"
4921 "pullup"
4922 "rcmos" "real" "realtime" "reg" "release" "repeat" "rnmos" "rpmos" "rtran"
4923 "rtranif0" "rtranif1"
4924 "scalared" "signed" "small" "specify" "specparam" "strength" "strong0"
4925 "strong1" "supply" "supply0" "supply1"
4926 "table" "task" "time" "tran" "tranif0" "tranif1" "tri" "tri0" "tri1"
4927 "triand" "trior" "trireg"
4928 "vectored" "wait" "wand" "weak0" "weak1" "while" "wire" "wor" "xnor" "xor"
4929 )
4930 "List of Verilog keywords as candidate for additional reserved words.")
d2ddb974 4931
fda91268 4932(defconst vhdl-02-types
5eabfe72
KH
4933 '(
4934 "boolean" "bit" "bit_vector" "character" "severity_level" "integer"
4935 "real" "time" "natural" "positive" "string" "line" "text" "side"
4936 "unsigned" "signed" "delay_length" "file_open_kind" "file_open_status"
4937 "std_logic" "std_logic_vector"
4938 "std_ulogic" "std_ulogic_vector"
4939 )
fda91268 4940 "List of VHDL'02 standardized types.")
d2ddb974 4941
5eabfe72 4942(defconst vhdl-ams-types
fda91268 4943 ;; standards: IEEE Std 1076.1-2007, IEEE Std 1076.1.1-2004
5eabfe72 4944 '(
fda91268 4945 ;; package `standard'
5eabfe72 4946 "domain_type" "real_vector"
fda91268
RZ
4947 ;; package `energy_systems'
4948 "energy" "power" "periodicity" "real_across" "real_through" "unspecified"
4949 "unspecified_vector" "energy_vector" "power_vector" "periodicity_vector"
4950 "real_across_vector" "real_through_vector"
4951 ;; package `electrical_systems'
4952 "voltage" "current" "charge" "resistance" "conductance" "capacitance"
4953 "mmf" "electric_flux" "electric_flux_density" "electric_field_strength"
4954 "magnetic_flux" "magnetic_flux_density" "magnetic_field_strength"
4955 "inductance" "reluctance" "electrical" "electrical_vector" "magnetic"
4956 "magnetic_vector" "voltage_vector" "current_vector" "mmf_vector"
4957 "magnetic_flux_vector" "charge_vector" "resistance_vector"
4958 "conductance_vector" "capacitance_vector" "electric_flux_vector"
4959 "electric_flux_density_vector" "electric_field_strength_vector"
4960 "magnetic_flux_density_vector" "magnetic_field_strength_vector"
4961 "inductance_vector" "reluctance_vector" "ground"
4962 ;; package `mechanical_systems'
4963 "displacement" "force" "velocity" "acceleration" "mass" "stiffness"
4964 "damping" "momentum" "angle" "torque" "angular_velocity"
4965 "angular_acceleration" "moment_inertia" "angular_momentum"
4966 "angular_stiffness" "angular_damping" "translational"
4967 "translational_vector" "translational_velocity"
4968 "translational_velocity_vector" "rotational" "rotational_vector"
4969 "rotational_velocity" "rotational_velocity_vector" "displacement_vector"
4970 "force_vector" "velocity_vector" "force_velocity_vector" "angle_vector"
4971 "torque_vector" "angular_velocity_vector" "torque_velocity_vector"
4972 "acceleration_vector" "mass_vector" "stiffness_vector" "damping_vector"
4973 "momentum_vector" "angular_acceleration_vector" "moment_inertia_vector"
4974 "angular_momentum_vector" "angular_stiffness_vector"
4975 "angular_damping_vector" "anchor" "translational_v_ref"
4976 "rotational_v_ref" "translational_v" "rotational_v"
4977 ;; package `radiant_systems'
4978 "illuminance" "luminous_flux" "luminous_intensity" "irradiance" "radiant"
4979 "radiant_vector" "luminous_intensity_vector" "luminous_flux_vector"
4980 "illuminance_vector" "irradiance_vector"
4981 ;; package `thermal_systems'
4982 "temperature" "heat_flow" "thermal_capacitance" "thermal_resistance"
4983 "thermal_conductance" "thermal" "thermal_vector" "temperature_vector"
4984 "heat_flow_vector" "thermal_capacitance_vector"
4985 "thermal_resistance_vector" "thermal_conductance_vector"
4986 ;; package `fluidic_systems'
4987 "pressure" "vflow_rate" "mass_flow_rate" "volume" "density" "viscosity"
4988 "fresistance" "fconductance" "fcapacitance" "inertance" "cfresistance"
4989 "cfcapacitance" "cfinertance" "cfconductance" "fluidic" "fluidic_vector"
4990 "compressible_fluidic" "compressible_fluidic_vector" "pressure_vector"
4991 "vflow_rate_vector" "mass_flow_rate_vector" "volume_vector"
4992 "density_vector" "viscosity_vector" "fresistance_vector"
4993 "fconductance_vector" "fcapacitance_vector" "inertance_vector"
4994 "cfresistance_vector" "cfconductance_vector" "cfcapacitance_vector"
4995 "cfinertance_vector"
4996 )
5eabfe72 4997 "List of VHDL-AMS standardized types.")
d2ddb974 4998
5eabfe72
KH
4999(defconst vhdl-math-types
5000 '(
fda91268 5001 "complex" "complex_polar" "positive_real" "principal_value"
5eabfe72
KH
5002 )
5003 "List of Math Packages standardized types.")
d2ddb974 5004
fda91268 5005(defconst vhdl-02-attributes
5eabfe72
KH
5006 '(
5007 "base" "left" "right" "high" "low" "pos" "val" "succ"
5008 "pred" "leftof" "rightof" "range" "reverse_range"
5009 "length" "delayed" "stable" "quiet" "transaction"
5010 "event" "active" "last_event" "last_active" "last_value"
5011 "driving" "driving_value" "ascending" "value" "image"
5012 "simple_name" "instance_name" "path_name"
5013 "foreign"
5014 )
fda91268 5015 "List of VHDL'02 standardized attributes.")
d2ddb974 5016
5eabfe72
KH
5017(defconst vhdl-ams-attributes
5018 '(
5019 "across" "through"
5020 "reference" "contribution" "tolerance"
5021 "dot" "integ" "delayed" "above" "zoh" "ltf" "ztf"
5022 "ramp" "slew"
5023 )
5024 "List of VHDL-AMS standardized attributes.")
d2ddb974 5025
fda91268 5026(defconst vhdl-02-enum-values
5eabfe72
KH
5027 '(
5028 "true" "false"
5029 "note" "warning" "error" "failure"
5030 "read_mode" "write_mode" "append_mode"
5031 "open_ok" "status_error" "name_error" "mode_error"
5032 "fs" "ps" "ns" "us" "ms" "sec" "min" "hr"
5033 "right" "left"
5034 )
fda91268 5035 "List of VHDL'02 standardized enumeration values.")
d2ddb974 5036
5eabfe72
KH
5037(defconst vhdl-ams-enum-values
5038 '(
5039 "quiescent_domain" "time_domain" "frequency_domain"
3dcb36b7
JB
5040 ;; from `nature_pkg' package
5041 "eps0" "mu0" "ground" "mecvf_gnd" "mecpf_gnd" "rot_gnd" "fld_gnd"
5eabfe72
KH
5042 )
5043 "List of VHDL-AMS standardized enumeration values.")
5044
fda91268
RZ
5045(defconst vhdl-ams-constants
5046 ;; standard: IEEE Std 1076.1.1-2004
5047 '(
5048 ;; package `fundamental_constants'
5049 "phys_q" "phys_eps0" "phys_mu0" "phys_k" "phys_gravity" "phys_ctok"
5050 "phys_c" "phys_h" "phys_h_over_2_pi" "yocto" "zepto" "atto" "femto"
5051 "pico" "nano" "micro" "milli" "centi" "deci" "deka" "hecto" "kilo" "mega"
5052 "giga" "tera" "peta" "exa" "zetta" "yotta" "deca"
5053 ;; package `material_constants'
5054 "phys_eps_si" "phys_eps_sio2" "phys_e_si" "phys_e_sio2" "phys_e_poly"
5055 "phys_nu_si" "phys_nu_poly" "phys_rho_poly" "phys_rho_sio2"
5056 "ambient_temperature" "ambient_pressure" "ambient_illuminance"
5057 )
5058 "List of VHDL-AMS standardized constants.")
5059
5eabfe72 5060(defconst vhdl-math-constants
fda91268 5061 ;; standard: IEEE Std 1076.2-1996
5eabfe72 5062 '(
fda91268
RZ
5063 "math_1_over_e" "math_1_over_pi" "math_1_over_sqrt_2" "math_2_pi"
5064 "math_3_pi_over_2" "math_cbase_1" "math_cbase_j" "math_czero"
5065 "math_deg_to_rad" "math_e" "math_log10_of_e" "math_log2_of_e"
5066 "math_log_of_10" "math_log_of_2" "math_pi" "math_pi_over_2"
5067 "math_pi_over_3" "math_pi_over_4" "math_rad_to_deg" "math_sqrt_2"
5068 "math_sqrt_pi"
5eabfe72
KH
5069 )
5070 "List of Math Packages standardized constants.")
5071
fda91268 5072(defconst vhdl-02-functions
5eabfe72
KH
5073 '(
5074 "now" "resolved" "rising_edge" "falling_edge"
fda91268
RZ
5075 "read" "readline" "hread" "oread" "write" "writeline" "hwrite" "owrite"
5076 "endfile"
5eabfe72
KH
5077 "resize" "is_X" "std_match"
5078 "shift_left" "shift_right" "rotate_left" "rotate_right"
5079 "to_unsigned" "to_signed" "to_integer"
5080 "to_stdLogicVector" "to_stdULogic" "to_stdULogicVector"
5081 "to_bit" "to_bitVector" "to_X01" "to_X01Z" "to_UX01" "to_01"
5082 "conv_unsigned" "conv_signed" "conv_integer" "conv_std_logic_vector"
5083 "shl" "shr" "ext" "sxt"
3dcb36b7 5084 "deallocate"
5eabfe72 5085 )
fda91268 5086 "List of VHDL'02 standardized functions.")
5eabfe72
KH
5087
5088(defconst vhdl-ams-functions
5089 '(
fda91268 5090 ;; package `standard'
5eabfe72
KH
5091 "frequency"
5092 )
5093 "List of VHDL-AMS standardized functions.")
5094
5095(defconst vhdl-math-functions
fda91268 5096 ;; standard: IEEE Std 1076.2-1996
5eabfe72 5097 '(
fda91268
RZ
5098 "arccos" "arccosh" "arcsin" "arcsinh" "arctan" "arctanh" "arg"
5099 "cbrt" "ceil" "cmplx" "complex_to_polar" "conj" "cos" "cosh" "exp"
5100 "floor" "get_principal_value" "log" "log10" "log2" "polar_to_complex"
5101 "realmax" "realmin" "round" "sign" "sin" "sinh" "sqrt"
5102 "tan" "tanh" "trunc" "uniform"
5eabfe72
KH
5103 )
5104 "List of Math Packages standardized functions.")
5105
fda91268 5106(defconst vhdl-02-packages
5eabfe72
KH
5107 '(
5108 "std_logic_1164" "numeric_std" "numeric_bit"
5109 "standard" "textio"
5110 "std_logic_arith" "std_logic_signed" "std_logic_unsigned"
5111 "std_logic_misc" "std_logic_textio"
5112 "ieee" "std" "work"
5113 )
fda91268 5114 "List of VHDL'02 standardized packages and libraries.")
5eabfe72 5115
3dcb36b7
JB
5116(defconst vhdl-ams-packages
5117 '(
fda91268
RZ
5118 "fundamental_constants" "material_constants" "energy_systems"
5119 "electrical_systems" "mechanical_systems" "radiant_systems"
5120 "thermal_systems" "fluidic_systems"
3dcb36b7
JB
5121 )
5122 "List of VHDL-AMS standardized packages and libraries.")
5123
5eabfe72
KH
5124(defconst vhdl-math-packages
5125 '(
5126 "math_real" "math_complex"
5127 )
5128 "List of Math Packages standardized packages and libraries.")
5129
5130(defvar vhdl-keywords nil
5131 "List of VHDL keywords.")
5132
5133(defvar vhdl-types nil
5134 "List of VHDL standardized types.")
5135
5136(defvar vhdl-attributes nil
5137 "List of VHDL standardized attributes.")
5138
5139(defvar vhdl-enum-values nil
5140 "List of VHDL standardized enumeration values.")
5141
5142(defvar vhdl-constants nil
5143 "List of VHDL standardized constants.")
5144
5145(defvar vhdl-functions nil
5146 "List of VHDL standardized functions.")
5147
5148(defvar vhdl-packages nil
5149 "List of VHDL standardized packages and libraries.")
5150
5151(defvar vhdl-reserved-words nil
5152 "List of additional reserved words.")
5153
5154(defvar vhdl-keywords-regexp nil
5155 "Regexp for VHDL keywords.")
5156
5157(defvar vhdl-types-regexp nil
5158 "Regexp for VHDL standardized types.")
5159
5160(defvar vhdl-attributes-regexp nil
5161 "Regexp for VHDL standardized attributes.")
5162
5163(defvar vhdl-enum-values-regexp nil
5164 "Regexp for VHDL standardized enumeration values.")
5165
fda91268
RZ
5166(defvar vhdl-constants-regexp nil
5167 "Regexp for VHDL standardized constants.")
5168
5eabfe72
KH
5169(defvar vhdl-functions-regexp nil
5170 "Regexp for VHDL standardized functions.")
5171
5172(defvar vhdl-packages-regexp nil
5173 "Regexp for VHDL standardized packages and libraries.")
5174
5175(defvar vhdl-reserved-words-regexp nil
5176 "Regexp for additional reserved words.")
5177
3dcb36b7
JB
5178(defvar vhdl-directive-keywords-regexp nil
5179 "Regexp for compiler directive keywords.")
5180
fda91268
RZ
5181(defun vhdl-upcase-list (condition list)
5182 "Upcase all elements in LIST based on CONDITION."
5183 (when condition
5184 (let ((tmp-list list))
5185 (while tmp-list
5186 (setcar tmp-list (upcase (car tmp-list)))
5187 (setq tmp-list (cdr tmp-list)))))
5188 list)
5189
5eabfe72
KH
5190(defun vhdl-words-init ()
5191 "Initialize reserved words."
5192 (setq vhdl-keywords
fda91268
RZ
5193 (vhdl-upcase-list
5194 (and vhdl-highlight-case-sensitive vhdl-upper-case-keywords)
5195 (append vhdl-02-keywords
5196 (when (vhdl-standard-p 'ams) vhdl-ams-keywords))))
5eabfe72 5197 (setq vhdl-types
fda91268
RZ
5198 (vhdl-upcase-list
5199 (and vhdl-highlight-case-sensitive vhdl-upper-case-types)
5200 (append vhdl-02-types
5201 (when (vhdl-standard-p 'ams) vhdl-ams-types)
5202 (when (vhdl-standard-p 'math) vhdl-math-types))))
5eabfe72 5203 (setq vhdl-attributes
fda91268
RZ
5204 (vhdl-upcase-list
5205 (and vhdl-highlight-case-sensitive vhdl-upper-case-attributes)
5206 (append vhdl-02-attributes
5207 (when (vhdl-standard-p 'ams) vhdl-ams-attributes))))
5eabfe72 5208 (setq vhdl-enum-values
fda91268
RZ
5209 (vhdl-upcase-list
5210 (and vhdl-highlight-case-sensitive vhdl-upper-case-enum-values)
5211 (append vhdl-02-enum-values
5212 (when (vhdl-standard-p 'ams) vhdl-ams-enum-values))))
5eabfe72 5213 (setq vhdl-constants
fda91268
RZ
5214 (vhdl-upcase-list
5215 (and vhdl-highlight-case-sensitive vhdl-upper-case-constants)
5216 (append (when (vhdl-standard-p 'ams) vhdl-ams-constants)
5217 (when (vhdl-standard-p 'math) vhdl-math-constants)
5218 '(""))))
5eabfe72 5219 (setq vhdl-functions
fda91268 5220 (append vhdl-02-functions
5eabfe72
KH
5221 (when (vhdl-standard-p 'ams) vhdl-ams-functions)
5222 (when (vhdl-standard-p 'math) vhdl-math-functions)))
5223 (setq vhdl-packages
fda91268 5224 (append vhdl-02-packages
3dcb36b7 5225 (when (vhdl-standard-p 'ams) vhdl-ams-packages)
5eabfe72
KH
5226 (when (vhdl-standard-p 'math) vhdl-math-packages)))
5227 (setq vhdl-reserved-words
5228 (append (when vhdl-highlight-forbidden-words vhdl-forbidden-words)
5229 (when vhdl-highlight-verilog-keywords vhdl-verilog-keywords)
5230 '("")))
5231 (setq vhdl-keywords-regexp
5232 (concat "\\<\\(" (regexp-opt vhdl-keywords) "\\)\\>"))
5233 (setq vhdl-types-regexp
5234 (concat "\\<\\(" (regexp-opt vhdl-types) "\\)\\>"))
5235 (setq vhdl-attributes-regexp
5236 (concat "\\<\\(" (regexp-opt vhdl-attributes) "\\)\\>"))
5237 (setq vhdl-enum-values-regexp
5238 (concat "\\<\\(" (regexp-opt vhdl-enum-values) "\\)\\>"))
fda91268
RZ
5239 (setq vhdl-constants-regexp
5240 (concat "\\<\\(" (regexp-opt vhdl-constants) "\\)\\>"))
5eabfe72
KH
5241 (setq vhdl-functions-regexp
5242 (concat "\\<\\(" (regexp-opt vhdl-functions) "\\)\\>"))
5243 (setq vhdl-packages-regexp
5244 (concat "\\<\\(" (regexp-opt vhdl-packages) "\\)\\>"))
5245 (setq vhdl-reserved-words-regexp
5246 (concat "\\<\\("
5247 (unless (equal vhdl-forbidden-syntax "")
5248 (concat vhdl-forbidden-syntax "\\|"))
5249 (regexp-opt vhdl-reserved-words)
5250 "\\)\\>"))
3dcb36b7
JB
5251 (setq vhdl-directive-keywords-regexp
5252 (concat "\\<\\(" (mapconcat 'regexp-quote
5253 vhdl-directive-keywords "\\|") "\\)\\>"))
5eabfe72
KH
5254 (vhdl-abbrev-list-init))
5255
5256;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5257;; Words to expand
5258
5259(defvar vhdl-abbrev-list nil
5260 "Predefined abbreviations for VHDL.")
5261
5262(defun vhdl-abbrev-list-init ()
5263 (setq vhdl-abbrev-list
5264 (append
5265 (list vhdl-upper-case-keywords) vhdl-keywords
5266 (list vhdl-upper-case-types) vhdl-types
5267 (list vhdl-upper-case-attributes) vhdl-attributes
5268 (list vhdl-upper-case-enum-values) vhdl-enum-values
5269 (list vhdl-upper-case-constants) vhdl-constants
5270 (list nil) vhdl-functions
5271 (list nil) vhdl-packages)))
5272
5273;; initialize reserved words for VHDL Mode
5274(vhdl-words-init)
5275
5276
5277;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 5278;;; Indentation
5eabfe72
KH
5279;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5280
5281;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
5282;; Syntax analysis
5283
5284;; constant regular expressions for looking at various constructs
5285
5286(defconst vhdl-symbol-key "\\(\\w\\|\\s_\\)+"
5287 "Regexp describing a VHDL symbol.
5288We cannot use just `word' syntax class since `_' cannot be in word
5289class. Putting underscore in word class breaks forward word movement
5290behavior that users are familiar with.")
5291
fda91268 5292(defconst vhdl-case-header-key "case[( \t\n\r\f][^;=>]+[) \t\n\r\f]is"
d2ddb974
KH
5293 "Regexp describing a case statement header key.")
5294
5295(defconst vhdl-label-key
5296 (concat "\\(" vhdl-symbol-key "\\s-*:\\)[^=]")
5297 "Regexp describing a VHDL label.")
5298
5299;; Macro definitions:
5300
5301(defmacro vhdl-point (position)
5eabfe72
KH
5302 "Return the value of point at certain commonly referenced POSITIONs.
5303POSITION can be one of the following symbols:
5304
5305bol -- beginning of line
5306eol -- end of line
5307bod -- beginning of defun
5308boi -- back to indentation
5309eoi -- last whitespace on line
5310ionl -- indentation of next line
5311iopl -- indentation of previous line
5312bonl -- beginning of next line
5313bopl -- beginning of previous line
5314
5315This function does not modify point or mark."
d2ddb974 5316 (or (and (eq 'quote (car-safe position))
3dcb36b7
JB
5317 (null (cddr position)))
5318 (error "ERROR: Bad buffer position requested: %s" position))
d2ddb974 5319 (setq position (nth 1 position))
d4a5b644
GM
5320 `(let ((here (point)))
5321 ,@(cond
5322 ((eq position 'bol) '((beginning-of-line)))
5323 ((eq position 'eol) '((end-of-line)))
5324 ((eq position 'bod) '((save-match-data
5325 (vhdl-beginning-of-defun))))
5326 ((eq position 'boi) '((back-to-indentation)))
3dcb36b7 5327 ((eq position 'eoi) '((end-of-line) (skip-chars-backward " \t")))
d4a5b644
GM
5328 ((eq position 'bonl) '((forward-line 1)))
5329 ((eq position 'bopl) '((forward-line -1)))
5330 ((eq position 'iopl)
5331 '((forward-line -1)
5332 (back-to-indentation)))
5333 ((eq position 'ionl)
5334 '((forward-line 1)
5335 (back-to-indentation)))
3dcb36b7 5336 (t (error "ERROR: Unknown buffer position requested: %s" position))
d4a5b644
GM
5337 )
5338 (prog1
5339 (point)
5340 (goto-char here))
5341 ;; workaround for an Emacs18 bug -- blech! Well, at least it
5342 ;; doesn't hurt for v19
5343 ,@nil
5344 ))
d2ddb974
KH
5345
5346(defmacro vhdl-safe (&rest body)
5eabfe72 5347 "Safely execute BODY, return nil if an error occurred."
d4a5b644
GM
5348 `(condition-case nil
5349 (progn ,@body)
5350 (error nil)))
d2ddb974
KH
5351
5352(defmacro vhdl-add-syntax (symbol &optional relpos)
5eabfe72
KH
5353 "A simple macro to append the syntax in SYMBOL to the syntax list.
5354Try to increase performance by using this macro."
d4a5b644
GM
5355 `(setq vhdl-syntactic-context
5356 (cons (cons ,symbol ,relpos) vhdl-syntactic-context)))
d2ddb974
KH
5357
5358(defmacro vhdl-has-syntax (symbol)
5eabfe72
KH
5359 "A simple macro to return check the syntax list.
5360Try to increase performance by using this macro."
d4a5b644 5361 `(assoc ,symbol vhdl-syntactic-context))
d2ddb974
KH
5362
5363;; Syntactic element offset manipulation:
5364
5365(defun vhdl-read-offset (langelem)
5eabfe72 5366 "Read new offset value for LANGELEM from minibuffer.
2e8b9c7d 5367Return a valid value only."
d2ddb974
KH
5368 (let ((oldoff (format "%s" (cdr-safe (assq langelem vhdl-offsets-alist))))
5369 (errmsg "Offset must be int, func, var, or one of +, -, ++, --: ")
5370 (prompt "Offset: ")
5371 offset input interned)
5372 (while (not offset)
5373 (setq input (read-string prompt oldoff)
5374 offset (cond ((string-equal "+" input) '+)
5375 ((string-equal "-" input) '-)
5376 ((string-equal "++" input) '++)
5377 ((string-equal "--" input) '--)
5378 ((string-match "^-?[0-9]+$" input)
027a4b6b 5379 (string-to-number input))
d2ddb974
KH
5380 ((fboundp (setq interned (intern input)))
5381 interned)
5382 ((boundp interned) interned)
5383 ;; error, but don't signal one, keep trying
5384 ;; to read an input value
5385 (t (ding)
5386 (setq prompt errmsg)
5387 nil))))
5388 offset))
5389
5390(defun vhdl-set-offset (symbol offset &optional add-p)
5391 "Change the value of a syntactic element symbol in `vhdl-offsets-alist'.
5392SYMBOL is the syntactic element symbol to change and OFFSET is the new
a4c6cfad 5393offset for that syntactic element. Optional ADD-P says to add SYMBOL to
d2ddb974
KH
5394`vhdl-offsets-alist' if it doesn't already appear there."
5395 (interactive
5396 (let* ((langelem
5397 (intern (completing-read
5398 (concat "Syntactic symbol to change"
5399 (if current-prefix-arg " or add" "")
5400 ": ")
5401 (mapcar
5402 (function
5403 (lambda (langelem)
5404 (cons (format "%s" (car langelem)) nil)))
5405 vhdl-offsets-alist)
5406 nil (not current-prefix-arg)
5407 ;; initial contents tries to be the last element
5408 ;; on the syntactic analysis list for the current
5409 ;; line
5410 (let* ((syntax (vhdl-get-syntactic-context))
5411 (len (length syntax))
5412 (ic (format "%s" (car (nth (1- len) syntax)))))
5eabfe72 5413 ic)
d2ddb974
KH
5414 )))
5415 (offset (vhdl-read-offset langelem)))
5416 (list langelem offset current-prefix-arg)))
5417 ;; sanity check offset
5418 (or (eq offset '+)
5419 (eq offset '-)
5420 (eq offset '++)
5421 (eq offset '--)
5422 (integerp offset)
5423 (fboundp offset)
5424 (boundp offset)
3dcb36b7 5425 (error "ERROR: Offset must be int, func, var, or one of +, -, ++, --: %s"
d2ddb974
KH
5426 offset))
5427 (let ((entry (assq symbol vhdl-offsets-alist)))
5428 (if entry
5429 (setcdr entry offset)
5430 (if add-p
5eabfe72
KH
5431 (setq vhdl-offsets-alist
5432 (cons (cons symbol offset) vhdl-offsets-alist))
3dcb36b7 5433 (error "ERROR: %s is not a valid syntactic symbol" symbol))))
d2ddb974
KH
5434 (vhdl-keep-region-active))
5435
5436(defun vhdl-set-style (style &optional local)
5eabfe72 5437 "Set `vhdl-mode' variables to use one of several different indentation styles.
d2ddb974
KH
5438STYLE is a string representing the desired style and optional LOCAL is
5439a flag which, if non-nil, means to make the style variables being
5440changed buffer local, instead of the default, which is to set the
5441global variables. Interactively, the flag comes from the prefix
5442argument. The styles are chosen from the `vhdl-style-alist' variable."
5443 (interactive (list (completing-read "Use which VHDL indentation style? "
5eabfe72 5444 vhdl-style-alist nil t)
d2ddb974
KH
5445 current-prefix-arg))
5446 (let ((vars (cdr (assoc style vhdl-style-alist))))
5447 (or vars
3dcb36b7 5448 (error "ERROR: Invalid VHDL indentation style `%s'" style))
d2ddb974 5449 ;; set all the variables
51b5ad57 5450 (mapc
d2ddb974
KH
5451 (function
5452 (lambda (varentry)
5453 (let ((var (car varentry))
5454 (val (cdr varentry)))
d2ddb974
KH
5455 ;; special case for vhdl-offsets-alist
5456 (if (not (eq var 'vhdl-offsets-alist))
175069ef 5457 (set (if local (make-local-variable var) var) val)
d2ddb974 5458 ;; reset vhdl-offsets-alist to the default value first
175069ef
SM
5459 (set (if local (make-local-variable var) var)
5460 (copy-alist vhdl-offsets-alist-default))
d2ddb974
KH
5461 ;; now set the langelems that are different
5462 (mapcar
5463 (function
5464 (lambda (langentry)
5465 (let ((langelem (car langentry))
5466 (offset (cdr langentry)))
5467 (vhdl-set-offset langelem offset)
5468 )))
5469 val))
5470 )))
5471 vars))
5472 (vhdl-keep-region-active))
5473
5474(defun vhdl-get-offset (langelem)
5eabfe72
KH
5475 "Get offset from LANGELEM which is a cons cell of the form:
5476\(SYMBOL . RELPOS). The symbol is matched against
5477vhdl-offsets-alist and the offset found there is either returned,
5478or added to the indentation at RELPOS. If RELPOS is nil, then
5479the offset is simply returned."
d2ddb974
KH
5480 (let* ((symbol (car langelem))
5481 (relpos (cdr langelem))
5482 (match (assq symbol vhdl-offsets-alist))
5483 (offset (cdr-safe match)))
5484 ;; offset can be a number, a function, a variable, or one of the
5485 ;; symbols + or -
5486 (cond
5487 ((not match)
5488 (if vhdl-strict-syntax-p
3dcb36b7 5489 (error "ERROR: Don't know how to indent a %s" symbol)
d2ddb974
KH
5490 (setq offset 0
5491 relpos 0)))
5492 ((eq offset '+) (setq offset vhdl-basic-offset))
5493 ((eq offset '-) (setq offset (- vhdl-basic-offset)))
5494 ((eq offset '++) (setq offset (* 2 vhdl-basic-offset)))
5495 ((eq offset '--) (setq offset (* 2 (- vhdl-basic-offset))))
5496 ((and (not (numberp offset))
5497 (fboundp offset))
5498 (setq offset (funcall offset langelem)))
5499 ((not (numberp offset))
5500 (setq offset (eval offset)))
5501 )
5502 (+ (if (and relpos
5503 (< relpos (vhdl-point 'bol)))
5504 (save-excursion
5505 (goto-char relpos)
5506 (current-column))
5507 0)
5508 offset)))
5509
5510;; Syntactic support functions:
5511
3dcb36b7
JB
5512(defun vhdl-in-comment-p ()
5513 "Check if point is in a comment."
5514 (eq (vhdl-in-literal) 'comment))
5515
5516(defun vhdl-in-string-p ()
5517 "Check if point is in a string."
5518 (eq (vhdl-in-literal) 'string))
d2ddb974 5519
fda91268
RZ
5520(defun vhdl-in-quote-p ()
5521 "Check if point is in a quote ('x')."
5522 (or (and (> (point) (point-min))
5523 (< (1+ (point)) (point-max))
5524 (= (char-before (point)) ?\')
5525 (= (char-after (1+ (point))) ?\'))
5526 (and (> (1- (point)) (point-min))
5527 (< (point) (point-max))
5528 (= (char-before (1- (point))) ?\')
5529 (= (char-after (point)) ?\'))))
5530
3dcb36b7 5531(defun vhdl-in-literal ()
5eabfe72 5532 "Determine if point is in a VHDL literal."
d2ddb974 5533 (save-excursion
5eabfe72 5534 (let ((state (parse-partial-sexp (vhdl-point 'bol) (point))))
d2ddb974
KH
5535 (cond
5536 ((nth 3 state) 'string)
5537 ((nth 4 state) 'comment)
0a2e512a 5538 ((vhdl-beginning-of-macro) 'pound)
5eabfe72 5539 (t nil)))))
d2ddb974 5540
fda91268
RZ
5541(defun vhdl-in-extended-identifier-p ()
5542 "Determine if point is inside extended identifier (delimited by '\')."
5543 (save-match-data
5544 (and (save-excursion (re-search-backward "\\\\" (vhdl-point 'bol) t))
5545 (save-excursion (re-search-forward "\\\\" (vhdl-point 'eol) t)))))
5546
3dcb36b7
JB
5547(defun vhdl-forward-comment (&optional direction)
5548 "Skip all comments (including whitespace). Skip backwards if DIRECTION is
5549negative, skip forward otherwise."
5550 (interactive "p")
5551 (if (and direction (< direction 0))
5552 ;; skip backwards
5553 (progn
fda91268 5554 (skip-chars-backward " \t\n\r\f")
3dcb36b7
JB
5555 (while (re-search-backward "^[^\"-]*\\(\\(-?\"[^\"]*\"\\|-[^\"-]\\)[^\"-]*\\)*\\(--\\)" (vhdl-point 'bol) t)
5556 (goto-char (match-beginning 3))
fda91268 5557 (skip-chars-backward " \t\n\r\f")))
3dcb36b7 5558 ;; skip forwards
fda91268 5559 (skip-chars-forward " \t\n\r\f")
3dcb36b7
JB
5560 (while (looking-at "--.*")
5561 (goto-char (match-end 0))
fda91268 5562 (skip-chars-forward " \t\n\r\f"))))
3dcb36b7
JB
5563
5564;; XEmacs hack: work around buggy `forward-comment' in XEmacs 21.4+
f8246027 5565(unless (and (featurep 'xemacs) (string< "21.2" emacs-version))
3dcb36b7
JB
5566 (defalias 'vhdl-forward-comment 'forward-comment))
5567
fda91268
RZ
5568(defun vhdl-back-to-indentation ()
5569 "Move point to the first non-whitespace character on this line."
5570 (interactive)
5571 (beginning-of-line 1)
5572 (skip-syntax-forward " " (vhdl-point 'eol)))
5573
5574;; XEmacs hack: work around old `back-to-indentation' in XEmacs
5575(when (featurep 'xemacs)
5576 (defalias 'back-to-indentation 'vhdl-back-to-indentation))
5577
d2ddb974
KH
5578;; This is the best we can do in Win-Emacs.
5579(defun vhdl-win-il (&optional lim)
5eabfe72 5580 "Determine if point is in a VHDL literal."
d2ddb974
KH
5581 (save-excursion
5582 (let* ((here (point))
5583 (state nil)
5584 (match nil)
5585 (lim (or lim (vhdl-point 'bod))))
5586 (goto-char lim )
5587 (while (< (point) here)
5588 (setq match
5589 (and (re-search-forward "--\\|[\"']"
5590 here 'move)
5591 (buffer-substring (match-beginning 0) (match-end 0))))
5592 (setq state
5593 (cond
5594 ;; no match
5595 ((null match) nil)
5596 ;; looking at the opening of a VHDL style comment
5597 ((string= "--" match)
5598 (if (<= here (progn (end-of-line) (point))) 'comment))
5599 ;; looking at the opening of a double quote string
5600 ((string= "\"" match)
5601 (if (not (save-restriction
5602 ;; this seems to be necessary since the
5603 ;; re-search-forward will not work without it
5604 (narrow-to-region (point) here)
5605 (re-search-forward
5606 ;; this regexp matches a double quote
5607 ;; which is preceded by an even number
5608 ;; of backslashes, including zero
5609 "\\([^\\]\\|^\\)\\(\\\\\\\\\\)*\"" here 'move)))
5610 'string))
5611 ;; looking at the opening of a single quote string
5612 ((string= "'" match)
5613 (if (not (save-restriction
5614 ;; see comments from above
5615 (narrow-to-region (point) here)
5616 (re-search-forward
5617 ;; this matches a single quote which is
5618 ;; preceded by zero or two backslashes.
5619 "\\([^\\]\\|^\\)\\(\\\\\\\\\\)?'"
5620 here 'move)))
5621 'string))
5622 (t nil)))
5623 ) ; end-while
5624 state)))
5625
5eabfe72 5626(and (string-match "Win-Emacs" emacs-version)
d2ddb974
KH
5627 (fset 'vhdl-in-literal 'vhdl-win-il))
5628
5629;; Skipping of "syntactic whitespace". Syntactic whitespace is
5630;; defined as lexical whitespace or comments. Search no farther back
5631;; or forward than optional LIM. If LIM is omitted, (point-min) is
5632;; used for backward skipping, (point-max) is used for forward
5633;; skipping.
5634
5635(defun vhdl-forward-syntactic-ws (&optional lim)
5eabfe72 5636 "Forward skip of syntactic whitespace."
0a2e512a
RF
5637 (let* ((here (point-max))
5638 (hugenum (point-max)))
5639 (while (/= here (point))
5640 (setq here (point))
5641 (vhdl-forward-comment hugenum)
5642 ;; skip preprocessor directives
5643 (when (and (eq (char-after) ?#)
5644 (= (vhdl-point 'boi) (point)))
5645 (while (and (eq (char-before (vhdl-point 'eol)) ?\\)
5646 (= (forward-line 1) 0)))
5647 (end-of-line)))
5648 (if lim (goto-char (min (point) lim)))))
5649
d2ddb974
KH
5650
5651;; This is the best we can do in Win-Emacs.
5652(defun vhdl-win-fsws (&optional lim)
5eabfe72 5653 "Forward skip syntactic whitespace for Win-Emacs."
d2ddb974
KH
5654 (let ((lim (or lim (point-max)))
5655 stop)
5656 (while (not stop)
5657 (skip-chars-forward " \t\n\r\f" lim)
5658 (cond
5659 ;; vhdl comment
5660 ((looking-at "--") (end-of-line))
5661 ;; none of the above
3dcb36b7 5662 (t (setq stop t))))))
d2ddb974 5663
5eabfe72 5664(and (string-match "Win-Emacs" emacs-version)
d2ddb974
KH
5665 (fset 'vhdl-forward-syntactic-ws 'vhdl-win-fsws))
5666
0a2e512a
RF
5667(defun vhdl-beginning-of-macro (&optional lim)
5668 "Go to the beginning of a cpp macro definition (nicked from `cc-engine')."
5669 (let ((here (point)))
5670 (beginning-of-line)
5671 (while (eq (char-before (1- (point))) ?\\)
5672 (forward-line -1))
5673 (back-to-indentation)
5674 (if (and (<= (point) here)
5675 (eq (char-after) ?#))
5676 t
5677 (goto-char here)
5678 nil)))
5679
d2ddb974 5680(defun vhdl-backward-syntactic-ws (&optional lim)
5eabfe72 5681 "Backward skip over syntactic whitespace."
0a2e512a
RF
5682 (let* ((here (point-min))
5683 (hugenum (- (point-max))))
5684 (while (/= here (point))
5685 (setq here (point))
5686 (vhdl-forward-comment hugenum)
5687 (vhdl-beginning-of-macro))
5688 (if lim (goto-char (max (point) lim)))))
d2ddb974
KH
5689
5690;; This is the best we can do in Win-Emacs.
5691(defun vhdl-win-bsws (&optional lim)
5eabfe72 5692 "Backward skip syntactic whitespace for Win-Emacs."
d2ddb974
KH
5693 (let ((lim (or lim (vhdl-point 'bod)))
5694 stop)
5695 (while (not stop)
5696 (skip-chars-backward " \t\n\r\f" lim)
5697 (cond
5698 ;; vhdl comment
3dcb36b7 5699 ((eq (vhdl-in-literal) 'comment)
d2ddb974
KH
5700 (skip-chars-backward "^-" lim)
5701 (skip-chars-backward "-" lim)
5702 (while (not (or (and (= (following-char) ?-)
5703 (= (char-after (1+ (point))) ?-))
5704 (<= (point) lim)))
5705 (skip-chars-backward "^-" lim)
5706 (skip-chars-backward "-" lim)))
5707 ;; none of the above
3dcb36b7 5708 (t (setq stop t))))))
d2ddb974 5709
5eabfe72 5710(and (string-match "Win-Emacs" emacs-version)
d2ddb974
KH
5711 (fset 'vhdl-backward-syntactic-ws 'vhdl-win-bsws))
5712
5713;; Functions to help finding the correct indentation column:
5714
5715(defun vhdl-first-word (point)
5716 "If the keyword at POINT is at boi, then return (current-column) at
5717that point, else nil."
5718 (save-excursion
5719 (and (goto-char point)
5720 (eq (point) (vhdl-point 'boi))
5721 (current-column))))
5722
5723(defun vhdl-last-word (point)
5724 "If the keyword at POINT is at eoi, then return (current-column) at
5725that point, else nil."
5726 (save-excursion
5727 (and (goto-char point)
5728 (save-excursion (or (eq (progn (forward-sexp) (point))
5729 (vhdl-point 'eoi))
5730 (looking-at "\\s-*\\(--\\)?")))
5731 (current-column))))
5732
5733;; Core syntactic evaluation functions:
5734
5735(defconst vhdl-libunit-re
5736 "\\b\\(architecture\\|configuration\\|entity\\|package\\)\\b[^_]")
5737
5738(defun vhdl-libunit-p ()
5739 (and
5740 (save-excursion
5741 (forward-sexp)
fda91268 5742 (skip-chars-forward " \t\n\r\f")
d2ddb974
KH
5743 (not (looking-at "is\\b[^_]")))
5744 (save-excursion
5745 (backward-sexp)
5746 (and (not (looking-at "use\\b[^_]"))
5747 (progn
5748 (forward-sexp)
5749 (vhdl-forward-syntactic-ws)
5750 (/= (following-char) ?:))))
5751 ))
5752
5753(defconst vhdl-defun-re
5eabfe72 5754 "\\b\\(architecture\\|block\\|configuration\\|entity\\|package\\|process\\|procedural\\|procedure\\|function\\)\\b[^_]")
d2ddb974
KH
5755
5756(defun vhdl-defun-p ()
5757 (save-excursion
5eabfe72
KH
5758 (if (looking-at "block\\|process\\|procedural")
5759 ;; "block", "process", "procedural":
d2ddb974
KH
5760 (save-excursion
5761 (backward-sexp)
5762 (not (looking-at "end\\s-+\\w")))
5763 ;; "architecture", "configuration", "entity",
5764 ;; "package", "procedure", "function":
5765 t)))
5766
5767(defun vhdl-corresponding-defun ()
5768 "If the word at the current position corresponds to a \"defun\"
5769keyword, then return a string that can be used to find the
5770corresponding \"begin\" keyword, else return nil."
5771 (save-excursion
5772 (and (looking-at vhdl-defun-re)
5773 (vhdl-defun-p)
5eabfe72
KH
5774 (if (looking-at "block\\|process\\|procedural")
5775 ;; "block", "process". "procedural:
d2ddb974
KH
5776 (buffer-substring (match-beginning 0) (match-end 0))
5777 ;; "architecture", "configuration", "entity", "package",
5778 ;; "procedure", "function":
5779 "is"))))
5780
5781(defconst vhdl-begin-fwd-re
fda91268 5782 "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\(\\s-+body\\)?\\|units\\|use\\|record\\|protected\\(\\s-+body\\)?\\|for\\)\\b\\([^_]\\|\\'\\)"
d2ddb974
KH
5783 "A regular expression for searching forward that matches all known
5784\"begin\" keywords.")
5785
5786(defconst vhdl-begin-bwd-re
fda91268 5787 "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|procedural\\(\\s-+body\\)?\\|units\\|use\\|record\\|protected\\(\\s-+body\\)?\\|for\\)\\b[^_]"
d2ddb974
KH
5788 "A regular expression for searching backward that matches all known
5789\"begin\" keywords.")
5790
5791(defun vhdl-begin-p (&optional lim)
5792 "Return t if we are looking at a real \"begin\" keyword.
5793Assumes that the caller will make sure that we are looking at
5794vhdl-begin-fwd-re, and are not inside a literal, and that we are not in
5795the middle of an identifier that just happens to contain a \"begin\"
5796keyword."
5797 (cond
5798 ;; "[architecture|case|configuration|entity|package|
5799 ;; procedure|function] ... is":
5800 ((and (looking-at "i")
5801 (save-excursion
5802 ;; Skip backward over first sexp (needed to skip over a
5803 ;; procedure interface list, and is harmless in other
5804 ;; situations). Note that we need "return" in the
5805 ;; following search list so that we don't run into
5806 ;; semicolons in the function interface list.
5807 (backward-sexp)
5808 (let (foundp)
5809 (while (and (not foundp)
5810 (re-search-backward
5eabfe72 5811 ";\\|\\b\\(architecture\\|case\\|configuration\\|entity\\|package\\|procedure\\|return\\|is\\|begin\\|process\\|procedural\\|block\\)\\b[^_]"
d2ddb974
KH
5812 lim 'move))
5813 (if (or (= (preceding-char) ?_)
3dcb36b7 5814 (vhdl-in-literal))
d2ddb974
KH
5815 (backward-char)
5816 (setq foundp t))))
5817 (and (/= (following-char) ?\;)
5eabfe72 5818 (not (looking-at "is\\|begin\\|process\\|procedural\\|block")))))
d2ddb974 5819 t)
fda91268
RZ
5820 ;; "begin", "then", "use":
5821 ((looking-at "be\\|t\\|use")
d2ddb974
KH
5822 t)
5823 ;; "else":
5824 ((and (looking-at "e")
5825 ;; make sure that the "else" isn't inside a
5826 ;; conditional signal assignment.
5827 (save-excursion
fda91268 5828 (vhdl-re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move)
d2ddb974
KH
5829 (or (eq (following-char) ?\;)
5830 (eq (point) lim))))
5831 t)
5eabfe72 5832 ;; "block", "generate", "loop", "process", "procedural",
fda91268
RZ
5833 ;; "units", "record", "protected body":
5834 ((and (looking-at "block\\|generate\\|loop\\|process\\|procedural\\|protected\\(\\s-+body\\)?\\|units\\|record")
d2ddb974
KH
5835 (save-excursion
5836 (backward-sexp)
5837 (not (looking-at "end\\s-+\\w"))))
5838 t)
5839 ;; "component":
5840 ((and (looking-at "c")
5841 (save-excursion
5842 (backward-sexp)
5843 (not (looking-at "end\\s-+\\w")))
5844 ;; look out for the dreaded entity class in an attribute
5845 (save-excursion
5846 (vhdl-backward-syntactic-ws lim)
5847 (/= (preceding-char) ?:)))
5848 t)
5849 ;; "for" (inside configuration declaration):
5850 ((and (looking-at "f")
5851 (save-excursion
5852 (backward-sexp)
5853 (not (looking-at "end\\s-+\\w")))
5854 (vhdl-has-syntax 'configuration))
5855 t)
5856 ))
5857
5858(defun vhdl-corresponding-mid (&optional lim)
5859 (cond
5eabfe72 5860 ((looking-at "is\\|block\\|generate\\|process\\|procedural")
d2ddb974 5861 "begin")
fda91268 5862 ((looking-at "then\\|use")
d2ddb974
KH
5863 "<else>")
5864 (t
5865 "end")))
5866
5867(defun vhdl-corresponding-end (&optional lim)
5868 "If the word at the current position corresponds to a \"begin\"
5869keyword, then return a vector containing enough information to find
5870the corresponding \"end\" keyword, else return nil. The keyword to
5871search forward for is aref 0. The column in which the keyword must
5872appear is aref 1 or nil if any column is suitable.
5873Assumes that the caller will make sure that we are not in the middle
5874of an identifier that just happens to contain a \"begin\" keyword."
5875 (save-excursion
5876 (and (looking-at vhdl-begin-fwd-re)
fda91268
RZ
5877 (or (not (looking-at "\\<use\\>"))
5878 (save-excursion (back-to-indentation)
5879 (looking-at "\\(\\w+\\s-*:\\s-*\\)?\\<\\(case\\|elsif\\|if\\)\\>")))
d2ddb974 5880 (/= (preceding-char) ?_)
3dcb36b7 5881 (not (vhdl-in-literal))
d2ddb974
KH
5882 (vhdl-begin-p lim)
5883 (cond
5884 ;; "is", "generate", "loop":
5885 ((looking-at "[igl]")
5886 (vector "end"
5887 (and (vhdl-last-word (point))
5888 (or (vhdl-first-word (point))
5889 (save-excursion
5890 (vhdl-beginning-of-statement-1 lim)
5891 (vhdl-backward-skip-label lim)
5892 (vhdl-first-word (point)))))))
5893 ;; "begin", "else", "for":
5894 ((looking-at "be\\|[ef]")
5895 (vector "end"
5896 (and (vhdl-last-word (point))
5897 (or (vhdl-first-word (point))
5898 (save-excursion
5899 (vhdl-beginning-of-statement-1 lim)
5900 (vhdl-backward-skip-label lim)
5901 (vhdl-first-word (point)))))))
fda91268
RZ
5902 ;; "component", "units", "record", "protected body":
5903 ((looking-at "component\\|units\\|protected\\(\\s-+body\\)?\\|record")
d2ddb974
KH
5904 ;; The first end found will close the block
5905 (vector "end" nil))
5eabfe72 5906 ;; "block", "process", "procedural":
d2ddb974
KH
5907 ((looking-at "bl\\|p")
5908 (vector "end"
5909 (or (vhdl-first-word (point))
5910 (save-excursion
5911 (vhdl-beginning-of-statement-1 lim)
5912 (vhdl-backward-skip-label lim)
5913 (vhdl-first-word (point))))))
5914 ;; "then":
fda91268
RZ
5915 ((looking-at "t\\|use")
5916 (vector "elsif\\|else\\|end\\s-+\\(if\\|use\\)"
d2ddb974
KH
5917 (and (vhdl-last-word (point))
5918 (or (vhdl-first-word (point))
5919 (save-excursion
5920 (vhdl-beginning-of-statement-1 lim)
5921 (vhdl-backward-skip-label lim)
5922 (vhdl-first-word (point)))))))
5923 ))))
5924
5925(defconst vhdl-end-fwd-re "\\b\\(end\\|else\\|elsif\\)\\b\\([^_]\\|\\'\\)")
5926
5927(defconst vhdl-end-bwd-re "\\b\\(end\\|else\\|elsif\\)\\b[^_]")
5928
5929(defun vhdl-end-p (&optional lim)
5930 "Return t if we are looking at a real \"end\" keyword.
5931Assumes that the caller will make sure that we are looking at
5932vhdl-end-fwd-re, and are not inside a literal, and that we are not in
5933the middle of an identifier that just happens to contain an \"end\"
5934keyword."
5935 (or (not (looking-at "else"))
5936 ;; make sure that the "else" isn't inside a conditional signal
5937 ;; assignment.
5938 (save-excursion
5939 (re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move)
5940 (or (eq (following-char) ?\;)
0a2e512a
RF
5941 (eq (point) lim)
5942 (vhdl-in-literal)))))
d2ddb974
KH
5943
5944(defun vhdl-corresponding-begin (&optional lim)
5945 "If the word at the current position corresponds to an \"end\"
5946keyword, then return a vector containing enough information to find
5947the corresponding \"begin\" keyword, else return nil. The keyword to
a4c6cfad 5948search backward for is aref 0. The column in which the keyword must
d2ddb974
KH
5949appear is aref 1 or nil if any column is suitable. The supplementary
5950keyword to search forward for is aref 2 or nil if this is not
5951required. If aref 3 is t, then the \"begin\" keyword may be found in
5952the middle of a statement.
5953Assumes that the caller will make sure that we are not in the middle
5954of an identifier that just happens to contain an \"end\" keyword."
5955 (save-excursion
5956 (let (pos)
5957 (if (and (looking-at vhdl-end-fwd-re)
3dcb36b7 5958 (not (vhdl-in-literal))
d2ddb974
KH
5959 (vhdl-end-p lim))
5960 (if (looking-at "el")
5961 ;; "else", "elsif":
fda91268 5962 (vector "if\\|elsif" (vhdl-first-word (point)) "then\\|use" nil)
d2ddb974
KH
5963 ;; "end ...":
5964 (setq pos (point))
5965 (forward-sexp)
fda91268 5966 (skip-chars-forward " \t\n\r\f")
d2ddb974
KH
5967 (cond
5968 ;; "end if":
5969 ((looking-at "if\\b[^_]")
5970 (vector "else\\|elsif\\|if"
5971 (vhdl-first-word pos)
fda91268 5972 "else\\|then\\|use" nil))
d2ddb974
KH
5973 ;; "end component":
5974 ((looking-at "component\\b[^_]")
5975 (vector (buffer-substring (match-beginning 1)
5976 (match-end 1))
5977 (vhdl-first-word pos)
5978 nil nil))
fda91268
RZ
5979 ;; "end units", "end record", "end protected":
5980 ((looking-at "\\(units\\|record\\|protected\\(\\s-+body\\)?\\)\\b[^_]")
d2ddb974
KH
5981 (vector (buffer-substring (match-beginning 1)
5982 (match-end 1))
5983 (vhdl-first-word pos)
5984 nil t))
5eabfe72
KH
5985 ;; "end block", "end process", "end procedural":
5986 ((looking-at "\\(block\\|process\\|procedural\\)\\b[^_]")
d2ddb974
KH
5987 (vector "begin" (vhdl-first-word pos) nil nil))
5988 ;; "end case":
5989 ((looking-at "case\\b[^_]")
5990 (vector "case" (vhdl-first-word pos) "is" nil))
5991 ;; "end generate":
5992 ((looking-at "generate\\b[^_]")
5993 (vector "generate\\|for\\|if"
5994 (vhdl-first-word pos)
5995 "generate" nil))
5996 ;; "end loop":
5997 ((looking-at "loop\\b[^_]")
5998 (vector "loop\\|while\\|for"
5999 (vhdl-first-word pos)
6000 "loop" nil))
6001 ;; "end for" (inside configuration declaration):
6002 ((looking-at "for\\b[^_]")
6003 (vector "for" (vhdl-first-word pos) nil nil))
6004 ;; "end [id]":
6005 (t
6006 (vector "begin\\|architecture\\|configuration\\|entity\\|package\\|procedure\\|function"
6007 (vhdl-first-word pos)
6008 ;; return an alist of (statement . keyword) mappings
6009 '(
6010 ;; "begin ... end [id]":
0a2e512a 6011 ("begin" . nil)
d2ddb974 6012 ;; "architecture ... is ... begin ... end [id]":
0a2e512a 6013 ("architecture" . "is")
d2ddb974
KH
6014 ;; "configuration ... is ... end [id]":
6015 ("configuration" . "is")
6016 ;; "entity ... is ... end [id]":
0a2e512a 6017 ("entity" . "is")
d2ddb974 6018 ;; "package ... is ... end [id]":
0a2e512a 6019 ("package" . "is")
d2ddb974
KH
6020 ;; "procedure ... is ... begin ... end [id]":
6021 ("procedure" . "is")
6022 ;; "function ... is ... begin ... end [id]":
6023 ("function" . "is")
6024 )
6025 nil))
6026 ))) ; "end ..."
6027 )))
6028
6029(defconst vhdl-leader-re
5eabfe72 6030 "\\b\\(block\\|component\\|process\\|procedural\\|for\\)\\b[^_]")
d2ddb974
KH
6031
6032(defun vhdl-end-of-leader ()
6033 (save-excursion
5eabfe72 6034 (cond ((looking-at "block\\|process\\|procedural")
d2ddb974
KH
6035 (if (save-excursion
6036 (forward-sexp)
fda91268 6037 (skip-chars-forward " \t\n\r\f")
d2ddb974
KH
6038 (= (following-char) ?\())
6039 (forward-sexp 2)
6040 (forward-sexp))
fda91268 6041 (when (looking-at "[ \t\n\r\f]*is")
3dcb36b7 6042 (goto-char (match-end 0)))
d2ddb974
KH
6043 (point))
6044 ((looking-at "component")
6045 (forward-sexp 2)
fda91268 6046 (when (looking-at "[ \t\n\r\f]*is")
3dcb36b7 6047 (goto-char (match-end 0)))
d2ddb974
KH
6048 (point))
6049 ((looking-at "for")
6050 (forward-sexp 2)
fda91268 6051 (skip-chars-forward " \t\n\r\f")
d2ddb974
KH
6052 (while (looking-at "[,:(]")
6053 (forward-sexp)
fda91268 6054 (skip-chars-forward " \t\n\r\f"))
d2ddb974
KH
6055 (point))
6056 (t nil)
6057 )))
6058
6059(defconst vhdl-trailer-re
fda91268 6060 "\\b\\(is\\|then\\|generate\\|loop\\|record\\|protected\\(\\s-+body\\)?\\|use\\)\\b[^_]")
d2ddb974
KH
6061
6062(defconst vhdl-statement-fwd-re
fda91268 6063 "\\b\\(if\\|for\\|while\\|loop\\)\\b\\([^_]\\|\\'\\)"
d2ddb974
KH
6064 "A regular expression for searching forward that matches all known
6065\"statement\" keywords.")
6066
6067(defconst vhdl-statement-bwd-re
fda91268 6068 "\\b\\(if\\|for\\|while\\|loop\\)\\b[^_]"
d2ddb974
KH
6069 "A regular expression for searching backward that matches all known
6070\"statement\" keywords.")
6071
6072(defun vhdl-statement-p (&optional lim)
6073 "Return t if we are looking at a real \"statement\" keyword.
6074Assumes that the caller will make sure that we are looking at
5eabfe72
KH
6075vhdl-statement-fwd-re, and are not inside a literal, and that we are not
6076in the middle of an identifier that just happens to contain a
6077\"statement\" keyword."
d2ddb974
KH
6078 (cond
6079 ;; "for" ... "generate":
6080 ((and (looking-at "f")
6081 ;; Make sure it's the start of a parameter specification.
6082 (save-excursion
6083 (forward-sexp 2)
fda91268 6084 (skip-chars-forward " \t\n\r\f")
d2ddb974
KH
6085 (looking-at "in\\b[^_]"))
6086 ;; Make sure it's not an "end for".
6087 (save-excursion
6088 (backward-sexp)
6089 (not (looking-at "end\\s-+\\w"))))
6090 t)
6091 ;; "if" ... "then", "if" ... "generate", "if" ... "loop":
6092 ((and (looking-at "i")
6093 ;; Make sure it's not an "end if".
6094 (save-excursion
6095 (backward-sexp)
6096 (not (looking-at "end\\s-+\\w"))))
6097 t)
6098 ;; "while" ... "loop":
6099 ((looking-at "w")
6100 t)
6101 ))
6102
fda91268 6103(defconst vhdl-case-alternative-re "when[( \t\n\r\f][^;=>]+=>"
d2ddb974
KH
6104 "Regexp describing a case statement alternative key.")
6105
6106(defun vhdl-case-alternative-p (&optional lim)
6107 "Return t if we are looking at a real case alternative.
6108Assumes that the caller will make sure that we are looking at
6109vhdl-case-alternative-re, and are not inside a literal, and that
6110we are not in the middle of an identifier that just happens to
6111contain a \"when\" keyword."
6112 (save-excursion
6113 (let (foundp)
6114 (while (and (not foundp)
6115 (re-search-backward ";\\|<=" lim 'move))
6116 (if (or (= (preceding-char) ?_)
3dcb36b7 6117 (vhdl-in-literal))
d2ddb974
KH
6118 (backward-char)
6119 (setq foundp t)))
6120 (or (eq (following-char) ?\;)
6121 (eq (point) lim)))
6122 ))
6123
6124;; Core syntactic movement functions:
6125
6126(defconst vhdl-b-t-b-re
6127 (concat vhdl-begin-bwd-re "\\|" vhdl-end-bwd-re))
6128
6129(defun vhdl-backward-to-block (&optional lim)
6130 "Move backward to the previous \"begin\" or \"end\" keyword."
6131 (let (foundp)
6132 (while (and (not foundp)
6133 (re-search-backward vhdl-b-t-b-re lim 'move))
6134 (if (or (= (preceding-char) ?_)
3dcb36b7 6135 (vhdl-in-literal))
d2ddb974
KH
6136 (backward-char)
6137 (cond
6138 ;; "begin" keyword:
6139 ((and (looking-at vhdl-begin-fwd-re)
fda91268
RZ
6140 (or (not (looking-at "\\<use\\>"))
6141 (save-excursion (back-to-indentation)
6142 (looking-at "\\(\\w+\\s-*:\\s-*\\)?\\<\\(case\\|elsif\\|if\\)\\>")))
d2ddb974
KH
6143 (/= (preceding-char) ?_)
6144 (vhdl-begin-p lim))
6145 (setq foundp 'begin))
6146 ;; "end" keyword:
6147 ((and (looking-at vhdl-end-fwd-re)
6148 (/= (preceding-char) ?_)
6149 (vhdl-end-p lim))
6150 (setq foundp 'end))
6151 ))
6152 )
6153 foundp
6154 ))
6155
6156(defun vhdl-forward-sexp (&optional count lim)
6157 "Move forward across one balanced expression (sexp).
6158With COUNT, do it that many times."
6159 (interactive "p")
6160 (let ((count (or count 1))
6161 (case-fold-search t)
6162 end-vec target)
6163 (save-excursion
6164 (while (> count 0)
6165 ;; skip whitespace
fda91268 6166 (skip-chars-forward " \t\n\r\f")
d2ddb974
KH
6167 ;; Check for an unbalanced "end" keyword
6168 (if (and (looking-at vhdl-end-fwd-re)
6169 (/= (preceding-char) ?_)
3dcb36b7 6170 (not (vhdl-in-literal))
d2ddb974
KH
6171 (vhdl-end-p lim)
6172 (not (looking-at "else")))
6173 (error
3dcb36b7 6174 "ERROR: Containing expression ends prematurely in vhdl-forward-sexp"))
d2ddb974
KH
6175 ;; If the current keyword is a "begin" keyword, then find the
6176 ;; corresponding "end" keyword.
6177 (if (setq end-vec (vhdl-corresponding-end lim))
6178 (let (
6179 ;; end-re is the statement keyword to search for
6180 (end-re
6181 (concat "\\b\\(" (aref end-vec 0) "\\)\\b\\([^_]\\|\\'\\)"))
6182 ;; column is either the statement keyword target column
6183 ;; or nil
6184 (column (aref end-vec 1))
6185 (eol (vhdl-point 'eol))
6186 foundp literal placeholder)
6187 ;; Look for the statement keyword.
6188 (while (and (not foundp)
6189 (re-search-forward end-re nil t)
6190 (setq placeholder (match-end 1))
6191 (goto-char (match-beginning 0)))
6192 ;; If we are in a literal, or not in the right target
6193 ;; column and not on the same line as the begin, then
6194 ;; try again.
6195 (if (or (and column
6196 (/= (current-indentation) column)
6197 (> (point) eol))
6198 (= (preceding-char) ?_)
3dcb36b7 6199 (setq literal (vhdl-in-literal)))
d2ddb974
KH
6200 (if (eq literal 'comment)
6201 (end-of-line)
6202 (forward-char))
6203 ;; An "else" keyword corresponds to both the opening brace
6204 ;; of the following sexp and the closing brace of the
6205 ;; previous sexp.
6206 (if (not (looking-at "else"))
6207 (goto-char placeholder))
6208 (setq foundp t))
6209 )
6210 (if (not foundp)
3dcb36b7 6211 (error "ERROR: Unbalanced keywords in vhdl-forward-sexp"))
d2ddb974
KH
6212 )
6213 ;; If the current keyword is not a "begin" keyword, then just
6214 ;; perform the normal forward-sexp.
6215 (forward-sexp)
6216 )
6217 (setq count (1- count))
6218 )
6219 (setq target (point)))
6220 (goto-char target)
6221 nil))
6222
6223(defun vhdl-backward-sexp (&optional count lim)
6224 "Move backward across one balanced expression (sexp).
6225With COUNT, do it that many times. LIM bounds any required backward
6226searches."
6227 (interactive "p")
6228 (let ((count (or count 1))
6229 (case-fold-search t)
6230 begin-vec target)
6231 (save-excursion
6232 (while (> count 0)
6233 ;; Perform the normal backward-sexp, unless we are looking at
6234 ;; "else" - an "else" keyword corresponds to both the opening brace
6235 ;; of the following sexp and the closing brace of the previous sexp.
6236 (if (and (looking-at "else\\b\\([^_]\\|\\'\\)")
6237 (/= (preceding-char) ?_)
3dcb36b7 6238 (not (vhdl-in-literal)))
d2ddb974
KH
6239 nil
6240 (backward-sexp)
6241 (if (and (looking-at vhdl-begin-fwd-re)
fda91268
RZ
6242 (or (not (looking-at "\\<use\\>"))
6243 (save-excursion
6244 (back-to-indentation)
6245 (looking-at "\\(\\w+\\s-*:\\s-*\\)?\\<\\(case\\|elsif\\|if\\)\\>")))
d2ddb974 6246 (/= (preceding-char) ?_)
3dcb36b7 6247 (not (vhdl-in-literal))
d2ddb974 6248 (vhdl-begin-p lim))
3dcb36b7 6249 (error "ERROR: Containing expression ends prematurely in vhdl-backward-sexp")))
d2ddb974
KH
6250 ;; If the current keyword is an "end" keyword, then find the
6251 ;; corresponding "begin" keyword.
6252 (if (and (setq begin-vec (vhdl-corresponding-begin lim))
6253 (/= (preceding-char) ?_))
6254 (let (
6255 ;; begin-re is the statement keyword to search for
6256 (begin-re
6257 (concat "\\b\\(" (aref begin-vec 0) "\\)\\b[^_]"))
6258 ;; column is either the statement keyword target column
6259 ;; or nil
6260 (column (aref begin-vec 1))
6261 ;; internal-p controls where the statement keyword can
6262 ;; be found.
6263 (internal-p (aref begin-vec 3))
6264 (last-backward (point)) last-forward
6265 foundp literal keyword)
6266 ;; Look for the statement keyword.
6267 (while (and (not foundp)
6268 (re-search-backward begin-re lim t)
6269 (setq keyword
6270 (buffer-substring (match-beginning 1)
6271 (match-end 1))))
6272 ;; If we are in a literal or in the wrong column,
6273 ;; then try again.
6274 (if (or (and column
6275 (and (/= (current-indentation) column)
6276 ;; possibly accept current-column as
6277 ;; well as current-indentation.
6278 (or (not internal-p)
6279 (/= (current-column) column))))
6280 (= (preceding-char) ?_)
3dcb36b7 6281 (vhdl-in-literal))
d2ddb974
KH
6282 (backward-char)
6283 ;; If there is a supplementary keyword, then
6284 ;; search forward for it.
6285 (if (and (setq begin-re (aref begin-vec 2))
6286 (or (not (listp begin-re))
6287 ;; If begin-re is an alist, then find the
6288 ;; element corresponding to the actual
6289 ;; keyword that we found.
6290 (progn
6291 (setq begin-re
6292 (assoc keyword begin-re))
6293 (and begin-re
6294 (setq begin-re (cdr begin-re))))))
6295 (and
6296 (setq begin-re
6297 (concat "\\b\\(" begin-re "\\)\\b[^_]"))
6298 (save-excursion
6299 (setq last-forward (point))
6300 ;; Look for the supplementary keyword
6301 ;; (bounded by the backward search start
6302 ;; point).
6303 (while (and (not foundp)
6304 (re-search-forward begin-re
6305 last-backward t)
6306 (goto-char (match-beginning 1)))
6307 ;; If we are in a literal, then try again.
6308 (if (or (= (preceding-char) ?_)
6309 (setq literal
3dcb36b7 6310 (vhdl-in-literal)))
d2ddb974
KH
6311 (if (eq literal 'comment)
6312 (goto-char
6313 (min (vhdl-point 'eol) last-backward))
6314 (forward-char))
6315 ;; We have found the supplementary keyword.
6316 ;; Save the position of the keyword in foundp.
6317 (setq foundp (point)))
6318 )
6319 foundp)
6320 ;; If the supplementary keyword was found, then
6321 ;; move point to the supplementary keyword.
6322 (goto-char foundp))
6323 ;; If there was no supplementary keyword, then
6324 ;; point is already at the statement keyword.
6325 (setq foundp t)))
6326 ) ; end of the search for the statement keyword
6327 (if (not foundp)
3dcb36b7 6328 (error "ERROR: Unbalanced keywords in vhdl-backward-sexp"))
d2ddb974
KH
6329 ))
6330 (setq count (1- count))
6331 )
6332 (setq target (point)))
6333 (goto-char target)
6334 nil))
6335
6336(defun vhdl-backward-up-list (&optional count limit)
6337 "Move backward out of one level of blocks.
6338With argument, do this that many times."
6339 (interactive "p")
6340 (let ((count (or count 1))
6341 target)
6342 (save-excursion
6343 (while (> count 0)
6344 (if (looking-at vhdl-defun-re)
3dcb36b7 6345 (error "ERROR: Unbalanced blocks"))
d2ddb974
KH
6346 (vhdl-backward-to-block limit)
6347 (setq count (1- count)))
6348 (setq target (point)))
6349 (goto-char target)))
6350
6351(defun vhdl-end-of-defun (&optional count)
6352 "Move forward to the end of a VHDL defun."
6353 (interactive)
6354 (let ((case-fold-search t))
6355 (vhdl-beginning-of-defun)
5eabfe72 6356 (if (not (looking-at "block\\|process\\|procedural"))
d2ddb974
KH
6357 (re-search-forward "\\bis\\b"))
6358 (vhdl-forward-sexp)))
6359
6360(defun vhdl-mark-defun ()
6361 "Put mark at end of this \"defun\", point at beginning."
6362 (interactive)
6363 (let ((case-fold-search t))
6364 (push-mark)
6365 (vhdl-beginning-of-defun)
6366 (push-mark)
5eabfe72 6367 (if (not (looking-at "block\\|process\\|procedural"))
d2ddb974
KH
6368 (re-search-forward "\\bis\\b"))
6369 (vhdl-forward-sexp)
6370 (exchange-point-and-mark)))
6371
6372(defun vhdl-beginning-of-libunit ()
6373 "Move backward to the beginning of a VHDL library unit.
6374Returns the location of the corresponding begin keyword, unless search
5eabfe72
KH
6375stops due to beginning or end of buffer.
6376Note that if point is between the \"libunit\" keyword and the
6377corresponding \"begin\" keyword, then that libunit will not be
a3dd3c0e
JB
6378recognized, and the search will continue backwards. If point is
6379at the \"begin\" keyword, then the defun will be recognized. The
5eabfe72 6380returned point is at the first character of the \"libunit\" keyword."
d2ddb974
KH
6381 (let ((last-forward (point))
6382 (last-backward
6383 ;; Just in case we are actually sitting on the "begin"
6384 ;; keyword, allow for the keyword and an extra character,
6385 ;; as this will be used when looking forward for the
6386 ;; "begin" keyword.
6387 (save-excursion (forward-word 1) (1+ (point))))
6388 foundp literal placeholder)
6389 ;; Find the "libunit" keyword.
6390 (while (and (not foundp)
6391 (re-search-backward vhdl-libunit-re nil 'move))
6392 ;; If we are in a literal, or not at a real libunit, then try again.
6393 (if (or (= (preceding-char) ?_)
3dcb36b7 6394 (vhdl-in-literal)
d2ddb974
KH
6395 (not (vhdl-libunit-p)))
6396 (backward-char)
6397 ;; Find the corresponding "begin" keyword.
6398 (setq last-forward (point))
6399 (while (and (not foundp)
6400 (re-search-forward "\\bis\\b[^_]" last-backward t)
6401 (setq placeholder (match-beginning 0)))
6402 (if (or (= (preceding-char) ?_)
3dcb36b7 6403 (setq literal (vhdl-in-literal)))
d2ddb974
KH
6404 ;; It wasn't a real keyword, so keep searching.
6405 (if (eq literal 'comment)
6406 (goto-char
6407 (min (vhdl-point 'eol) last-backward))
6408 (forward-char))
6409 ;; We have found the begin keyword, loop will exit.
6410 (setq foundp placeholder)))
6411 ;; Go back to the libunit keyword
6412 (goto-char last-forward)))
6413 foundp))
6414
6415(defun vhdl-beginning-of-defun (&optional count)
6416 "Move backward to the beginning of a VHDL defun.
6417With argument, do it that many times.
6418Returns the location of the corresponding begin keyword, unless search
6419stops due to beginning or end of buffer."
6420 ;; Note that if point is between the "defun" keyword and the
6421 ;; corresponding "begin" keyword, then that defun will not be
0a2e512a
RF
6422 ;; recognized, and the search will continue backwards. If point is
6423 ;; at the "begin" keyword, then the defun will be recognized. The
d2ddb974
KH
6424 ;; returned point is at the first character of the "defun" keyword.
6425 (interactive "p")
6426 (let ((count (or count 1))
6427 (case-fold-search t)
6428 (last-forward (point))
6429 foundp)
6430 (while (> count 0)
6431 (setq foundp nil)
6432 (goto-char last-forward)
6433 (let ((last-backward
6434 ;; Just in case we are actually sitting on the "begin"
6435 ;; keyword, allow for the keyword and an extra character,
6436 ;; as this will be used when looking forward for the
6437 ;; "begin" keyword.
6438 (save-excursion (forward-word 1) (1+ (point))))
6439 begin-string literal)
6440 (while (and (not foundp)
6441 (re-search-backward vhdl-defun-re nil 'move))
6442 ;; If we are in a literal, then try again.
6443 (if (or (= (preceding-char) ?_)
3dcb36b7 6444 (vhdl-in-literal))
d2ddb974
KH
6445 (backward-char)
6446 (if (setq begin-string (vhdl-corresponding-defun))
6447 ;; This is a real defun keyword.
6448 ;; Find the corresponding "begin" keyword.
6449 ;; Look for the begin keyword.
6450 (progn
6451 ;; Save the search start point.
6452 (setq last-forward (point))
6453 (while (and (not foundp)
6454 (search-forward begin-string last-backward t))
6455 (if (or (= (preceding-char) ?_)
6456 (save-match-data
3dcb36b7 6457 (setq literal (vhdl-in-literal))))
d2ddb974
KH
6458 ;; It wasn't a real keyword, so keep searching.
6459 (if (eq literal 'comment)
6460 (goto-char
6461 (min (vhdl-point 'eol) last-backward))
6462 (forward-char))
6463 ;; We have found the begin keyword, loop will exit.
6464 (setq foundp (match-beginning 0)))
6465 )
6466 ;; Go back to the defun keyword
6467 (goto-char last-forward)) ; end search for begin keyword
6468 ))
6469 ) ; end of the search for the defun keyword
6470 )
6471 (setq count (1- count))
6472 )
6473 (vhdl-keep-region-active)
6474 foundp))
6475
8d422bd5 6476(defun vhdl-beginning-of-statement (&optional count lim interactive)
d2ddb974
KH
6477 "Go to the beginning of the innermost VHDL statement.
6478With prefix arg, go back N - 1 statements. If already at the
6479beginning of a statement then go to the beginning of the preceding
6480one. If within a string or comment, or next to a comment (only
6481whitespace between), move by sentences instead of statements.
6482
8d422bd5 6483When called from a program, this function takes 3 optional args: the
0a2e512a
RF
6484prefix arg, a buffer position limit which is the farthest back to
6485search, and an argument indicating an interactive call."
8d422bd5 6486 (interactive "p\np")
d2ddb974
KH
6487 (let ((count (or count 1))
6488 (case-fold-search t)
6489 (lim (or lim (point-min)))
6490 (here (point))
6491 state)
6492 (save-excursion
6493 (goto-char lim)
6494 (setq state (parse-partial-sexp (point) here nil nil)))
8d422bd5 6495 (if (and interactive
d2ddb974
KH
6496 (or (nth 3 state)
6497 (nth 4 state)
6498 (looking-at (concat "[ \t]*" comment-start-skip))))
6499 (forward-sentence (- count))
6500 (while (> count 0)
6501 (vhdl-beginning-of-statement-1 lim)
6502 (setq count (1- count))))
6503 ;; its possible we've been left up-buf of lim
6504 (goto-char (max (point) lim))
6505 )
6506 (vhdl-keep-region-active))
6507
6508(defconst vhdl-e-o-s-re
6509 (concat ";\\|" vhdl-begin-fwd-re "\\|" vhdl-statement-fwd-re))
6510
6511(defun vhdl-end-of-statement ()
6512 "Very simple implementation."
6513 (interactive)
6514 (re-search-forward vhdl-e-o-s-re))
6515
6516(defconst vhdl-b-o-s-re
fda91268 6517 (concat ";[^_]\\|\([^_]\\|\)[^_]\\|\\bwhen\\b[^_]\\|"
d2ddb974
KH
6518 vhdl-begin-bwd-re "\\|" vhdl-statement-bwd-re))
6519
6520(defun vhdl-beginning-of-statement-1 (&optional lim)
5eabfe72
KH
6521 "Move to the start of the current statement, or the previous
6522statement if already at the beginning of one."
d2ddb974
KH
6523 (let ((lim (or lim (point-min)))
6524 (here (point))
6525 (pos (point))
6526 donep)
6527 ;; go backwards one balanced expression, but be careful of
6528 ;; unbalanced paren being reached
6529 (if (not (vhdl-safe (progn (backward-sexp) t)))
6530 (progn
6531 (backward-up-list 1)
6532 (forward-char)
6533 (vhdl-forward-syntactic-ws here)
6534 (setq donep t)))
6535 (while (and (not donep)
6536 (not (bobp))
6537 ;; look backwards for a statement boundary
fda91268 6538 (progn (forward-char) (re-search-backward vhdl-b-o-s-re lim 'move)))
d2ddb974 6539 (if (or (= (preceding-char) ?_)
3dcb36b7 6540 (vhdl-in-literal))
d2ddb974
KH
6541 (backward-char)
6542 (cond
6543 ;; If we are looking at an open paren, then stop after it
6544 ((eq (following-char) ?\()
6545 (forward-char)
6546 (vhdl-forward-syntactic-ws here)
6547 (setq donep t))
6548 ;; If we are looking at a close paren, then skip it
6549 ((eq (following-char) ?\))
6550 (forward-char)
6551 (setq pos (point))
6552 (backward-sexp)
6553 (if (< (point) lim)
6554 (progn (goto-char pos)
6555 (vhdl-forward-syntactic-ws here)
6556 (setq donep t))))
6557 ;; If we are looking at a semicolon, then stop
fda91268 6558 ((and (eq (following-char) ?\;) (not (vhdl-in-quote-p)))
d2ddb974
KH
6559 (progn
6560 (forward-char)
6561 (vhdl-forward-syntactic-ws here)
6562 (setq donep t)))
6563 ;; If we are looking at a "begin", then stop
6564 ((and (looking-at vhdl-begin-fwd-re)
fda91268
RZ
6565 (or (not (looking-at "\\<use\\>"))
6566 (save-excursion
6567 (back-to-indentation)
6568 (looking-at "\\(\\w+\\s-*:\\s-*\\)?\\<\\(case\\|elsif\\|if\\)\\>")))
d2ddb974
KH
6569 (/= (preceding-char) ?_)
6570 (vhdl-begin-p nil))
6571 ;; If it's a leader "begin", then find the
6572 ;; right place
6573 (if (looking-at vhdl-leader-re)
6574 (save-excursion
6575 ;; set a default stop point at the begin
6576 (setq pos (point))
6577 ;; is the start point inside the leader area ?
6578 (goto-char (vhdl-end-of-leader))
6579 (vhdl-forward-syntactic-ws here)
6580 (if (< (point) here)
6581 ;; start point was not inside leader area
6582 ;; set stop point at word after leader
6583 (setq pos (point))))
6584 (forward-word 1)
6585 (vhdl-forward-syntactic-ws here)
6586 (setq pos (point)))
6587 (goto-char pos)
6588 (setq donep t))
6589 ;; If we are looking at a "statement", then stop
6590 ((and (looking-at vhdl-statement-fwd-re)
6591 (/= (preceding-char) ?_)
6592 (vhdl-statement-p nil))
6593 (setq donep t))
6594 ;; If we are looking at a case alternative key, then stop
5eabfe72
KH
6595 ((and (looking-at vhdl-case-alternative-re)
6596 (vhdl-case-alternative-p lim))
d2ddb974
KH
6597 (save-excursion
6598 ;; set a default stop point at the when
6599 (setq pos (point))
6600 ;; is the start point inside the case alternative key ?
6601 (looking-at vhdl-case-alternative-re)
6602 (goto-char (match-end 0))
6603 (vhdl-forward-syntactic-ws here)
6604 (if (< (point) here)
6605 ;; start point was not inside the case alternative key
6606 ;; set stop point at word after case alternative keyleader
6607 (setq pos (point))))
6608 (goto-char pos)
6609 (setq donep t))
6610 ;; Bogus find, continue
6611 (t
6612 (backward-char)))))
6613 ))
6614
6615;; Defuns for calculating the current syntactic state:
6616
6617(defun vhdl-get-library-unit (bod placeholder)
a4c6cfad
JB
6618 "If there is an enclosing library unit at BOD, with its \"begin\"
6619keyword at PLACEHOLDER, then return the library unit type."
d2ddb974
KH
6620 (let ((here (vhdl-point 'bol)))
6621 (if (save-excursion
6622 (goto-char placeholder)
6623 (vhdl-safe (vhdl-forward-sexp 1 bod))
6624 (<= here (point)))
6625 (save-excursion
6626 (goto-char bod)
6627 (cond
6628 ((looking-at "e") 'entity)
6629 ((looking-at "a") 'architecture)
6630 ((looking-at "c") 'configuration)
6631 ((looking-at "p")
6632 (save-excursion
6633 (goto-char bod)
6634 (forward-sexp)
6635 (vhdl-forward-syntactic-ws here)
6636 (if (looking-at "body\\b[^_]")
6637 'package-body 'package))))))
6638 ))
6639
6640(defun vhdl-get-block-state (&optional lim)
5eabfe72 6641 "Finds and records all the closest opens.
a4c6cfad 6642LIM is the furthest back we need to search (it should be the
5eabfe72 6643previous libunit keyword)."
d2ddb974
KH
6644 (let ((here (point))
6645 (lim (or lim (point-min)))
6646 keyword sexp-start sexp-mid sexp-end
6647 preceding-sexp containing-sexp
6648 containing-begin containing-mid containing-paren)
6649 (save-excursion
6650 ;; Find the containing-paren, and use that as the limit
6651 (if (setq containing-paren
6652 (save-restriction
6653 (narrow-to-region lim (point))
6654 (vhdl-safe (scan-lists (point) -1 1))))
6655 (setq lim containing-paren))
6656 ;; Look backwards for "begin" and "end" keywords.
6657 (while (and (> (point) lim)
6658 (not containing-sexp))
6659 (setq keyword (vhdl-backward-to-block lim))
6660 (cond
6661 ((eq keyword 'begin)
6662 ;; Found a "begin" keyword
6663 (setq sexp-start (point))
6664 (setq sexp-mid (vhdl-corresponding-mid lim))
6665 (setq sexp-end (vhdl-safe
6666 (save-excursion
6667 (vhdl-forward-sexp 1 lim) (point))))
6668 (if (and sexp-end (<= sexp-end here))
6669 ;; we want to record this sexp, but we only want to
6670 ;; record the last-most of any of them before here
6671 (or preceding-sexp
6672 (setq preceding-sexp sexp-start))
6673 ;; we're contained in this sexp so put sexp-start on
6674 ;; front of list
6675 (setq containing-sexp sexp-start)
6676 (setq containing-mid sexp-mid)
6677 (setq containing-begin t)))
6678 ((eq keyword 'end)
6679 ;; Found an "end" keyword
6680 (forward-sexp)
6681 (setq sexp-end (point))
6682 (setq sexp-mid nil)
6683 (setq sexp-start
6684 (or (vhdl-safe (vhdl-backward-sexp 1 lim) (point))
6685 (progn (backward-sexp) (point))))
6686 ;; we want to record this sexp, but we only want to
6687 ;; record the last-most of any of them before here
6688 (or preceding-sexp
6689 (setq preceding-sexp sexp-start)))
6690 )))
6691 ;; Check if the containing-paren should be the containing-sexp
6692 (if (and containing-paren
6693 (or (null containing-sexp)
6694 (< containing-sexp containing-paren)))
6695 (setq containing-sexp containing-paren
6696 preceding-sexp nil
6697 containing-begin nil
6698 containing-mid nil))
6699 (vector containing-sexp preceding-sexp containing-begin containing-mid)
6700 ))
6701
6702
6703(defconst vhdl-s-c-a-re
6704 (concat vhdl-case-alternative-re "\\|" vhdl-case-header-key))
6705
6706(defun vhdl-skip-case-alternative (&optional lim)
5eabfe72 6707 "Skip forward over case/when bodies, with optional maximal
a4c6cfad
JB
6708limit. If no next case alternative is found, nil is returned and
6709point is not moved."
d2ddb974
KH
6710 (let ((lim (or lim (point-max)))
6711 (here (point))
6712 donep foundp)
6713 (while (and (< (point) lim)
6714 (not donep))
6715 (if (and (re-search-forward vhdl-s-c-a-re lim 'move)
6716 (save-match-data
6717 (not (vhdl-in-literal)))
6718 (/= (match-beginning 0) here))
6719 (progn
6720 (goto-char (match-beginning 0))
6721 (cond
6722 ((and (looking-at "case")
6723 (re-search-forward "\\bis[^_]" lim t))
6724 (backward-sexp)
6725 (vhdl-forward-sexp))
6726 (t
6727 (setq donep t
6728 foundp t))))))
6729 (if (not foundp)
6730 (goto-char here))
6731 foundp))
6732
6733(defun vhdl-backward-skip-label (&optional lim)
5eabfe72 6734 "Skip backward over a label, with optional maximal
a4c6cfad 6735limit. If label is not found, nil is returned and point
5eabfe72 6736is not moved."
d2ddb974
KH
6737 (let ((lim (or lim (point-min)))
6738 placeholder)
6739 (if (save-excursion
6740 (vhdl-backward-syntactic-ws lim)
6741 (and (eq (preceding-char) ?:)
6742 (progn
6743 (backward-sexp)
6744 (setq placeholder (point))
6745 (looking-at vhdl-label-key))))
6746 (goto-char placeholder))
6747 ))
6748
6749(defun vhdl-forward-skip-label (&optional lim)
5eabfe72
KH
6750 "Skip forward over a label, with optional maximal
6751limit. If label is not found, nil is returned and point
6752is not moved."
d2ddb974
KH
6753 (let ((lim (or lim (point-max))))
6754 (if (looking-at vhdl-label-key)
6755 (progn
6756 (goto-char (match-end 0))
6757 (vhdl-forward-syntactic-ws lim)))
6758 ))
6759
6760(defun vhdl-get-syntactic-context ()
5eabfe72 6761 "Guess the syntactic description of the current line of VHDL code."
d2ddb974
KH
6762 (save-excursion
6763 (save-restriction
6764 (beginning-of-line)
6765 (let* ((indent-point (point))
6766 (case-fold-search t)
6767 vec literal containing-sexp preceding-sexp
6768 containing-begin containing-mid containing-leader
6769 char-before-ip char-after-ip begin-after-ip end-after-ip
6770 placeholder lim library-unit
6771 )
6772
6773 ;; Reset the syntactic context
6774 (setq vhdl-syntactic-context nil)
6775
6776 (save-excursion
6777 ;; Move to the start of the previous library unit, and
6778 ;; record the position of the "begin" keyword.
6779 (setq placeholder (vhdl-beginning-of-libunit))
6780 ;; The position of the "libunit" keyword gives us a gross
6781 ;; limit point.
6782 (setq lim (point))
6783 )
6784
6785 ;; If there is a previous library unit, and we are enclosed by
6786 ;; it, then set the syntax accordingly.
6787 (and placeholder
6788 (setq library-unit (vhdl-get-library-unit lim placeholder))
6789 (vhdl-add-syntax library-unit lim))
6790
6791 ;; Find the surrounding state.
6792 (if (setq vec (vhdl-get-block-state lim))
6793 (progn
6794 (setq containing-sexp (aref vec 0))
6795 (setq preceding-sexp (aref vec 1))
6796 (setq containing-begin (aref vec 2))
6797 (setq containing-mid (aref vec 3))
6798 ))
6799
6800 ;; set the limit on the farthest back we need to search
6801 (setq lim (if containing-sexp
6802 (save-excursion
6803 (goto-char containing-sexp)
6804 ;; set containing-leader if required
6805 (if (looking-at vhdl-leader-re)
6806 (setq containing-leader (vhdl-end-of-leader)))
6807 (vhdl-point 'bol))
6808 (point-min)))
6809
6810 ;; cache char before and after indent point, and move point to
6811 ;; the most likely position to perform the majority of tests
6812 (goto-char indent-point)
6813 (skip-chars-forward " \t")
3dcb36b7 6814 (setq literal (vhdl-in-literal))
d2ddb974
KH
6815 (setq char-after-ip (following-char))
6816 (setq begin-after-ip (and
6817 (not literal)
6818 (looking-at vhdl-begin-fwd-re)
fda91268
RZ
6819 (or (not (looking-at "\\<use\\>"))
6820 (save-excursion
6821 (back-to-indentation)
6822 (looking-at "\\(\\w+\\s-*:\\s-*\\)?\\<\\(case\\|elsif\\|if\\)\\>")))
d2ddb974
KH
6823 (vhdl-begin-p)))
6824 (setq end-after-ip (and
6825 (not literal)
6826 (looking-at vhdl-end-fwd-re)
6827 (vhdl-end-p)))
6828 (vhdl-backward-syntactic-ws lim)
6829 (setq char-before-ip (preceding-char))
6830 (goto-char indent-point)
6831 (skip-chars-forward " \t")
6832
6833 ;; now figure out syntactic qualities of the current line
6834 (cond
6835 ;; CASE 1: in a string or comment.
6836 ((memq literal '(string comment))
6837 (vhdl-add-syntax literal (vhdl-point 'bopl)))
6838 ;; CASE 2: Line is at top level.
6839 ((null containing-sexp)
6840 ;; Find the point to which indentation will be relative
6841 (save-excursion
6842 (if (null preceding-sexp)
6843 ;; CASE 2X.1
6844 ;; no preceding-sexp -> use the preceding statement
6845 (vhdl-beginning-of-statement-1 lim)
6846 ;; CASE 2X.2
6847 ;; if there is a preceding-sexp then indent relative to it
6848 (goto-char preceding-sexp)
6849 ;; if not at boi, then the block-opening keyword is
6850 ;; probably following a label, so we need a different
6851 ;; relpos
6852 (if (/= (point) (vhdl-point 'boi))
6853 ;; CASE 2X.3
6854 (vhdl-beginning-of-statement-1 lim)))
6855 ;; v-b-o-s could have left us at point-min
6856 (and (bobp)
6857 ;; CASE 2X.4
6858 (vhdl-forward-syntactic-ws indent-point))
6859 (setq placeholder (point)))
6860 (cond
6861 ;; CASE 2A : we are looking at a block-open
6862 (begin-after-ip
6863 (vhdl-add-syntax 'block-open placeholder))
6864 ;; CASE 2B: we are looking at a block-close
6865 (end-after-ip
6866 (vhdl-add-syntax 'block-close placeholder))
6867 ;; CASE 2C: we are looking at a top-level statement
6868 ((progn
6869 (vhdl-backward-syntactic-ws lim)
6870 (or (bobp)
fda91268
RZ
6871 (and (= (preceding-char) ?\;)
6872 (not (vhdl-in-quote-p)))))
d2ddb974
KH
6873 (vhdl-add-syntax 'statement placeholder))
6874 ;; CASE 2D: we are looking at a top-level statement-cont
6875 (t
6876 (vhdl-beginning-of-statement-1 lim)
6877 ;; v-b-o-s could have left us at point-min
6878 (and (bobp)
6879 ;; CASE 2D.1
6880 (vhdl-forward-syntactic-ws indent-point))
6881 (vhdl-add-syntax 'statement-cont (point)))
6882 )) ; end CASE 2
6883 ;; CASE 3: line is inside parentheses. Most likely we are
6884 ;; either in a subprogram argument (interface) list, or a
6885 ;; continued expression containing parentheses.
6886 ((null containing-begin)
6887 (vhdl-backward-syntactic-ws containing-sexp)
6888 (cond
6889 ;; CASE 3A: we are looking at the arglist closing paren
6890 ((eq char-after-ip ?\))
6891 (goto-char containing-sexp)
6892 (vhdl-add-syntax 'arglist-close (vhdl-point 'boi)))
6893 ;; CASE 3B: we are looking at the first argument in an empty
6894 ;; argument list.
6895 ((eq char-before-ip ?\()
6896 (goto-char containing-sexp)
6897 (vhdl-add-syntax 'arglist-intro (vhdl-point 'boi)))
6898 ;; CASE 3C: we are looking at an arglist continuation line,
6899 ;; but the preceding argument is on the same line as the
6900 ;; opening paren. This case includes multi-line
6901 ;; expression paren groupings.
6902 ((and (save-excursion
6903 (goto-char (1+ containing-sexp))
6904 (skip-chars-forward " \t")
6905 (not (eolp))
6906 (not (looking-at "--")))
6907 (save-excursion
6908 (vhdl-beginning-of-statement-1 containing-sexp)
6909 (skip-chars-backward " \t(")
fda91268
RZ
6910 (while (and (= (preceding-char) ?\;)
6911 (not (vhdl-in-quote-p)))
6912 (vhdl-beginning-of-statement-1 containing-sexp)
6913 (skip-chars-backward " \t("))
d2ddb974
KH
6914 (<= (point) containing-sexp)))
6915 (goto-char containing-sexp)
6916 (vhdl-add-syntax 'arglist-cont-nonempty (vhdl-point 'boi)))
6917 ;; CASE 3D: we are looking at just a normal arglist
6918 ;; continuation line
6919 (t (vhdl-beginning-of-statement-1 containing-sexp)
6920 (vhdl-forward-syntactic-ws indent-point)
6921 (vhdl-add-syntax 'arglist-cont (vhdl-point 'boi)))
6922 ))
6923 ;; CASE 4: A block mid open
6924 ((and begin-after-ip
6925 (looking-at containing-mid))
6926 (goto-char containing-sexp)
6927 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
6928 (if (looking-at vhdl-trailer-re)
6929 ;; CASE 4.1
6930 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
6931 (vhdl-backward-skip-label (vhdl-point 'boi))
6932 (vhdl-add-syntax 'block-open (point)))
6933 ;; CASE 5: block close brace
6934 (end-after-ip
6935 (goto-char containing-sexp)
6936 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
6937 (if (looking-at vhdl-trailer-re)
6938 ;; CASE 5.1
6939 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
6940 (vhdl-backward-skip-label (vhdl-point 'boi))
6941 (vhdl-add-syntax 'block-close (point)))
6942 ;; CASE 6: A continued statement
6943 ((and (/= char-before-ip ?\;)
6944 ;; check it's not a trailer begin keyword, or a begin
6945 ;; keyword immediately following a label.
6946 (not (and begin-after-ip
6947 (or (looking-at vhdl-trailer-re)
6948 (save-excursion
6949 (vhdl-backward-skip-label containing-sexp)))))
6950 ;; check it's not a statement keyword
6951 (not (and (looking-at vhdl-statement-fwd-re)
6952 (vhdl-statement-p)))
6953 ;; see if the b-o-s is before the indent point
6954 (> indent-point
6955 (save-excursion
6956 (vhdl-beginning-of-statement-1 containing-sexp)
6957 ;; If we ended up after a leader, then this will
6958 ;; move us forward to the start of the first
6959 ;; statement. Note that a containing sexp here is
6960 ;; always a keyword, not a paren, so this will
6961 ;; have no effect if we hit the containing-sexp.
6962 (vhdl-forward-syntactic-ws indent-point)
6963 (setq placeholder (point))))
6964 ;; check it's not a block-intro
6965 (/= placeholder containing-sexp)
6966 ;; check it's not a case block-intro
6967 (save-excursion
6968 (goto-char placeholder)
6969 (or (not (looking-at vhdl-case-alternative-re))
6970 (> (match-end 0) indent-point))))
6971 ;; Make placeholder skip a label, but only if it puts us
6972 ;; before the indent point at the start of a line.
6973 (let ((new placeholder))
6974 (if (and (> indent-point
6975 (save-excursion
6976 (goto-char placeholder)
6977 (vhdl-forward-skip-label indent-point)
6978 (setq new (point))))
6979 (save-excursion
6980 (goto-char new)
6981 (eq new (progn (back-to-indentation) (point)))))
09ae5da1 6982 (setq placeholder new)))
d2ddb974
KH
6983 (vhdl-add-syntax 'statement-cont placeholder)
6984 (if begin-after-ip
6985 (vhdl-add-syntax 'block-open)))
6986 ;; Statement. But what kind?
6987 ;; CASE 7: A case alternative key
6988 ((and (looking-at vhdl-case-alternative-re)
6989 (vhdl-case-alternative-p containing-sexp))
6990 ;; for a case alternative key, we set relpos to the first
6991 ;; non-whitespace char on the line containing the "case"
6992 ;; keyword.
6993 (goto-char containing-sexp)
6994 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
6995 (if (looking-at vhdl-trailer-re)
6996 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
6997 (vhdl-add-syntax 'case-alternative (vhdl-point 'boi)))
6998 ;; CASE 8: statement catchall
6999 (t
7000 ;; we know its a statement, but we need to find out if it is
7001 ;; the first statement in a block
7002 (if containing-leader
7003 (goto-char containing-leader)
7004 (goto-char containing-sexp)
7005 ;; Note that a containing sexp here is always a keyword,
7006 ;; not a paren, so skip over the keyword.
7007 (forward-sexp))
7008 ;; move to the start of the first statement
7009 (vhdl-forward-syntactic-ws indent-point)
7010 (setq placeholder (point))
7011 ;; we want to ignore case alternatives keys when skipping forward
7012 (let (incase-p)
7013 (while (looking-at vhdl-case-alternative-re)
7014 (setq incase-p (point))
7015 ;; we also want to skip over the body of the
7016 ;; case/when statement if that doesn't put us at
7017 ;; after the indent-point
7018 (while (vhdl-skip-case-alternative indent-point))
7019 ;; set up the match end
7020 (looking-at vhdl-case-alternative-re)
7021 (goto-char (match-end 0))
7022 ;; move to the start of the first case alternative statement
7023 (vhdl-forward-syntactic-ws indent-point)
7024 (setq placeholder (point)))
7025 (cond
7026 ;; CASE 8A: we saw a case/when statement so we must be
7027 ;; in a switch statement. find out if we are at the
7028 ;; statement just after a case alternative key
7029 ((and incase-p
7030 (= (point) indent-point))
7031 ;; relpos is the "when" keyword
7032 (vhdl-add-syntax 'statement-case-intro incase-p))
7033 ;; CASE 8B: any old statement
7034 ((< (point) indent-point)
7035 ;; relpos is the first statement of the block
7036 (vhdl-add-syntax 'statement placeholder)
7037 (if begin-after-ip
7038 (vhdl-add-syntax 'block-open)))
7039 ;; CASE 8C: first statement in a block
7040 (t
7041 (goto-char containing-sexp)
7042 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
7043 (if (looking-at vhdl-trailer-re)
7044 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
7045 (vhdl-backward-skip-label (vhdl-point 'boi))
7046 (vhdl-add-syntax 'statement-block-intro (point))
7047 (if begin-after-ip
7048 (vhdl-add-syntax 'block-open)))
7049 )))
7050 )
7051
7052 ;; now we need to look at any modifiers
7053 (goto-char indent-point)
7054 (skip-chars-forward " \t")
7055 (if (looking-at "--")
7056 (vhdl-add-syntax 'comment))
0a2e512a
RF
7057 (if (eq literal 'pound)
7058 (vhdl-add-syntax 'cpp-macro))
d2ddb974
KH
7059 ;; return the syntax
7060 vhdl-syntactic-context))))
7061
7062;; Standard indentation line-ups:
7063
7064(defun vhdl-lineup-arglist (langelem)
5eabfe72
KH
7065 "Lineup the current arglist line with the arglist appearing just
7066after the containing paren which starts the arglist."
d2ddb974
KH
7067 (save-excursion
7068 (let* ((containing-sexp
7069 (save-excursion
7070 ;; arglist-cont-nonempty gives relpos ==
7071 ;; to boi of containing-sexp paren. This
7072 ;; is good when offset is +, but bad
7073 ;; when it is vhdl-lineup-arglist, so we
7074 ;; have to special case a kludge here.
7075 (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
7076 (progn
7077 (beginning-of-line)
7078 (backward-up-list 1)
7079 (skip-chars-forward " \t" (vhdl-point 'eol)))
7080 (goto-char (cdr langelem)))
7081 (point)))
7082 (cs-curcol (save-excursion
7083 (goto-char (cdr langelem))
7084 (current-column))))
7085 (if (save-excursion
7086 (beginning-of-line)
7087 (looking-at "[ \t]*)"))
7088 (progn (goto-char (match-end 0))
7089 (backward-sexp)
7090 (forward-char)
7091 (vhdl-forward-syntactic-ws)
7092 (- (current-column) cs-curcol))
7093 (goto-char containing-sexp)
7094 (or (eolp)
7095 (let ((eol (vhdl-point 'eol))
7096 (here (progn
7097 (forward-char)
7098 (skip-chars-forward " \t")
7099 (point))))
7100 (vhdl-forward-syntactic-ws)
7101 (if (< (point) eol)
7102 (goto-char here))))
7103 (- (current-column) cs-curcol)
7104 ))))
7105
7106(defun vhdl-lineup-arglist-intro (langelem)
5eabfe72 7107 "Lineup an arglist-intro line to just after the open paren."
d2ddb974
KH
7108 (save-excursion
7109 (let ((cs-curcol (save-excursion
7110 (goto-char (cdr langelem))
7111 (current-column)))
7112 (ce-curcol (save-excursion
7113 (beginning-of-line)
7114 (backward-up-list 1)
7115 (skip-chars-forward " \t" (vhdl-point 'eol))
7116 (current-column))))
7117 (- ce-curcol cs-curcol -1))))
7118
7119(defun vhdl-lineup-comment (langelem)
5eabfe72
KH
7120 "Support old behavior for comment indentation. We look at
7121vhdl-comment-only-line-offset to decide how to indent comment
7122only-lines."
d2ddb974
KH
7123 (save-excursion
7124 (back-to-indentation)
7125 ;; at or to the right of comment-column
7126 (if (>= (current-column) comment-column)
7127 (vhdl-comment-indent)
7128 ;; otherwise, indent as specified by vhdl-comment-only-line-offset
7129 (if (not (bolp))
7130 (or (car-safe vhdl-comment-only-line-offset)
7131 vhdl-comment-only-line-offset)
7132 (or (cdr-safe vhdl-comment-only-line-offset)
7133 (car-safe vhdl-comment-only-line-offset)
0a2e512a 7134 -1000 ;jam it against the left side
d2ddb974
KH
7135 )))))
7136
7137(defun vhdl-lineup-statement-cont (langelem)
5eabfe72 7138 "Line up statement-cont after the assignment operator."
d2ddb974
KH
7139 (save-excursion
7140 (let* ((relpos (cdr langelem))
7141 (assignp (save-excursion
7142 (goto-char (vhdl-point 'boi))
fda91268 7143 (and (re-search-forward "\\(<\\|:\\|=\\)="
d2ddb974
KH
7144 (vhdl-point 'eol) t)
7145 (- (point) (vhdl-point 'boi)))))
7146 (curcol (progn
7147 (goto-char relpos)
7148 (current-column)))
7149 foundp)
7150 (while (and (not foundp)
7151 (< (point) (vhdl-point 'eol)))
fda91268 7152 (re-search-forward "\\(<\\|:\\|=\\)=\\|(" (vhdl-point 'eol) 'move)
3dcb36b7 7153 (if (vhdl-in-literal)
d2ddb974
KH
7154 (forward-char)
7155 (if (= (preceding-char) ?\()
7156 ;; skip over any parenthesized expressions
7157 (goto-char (min (vhdl-point 'eol)
7158 (scan-lists (point) 1 1)))
7159 ;; found an assignment operator (not at eol)
7160 (setq foundp (not (looking-at "\\s-*$"))))))
7161 (if (not foundp)
7162 ;; there's no assignment operator on the line
7163 vhdl-basic-offset
7164 ;; calculate indentation column after assign and ws, unless
7165 ;; our line contains an assignment operator
7166 (if (not assignp)
7167 (progn
7168 (forward-char)
7169 (skip-chars-forward " \t")
7170 (setq assignp 0)))
7171 (- (current-column) assignp curcol))
7172 )))
7173
5eabfe72 7174;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 7175;; Progress reporting
d2ddb974 7176
3dcb36b7
JB
7177(defvar vhdl-progress-info nil
7178 "Array variable for progress information: 0 begin, 1 end, 2 time.")
5eabfe72 7179
3dcb36b7
JB
7180(defun vhdl-update-progress-info (string pos)
7181 "Update progress information."
7182 (when (and vhdl-progress-info (not noninteractive)
7183 (< vhdl-progress-interval
7184 (- (nth 1 (current-time)) (aref vhdl-progress-info 2))))
b0cf7916
JB
7185 (let ((delta (- (aref vhdl-progress-info 1)
7186 (aref vhdl-progress-info 0))))
7187 (if (= 0 delta)
7188 (message (concat string "... (100%s)") "%")
7189 (message (concat string "... (%2d%s)")
7190 (/ (* 100 (- pos (aref vhdl-progress-info 0)))
7191 delta) "%")))
3dcb36b7 7192 (aset vhdl-progress-info 2 (nth 1 (current-time)))))
5eabfe72 7193
3dcb36b7
JB
7194;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7195;; Indentation commands
5eabfe72
KH
7196
7197(defun vhdl-electric-tab (&optional prefix-arg)
97610156 7198 "If preceding character is part of a word or a paren then hippie-expand,
3dcb36b7
JB
7199else if right of non whitespace on line then insert tab,
7200else if last command was a tab or return then dedent one step or if a comment
7201toggle between normal indent and inline comment indent,
d2ddb974
KH
7202else indent `correctly'."
7203 (interactive "*P")
3dcb36b7
JB
7204 (vhdl-prepare-search-2
7205 (cond
75e0af77
DN
7206 ;; indent region if region is active
7207 ((and (not (featurep 'xemacs)) (use-region-p))
7208 (vhdl-indent-region (region-beginning) (region-end) nil))
3dcb36b7
JB
7209 ;; expand word
7210 ((= (char-syntax (preceding-char)) ?w)
7211 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
7212 (case-replace nil)
7213 (hippie-expand-only-buffers
7214 (or (and (boundp 'hippie-expand-only-buffers)
7215 hippie-expand-only-buffers)
7216 '(vhdl-mode))))
7217 (vhdl-expand-abbrev prefix-arg)))
7218 ;; expand parenthesis
7219 ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
7220 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
7221 (case-replace nil))
7222 (vhdl-expand-paren prefix-arg)))
7223 ;; insert tab
7224 ((> (current-column) (current-indentation))
7225 (insert-tab))
7226 ;; toggle comment indent
7227 ((and (looking-at "--")
7228 (or (eq last-command 'vhdl-electric-tab)
7229 (eq last-command 'vhdl-electric-return)))
7230 (cond ((= (current-indentation) 0) ; no indent
7231 (indent-to 1)
7232 (indent-according-to-mode))
7233 ((< (current-indentation) comment-column) ; normal indent
7234 (indent-to comment-column)
7235 (indent-according-to-mode))
7236 (t ; inline comment indent
453cfeb3 7237 (delete-region (line-beginning-position) (point)))))
3dcb36b7
JB
7238 ;; dedent
7239 ((and (>= (current-indentation) vhdl-basic-offset)
7240 (or (eq last-command 'vhdl-electric-tab)
7241 (eq last-command 'vhdl-electric-return)))
7242 (backward-delete-char-untabify vhdl-basic-offset nil))
7243 ;; indent line
7244 (t (indent-according-to-mode)))
5eabfe72
KH
7245 (setq this-command 'vhdl-electric-tab)))
7246
7247(defun vhdl-electric-return ()
d2ddb974
KH
7248 "newline-and-indent or indent-new-comment-line if in comment and preceding
7249character is a space."
7250 (interactive)
7251 (if (and (= (preceding-char) ? ) (vhdl-in-comment-p))
7252 (indent-new-comment-line)
fda91268
RZ
7253 (when (and (>= (preceding-char) ?a) (<= (preceding-char) ?z)
7254 (not (vhdl-in-comment-p)))
3dcb36b7 7255 (vhdl-fix-case-word -1))
5eabfe72
KH
7256 (newline-and-indent)))
7257
d2ddb974 7258(defun vhdl-indent-line ()
5eabfe72 7259 "Indent the current line as VHDL code. Returns the amount of
d2ddb974
KH
7260indentation change."
7261 (interactive)
3dcb36b7 7262 (let* ((syntax (and vhdl-indent-syntax-based (vhdl-get-syntactic-context)))
d2ddb974 7263 (pos (- (point-max) (point)))
fda91268 7264 (is-comment nil)
3dcb36b7
JB
7265 (indent
7266 (if syntax
7267 ;; indent syntax-based
7268 (if (and (eq (caar syntax) 'comment)
7269 (>= (vhdl-get-offset (car syntax)) comment-column))
7270 ;; special case: comments at or right of comment-column
7271 (vhdl-get-offset (car syntax))
fda91268
RZ
7272 ;; align comments like following code line
7273 (when vhdl-indent-comment-like-next-code-line
7274 (save-excursion
7275 (while (eq (caar syntax) 'comment)
7276 (setq is-comment t)
7277 (beginning-of-line 2)
7278 (setq syntax (vhdl-get-syntactic-context)))))
7279 (when is-comment
7280 (setq syntax (cons (cons 'comment nil) syntax)))
3dcb36b7
JB
7281 (apply '+ (mapcar 'vhdl-get-offset syntax)))
7282 ;; indent like previous nonblank line
7283 (save-excursion (beginning-of-line)
7284 (re-search-backward "^[^\n]" nil t)
7285 (current-indentation))))
5eabfe72 7286 (shift-amt (- indent (current-indentation))))
d2ddb974
KH
7287 (and vhdl-echo-syntactic-information-p
7288 (message "syntax: %s, indent= %d" syntax indent))
fda91268
RZ
7289 (let ((has-formfeed
7290 (save-excursion (beginning-of-line) (looking-at "\\s-*\f"))))
7291 (when (or (not (zerop shift-amt)) has-formfeed)
7292 (delete-region (vhdl-point 'bol) (vhdl-point 'boi))
7293 (beginning-of-line)
7294 (when has-formfeed (insert "\f"))
7295 (indent-to indent)))
d2ddb974
KH
7296 (if (< (point) (vhdl-point 'boi))
7297 (back-to-indentation)
7298 ;; If initial point was within line's indentation, position after
7299 ;; the indentation. Else stay at same point in text.
5eabfe72
KH
7300 (when (> (- (point-max) pos) (point))
7301 (goto-char (- (point-max) pos))))
d2ddb974 7302 (run-hooks 'vhdl-special-indent-hook)
3dcb36b7 7303 (vhdl-update-progress-info "Indenting" (vhdl-current-line))
d2ddb974
KH
7304 shift-amt))
7305
fda91268 7306(defun vhdl-indent-region (beg end &optional column)
5eabfe72
KH
7307 "Indent region as VHDL code.
7308Adds progress reporting to `indent-region'."
7309 (interactive "r\nP")
3dcb36b7
JB
7310 (when vhdl-progress-interval
7311 (setq vhdl-progress-info (vector (count-lines (point-min) beg)
7312 (count-lines (point-min) end) 0)))
7313 (indent-region beg end column)
5eabfe72
KH
7314 (when vhdl-progress-interval (message "Indenting...done"))
7315 (setq vhdl-progress-info nil))
d2ddb974 7316
3dcb36b7
JB
7317(defun vhdl-indent-buffer ()
7318 "Indent whole buffer as VHDL code.
7319Calls `indent-region' for whole buffer and adds progress reporting."
7320 (interactive)
fda91268 7321 (vhdl-indent-region (point-min) (point-max)))
3dcb36b7
JB
7322
7323(defun vhdl-indent-group ()
7324 "Indent group of lines between empty lines."
7325 (interactive)
7326 (let ((beg (save-excursion
7327 (if (re-search-backward vhdl-align-group-separate nil t)
7328 (point-marker)
7329 (point-min-marker))))
7330 (end (save-excursion
7331 (if (re-search-forward vhdl-align-group-separate nil t)
7332 (point-marker)
7333 (point-max-marker)))))
fda91268 7334 (vhdl-indent-region beg end)))
3dcb36b7 7335
d2ddb974
KH
7336(defun vhdl-indent-sexp (&optional endpos)
7337 "Indent each line of the list starting just after point.
7338If optional arg ENDPOS is given, indent each line, stopping when
7339ENDPOS is encountered."
7340 (interactive)
7341 (save-excursion
7342 (let ((beg (point))
5eabfe72 7343 (end (progn (vhdl-forward-sexp nil endpos) (point))))
d2ddb974
KH
7344 (indent-region beg end nil))))
7345
5eabfe72 7346;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
7347;; Miscellaneous commands
7348
7349(defun vhdl-show-syntactic-information ()
7350 "Show syntactic information for current line."
7351 (interactive)
3dcb36b7 7352 (message "Syntactic analysis: %s" (vhdl-get-syntactic-context))
d2ddb974
KH
7353 (vhdl-keep-region-active))
7354
7355;; Verification and regression functions:
7356
7357(defun vhdl-regress-line (&optional arg)
7358 "Check syntactic information for current line."
7359 (interactive "P")
7360 (let ((expected (save-excursion
7361 (end-of-line)
5eabfe72
KH
7362 (when (search-backward " -- ((" (vhdl-point 'bol) t)
7363 (forward-char 4)
7364 (read (current-buffer)))))
d2ddb974
KH
7365 (actual (vhdl-get-syntactic-context))
7366 (expurgated))
7367 ;; remove the library unit symbols
51b5ad57 7368 (mapc
d2ddb974
KH
7369 (function
7370 (lambda (elt)
7371 (if (memq (car elt) '(entity configuration package
7372 package-body architecture))
7373 nil
7374 (setq expurgated (append expurgated (list elt))))))
7375 actual)
7376 (if (and (not arg) expected (listp expected))
7377 (if (not (equal expected expurgated))
3dcb36b7 7378 (error "ERROR: Should be: %s, is: %s" expected expurgated))
d2ddb974
KH
7379 (save-excursion
7380 (beginning-of-line)
5eabfe72
KH
7381 (when (not (looking-at "^\\s-*\\(--.*\\)?$"))
7382 (end-of-line)
7383 (if (search-backward " -- ((" (vhdl-point 'bol) t)
453cfeb3 7384 (delete-region (point) (line-end-position)))
5eabfe72
KH
7385 (insert " -- ")
7386 (insert (format "%s" expurgated))))))
d2ddb974
KH
7387 (vhdl-keep-region-active))
7388
7389
5eabfe72
KH
7390;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7391;;; Alignment, whitespace fixup, beautifying
7392;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974 7393
3dcb36b7 7394(defconst vhdl-align-alist
d2ddb974
KH
7395 '(
7396 ;; after some keywords
fda91268
RZ
7397 (vhdl-mode "^\\s-*\\(across\\|constant\\|quantity\\|signal\\|subtype\\|terminal\\|through\\|type\\|variable\\)[ \t]"
7398 "^\\s-*\\(across\\|constant\\|quantity\\|signal\\|subtype\\|terminal\\|through\\|type\\|variable\\)\\([ \t]+\\)" 2)
d2ddb974 7399 ;; before ':'
5eabfe72 7400 (vhdl-mode ":[^=]" "\\([ \t]*\\):[^=]")
d2ddb974 7401 ;; after direction specifications
5eabfe72
KH
7402 (vhdl-mode ":[ \t]*\\(in\\|out\\|inout\\|buffer\\|\\)\\>"
7403 ":[ \t]*\\(in\\|out\\|inout\\|buffer\\|\\)\\([ \t]+\\)" 2)
7404 ;; before "==", ":=", "=>", and "<="
fda91268 7405 (vhdl-mode "[<:=]=" "\\([ \t]*\\)\\??[<:=]=" 1) ; since "<= ... =>" can occur
5eabfe72 7406 (vhdl-mode "=>" "\\([ \t]*\\)=>" 1)
fda91268 7407 (vhdl-mode "[<:=]=" "\\([ \t]*\\)\\??[<:=]=" 1) ; since "=> ... <=" can occur
d2ddb974
KH
7408 ;; before some keywords
7409 (vhdl-mode "[ \t]after\\>" "[^ \t]\\([ \t]+\\)after\\>" 1)
d2ddb974
KH
7410 (vhdl-mode "[ \t]when\\>" "[^ \t]\\([ \t]+\\)when\\>" 1)
7411 (vhdl-mode "[ \t]else\\>" "[^ \t]\\([ \t]+\\)else\\>" 1)
fda91268
RZ
7412 (vhdl-mode "[ \t]across\\>" "[^ \t]\\([ \t]+\\)across\\>" 1)
7413 (vhdl-mode "[ \t]through\\>" "[^ \t]\\([ \t]+\\)through\\>" 1)
3dcb36b7
JB
7414 ;; before "=>" since "when/else ... =>" can occur
7415 (vhdl-mode "=>" "\\([ \t]*\\)=>" 1)
d2ddb974 7416 )
5eabfe72 7417 "The format of this alist is (MODES [or MODE] REGEXP ALIGN-PATTERN SUBEXP).
d2ddb974
KH
7418It is searched in order. If REGEXP is found anywhere in the first
7419line of a region to be aligned, ALIGN-PATTERN will be used for that
7420region. ALIGN-PATTERN must include the whitespace to be expanded or
5eabfe72
KH
7421contracted. It may also provide regexps for the text surrounding the
7422whitespace. SUBEXP specifies which sub-expression of
d2ddb974
KH
7423ALIGN-PATTERN matches the white space to be expanded/contracted.")
7424
3dcb36b7
JB
7425;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7426;; Align code
7427
d2ddb974
KH
7428(defvar vhdl-align-try-all-clauses t
7429 "If REGEXP is not found on the first line of the region that clause
5eabfe72 7430is ignored. If this variable is non-nil, then the clause is tried anyway.")
d2ddb974 7431
3dcb36b7
JB
7432(defun vhdl-do-group (function &optional spacing)
7433 "Apply FUNCTION on group of lines between empty lines."
7434 (let
7435 ;; search for group beginning
7436 ((beg (save-excursion
7437 (if (re-search-backward vhdl-align-group-separate nil t)
7438 (progn (beginning-of-line 2) (back-to-indentation) (point))
7439 (point-min))))
7440 ;; search for group end
7441 (end (save-excursion
7442 (if (re-search-forward vhdl-align-group-separate nil t)
7443 (progn (beginning-of-line) (point))
7444 (point-max)))))
7445 ;; run FUNCTION
7446 (funcall function beg end spacing)))
7447
7448(defun vhdl-do-list (function &optional spacing)
7449 "Apply FUNCTION to the lines of a list surrounded by a balanced group of
7450parentheses."
7451 (let (beg end)
7452 (save-excursion
7453 ;; search for beginning of balanced group of parentheses
7454 (setq beg (vhdl-re-search-backward "[()]" nil t))
7455 (while (looking-at ")")
7456 (forward-char) (backward-sexp)
7457 (setq beg (vhdl-re-search-backward "[()]" nil t)))
7458 ;; search for end of balanced group of parentheses
7459 (when beg
7460 (forward-list)
7461 (setq end (point))
7462 (goto-char (1+ beg))
fda91268 7463 (skip-chars-forward " \t\n\r\f")
3dcb36b7
JB
7464 (setq beg (point))))
7465 ;; run FUNCTION
7466 (if beg
7467 (funcall function beg end spacing)
7468 (error "ERROR: Not within a list enclosed by a pair of parentheses"))))
7469
7470(defun vhdl-do-same-indent (function &optional spacing)
7471 "Apply FUNCTION to block of lines with same indent."
7472 (let ((indent (current-indentation))
7473 beg end)
7474 ;; search for first line with same indent
7475 (save-excursion
7476 (while (and (not (bobp))
7477 (or (looking-at "^\\s-*\\(--.*\\)?$")
7478 (= (current-indentation) indent)))
7479 (unless (looking-at "^\\s-*$")
7480 (back-to-indentation) (setq beg (point)))
7481 (beginning-of-line -0)))
7482 ;; search for last line with same indent
7483 (save-excursion
7484 (while (and (not (eobp))
7485 (or (looking-at "^\\s-*\\(--.*\\)?$")
7486 (= (current-indentation) indent)))
7487 (if (looking-at "^\\s-*$")
7488 (beginning-of-line 2)
7489 (beginning-of-line 2)
7490 (setq end (point)))))
7491 ;; run FUNCTION
7492 (funcall function beg end spacing)))
7493
7494(defun vhdl-align-region-1 (begin end &optional spacing alignment-list indent)
d2ddb974 7495 "Attempt to align a range of lines based on the content of the
5eabfe72
KH
7496lines. The definition of `alignment-list' determines the matching
7497order and the manner in which the lines are aligned. If ALIGNMENT-LIST
7498is not specified `vhdl-align-alist' is used. If INDENT is non-nil,
d2ddb974
KH
7499indentation is done before aligning."
7500 (interactive "r\np")
5eabfe72
KH
7501 (setq alignment-list (or alignment-list vhdl-align-alist))
7502 (setq spacing (or spacing 1))
d2ddb974
KH
7503 (save-excursion
7504 (let (bol indent)
7505 (goto-char end)
7506 (setq end (point-marker))
7507 (goto-char begin)
5eabfe72 7508 (setq bol (setq begin (progn (beginning-of-line) (point))))
3dcb36b7 7509; (untabify bol end)
5eabfe72
KH
7510 (when indent
7511 (indent-region bol end nil))))
3dcb36b7
JB
7512 (let ((copy (copy-alist alignment-list)))
7513 (vhdl-prepare-search-2
5eabfe72
KH
7514 (while copy
7515 (save-excursion
7516 (goto-char begin)
7517 (let (element
e180ab9f 7518 (eol (point-at-eol)))
5eabfe72
KH
7519 (setq element (nth 0 copy))
7520 (when (and (or (and (listp (car element))
7521 (memq major-mode (car element)))
7522 (eq major-mode (car element)))
7523 (or vhdl-align-try-all-clauses
7524 (re-search-forward (car (cdr element)) eol t)))
3dcb36b7 7525 (vhdl-align-region-2 begin end (car (cdr (cdr element)))
5eabfe72
KH
7526 (car (cdr (cdr (cdr element)))) spacing))
7527 (setq copy (cdr copy))))))))
7528
3dcb36b7 7529(defun vhdl-align-region-2 (begin end match &optional substr spacing)
d2ddb974 7530 "Align a range of lines from BEGIN to END. The regular expression
a4c6cfad 7531MATCH must match exactly one field: the whitespace to be
d2ddb974 7532contracted/expanded. The alignment column will equal the
a4c6cfad 7533rightmost column of the widest whitespace block. SPACING is
d2ddb974
KH
7534the amount of extra spaces to add to the calculated maximum required.
7535SPACING defaults to 1 so that at least one space is inserted after
7536the token in MATCH."
5eabfe72
KH
7537 (setq spacing (or spacing 1))
7538 (setq substr (or substr 1))
d2ddb974
KH
7539 (save-excursion
7540 (let (distance (max 0) (lines 0) bol eol width)
7541 ;; Determine the greatest whitespace distance to the alignment
7542 ;; character
7543 (goto-char begin)
e180ab9f 7544 (setq eol (point-at-eol)
5eabfe72 7545 bol (setq begin (progn (beginning-of-line) (point))))
d2ddb974 7546 (while (< bol end)
5eabfe72 7547 (save-excursion
fda91268
RZ
7548 (when (and (vhdl-re-search-forward match eol t)
7549 (save-excursion
7550 (goto-char (match-beginning 0))
7551 (forward-char)
7552 (and (not (vhdl-in-literal))
7553 (not (vhdl-in-quote-p))
7554 (not (vhdl-in-extended-identifier-p))))
7555 (not (looking-at "\\s-*$")))
5eabfe72
KH
7556 (setq distance (- (match-beginning substr) bol))
7557 (when (> distance max)
7558 (setq max distance))))
7559 (forward-line)
7560 (setq bol (point)
e180ab9f 7561 eol (point-at-eol))
5eabfe72 7562 (setq lines (1+ lines)))
d2ddb974
KH
7563 ;; Now insert enough maxs to push each assignment operator to
7564 ;; the same column. We need to use 'lines' as a counter, since
7565 ;; the location of the mark may change
7566 (goto-char (setq bol begin))
e180ab9f 7567 (setq eol (point-at-eol))
d2ddb974 7568 (while (> lines 0)
fda91268
RZ
7569 (when (and (vhdl-re-search-forward match eol t)
7570 (save-excursion
7571 (goto-char (match-beginning 0))
7572 (forward-char)
7573 (and (not (vhdl-in-literal))
7574 (not (vhdl-in-quote-p))
7575 (not (vhdl-in-extended-identifier-p))))
7576 (not (looking-at "\\s-*$"))
7577 (> (match-beginning 0) ; not if at boi
7578 (save-excursion (back-to-indentation) (point))))
5eabfe72
KH
7579 (setq width (- (match-end substr) (match-beginning substr)))
7580 (setq distance (- (match-beginning substr) bol))
7581 (goto-char (match-beginning substr))
7582 (delete-char width)
7583 (insert-char ? (+ (- max distance) spacing)))
7584 (beginning-of-line)
7585 (forward-line)
7586 (setq bol (point)
e180ab9f 7587 eol (point-at-eol))
5eabfe72
KH
7588 (setq lines (1- lines))))))
7589
3dcb36b7
JB
7590(defun vhdl-align-region-groups (beg end &optional spacing
7591 no-message no-comments)
7592 "Align region, treat groups of lines separately."
d2ddb974 7593 (interactive "r\nP")
5eabfe72 7594 (save-excursion
3dcb36b7 7595 (let (orig pos)
5eabfe72
KH
7596 (goto-char beg)
7597 (beginning-of-line)
3dcb36b7 7598 (setq orig (point-marker))
5eabfe72
KH
7599 (setq beg (point))
7600 (goto-char end)
7601 (setq end (point-marker))
7602 (untabify beg end)
3dcb36b7
JB
7603 (unless no-message
7604 (when vhdl-progress-interval
7605 (setq vhdl-progress-info (vector (count-lines (point-min) beg)
7606 (count-lines (point-min) end) 0))))
5eabfe72
KH
7607 (vhdl-fixup-whitespace-region beg end t)
7608 (goto-char beg)
7609 (if (not vhdl-align-groups)
7610 ;; align entire region
3dcb36b7
JB
7611 (progn (vhdl-align-region-1 beg end spacing)
7612 (unless no-comments
7613 (vhdl-align-inline-comment-region-1 beg end)))
5eabfe72
KH
7614 ;; align groups
7615 (while (and (< beg end)
3dcb36b7 7616 (re-search-forward vhdl-align-group-separate end t))
5eabfe72 7617 (setq pos (point-marker))
3dcb36b7
JB
7618 (vhdl-align-region-1 beg pos spacing)
7619 (unless no-comments (vhdl-align-inline-comment-region-1 beg pos))
7620 (vhdl-update-progress-info "Aligning" (vhdl-current-line))
5eabfe72
KH
7621 (setq beg (1+ pos))
7622 (goto-char beg))
7623 ;; align last group
7624 (when (< beg end)
3dcb36b7
JB
7625 (vhdl-align-region-1 beg end spacing)
7626 (unless no-comments (vhdl-align-inline-comment-region-1 beg end))
7627 (vhdl-update-progress-info "Aligning" (vhdl-current-line))))
7628 (when vhdl-indent-tabs-mode
7629 (tabify orig end))
7630 (unless no-message
7631 (when vhdl-progress-interval (message "Aligning...done"))
7632 (setq vhdl-progress-info nil)))))
7633
7634(defun vhdl-align-region (beg end &optional spacing)
7635 "Align region, treat blocks with same indent and argument lists separately."
7636 (interactive "r\nP")
7637 (if (not vhdl-align-same-indent)
7638 ;; align entire region
7639 (vhdl-align-region-groups beg end spacing)
7640 ;; align blocks with same indent and argument lists
7641 (save-excursion
7642 (let ((cur-beg beg)
7643 indent cur-end)
7644 (when vhdl-progress-interval
7645 (setq vhdl-progress-info (vector (count-lines (point-min) beg)
7646 (count-lines (point-min) end) 0)))
7647 (goto-char end)
7648 (setq end (point-marker))
7649 (goto-char cur-beg)
7650 (while (< (point) end)
7651 ;; is argument list opening?
7652 (if (setq cur-beg (nth 1 (save-excursion (parse-partial-sexp
7653 (point) (vhdl-point 'eol)))))
7654 ;; determine region for argument list
7655 (progn (goto-char cur-beg)
7656 (forward-sexp)
7657 (setq cur-end (point))
7658 (beginning-of-line 2))
7659 ;; determine region with same indent
7660 (setq indent (current-indentation))
7661 (setq cur-beg (point))
7662 (setq cur-end (vhdl-point 'bonl))
7663 (beginning-of-line 2)
7664 (while (and (< (point) end)
7665 (or (looking-at "^\\s-*\\(--.*\\)?$")
7666 (= (current-indentation) indent))
7667 (<= (save-excursion
7668 (nth 0 (parse-partial-sexp
7669 (point) (vhdl-point 'eol)))) 0))
7670 (unless (looking-at "^\\s-*$")
7671 (setq cur-end (vhdl-point 'bonl)))
7672 (beginning-of-line 2)))
7673 ;; align region
7674 (vhdl-align-region-groups cur-beg cur-end spacing t t))
7675 (vhdl-align-inline-comment-region beg end spacing noninteractive)
7676 (when vhdl-progress-interval (message "Aligning...done"))
7677 (setq vhdl-progress-info nil)))))
5eabfe72
KH
7678
7679(defun vhdl-align-group (&optional spacing)
7680 "Align group of lines between empty lines."
7681 (interactive)
3dcb36b7 7682 (vhdl-do-group 'vhdl-align-region spacing))
5eabfe72 7683
3dcb36b7
JB
7684(defun vhdl-align-list (&optional spacing)
7685 "Align the lines of a list surrounded by a balanced group of parentheses."
5eabfe72 7686 (interactive)
3dcb36b7
JB
7687 (vhdl-do-list 'vhdl-align-region-groups spacing))
7688
7689(defun vhdl-align-same-indent (&optional spacing)
7690 "Align block of lines with same indent."
7691 (interactive)
7692 (vhdl-do-same-indent 'vhdl-align-region-groups spacing))
7693
7694(defun vhdl-align-declarations (&optional spacing)
7695 "Align the lines within the declarative part of a design unit."
7696 (interactive)
7697 (let (beg end)
7698 (vhdl-prepare-search-2
7699 (save-excursion
7700 ;; search for declarative part
7701 (when (and (re-search-backward "^\\(architecture\\|begin\\|configuration\\|end\\|entity\\|package\\)\\>" nil t)
7702 (not (member (upcase (match-string 1)) '("BEGIN" "END"))))
7703 (setq beg (point))
7704 (re-search-forward "^\\(begin\\|end\\)\\>" nil t)
7705 (setq end (point)))))
7706 (if beg
7707 (vhdl-align-region-groups beg end spacing)
7708 (error "ERROR: Not within the declarative part of a design unit"))))
7709
7710(defun vhdl-align-buffer ()
7711 "Align buffer."
7712 (interactive)
7713 (vhdl-align-region (point-min) (point-max)))
7714
7715;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7716;; Align inline comments
7717
7718(defun vhdl-align-inline-comment-region-1 (beg end &optional spacing)
7719 "Align inline comments in region."
7720 (save-excursion
7721 (let ((start-max comment-column)
7722 (length-max 0)
7723 comment-list start-list tmp-list start length
7724 cur-start prev-start no-code)
7725 (setq spacing (or spacing 2))
7726 (vhdl-prepare-search-2
7727 (goto-char beg)
7728 ;; search for comment start positions and lengths
7729 (while (< (point) end)
7730 (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>"))
fda91268 7731 (looking-at "^\\(.*[^ \t\n\r\f-]+\\)\\s-*\\(--.*\\)$")
3dcb36b7
JB
7732 (not (save-excursion (goto-char (match-beginning 2))
7733 (vhdl-in-literal))))
7734 (setq start (+ (- (match-end 1) (match-beginning 1)) spacing))
7735 (setq length (- (match-end 2) (match-beginning 2)))
7736 (setq start-max (max start start-max))
7737 (setq length-max (max length length-max))
7738 (setq comment-list (cons (cons start length) comment-list)))
7739 (beginning-of-line 2))
7740 (setq comment-list
7741 (sort comment-list (function (lambda (a b) (> (car a) (car b))))))
7742 ;; reduce start positions
7743 (setq start-list (list (caar comment-list)))
7744 (setq comment-list (cdr comment-list))
7745 (while comment-list
7746 (unless (or (= (caar comment-list) (car start-list))
7747 (<= (+ (car start-list) (cdar comment-list))
7748 end-comment-column))
7749 (setq start-list (cons (caar comment-list) start-list)))
7750 (setq comment-list (cdr comment-list)))
7751 ;; align lines as nicely as possible
7752 (goto-char beg)
7753 (while (< (point) end)
7754 (setq cur-start nil)
7755 (when (and (not (looking-at "^\\s-*\\(begin\\|end\\)\\>"))
fda91268 7756 (or (and (looking-at "^\\(.*[^ \t\n\r\f-]+\\)\\(\\s-*\\)\\(--.*\\)$")
3dcb36b7
JB
7757 (not (save-excursion
7758 (goto-char (match-beginning 3))
7759 (vhdl-in-literal))))
7760 (and (looking-at "^\\(\\)\\(\\s-*\\)\\(--.*\\)$")
7761 (>= (- (match-end 2) (match-beginning 2))
7762 comment-column))))
7763 (setq start (+ (- (match-end 1) (match-beginning 1)) spacing))
7764 (setq length (- (match-end 3) (match-beginning 3)))
7765 (setq no-code (= (match-beginning 1) (match-end 1)))
7766 ;; insert minimum whitespace
7767 (goto-char (match-end 2))
7768 (delete-region (match-beginning 2) (match-end 2))
7769 (insert-char ?\ spacing)
7770 (setq tmp-list start-list)
7771 ;; insert additional whitespace to align
7772 (setq cur-start
7773 (cond
7774 ;; align comment-only line to inline comment of previous line
7775 ((and no-code prev-start
7776 (<= length (- end-comment-column prev-start)))
7777 prev-start)
7778 ;; align all comments at `start-max' if this is possible
7779 ((<= (+ start-max length-max) end-comment-column)
7780 start-max)
7781 ;; align at `comment-column' if possible
7782 ((and (<= start comment-column)
7783 (<= length (- end-comment-column comment-column)))
7784 comment-column)
7785 ;; align at left-most possible start position otherwise
7786 (t
7787 (while (and tmp-list (< (car tmp-list) start))
7788 (setq tmp-list (cdr tmp-list)))
7789 (car tmp-list))))
7790 (indent-to cur-start))
7791 (setq prev-start cur-start)
7792 (beginning-of-line 2))))))
d2ddb974 7793
5eabfe72
KH
7794(defun vhdl-align-inline-comment-region (beg end &optional spacing no-message)
7795 "Align inline comments within a region. Groups of code lines separated by
7796empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
d2ddb974 7797 (interactive "r\nP")
5eabfe72 7798 (save-excursion
3dcb36b7 7799 (let (orig pos)
5eabfe72
KH
7800 (goto-char beg)
7801 (beginning-of-line)
3dcb36b7 7802 (setq orig (point-marker))
5eabfe72
KH
7803 (setq beg (point))
7804 (goto-char end)
7805 (setq end (point-marker))
7806 (untabify beg end)
7807 (unless no-message (message "Aligning inline comments..."))
7808 (goto-char beg)
7809 (if (not vhdl-align-groups)
7810 ;; align entire region
7811 (vhdl-align-inline-comment-region-1 beg end spacing)
7812 ;; align groups
3dcb36b7
JB
7813 (while (and (< beg end)
7814 (re-search-forward vhdl-align-group-separate end t))
5eabfe72
KH
7815 (setq pos (point-marker))
7816 (vhdl-align-inline-comment-region-1 beg pos spacing)
7817 (setq beg (1+ pos))
7818 (goto-char beg))
7819 ;; align last group
7820 (when (< beg end)
3dcb36b7
JB
7821 (vhdl-align-inline-comment-region-1 beg end spacing)))
7822 (when vhdl-indent-tabs-mode
7823 (tabify orig end))
7824 (unless no-message (message "Aligning inline comments...done")))))
5eabfe72
KH
7825
7826(defun vhdl-align-inline-comment-group (&optional spacing)
7827 "Align inline comments within a group of lines between empty lines."
7828 (interactive)
7829 (save-excursion
7830 (let ((start (point))
7831 beg end)
3dcb36b7 7832 (setq end (if (re-search-forward vhdl-align-group-separate nil t)
5eabfe72
KH
7833 (point-marker) (point-max)))
7834 (goto-char start)
3dcb36b7
JB
7835 (setq beg (if (re-search-backward vhdl-align-group-separate nil t)
7836 (point) (point-min)))
5eabfe72
KH
7837 (untabify beg end)
7838 (message "Aligning inline comments...")
7839 (vhdl-align-inline-comment-region-1 beg end)
3dcb36b7
JB
7840 (when vhdl-indent-tabs-mode
7841 (tabify beg end))
5eabfe72
KH
7842 (message "Aligning inline comments...done"))))
7843
7844(defun vhdl-align-inline-comment-buffer ()
7845 "Align inline comments within buffer. Groups of code lines separated by
7846empty lines are aligned individually, if `vhdl-align-groups' is non-nil."
7847 (interactive)
7848 (vhdl-align-inline-comment-region (point-min) (point-max)))
7849
3dcb36b7
JB
7850;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7851;; Fixup whitespace
7852
5eabfe72
KH
7853(defun vhdl-fixup-whitespace-region (beg end &optional no-message)
7854 "Fixup whitespace in region. Surround operator symbols by one space,
7855eliminate multiple spaces (except at beginning of line), eliminate spaces at
3dcb36b7 7856end of line, do nothing in comments and strings."
5eabfe72
KH
7857 (interactive "r")
7858 (unless no-message (message "Fixing up whitespace..."))
7859 (save-excursion
7860 (goto-char end)
7861 (setq end (point-marker))
5eabfe72
KH
7862 ;; have no space before and one space after `,' and ';'
7863 (goto-char beg)
fda91268 7864 (while (re-search-forward "\\(--.*\n\\|\"[^\"\n]*[\"\n]\\|\'.\'\\|\\\\[^\\\n]*[\\\n]\\)\\|\\(\\s-*\\([,;]\\)\\)" end t)
3dcb36b7
JB
7865 (if (match-string 1)
7866 (goto-char (match-end 1))
fda91268 7867 (replace-match "\\3 " nil nil nil 2)))
3dcb36b7
JB
7868 ;; have no space after `('
7869 (goto-char beg)
fda91268 7870 (while (re-search-forward "\\(--.*\n\\|\"[^\"\n]*[\"\n]\\|\'.\'\\|\\\\[^\\\n]*[\\\n]\\)\\|\\((\\)\\s-+" end t)
3dcb36b7
JB
7871 (if (match-string 1)
7872 (goto-char (match-end 1))
7873 (replace-match "\\2")))
7874 ;; have no space before `)'
7875 (goto-char beg)
fda91268 7876 (while (re-search-forward "\\(--.*\n\\|\"[^\"\n]*[\"\n]\\|\'.\'\\|\\\\[^\\\n]*[\\\n]\\|^\\s-+\\)\\|\\s-+\\()\\)" end t)
3dcb36b7
JB
7877 (if (match-string 1)
7878 (goto-char (match-end 1))
7879 (replace-match "\\2")))
7880 ;; surround operator symbols by one space
7881 (goto-char beg)
fda91268
RZ
7882 (while (re-search-forward "\\(--.*\n\\|\"[^\"\n]*[\"\n]\\|\'.\'\\|\\\\[^\\\n]*[\\\n]\\)\\|\\(\\([^/:<>=]\\)\\(:\\|\\??=\\|\\??<<\\|\\??>>\\|\\??<\\|\\??>\\|:=\\|\\??<=\\|\\??>=\\|=>\\|\\??/=\\|\\?\\?\\)\\([^=>]\\|$\\)\\)" end t)
7883 (if (or (match-string 1)
7884 (<= (match-beginning 0) ; not if at boi
7885 (save-excursion (back-to-indentation) (point))))
7886 (goto-char (match-end 0))
0a2e512a
RF
7887 (replace-match "\\3 \\4 \\5")
7888 (goto-char (match-end 2))))
5eabfe72
KH
7889 ;; eliminate multiple spaces and spaces at end of line
7890 (goto-char beg)
7891 (while (or (and (looking-at "--.*\n") (re-search-forward "--.*\n" end t))
fda91268 7892 (and (looking-at "--.*") (re-search-forward "--.*" end t))
3dcb36b7 7893 (and (looking-at "\"") (re-search-forward "\"[^\"\n]*[\"\n]" end t))
5eabfe72
KH
7894 (and (looking-at "\\s-+$") (re-search-forward "\\s-+$" end t)
7895 (progn (replace-match "" nil nil) t))
7896 (and (looking-at "\\s-+;") (re-search-forward "\\s-+;" end t)
7897 (progn (replace-match ";" nil nil) t))
7898 (and (looking-at "^\\s-+") (re-search-forward "^\\s-+" end t))
7899 (and (looking-at "\\s-+--") (re-search-forward "\\s-+" end t)
3dcb36b7 7900 (progn (replace-match " " nil nil) t))
5eabfe72 7901 (and (looking-at "\\s-+") (re-search-forward "\\s-+" end t)
3dcb36b7 7902 (progn (replace-match " " nil nil) t))
fda91268 7903 (and (looking-at "-") (re-search-forward "-" end t))
0a2e512a
RF
7904; (re-search-forward "[^ \t-]+" end t))))
7905 (re-search-forward "[^ \t\"-]+" end t))))
5eabfe72
KH
7906 (unless no-message (message "Fixing up whitespace...done")))
7907
7908(defun vhdl-fixup-whitespace-buffer ()
7909 "Fixup whitespace in buffer. Surround operator symbols by one space,
7910eliminate multiple spaces (except at beginning of line), eliminate spaces at
7911end of line, do nothing in comments."
7912 (interactive)
7913 (vhdl-fixup-whitespace-region (point-min) (point-max)))
7914
3dcb36b7
JB
7915;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7916;; Beautify
7917
5eabfe72
KH
7918(defun vhdl-beautify-region (beg end)
7919 "Beautify region by applying indentation, whitespace fixup, alignment, and
3dcb36b7
JB
7920case fixing to a region. Calls functions `vhdl-indent-buffer',
7921`vhdl-align-buffer' (option `vhdl-align-groups' set to non-nil), and
5eabfe72
KH
7922`vhdl-fix-case-buffer'."
7923 (interactive "r")
3dcb36b7 7924 (setq end (save-excursion (goto-char end) (point-marker)))
fda91268 7925 (vhdl-indent-region beg end)
5eabfe72 7926 (let ((vhdl-align-groups t))
3dcb36b7 7927 (vhdl-align-region beg end))
5eabfe72
KH
7928 (vhdl-fix-case-region beg end))
7929
7930(defun vhdl-beautify-buffer ()
7931 "Beautify buffer by applying indentation, whitespace fixup, alignment, and
7932case fixing to entire buffer. Calls `vhdl-beautify-region' for the entire
7933buffer."
7934 (interactive)
3dcb36b7
JB
7935 (vhdl-beautify-region (point-min) (point-max))
7936 (when noninteractive (save-buffer)))
7937
7938;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7939;; Code filling
7940
7941(defun vhdl-fill-region (beg end &optional arg)
7942 "Fill lines for a region of code."
8d422bd5 7943 (interactive "r\np")
3dcb36b7
JB
7944 (save-excursion
7945 (goto-char beg)
f35aff82 7946 (let ((margin (if arg (current-indentation) (current-column))))
3dcb36b7
JB
7947 (goto-char end)
7948 (setq end (point-marker))
7949 ;; remove inline comments, newlines and whitespace
7950 (vhdl-comment-kill-region beg end)
7951 (vhdl-comment-kill-inline-region beg end)
7952 (subst-char-in-region beg (1- end) ?\n ?\ )
7953 (vhdl-fixup-whitespace-region beg end)
7954 ;; wrap and end-comment-column
7955 (goto-char beg)
7956 (while (re-search-forward "\\s-" end t)
7957 (when(> (current-column) vhdl-end-comment-column)
7958 (backward-char)
7959 (when (re-search-backward "\\s-" beg t)
7960 (replace-match "\n")
7961 (indent-to margin)))))))
7962
7963(defun vhdl-fill-group ()
7964 "Fill group of lines between empty lines."
7965 (interactive)
7966 (vhdl-do-group 'vhdl-fill-region))
7967
7968(defun vhdl-fill-list ()
7969 "Fill the lines of a list surrounded by a balanced group of parentheses."
7970 (interactive)
7971 (vhdl-do-list 'vhdl-fill-region))
7972
7973(defun vhdl-fill-same-indent ()
7974 "Fill the lines of block of lines with same indent."
7975 (interactive)
7976 (vhdl-do-same-indent 'vhdl-fill-region))
7977
7978
7979;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7980;;; Code updating/fixing
7981;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7982
7983;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7984;; Sensitivity list update
7985
7986;; Strategy:
7987;; - no sensitivity list is generated for processes with wait statements
7988;; - otherwise, do the following:
7989;; 1. scan for all local signals (ports, signals declared in arch./blocks)
7990;; 2. scan for all signals already in the sensitivity list (in order to catch
7991;; manually entered global signals)
7992;; 3. signals from 1. and 2. form the list of visible signals
7993;; 4. search for if/elsif conditions containing an event (sequential code)
7994;; 5. scan for strings that are within syntactical regions where signals are
7995;; read but not within sequential code, and that correspond to visible
7996;; signals
7997;; 6. replace sensitivity list by list of signals from 5.
7998
7999(defun vhdl-update-sensitivity-list-process ()
8000 "Update sensitivity list of current process."
8001 (interactive)
8002 (save-excursion
8003 (vhdl-prepare-search-2
8004 (end-of-line)
8005 ;; look whether in process
fda91268 8006 (if (not (and (re-search-backward "^\\s-*\\(\\w+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?\\(process\\|end\\s-+process\\)\\>" nil t)
3dcb36b7
JB
8007 (equal (upcase (match-string 2)) "PROCESS")
8008 (save-excursion (re-search-forward "^\\s-*end\\s-+process\\>" nil t))))
8009 (error "ERROR: Not within a process")
8010 (message "Updating sensitivity list...")
8011 (vhdl-update-sensitivity-list)
8012 (message "Updating sensitivity list...done")))))
8013
8014(defun vhdl-update-sensitivity-list-buffer ()
8015 "Update sensitivity list of all processes in current buffer."
8016 (interactive)
8017 (save-excursion
8018 (vhdl-prepare-search-2
8019 (goto-char (point-min))
8020 (message "Updating sensitivity lists...")
fda91268 8021 (while (re-search-forward "^\\s-*\\(\\w+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?process\\>" nil t)
3dcb36b7 8022 (goto-char (match-beginning 0))
0a2e512a 8023 (condition-case nil (vhdl-update-sensitivity-list) (error "")))
3dcb36b7
JB
8024 (message "Updating sensitivity lists...done"))))
8025
8026(defun vhdl-update-sensitivity-list ()
8027 "Update sensitivity list."
8028 (let ((proc-beg (point))
8029 (proc-end (re-search-forward "^\\s-*end\\s-+process\\>" nil t))
fda91268
RZ
8030 (proc-mid (vhdl-re-search-backward
8031 "\\(\\(\\<begin\\>\\)\\|^\\s-*process\\>\\)" nil t))
3dcb36b7
JB
8032 seq-region-list)
8033 (cond
fda91268
RZ
8034 ;; error if 'begin' keyword missing
8035 ((not (match-string 2))
8036 (error "ERROR: No 'begin' keyword found"))
3dcb36b7
JB
8037 ;; search for wait statement (no sensitivity list allowed)
8038 ((progn (goto-char proc-mid)
8039 (vhdl-re-search-forward "\\<wait\\>" proc-end t))
8040 (error "ERROR: Process with wait statement, sensitivity list not generated"))
8041 ;; combinational process (update sensitivity list)
8042 (t
8043 (let
8044 ;; scan for visible signals
8045 ((visible-list (vhdl-get-visible-signals))
8046 ;; define syntactic regions where signals are read
8047 (scan-regions-list
8048 '(;; right-hand side of signal/variable assignment
8049 ;; (special case: "<=" is relational operator in a condition)
8050 ((re-search-forward "[<:]=" proc-end t)
8051 (re-search-forward ";\\|\\<\\(then\\|loop\\|report\\|severity\\|is\\)\\>" proc-end t))
8052 ;; if condition
8053 ((re-search-forward "^\\s-*if\\>" proc-end t)
8054 (re-search-forward "\\<then\\>" proc-end t))
8055 ;; elsif condition
8056 ((re-search-forward "\\<elsif\\>" proc-end t)
8057 (re-search-forward "\\<then\\>" proc-end t))
8058 ;; while loop condition
8059 ((re-search-forward "^\\s-*while\\>" proc-end t)
8060 (re-search-forward "\\<loop\\>" proc-end t))
8061 ;; exit/next condition
8062 ((re-search-forward "\\<\\(exit\\|next\\)\\s-+\\w+\\s-+when\\>" proc-end t)
8063 (re-search-forward ";" proc-end t))
8064 ;; assert condition
8065 ((re-search-forward "\\<assert\\>" proc-end t)
8066 (re-search-forward "\\(\\<report\\>\\|\\<severity\\>\\|;\\)" proc-end t))
8067 ;; case expression
8068 ((re-search-forward "^\\s-*case\\>" proc-end t)
8069 (re-search-forward "\\<is\\>" proc-end t))
fda91268
RZ
8070 ;; parameter list of procedure call, array index
8071 ((and (re-search-forward "^\\s-*\\(\\w\\|\\.\\)+[ \t\n\r\f]*(" proc-end t)
0a2e512a
RF
8072 (1- (point)))
8073 (progn (backward-char) (forward-sexp)
8074 (while (looking-at "(") (forward-sexp)) (point)))))
fda91268 8075 name field read-list sens-list signal-list
3dcb36b7
JB
8076 sens-beg sens-end beg end margin)
8077 ;; scan for signals in old sensitivity list
8078 (goto-char proc-beg)
8079 (re-search-forward "\\<process\\>" proc-mid t)
fda91268 8080 (if (not (looking-at "[ \t\n\r\f]*("))
3dcb36b7 8081 (setq sens-beg (point))
fda91268 8082 (setq sens-beg (re-search-forward "\\([ \t\n\r\f]*\\)([ \t\n\r\f]*" nil t))
3dcb36b7
JB
8083 (goto-char (match-end 1))
8084 (forward-sexp)
8085 (setq sens-end (1- (point)))
8086 (goto-char sens-beg)
8087 (while (and (re-search-forward "\\(\\w+\\)" sens-end t)
8088 (setq sens-list
8089 (cons (downcase (match-string 0)) sens-list))
8090 (re-search-forward "\\s-*,\\s-*" sens-end t))))
8091 (setq signal-list (append visible-list sens-list))
8092 ;; search for sequential parts
8093 (goto-char proc-mid)
8094 (while (setq beg (re-search-forward "^\\s-*\\(els\\)?if\\>" proc-end t))
8095 (setq end (re-search-forward "\\<then\\>" proc-end t))
8096 (when (re-search-backward "\\('event\\|\\<\\(falling\\|rising\\)_edge\\)\\>" beg t)
8097 (goto-char end)
8098 (backward-word 1)
8099 (vhdl-forward-sexp)
8100 (setq seq-region-list (cons (cons end (point)) seq-region-list))
8101 (beginning-of-line)))
8102 ;; scan for signals read in process
8103 (while scan-regions-list
8104 (goto-char proc-mid)
8105 (while (and (setq beg (eval (nth 0 (car scan-regions-list))))
8106 (setq end (eval (nth 1 (car scan-regions-list)))))
8107 (goto-char beg)
8108 (unless (or (vhdl-in-literal)
8109 (and seq-region-list
8110 (let ((tmp-list seq-region-list))
8111 (while (and tmp-list
8112 (< (point) (caar tmp-list)))
8113 (setq tmp-list (cdr tmp-list)))
8114 (and tmp-list (< (point) (cdar tmp-list))))))
fda91268 8115 (while (vhdl-re-search-forward "[^'\".]\\<\\([a-zA-Z]\\w*\\)\\(\\(\\.\\w+\\|[ \t\n\r\f]*([^)]*)\\)*\\)[ \t\n\r\f]*\\('\\(\\w+\\)\\|\\(=>\\)\\)?" end t)
3dcb36b7 8116 (setq name (match-string 1))
fda91268
RZ
8117 (when vhdl-array-index-record-field-in-sensitivity-list
8118 (setq field (match-string 2)))
8119 (when (and (not (match-string 6)) ; not when formal parameter
8120 (not (and (match-string 5) ; not event attribute
8121 (not (member (downcase (match-string 5))
0a2e512a
RF
8122 '("event" "last_event" "transaction")))))
8123 (member (downcase name) signal-list))
fda91268
RZ
8124 (unless (member-ignore-case (concat name field) read-list)
8125 (setq read-list (cons (concat name field) read-list))))
0a2e512a 8126 (goto-char (match-end 1)))))
3dcb36b7
JB
8127 (setq scan-regions-list (cdr scan-regions-list)))
8128 ;; update sensitivity list
8129 (goto-char sens-beg)
8130 (if sens-end
8131 (delete-region sens-beg sens-end)
8132 (when read-list
8133 (insert " ()") (backward-char)))
8134 (setq read-list (sort read-list 'string<))
8135 (when read-list
8136 (setq margin (current-column))
8137 (insert (car read-list))
8138 (setq read-list (cdr read-list))
8139 (while read-list
8140 (insert ",")
8141 (if (<= (+ (current-column) (length (car read-list)) 2)
8142 end-comment-column)
8143 (insert " ")
8144 (insert "\n") (indent-to margin))
8145 (insert (car read-list))
8146 (setq read-list (cdr read-list)))))))))
8147
8148(defun vhdl-get-visible-signals ()
8149 "Get all signals visible in the current block."
0a2e512a
RF
8150 (let (beg end signal-list entity-name file-name)
8151 (vhdl-prepare-search-2
8152 ;; get entity name
8153 (save-excursion
8154 (unless (and (re-search-backward "^\\(architecture\\s-+\\w+\\s-+of\\s-+\\(\\w+\\)\\|end\\)\\>" nil t)
3dcb36b7 8155 (not (equal "END" (upcase (match-string 1))))
0a2e512a
RF
8156 (setq entity-name (match-string 2)))
8157 (error "ERROR: Not within an architecture")))
8158 ;; search for signals declared in entity port clause
8159 (save-excursion
8160 (goto-char (point-min))
8161 (unless (re-search-forward (concat "^entity\\s-+" entity-name "\\>") nil t)
8162 (setq file-name
8163 (concat (vhdl-replace-string vhdl-entity-file-name entity-name t)
8164 "." (file-name-extension (buffer-file-name)))))
8165 (vhdl-visit-file
8166 file-name t
8167 (vhdl-prepare-search-2
8168 (goto-char (point-min))
8169 (if (not (re-search-forward (concat "^entity\\s-+" entity-name "\\>") nil t))
8170 (error "ERROR: Entity \"%s\" not found:\n --> see option `vhdl-entity-file-name'" entity-name)
fda91268
RZ
8171 (when (setq beg (vhdl-re-search-forward
8172 "\\<port[ \t\n\r\f]*("
0a2e512a
RF
8173 (save-excursion
8174 (re-search-forward "^end\\>" nil t)) t))
8175 (setq end (save-excursion
8176 (backward-char) (forward-sexp) (point)))
8177 (vhdl-forward-syntactic-ws)
8178 (while (< (point) end)
fda91268 8179 (when (looking-at "signal[ \t\n\r\f]+")
0a2e512a 8180 (goto-char (match-end 0)))
fda91268 8181 (while (looking-at "\\(\\w+\\)[ \t\n\r\f,]+")
0a2e512a
RF
8182 (setq signal-list
8183 (cons (downcase (match-string 1)) signal-list))
8184 (goto-char (match-end 0))
8185 (vhdl-forward-syntactic-ws))
8186 (re-search-forward ";" end 1)
8187 (vhdl-forward-syntactic-ws)))))))
8188 ;; search for signals declared in architecture declarative part
8189 (save-excursion
8190 (if (not (and (setq beg (re-search-backward "^\\(architecture\\s-+\\w+\\s-+of\\s-+\\(\\w+\\)\\|end\\)\\>" nil t))
8191 (not (equal "END" (upcase (match-string 1))))
8192 (setq end (re-search-forward "^begin\\>" nil t))))
8193 (error "ERROR: No architecture declarative part found")
8194 ;; scan for all declared signal and alias names
8195 (goto-char beg)
8196 (while (re-search-forward "^\\s-*\\(\\(signal\\)\\|alias\\)\\>" end t)
8197 (when (= 0 (nth 0 (parse-partial-sexp beg (point))))
8198 (if (match-string 2)
8199 ;; scan signal name
fda91268 8200 (while (looking-at "[ \t\n\r\f,]+\\(\\w+\\)")
0a2e512a
RF
8201 (setq signal-list
8202 (cons (downcase (match-string 1)) signal-list))
8203 (goto-char (match-end 0)))
8204 ;; scan alias name, check is alias of (declared) signal
fda91268 8205 (when (and (looking-at "[ \t\n\r\f]+\\(\\w+\\)[^;]*\\<is[ \t\n\r\f]+\\(\\w+\\)")
0a2e512a
RF
8206 (member (downcase (match-string 2)) signal-list))
8207 (setq signal-list
8208 (cons (downcase (match-string 1)) signal-list))
8209 (goto-char (match-end 0))))
8210 (setq beg (point))))))
8211 ;; search for signals declared in surrounding block declarative parts
8212 (save-excursion
8213 (while (and (progn (while (and (setq beg (re-search-backward "^\\s-*\\(\\w+\\s-*:\\s-*block\\|\\(end\\)\\s-+block\\)\\>" nil t))
8214 (match-string 2))
8215 (goto-char (match-end 2))
8216 (vhdl-backward-sexp)
8217 (re-search-backward "^\\s-*\\w+\\s-*:\\s-*block\\>" nil t))
8218 beg)
8219 (setq end (re-search-forward "^\\s-*begin\\>" nil t)))
8220 ;; scan for all declared signal names
8221 (goto-char beg)
8222 (while (re-search-forward "^\\s-*\\(\\(signal\\)\\|alias\\)\\>" end t)
8223 (when (= 0 (nth 0 (parse-partial-sexp beg (point))))
8224 (if (match-string 2)
8225 ;; scan signal name
8226 (while (looking-at "[ \t\n,]+\\(\\w+\\)")
8227 (setq signal-list
8228 (cons (downcase (match-string 1)) signal-list))
8229 (goto-char (match-end 0)))
8230 ;; scan alias name, check is alias of (declared) signal
8231 (when (and (looking-at "[ \t\n]+\\(\\w+\\)[^;]*\\<is[ \t\n]+\\(\\w+\\)")
8232 (member (downcase (match-string 2)) signal-list))
8233 (setq signal-list
8234 (cons (downcase (match-string 1)) signal-list))
8235 (goto-char (match-end 0))))))
8236 (goto-char beg)))
8237 signal-list)))
3dcb36b7
JB
8238
8239;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8240;; Generic/port clause fixing
8241
fda91268
RZ
8242(defun vhdl-fix-clause-buffer ()
8243 "Fix all generic/port clauses in current buffer."
8244 (interactive)
8245 (save-excursion
8246 (vhdl-prepare-search-2
8247 (goto-char (point-min))
8248 (message "Fixing generic/port clauses...")
8249 (while (re-search-forward "^\\s-*\\(generic\\|port\\)[ \t\n\r\f]*(" nil t)
8250 (goto-char (match-end 0))
8251 (condition-case nil (vhdl-fix-clause) (error "")))
8252 (message "Fixing generic/port clauses...done"))))
8253
3dcb36b7
JB
8254(defun vhdl-fix-clause ()
8255 "Fix closing parenthesis within generic/port clause."
8256 (interactive)
8257 (save-excursion
8258 (vhdl-prepare-search-2
8259 (let ((pos (point))
8260 beg end)
fda91268
RZ
8261 (end-of-line)
8262 (if (not (re-search-backward "^\\s-*\\(generic\\|port\\)[ \t\n\r\f]*(" nil t))
3dcb36b7
JB
8263 (error "ERROR: Not within a generic/port clause")
8264 ;; search for end of clause
8265 (goto-char (match-end 0))
8266 (setq beg (1- (point)))
8267 (vhdl-forward-syntactic-ws)
fda91268 8268 (while (looking-at "\\w+\\([ \t\n\r\f]*,[ \t\n\r\f]*\\w+\\)*[ \t\n\r\f]*:[ \t\n\r\f]*\\w+[^;]*;")
3dcb36b7
JB
8269 (goto-char (1- (match-end 0)))
8270 (setq end (point-marker))
8271 (forward-char)
8272 (vhdl-forward-syntactic-ws))
8273 (goto-char end)
e180ab9f 8274 (when (> pos (point-at-eol))
3dcb36b7
JB
8275 (error "ERROR: Not within a generic/port clause"))
8276 ;; delete closing parenthesis on separate line (not supported style)
8277 (when (save-excursion (beginning-of-line) (looking-at "^\\s-*);"))
8278 (vhdl-line-kill)
8279 (vhdl-backward-syntactic-ws)
8280 (setq end (point-marker))
8281 (insert ";"))
8282 ;; delete superfluous parentheses
8283 (while (progn (goto-char beg)
8284 (condition-case () (forward-sexp)
8285 (error (goto-char (point-max))))
8286 (< (point) end))
d355a0b7 8287 (delete-char -1))
3dcb36b7
JB
8288 ;; add closing parenthesis
8289 (when (> (point) end)
8290 (goto-char end)
8291 (insert ")")))))))
8292
8293;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8294;; Miscellaneous
8295
8296(defun vhdl-remove-trailing-spaces ()
8297 "Remove trailing spaces in the whole buffer."
8298 (interactive)
8299 (save-match-data
8300 (save-excursion
8301 (goto-char (point-min))
8302 (while (re-search-forward "[ \t]+$" (point-max) t)
8303 (unless (vhdl-in-literal)
8304 (replace-match "" nil nil))))))
d2ddb974
KH
8305
8306
5eabfe72
KH
8307;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8308;;; Electrification
8309;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974 8310
5eabfe72
KH
8311(defconst vhdl-template-prompt-syntax "[^ =<>][^<>@.\n]*[^ =<>]"
8312 "Syntax of prompt inserted by template generators.")
8313
8314(defvar vhdl-template-invoked-by-hook nil
8315 "Indicates whether a template has been invoked by a hook or by key or menu.
8316Used for undoing after template abortion.")
8317
8318;; correct different behavior of function `unread-command-events' in XEmacs
3dcb36b7 8319(defun vhdl-character-to-event (arg))
5eabfe72 8320(defalias 'vhdl-character-to-event
4bcb9c95 8321 (if (fboundp 'character-to-event) 'character-to-event 'identity))
3dcb36b7
JB
8322
8323(defun vhdl-work-library ()
8324 "Return the working library name of the current project or \"work\" if no
8325project is defined."
8326 (vhdl-resolve-env-variable
8327 (or (nth 6 (aget vhdl-project-alist vhdl-project)) vhdl-default-library)))
5eabfe72
KH
8328
8329;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8330;; Enabling/disabling
8331
56eb0904 8332(define-minor-mode vhdl-electric-mode
5eabfe72 8333 "Toggle VHDL electric mode.
ac6c8639
CY
8334With a prefix argument ARG, enable the mode if ARG is positive,
8335and disable it otherwise. If called from Lisp, enable it if ARG
8336is omitted or nil."
56eb0904 8337 :global t)
5eabfe72 8338
56eb0904 8339(define-minor-mode vhdl-stutter-mode
5eabfe72 8340 "Toggle VHDL stuttering mode.
ac6c8639
CY
8341With a prefix argument ARG, enable the mode if ARG is positive,
8342and disable it otherwise. If called from Lisp, enable it if ARG
8343is omitted or nil."
56eb0904 8344 :global t)
5eabfe72
KH
8345
8346;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8347;; Stuttering
d2ddb974 8348
5eabfe72
KH
8349(defun vhdl-electric-dash (count)
8350 "-- starts a comment, --- draws a horizontal line,
a4c6cfad 8351---- starts a display comment."
d2ddb974 8352 (interactive "p")
3dcb36b7 8353 (if (and vhdl-stutter-mode (not (vhdl-in-literal)))
5eabfe72
KH
8354 (cond
8355 ((and abbrev-start-location (= abbrev-start-location (point)))
8356 (setq abbrev-start-location nil)
8357 (goto-char last-abbrev-location)
8358 (beginning-of-line nil)
8359 (vhdl-comment-display))
8360 ((/= (preceding-char) ?-) ; standard dash (minus)
d2ddb974 8361 (self-insert-command count))
5eabfe72
KH
8362 (t (self-insert-command count)
8363 (message "Enter '-' for horiz. line, 'CR' for commenting-out code, else enter comment")
8364 (let ((next-input (read-char)))
8365 (if (= next-input ?-) ; triple dash
8366 (progn
8367 (vhdl-comment-display-line)
8368 (message
8369 "Enter '-' for display comment, else continue coding")
8370 (let ((next-input (read-char)))
8371 (if (= next-input ?-) ; four dashes
8372 (vhdl-comment-display t)
8373 (setq unread-command-events ; pushback the char
8374 (list (vhdl-character-to-event next-input))))))
8375 (setq unread-command-events ; pushback the char
8376 (list (vhdl-character-to-event next-input)))
8377 (vhdl-comment-insert)))))
8378 (self-insert-command count)))
8379
8380(defun vhdl-electric-open-bracket (count) "'[' --> '(', '([' --> '['"
d2ddb974 8381 (interactive "p")
3dcb36b7 8382 (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal)))
5eabfe72
KH
8383 (if (= (preceding-char) ?\()
8384 (progn (delete-char -1) (insert-char ?\[ 1))
8385 (insert-char ?\( 1))
8386 (self-insert-command count)))
d2ddb974 8387
5eabfe72 8388(defun vhdl-electric-close-bracket (count) "']' --> ')', ')]' --> ']'"
d2ddb974 8389 (interactive "p")
3dcb36b7 8390 (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal)))
d2ddb974 8391 (progn
5eabfe72
KH
8392 (if (= (preceding-char) ?\))
8393 (progn (delete-char -1) (insert-char ?\] 1))
8394 (insert-char ?\) 1))
8395 (blink-matching-open))
8396 (self-insert-command count)))
d2ddb974 8397
5eabfe72 8398(defun vhdl-electric-quote (count) "'' --> \""
d2ddb974 8399 (interactive "p")
3dcb36b7 8400 (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal)))
1e4bd40d 8401 (if (= (preceding-char) last-input-event)
d355a0b7 8402 (progn (delete-char -1) (insert-char ?\" 1))
5eabfe72
KH
8403 (insert-char ?\' 1))
8404 (self-insert-command count)))
d2ddb974 8405
5eabfe72 8406(defun vhdl-electric-semicolon (count) "';;' --> ' : ', ': ;' --> ' := '"
d2ddb974 8407 (interactive "p")
3dcb36b7 8408 (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal)))
1e4bd40d 8409 (cond ((= (preceding-char) last-input-event)
5eabfe72 8410 (progn (delete-char -1)
3dcb36b7 8411 (unless (eq (preceding-char) ? ) (insert " "))
5eabfe72
KH
8412 (insert ": ")
8413 (setq this-command 'vhdl-electric-colon)))
8414 ((and
8415 (eq last-command 'vhdl-electric-colon) (= (preceding-char) ? ))
8416 (progn (delete-char -1) (insert "= ")))
8417 (t (insert-char ?\; 1)))
8418 (self-insert-command count)))
8419
8420(defun vhdl-electric-comma (count) "',,' --> ' <= '"
d2ddb974 8421 (interactive "p")
3dcb36b7 8422 (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal)))
1e4bd40d 8423 (cond ((= (preceding-char) last-input-event)
d2ddb974 8424 (progn (delete-char -1)
3dcb36b7 8425 (unless (eq (preceding-char) ? ) (insert " "))
d2ddb974 8426 (insert "<= ")))
5eabfe72
KH
8427 (t (insert-char ?\, 1)))
8428 (self-insert-command count)))
d2ddb974 8429
5eabfe72 8430(defun vhdl-electric-period (count) "'..' --> ' => '"
d2ddb974 8431 (interactive "p")
3dcb36b7 8432 (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal)))
1e4bd40d 8433 (cond ((= (preceding-char) last-input-event)
d2ddb974 8434 (progn (delete-char -1)
3dcb36b7 8435 (unless (eq (preceding-char) ? ) (insert " "))
d2ddb974 8436 (insert "=> ")))
5eabfe72
KH
8437 (t (insert-char ?\. 1)))
8438 (self-insert-command count)))
d2ddb974 8439
5eabfe72 8440(defun vhdl-electric-equal (count) "'==' --> ' == '"
d2ddb974 8441 (interactive "p")
3dcb36b7 8442 (if (and vhdl-stutter-mode (= count 1) (not (vhdl-in-literal)))
1e4bd40d 8443 (cond ((= (preceding-char) last-input-event)
5eabfe72 8444 (progn (delete-char -1)
3dcb36b7 8445 (unless (eq (preceding-char) ? ) (insert " "))
5eabfe72
KH
8446 (insert "== ")))
8447 (t (insert-char ?\= 1)))
8448 (self-insert-command count)))
d2ddb974 8449
5eabfe72 8450;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
8451;; VHDL templates
8452
5eabfe72
KH
8453(defun vhdl-template-paired-parens ()
8454 "Insert a pair of round parentheses, placing point between them."
d2ddb974 8455 (interactive)
5eabfe72
KH
8456 (insert "()")
8457 (backward-char))
d2ddb974 8458
5eabfe72
KH
8459(defun vhdl-template-alias ()
8460 "Insert alias declaration."
d2ddb974 8461 (interactive)
5eabfe72
KH
8462 (let ((start (point)))
8463 (vhdl-insert-keyword "ALIAS ")
8464 (when (vhdl-template-field "name" nil t start (point))
8465 (insert " : ")
8466 (unless (vhdl-template-field
8467 (concat "[type" (and (vhdl-standard-p 'ams) " or nature") "]")
8468 nil t)
d355a0b7 8469 (delete-char -3))
5eabfe72
KH
8470 (vhdl-insert-keyword " IS ")
8471 (vhdl-template-field "name" ";")
8472 (vhdl-comment-insert-inline))))
8473
8474(defun vhdl-template-architecture ()
8475 "Insert architecture."
8476 (interactive)
8477 (let ((margin (current-indentation))
8478 (start (point))
3dcb36b7 8479 arch-name)
d2ddb974 8480 (vhdl-insert-keyword "ARCHITECTURE ")
5eabfe72
KH
8481 (when (setq arch-name
8482 (vhdl-template-field "name" nil t start (point)))
d2ddb974 8483 (vhdl-insert-keyword " OF ")
3dcb36b7
JB
8484 (if (save-excursion
8485 (vhdl-prepare-search-1
8486 (vhdl-re-search-backward "\\<entity \\(\\w+\\) is\\>" nil t)))
8487 (insert (match-string 1))
5eabfe72 8488 (vhdl-template-field "entity name"))
3dcb36b7 8489 (vhdl-insert-keyword " IS\n")
5eabfe72
KH
8490 (vhdl-template-begin-end
8491 (unless (vhdl-standard-p '87) "ARCHITECTURE") arch-name margin
8492 (memq vhdl-insert-empty-lines '(unit all))))))
d2ddb974 8493
5eabfe72 8494(defun vhdl-template-array (kind &optional secondary)
d2ddb974
KH
8495 "Insert array type definition."
8496 (interactive)
5eabfe72
KH
8497 (let ((start (point)))
8498 (vhdl-insert-keyword "ARRAY (")
8499 (when (or (vhdl-template-field "range" nil (not secondary) start (point))
8500 secondary)
8501 (vhdl-insert-keyword ") OF ")
8502 (vhdl-template-field (if (eq kind 'type) "type" "nature"))
8503 (vhdl-insert-keyword ";"))))
8504
8505(defun vhdl-template-assert ()
8506 "Insert an assertion statement."
8507 (interactive)
8508 (let ((start (point)))
8509 (vhdl-insert-keyword "ASSERT ")
8510 (when vhdl-conditions-in-parenthesis (insert "("))
8511 (when (vhdl-template-field "condition (negated)" nil t start (point))
8512 (when vhdl-conditions-in-parenthesis (insert ")"))
8513 (setq start (point))
8514 (vhdl-insert-keyword " REPORT ")
8515 (unless (vhdl-template-field "string expression" nil nil nil nil t)
8516 (delete-region start (point)))
8517 (setq start (point))
8518 (vhdl-insert-keyword " SEVERITY ")
8519 (unless (vhdl-template-field "[NOTE | WARNING | ERROR | FAILURE]" nil t)
8520 (delete-region start (point)))
8521 (insert ";"))))
8522
8523(defun vhdl-template-attribute ()
8524 "Insert an attribute declaration or specification."
8525 (interactive)
8526 (if (eq (vhdl-decision-query
8527 "attribute" "(d)eclaration or (s)pecification?" t) ?s)
8528 (vhdl-template-attribute-spec)
8529 (vhdl-template-attribute-decl)))
d2ddb974 8530
5eabfe72
KH
8531(defun vhdl-template-attribute-decl ()
8532 "Insert an attribute declaration."
d2ddb974 8533 (interactive)
5eabfe72
KH
8534 (let ((start (point)))
8535 (vhdl-insert-keyword "ATTRIBUTE ")
8536 (when (vhdl-template-field "name" " : " t start (point))
8537 (vhdl-template-field "type" ";")
8538 (vhdl-comment-insert-inline))))
8539
8540(defun vhdl-template-attribute-spec ()
8541 "Insert an attribute specification."
8542 (interactive)
8543 (let ((start (point)))
8544 (vhdl-insert-keyword "ATTRIBUTE ")
8545 (when (vhdl-template-field "name" nil t start (point))
8546 (vhdl-insert-keyword " OF ")
8547 (vhdl-template-field "entity names | OTHERS | ALL" " : ")
8548 (vhdl-template-field "entity class")
8549 (vhdl-insert-keyword " IS ")
8550 (vhdl-template-field "expression" ";"))))
d2ddb974 8551
5eabfe72
KH
8552(defun vhdl-template-block ()
8553 "Insert a block."
d2ddb974 8554 (interactive)
5eabfe72
KH
8555 (let ((margin (current-indentation))
8556 (start (point))
8557 label)
8558 (vhdl-insert-keyword ": BLOCK ")
8559 (goto-char start)
8560 (when (setq label (vhdl-template-field "label" nil t start (+ (point) 8)))
8561 (forward-word 1)
8562 (forward-char 1)
d2ddb974 8563 (insert "(")
5eabfe72
KH
8564 (if (vhdl-template-field "[guard expression]" nil t)
8565 (insert ")")
8566 (delete-char -2))
8567 (unless (vhdl-standard-p '87) (vhdl-insert-keyword " IS"))
3dcb36b7 8568 (insert "\n")
5eabfe72
KH
8569 (vhdl-template-begin-end "BLOCK" label margin)
8570 (vhdl-comment-block))))
d2ddb974 8571
5eabfe72 8572(defun vhdl-template-block-configuration ()
d2ddb974
KH
8573 "Insert a block configuration statement."
8574 (interactive)
5eabfe72
KH
8575 (let ((margin (current-indentation))
8576 (start (point)))
d2ddb974 8577 (vhdl-insert-keyword "FOR ")
5eabfe72 8578 (when (vhdl-template-field "block name" nil t start (point))
d2ddb974
KH
8579 (vhdl-insert-keyword "\n\n")
8580 (indent-to margin)
8581 (vhdl-insert-keyword "END FOR;")
8582 (end-of-line 0)
5eabfe72 8583 (indent-to (+ margin vhdl-basic-offset)))))
d2ddb974 8584
5eabfe72
KH
8585(defun vhdl-template-break ()
8586 "Insert a break statement."
d2ddb974 8587 (interactive)
5eabfe72
KH
8588 (let (position)
8589 (vhdl-insert-keyword "BREAK")
8590 (setq position (point))
8591 (insert " ")
8592 (while (or
8593 (progn (vhdl-insert-keyword "FOR ")
8594 (if (vhdl-template-field "[quantity name]" " USE " t)
8595 (progn (vhdl-template-field "quantity name" " => ") t)
453cfeb3
CY
8596 (delete-region (point)
8597 (progn (forward-word -1) (point)))
8598 nil))
5eabfe72
KH
8599 (vhdl-template-field "[quantity name]" " => " t))
8600 (vhdl-template-field "expression")
8601 (setq position (point))
8602 (insert ", "))
8603 (delete-region position (point))
8604 (unless (vhdl-sequential-statement-p)
8605 (vhdl-insert-keyword " ON ")
8606 (if (vhdl-template-field "[sensitivity list]" nil t)
8607 (setq position (point))
8608 (delete-region position (point))))
8609 (vhdl-insert-keyword " WHEN ")
8610 (when vhdl-conditions-in-parenthesis (insert "("))
8611 (if (vhdl-template-field "[condition]" nil t)
8612 (when vhdl-conditions-in-parenthesis (insert ")"))
8613 (delete-region position (point)))
8614 (insert ";")))
8615
8616(defun vhdl-template-case (&optional kind)
8617 "Insert a case statement."
8618 (interactive)
8619 (let ((margin (current-indentation))
8620 (start (point))
8621 label)
fda91268
RZ
8622 (unless kind (setq kind (if (or (vhdl-sequential-statement-p)
8623 (not (vhdl-standard-p 'ams))) 'is 'use)))
5eabfe72
KH
8624 (if (or (not (eq vhdl-optional-labels 'all)) (vhdl-standard-p '87))
8625 (vhdl-insert-keyword "CASE ")
8626 (vhdl-insert-keyword ": CASE ")
8627 (goto-char start)
8628 (setq label (vhdl-template-field "[label]" nil t))
8629 (unless label (delete-char 2))
8630 (forward-word 1)
8631 (forward-char 1))
8632 (when (vhdl-template-field "expression" nil t start (point))
8633 (vhdl-insert-keyword (concat " " (if (eq kind 'is) "IS" "USE") "\n\n"))
d2ddb974 8634 (indent-to margin)
5eabfe72
KH
8635 (vhdl-insert-keyword "END CASE")
8636 (when label (insert " " label))
8637 (insert ";")
d2ddb974
KH
8638 (forward-line -1)
8639 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
8640 (vhdl-insert-keyword "WHEN ")
8641 (let ((position (point)))
8642 (insert " => ;\n")
8643 (indent-to (+ margin vhdl-basic-offset))
8644 (vhdl-insert-keyword "WHEN OTHERS => null;")
8645 (goto-char position)))))
d2ddb974 8646
5eabfe72
KH
8647(defun vhdl-template-case-is ()
8648 "Insert a sequential case statement."
d2ddb974 8649 (interactive)
5eabfe72
KH
8650 (vhdl-template-case 'is))
8651
8652(defun vhdl-template-case-use ()
8653 "Insert a simultaneous case statement."
8654 (interactive)
8655 (vhdl-template-case 'use))
8656
8657(defun vhdl-template-component ()
8658 "Insert a component declaration."
8659 (interactive)
8660 (vhdl-template-component-decl))
8661
8662(defun vhdl-template-component-conf ()
8663 "Insert a component configuration (uses `vhdl-template-configuration-spec'
8664since these are almost equivalent)."
8665 (interactive)
8666 (let ((margin (current-indentation))
8667 (result (vhdl-template-configuration-spec t)))
8668 (when result
8669 (insert "\n")
8670 (indent-to margin)
8671 (vhdl-insert-keyword "END FOR;")
8672 (when (eq result 'no-use)
8673 (end-of-line -0)))))
8674
8675(defun vhdl-template-component-decl ()
8676 "Insert a component declaration."
8677 (interactive)
8678 (let ((margin (current-indentation))
8679 (start (point))
8680 name end-column)
d2ddb974 8681 (vhdl-insert-keyword "COMPONENT ")
5eabfe72 8682 (when (setq name (vhdl-template-field "name" nil t start (point)))
3dcb36b7 8683 (unless (vhdl-standard-p '87) (vhdl-insert-keyword " IS"))
d2ddb974
KH
8684 (insert "\n\n")
8685 (indent-to margin)
5eabfe72
KH
8686 (vhdl-insert-keyword "END COMPONENT")
8687 (unless (vhdl-standard-p '87) (insert " " name))
8688 (insert ";")
8689 (setq end-column (current-column))
d2ddb974
KH
8690 (end-of-line -0)
8691 (indent-to (+ margin vhdl-basic-offset))
5eabfe72 8692 (vhdl-template-generic-list t t)
d2ddb974
KH
8693 (insert "\n")
8694 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
8695 (vhdl-template-port-list t)
8696 (beginning-of-line 2)
8697 (forward-char end-column))))
d2ddb974 8698
5eabfe72
KH
8699(defun vhdl-template-component-inst ()
8700 "Insert a component instantiation statement."
d2ddb974 8701 (interactive)
5eabfe72
KH
8702 (let ((margin (current-indentation))
8703 (start (point))
8704 unit position)
8705 (when (vhdl-template-field "instance label" nil t start (point))
8706 (insert ": ")
3dcb36b7 8707 (if (not (vhdl-use-direct-instantiation))
5eabfe72
KH
8708 (vhdl-template-field "component name")
8709 ;; direct instantiation
8710 (setq unit (vhdl-template-field
8711 "[COMPONENT | ENTITY | CONFIGURATION]" " " t))
8712 (setq unit (upcase (or unit "")))
8713 (cond ((equal unit "ENTITY")
3dcb36b7
JB
8714 (vhdl-template-field "library name" "." nil nil nil nil
8715 (vhdl-work-library))
5eabfe72
KH
8716 (vhdl-template-field "entity name" "(")
8717 (if (vhdl-template-field "[architecture name]" nil t)
8718 (insert ")")
8719 (delete-char -1)))
8720 ((equal unit "CONFIGURATION")
3dcb36b7
JB
8721 (vhdl-template-field "library name" "." nil nil nil nil
8722 (vhdl-work-library))
5eabfe72
KH
8723 (vhdl-template-field "configuration name"))
8724 (t (vhdl-template-field "component name"))))
8725 (insert "\n")
d2ddb974 8726 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
8727 (setq position (point))
8728 (vhdl-insert-keyword "GENERIC ")
8729 (when (vhdl-template-map position t t)
8730 (insert "\n")
8731 (indent-to (+ margin vhdl-basic-offset)))
8732 (setq position (point))
8733 (vhdl-insert-keyword "PORT ")
8734 (unless (vhdl-template-map position t t)
453cfeb3 8735 (delete-region (line-beginning-position) (point))
5eabfe72
KH
8736 (delete-char -1))
8737 (insert ";"))))
d2ddb974 8738
5eabfe72
KH
8739(defun vhdl-template-conditional-signal-asst ()
8740 "Insert a conditional signal assignment."
d2ddb974 8741 (interactive)
5eabfe72 8742 (when (vhdl-template-field "target signal")
d2ddb974 8743 (insert " <= ")
5eabfe72
KH
8744; (if (not (equal (vhdl-template-field "[GUARDED] [TRANSPORT]") ""))
8745; (insert " "))
d2ddb974 8746 (let ((margin (current-column))
5eabfe72
KH
8747 (start (point))
8748 position)
8749 (vhdl-template-field "waveform")
8750 (setq position (point))
d2ddb974 8751 (vhdl-insert-keyword " WHEN ")
5eabfe72
KH
8752 (when vhdl-conditions-in-parenthesis (insert "("))
8753 (while (and (vhdl-template-field "[condition]" nil t)
8754 (progn
8755 (when vhdl-conditions-in-parenthesis (insert ")"))
8756 (setq position (point))
8757 (vhdl-insert-keyword " ELSE")
8758 (insert "\n")
8759 (indent-to margin)
8760 (vhdl-template-field "[waveform]" nil t)))
8761 (setq position (point))
d2ddb974 8762 (vhdl-insert-keyword " WHEN ")
5eabfe72
KH
8763 (when vhdl-conditions-in-parenthesis (insert "(")))
8764 (delete-region position (point))
d2ddb974 8765 (insert ";")
3dcb36b7 8766 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1)))))
d2ddb974 8767
5eabfe72
KH
8768(defun vhdl-template-configuration ()
8769 "Insert a configuration specification if within an architecture,
d2ddb974
KH
8770a block or component configuration if within a configuration declaration,
8771a configuration declaration if not within a design unit."
8772 (interactive)
3dcb36b7
JB
8773 (vhdl-prepare-search-1
8774 (cond
8775 ((and (save-excursion ; architecture body
8776 (re-search-backward "^\\(architecture\\|end\\)\\>" nil t))
8777 (equal "ARCHITECTURE" (upcase (match-string 1))))
8778 (vhdl-template-configuration-spec))
8779 ((and (save-excursion ; configuration declaration
8780 (re-search-backward "^\\(configuration\\|end\\)\\>" nil t))
8781 (equal "CONFIGURATION" (upcase (match-string 1))))
8782 (if (eq (vhdl-decision-query
8783 "configuration" "(b)lock or (c)omponent configuration?" t) ?c)
8784 (vhdl-template-component-conf)
8785 (vhdl-template-block-configuration)))
8786 (t (vhdl-template-configuration-decl))))) ; otherwise
5eabfe72
KH
8787
8788(defun vhdl-template-configuration-spec (&optional optional-use)
8789 "Insert a configuration specification."
d2ddb974 8790 (interactive)
5eabfe72
KH
8791 (let ((margin (current-indentation))
8792 (start (point))
8793 aspect position)
d2ddb974 8794 (vhdl-insert-keyword "FOR ")
3dcb36b7 8795 (when (vhdl-template-field "instance names | OTHERS | ALL" " : "
5eabfe72 8796 t start (point))
3dcb36b7 8797 (vhdl-template-field "component name" "\n")
d2ddb974 8798 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
8799 (setq start (point))
8800 (vhdl-insert-keyword "USE ")
8801 (if (and optional-use
8802 (not (setq aspect (vhdl-template-field
8803 "[ENTITY | CONFIGURATION | OPEN]" " " t))))
8804 (progn (delete-region start (point)) 'no-use)
8805 (unless optional-use
8806 (setq aspect (vhdl-template-field
8807 "ENTITY | CONFIGURATION | OPEN" " ")))
8808 (setq aspect (upcase (or aspect "")))
8809 (cond ((equal aspect "ENTITY")
3dcb36b7
JB
8810 (vhdl-template-field "library name" "." nil nil nil nil
8811 (vhdl-work-library))
5eabfe72
KH
8812 (vhdl-template-field "entity name" "(")
8813 (if (vhdl-template-field "[architecture name]" nil t)
8814 (insert ")")
d2ddb974 8815 (delete-char -1))
5eabfe72
KH
8816 (insert "\n")
8817 (indent-to (+ margin (* 2 vhdl-basic-offset)))
8818 (setq position (point))
8819 (vhdl-insert-keyword "GENERIC ")
8820 (when (vhdl-template-map position t t)
8821 (insert "\n")
8822 (indent-to (+ margin (* 2 vhdl-basic-offset))))
8823 (setq position (point))
8824 (vhdl-insert-keyword "PORT ")
8825 (unless (vhdl-template-map position t t)
453cfeb3 8826 (delete-region (line-beginning-position) (point))
5eabfe72
KH
8827 (delete-char -1))
8828 (insert ";")
8829 t)
8830 ((equal aspect "CONFIGURATION")
3dcb36b7
JB
8831 (vhdl-template-field "library name" "." nil nil nil nil
8832 (vhdl-work-library))
5eabfe72 8833 (vhdl-template-field "configuration name" ";"))
d355a0b7 8834 (t (delete-char -1) (insert ";") t))))))
5eabfe72 8835
d2ddb974 8836
5eabfe72
KH
8837(defun vhdl-template-configuration-decl ()
8838 "Insert a configuration declaration."
d2ddb974 8839 (interactive)
5eabfe72
KH
8840 (let ((margin (current-indentation))
8841 (start (point))
5eabfe72 8842 entity-exists string name position)
d2ddb974 8843 (vhdl-insert-keyword "CONFIGURATION ")
5eabfe72 8844 (when (setq name (vhdl-template-field "name" nil t start (point)))
d2ddb974 8845 (vhdl-insert-keyword " OF ")
5eabfe72 8846 (save-excursion
3dcb36b7
JB
8847 (vhdl-prepare-search-1
8848 (setq entity-exists (vhdl-re-search-backward
5eabfe72
KH
8849 "\\<entity \\(\\w*\\) is\\>" nil t))
8850 (setq string (match-string 1))))
d2ddb974 8851 (if (and entity-exists (not (equal string "")))
5eabfe72
KH
8852 (insert string)
8853 (vhdl-template-field "entity name"))
8854 (vhdl-insert-keyword " IS\n")
8855 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
8856 (indent-to (+ margin vhdl-basic-offset))
8857 (setq position (point))
8858 (insert "\n")
8859 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
d2ddb974
KH
8860 (indent-to margin)
8861 (vhdl-insert-keyword "END ")
5eabfe72
KH
8862 (unless (vhdl-standard-p '87)
8863 (vhdl-insert-keyword "CONFIGURATION "))
d2ddb974 8864 (insert name ";")
5eabfe72 8865 (goto-char position))))
d2ddb974 8866
5eabfe72
KH
8867(defun vhdl-template-constant ()
8868 "Insert a constant declaration."
8869 (interactive)
8870 (let ((start (point))
8871 (in-arglist (vhdl-in-argument-list-p)))
8872 (vhdl-insert-keyword "CONSTANT ")
8873 (when (vhdl-template-field "name" nil t start (point))
d2ddb974 8874 (insert " : ")
5eabfe72
KH
8875 (when in-arglist (vhdl-insert-keyword "IN "))
8876 (vhdl-template-field "type")
d2ddb974 8877 (if in-arglist
5eabfe72
KH
8878 (progn (insert ";")
8879 (vhdl-comment-insert-inline))
d2ddb974
KH
8880 (let ((position (point)))
8881 (insert " := ")
5eabfe72
KH
8882 (unless (vhdl-template-field "[initialization]" nil t)
8883 (delete-region position (point)))
8884 (insert ";")
8885 (vhdl-comment-insert-inline))))))
d2ddb974 8886
5eabfe72 8887(defun vhdl-template-default ()
d2ddb974
KH
8888 "Insert nothing."
8889 (interactive)
8890 (insert " ")
8891 (unexpand-abbrev)
8892 (backward-word 1)
8893 (vhdl-case-word 1)
5eabfe72 8894 (forward-char 1))
d2ddb974 8895
5eabfe72 8896(defun vhdl-template-default-indent ()
d2ddb974
KH
8897 "Insert nothing and indent."
8898 (interactive)
8899 (insert " ")
8900 (unexpand-abbrev)
8901 (backward-word 1)
8902 (vhdl-case-word 1)
8903 (forward-char 1)
3dcb36b7 8904 (indent-according-to-mode))
d2ddb974 8905
5eabfe72 8906(defun vhdl-template-disconnect ()
d2ddb974
KH
8907 "Insert a disconnect statement."
8908 (interactive)
5eabfe72
KH
8909 (let ((start (point)))
8910 (vhdl-insert-keyword "DISCONNECT ")
8911 (when (vhdl-template-field "signal names | OTHERS | ALL"
8912 " : " t start (point))
8913 (vhdl-template-field "type")
8914 (vhdl-insert-keyword " AFTER ")
8915 (vhdl-template-field "time expression" ";"))))
8916
8917(defun vhdl-template-else ()
d2ddb974
KH
8918 "Insert an else statement."
8919 (interactive)
3dcb36b7
JB
8920 (let (margin)
8921 (vhdl-prepare-search-1
5eabfe72 8922 (vhdl-insert-keyword "ELSE")
3dcb36b7
JB
8923 (if (and (save-excursion (vhdl-re-search-backward "\\(\\<when\\>\\|;\\)" nil t))
8924 (equal "WHEN" (upcase (match-string 1))))
5eabfe72 8925 (insert " ")
3dcb36b7 8926 (indent-according-to-mode)
5eabfe72
KH
8927 (setq margin (current-indentation))
8928 (insert "\n")
8929 (indent-to (+ margin vhdl-basic-offset))))))
8930
8931(defun vhdl-template-elsif ()
d2ddb974
KH
8932 "Insert an elsif statement."
8933 (interactive)
5eabfe72
KH
8934 (let ((start (point))
8935 margin)
d2ddb974 8936 (vhdl-insert-keyword "ELSIF ")
3dcb36b7
JB
8937 (when (or (vhdl-sequential-statement-p) (vhdl-standard-p 'ams))
8938 (when vhdl-conditions-in-parenthesis (insert "("))
8939 (when (vhdl-template-field "condition" nil t start (point))
8940 (when vhdl-conditions-in-parenthesis (insert ")"))
8941 (indent-according-to-mode)
8942 (setq margin (current-indentation))
8943 (vhdl-insert-keyword
8944 (concat " " (if (vhdl-sequential-statement-p) "THEN" "USE") "\n"))
8945 (indent-to (+ margin vhdl-basic-offset))))))
d2ddb974 8946
5eabfe72
KH
8947(defun vhdl-template-entity ()
8948 "Insert an entity."
d2ddb974 8949 (interactive)
5eabfe72
KH
8950 (let ((margin (current-indentation))
8951 (start (point))
8952 name end-column)
d2ddb974 8953 (vhdl-insert-keyword "ENTITY ")
5eabfe72 8954 (when (setq name (vhdl-template-field "name" nil t start (point)))
d2ddb974
KH
8955 (vhdl-insert-keyword " IS\n\n")
8956 (indent-to margin)
8957 (vhdl-insert-keyword "END ")
5eabfe72
KH
8958 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ENTITY "))
8959 (insert name ";")
8960 (setq end-column (current-column))
d2ddb974
KH
8961 (end-of-line -0)
8962 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
8963 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
8964 (indent-to (+ margin vhdl-basic-offset))
8965 (when (vhdl-template-generic-list t)
8966 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")))
8967 (insert "\n")
8968 (indent-to (+ margin vhdl-basic-offset))
8969 (when (vhdl-template-port-list t)
8970 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n")))
8971 (beginning-of-line 2)
8972 (forward-char end-column))))
d2ddb974 8973
5eabfe72 8974(defun vhdl-template-exit ()
d2ddb974
KH
8975 "Insert an exit statement."
8976 (interactive)
5eabfe72
KH
8977 (let ((start (point)))
8978 (vhdl-insert-keyword "EXIT ")
3dcb36b7
JB
8979 (if (vhdl-template-field "[loop label]" nil t start (point))
8980 (let ((position (point)))
8981 (vhdl-insert-keyword " WHEN ")
8982 (when vhdl-conditions-in-parenthesis (insert "("))
8983 (if (vhdl-template-field "[condition]" nil t)
8984 (when vhdl-conditions-in-parenthesis (insert ")"))
8985 (delete-region position (point))))
d2ddb974 8986 (delete-char -1))
5eabfe72
KH
8987 (insert ";")))
8988
8989(defun vhdl-template-file ()
8990 "Insert a file declaration."
8991 (interactive)
8992 (let ((start (point)))
8993 (vhdl-insert-keyword "FILE ")
8994 (when (vhdl-template-field "name" nil t start (point))
8995 (insert " : ")
8996 (vhdl-template-field "type")
8997 (unless (vhdl-standard-p '87)
8998 (vhdl-insert-keyword " OPEN ")
8999 (unless (vhdl-template-field "[READ_MODE | WRITE_MODE | APPEND_MODE]"
9000 nil t)
d355a0b7 9001 (delete-char -6)))
5eabfe72
KH
9002 (vhdl-insert-keyword " IS ")
9003 (when (vhdl-standard-p '87)
9004 (vhdl-template-field "[IN | OUT]" " " t))
9005 (vhdl-template-field "filename-string" nil nil nil nil t)
9006 (insert ";")
9007 (vhdl-comment-insert-inline))))
d2ddb974 9008
5eabfe72
KH
9009(defun vhdl-template-for ()
9010 "Insert a block or component configuration if within a configuration
9011declaration, a configuration specification if within an architecture
3dcb36b7
JB
9012declarative part (and not within a subprogram), a for-loop if within a
9013sequential statement part (subprogram or process), and a for-generate
9014otherwise."
5eabfe72 9015 (interactive)
3dcb36b7
JB
9016 (vhdl-prepare-search-1
9017 (cond
9018 ((vhdl-sequential-statement-p) ; sequential statement
9019 (vhdl-template-for-loop))
9020 ((and (save-excursion ; configuration declaration
9021 (re-search-backward "^\\(configuration\\|end\\)\\>" nil t))
9022 (equal "CONFIGURATION" (upcase (match-string 1))))
9023 (if (eq (vhdl-decision-query
9024 "for" "(b)lock or (c)omponent configuration?" t) ?c)
9025 (vhdl-template-component-conf)
9026 (vhdl-template-block-configuration)))
9027 ((and (save-excursion
9028 (re-search-backward ; architecture declarative part
9029 "^\\(architecture\\|entity\\|begin\\|end\\)\\>" nil t))
9030 (equal "ARCHITECTURE" (upcase (match-string 1))))
9031 (vhdl-template-configuration-spec))
9032 (t (vhdl-template-for-generate))))) ; concurrent statement
5eabfe72
KH
9033
9034(defun vhdl-template-for-generate ()
9035 "Insert a for-generate."
d2ddb974 9036 (interactive)
5eabfe72
KH
9037 (let ((margin (current-indentation))
9038 (start (point))
3dcb36b7 9039 label position)
5eabfe72
KH
9040 (vhdl-insert-keyword ": FOR ")
9041 (setq position (point-marker))
9042 (goto-char start)
9043 (when (setq label (vhdl-template-field "label" nil t start position))
9044 (goto-char position)
9045 (vhdl-template-field "loop variable")
9046 (vhdl-insert-keyword " IN ")
9047 (vhdl-template-field "range")
9048 (vhdl-template-generate-body margin label))))
d2ddb974 9049
5eabfe72
KH
9050(defun vhdl-template-for-loop ()
9051 "Insert a for loop."
d2ddb974 9052 (interactive)
5eabfe72
KH
9053 (let ((margin (current-indentation))
9054 (start (point))
9055 label index)
9056 (if (not (eq vhdl-optional-labels 'all))
9057 (vhdl-insert-keyword "FOR ")
9058 (vhdl-insert-keyword ": FOR ")
9059 (goto-char start)
9060 (setq label (vhdl-template-field "[label]" nil t))
9061 (unless label (delete-char 2))
9062 (forward-word 1)
9063 (forward-char 1))
9064 (when (setq index (vhdl-template-field "loop variable"
9065 nil t start (point)))
d2ddb974 9066 (vhdl-insert-keyword " IN ")
5eabfe72 9067 (vhdl-template-field "range")
d2ddb974
KH
9068 (vhdl-insert-keyword " LOOP\n\n")
9069 (indent-to margin)
9070 (vhdl-insert-keyword "END LOOP")
5eabfe72
KH
9071 (if label
9072 (insert " " label ";")
d2ddb974 9073 (insert ";")
5eabfe72 9074 (when vhdl-self-insert-comments (insert " -- " index)))
d2ddb974 9075 (forward-line -1)
5eabfe72 9076 (indent-to (+ margin vhdl-basic-offset)))))
d2ddb974 9077
5eabfe72
KH
9078(defun vhdl-template-function (&optional kind)
9079 "Insert a function declaration or body."
d2ddb974 9080 (interactive)
5eabfe72
KH
9081 (let ((margin (current-indentation))
9082 (start (point))
9083 name)
9084 (vhdl-insert-keyword "FUNCTION ")
9085 (when (setq name (vhdl-template-field "name" nil t start (point)))
9086 (vhdl-template-argument-list t)
3dcb36b7 9087 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1))
d2ddb974 9088 (end-of-line)
5eabfe72 9089 (insert "\n")
d2ddb974 9090 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
9091 (vhdl-insert-keyword "RETURN ")
9092 (vhdl-template-field "type")
9093 (if (if kind (eq kind 'body)
9094 (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b))
3dcb36b7 9095 (progn (vhdl-insert-keyword " IS\n")
5eabfe72
KH
9096 (vhdl-template-begin-end
9097 (unless (vhdl-standard-p '87) "FUNCTION") name margin)
9098 (vhdl-comment-block))
9099 (insert ";")))))
9100
9101(defun vhdl-template-function-decl ()
9102 "Insert a function declaration."
9103 (interactive)
9104 (vhdl-template-function 'decl))
d2ddb974 9105
5eabfe72
KH
9106(defun vhdl-template-function-body ()
9107 "Insert a function declaration."
d2ddb974 9108 (interactive)
5eabfe72
KH
9109 (vhdl-template-function 'body))
9110
9111(defun vhdl-template-generate ()
9112 "Insert a generation scheme."
9113 (interactive)
9114 (if (eq (vhdl-decision-query nil "(f)or or (i)f?" t) ?i)
9115 (vhdl-template-if-generate)
9116 (vhdl-template-for-generate)))
d2ddb974 9117
5eabfe72
KH
9118(defun vhdl-template-generic ()
9119 "Insert generic declaration, or generic map in instantiation statements."
9120 (interactive)
3dcb36b7
JB
9121 (let ((start (point)))
9122 (vhdl-prepare-search-1
5eabfe72
KH
9123 (cond
9124 ((and (save-excursion ; entity declaration
9125 (re-search-backward "^\\(entity\\|end\\)\\>" nil t))
9126 (equal "ENTITY" (upcase (match-string 1))))
9127 (vhdl-template-generic-list nil))
9128 ((or (save-excursion
9129 (or (beginning-of-line)
9130 (looking-at "^\\s-*\\w+\\s-*:\\s-*\\w+")))
3dcb36b7 9131 (equal 'statement-cont (caar (vhdl-get-syntactic-context))))
5eabfe72
KH
9132 (vhdl-insert-keyword "GENERIC ")
9133 (vhdl-template-map start))
9134 (t (vhdl-template-generic-list nil t))))))
9135
9136(defun vhdl-template-group ()
9137 "Insert group or group template declaration."
9138 (interactive)
9139 (let ((start (point)))
9140 (if (eq (vhdl-decision-query
9141 "group" "(d)eclaration or (t)emplate declaration?" t) ?t)
9142 (vhdl-template-group-template)
9143 (vhdl-template-group-decl))))
9144
9145(defun vhdl-template-group-decl ()
9146 "Insert group declaration."
9147 (interactive)
9148 (let ((start (point)))
9149 (vhdl-insert-keyword "GROUP ")
9150 (when (vhdl-template-field "name" " : " t start (point))
9151 (vhdl-template-field "template name" " (")
9152 (vhdl-template-field "constituent list" ");")
9153 (vhdl-comment-insert-inline))))
9154
9155(defun vhdl-template-group-template ()
9156 "Insert group template declaration."
9157 (interactive)
9158 (let ((start (point)))
9159 (vhdl-insert-keyword "GROUP ")
9160 (when (vhdl-template-field "template name" nil t start (point))
9161 (vhdl-insert-keyword " IS (")
9162 (vhdl-template-field "entity class list" ");")
9163 (vhdl-comment-insert-inline))))
9164
5eabfe72
KH
9165(defun vhdl-template-if ()
9166 "Insert a sequential if statement or an if-generate statement."
9167 (interactive)
9168 (if (vhdl-sequential-statement-p)
9169 (vhdl-template-if-then)
9170 (if (and (vhdl-standard-p 'ams)
9171 (eq (vhdl-decision-query "if" "(g)enerate or (u)se?" t) ?u))
9172 (vhdl-template-if-use)
9173 (vhdl-template-if-generate))))
9174
9175(defun vhdl-template-if-generate ()
9176 "Insert an if-generate."
9177 (interactive)
9178 (let ((margin (current-indentation))
9179 (start (point))
3dcb36b7 9180 label position)
5eabfe72
KH
9181 (vhdl-insert-keyword ": IF ")
9182 (setq position (point-marker))
9183 (goto-char start)
9184 (when (setq label (vhdl-template-field "label" nil t start position))
9185 (goto-char position)
9186 (when vhdl-conditions-in-parenthesis (insert "("))
9187 (vhdl-template-field "condition")
9188 (when vhdl-conditions-in-parenthesis (insert ")"))
9189 (vhdl-template-generate-body margin label))))
d2ddb974 9190
5eabfe72
KH
9191(defun vhdl-template-if-then-use (kind)
9192 "Insert a sequential if statement."
9193 (interactive)
9194 (let ((margin (current-indentation))
9195 (start (point))
9196 label)
9197 (if (or (not (eq vhdl-optional-labels 'all)) (vhdl-standard-p '87))
9198 (vhdl-insert-keyword "IF ")
9199 (vhdl-insert-keyword ": IF ")
9200 (goto-char start)
9201 (setq label (vhdl-template-field "[label]" nil t))
9202 (unless label (delete-char 2))
9203 (forward-word 1)
9204 (forward-char 1))
9205 (when vhdl-conditions-in-parenthesis (insert "("))
9206 (when (vhdl-template-field "condition" nil t start (point))
9207 (when vhdl-conditions-in-parenthesis (insert ")"))
9208 (vhdl-insert-keyword
9209 (concat " " (if (eq kind 'then) "THEN" "USE") "\n\n"))
d2ddb974 9210 (indent-to margin)
fda91268 9211 (vhdl-insert-keyword (concat "END " (if (eq kind 'then) "IF" "USE")))
5eabfe72
KH
9212 (when label (insert " " label))
9213 (insert ";")
d2ddb974 9214 (forward-line -1)
5eabfe72
KH
9215 (indent-to (+ margin vhdl-basic-offset)))))
9216
9217(defun vhdl-template-if-then ()
9218 "Insert a sequential if statement."
9219 (interactive)
9220 (vhdl-template-if-then-use 'then))
9221
9222(defun vhdl-template-if-use ()
9223 "Insert a simultaneous if statement."
9224 (interactive)
9225 (vhdl-template-if-then-use 'use))
9226
9227(defun vhdl-template-instance ()
9228 "Insert a component instantiation statement."
9229 (interactive)
9230 (vhdl-template-component-inst))
d2ddb974 9231
5eabfe72 9232(defun vhdl-template-library ()
d2ddb974
KH
9233 "Insert a library specification."
9234 (interactive)
5eabfe72
KH
9235 (let ((margin (current-indentation))
9236 (start (point))
9237 name end-pos)
d2ddb974 9238 (vhdl-insert-keyword "LIBRARY ")
5eabfe72
KH
9239 (when (setq name (vhdl-template-field "names" nil t start (point)))
9240 (insert ";")
9241 (unless (string-match "," name)
9242 (setq end-pos (point))
9243 (insert "\n")
9244 (indent-to margin)
9245 (vhdl-insert-keyword "USE ")
9246 (insert name)
9247 (vhdl-insert-keyword "..ALL;")
9248 (backward-char 5)
9249 (if (vhdl-template-field "package name")
9250 (forward-char 5)
9251 (delete-region end-pos (+ (point) 5)))))))
9252
9253(defun vhdl-template-limit ()
9254 "Insert a limit."
d2ddb974 9255 (interactive)
5eabfe72
KH
9256 (let ((start (point)))
9257 (vhdl-insert-keyword "LIMIT ")
9258 (when (vhdl-template-field "quantity names | OTHERS | ALL" " : "
9259 t start (point))
9260 (vhdl-template-field "type")
9261 (vhdl-insert-keyword " WITH ")
9262 (vhdl-template-field "real expression" ";"))))
9263
9264(defun vhdl-template-loop ()
9265 "Insert a loop."
9266 (interactive)
9267 (let ((char (vhdl-decision-query nil "(w)hile, (f)or, or (b)are?" t)))
9268 (cond ((eq char ?w)
9269 (vhdl-template-while-loop))
9270 ((eq char ?f)
9271 (vhdl-template-for-loop))
9272 (t (vhdl-template-bare-loop)))))
9273
9274(defun vhdl-template-bare-loop ()
9275 "Insert a loop."
9276 (interactive)
9277 (let ((margin (current-indentation))
9278 (start (point))
9279 label)
9280 (if (not (eq vhdl-optional-labels 'all))
9281 (vhdl-insert-keyword "LOOP ")
9282 (vhdl-insert-keyword ": LOOP ")
9283 (goto-char start)
9284 (setq label (vhdl-template-field "[label]" nil t))
9285 (unless label (delete-char 2))
9286 (forward-word 1)
9287 (delete-char 1))
d2ddb974
KH
9288 (insert "\n\n")
9289 (indent-to margin)
9290 (vhdl-insert-keyword "END LOOP")
5eabfe72 9291 (insert (if label (concat " " label ";") ";"))
d2ddb974 9292 (forward-line -1)
5eabfe72 9293 (indent-to (+ margin vhdl-basic-offset))))
d2ddb974 9294
5eabfe72
KH
9295(defun vhdl-template-map (&optional start optional secondary)
9296 "Insert a map specification with association list."
d2ddb974 9297 (interactive)
5eabfe72
KH
9298 (let ((start (or start (point)))
9299 margin end-pos)
9300 (vhdl-insert-keyword "MAP (")
9301 (if (not vhdl-association-list-with-formals)
9302 (if (vhdl-template-field
9303 (concat (and optional "[") "association list" (and optional "]"))
9304 ")" (or (not secondary) optional)
9305 (and (not secondary) start) (point))
9306 t
9307 (if (and optional secondary) (delete-region start (point)))
9308 nil)
9309 (if vhdl-argument-list-indent
9310 (setq margin (current-column))
9311 (setq margin (+ (current-indentation) vhdl-basic-offset))
9312 (insert "\n")
9313 (indent-to margin))
9314 (if (vhdl-template-field
9315 (concat (and optional "[") "formal" (and optional "]"))
9316 " => " (or (not secondary) optional)
9317 (and (not secondary) start) (point))
9318 (progn
9319 (vhdl-template-field "actual" ",")
9320 (setq end-pos (point))
9321 (insert "\n")
9322 (indent-to margin)
9323 (while (vhdl-template-field "[formal]" " => " t)
9324 (vhdl-template-field "actual" ",")
9325 (setq end-pos (point))
9326 (insert "\n")
9327 (indent-to margin))
9328 (delete-region end-pos (point))
d355a0b7 9329 (delete-char -1)
5eabfe72 9330 (insert ")")
3dcb36b7 9331 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1))
5eabfe72
KH
9332 t)
9333 (when (and optional secondary) (delete-region start (point)))
9334 nil))))
d2ddb974 9335
5eabfe72 9336(defun vhdl-template-modify (&optional noerror)
d2ddb974
KH
9337 "Actualize modification date."
9338 (interactive)
3dcb36b7
JB
9339 (vhdl-prepare-search-2
9340 (save-excursion
9341 (goto-char (point-min))
9342 (if (re-search-forward vhdl-modify-date-prefix-string nil t)
9343 (progn (delete-region (point) (progn (end-of-line) (point)))
9344 (vhdl-template-insert-date))
9345 (unless noerror
a867ead0
DG
9346 (error "ERROR: Modification date prefix string \"%s\" not found"
9347 vhdl-modify-date-prefix-string))))))
9348
5eabfe72
KH
9349
9350(defun vhdl-template-modify-noerror ()
9351 "Call `vhdl-template-modify' with NOERROR non-nil."
9352 (vhdl-template-modify t))
9353
9354(defun vhdl-template-nature ()
9355 "Insert a nature declaration."
9356 (interactive)
9357 (let ((start (point))
9358 name mid-pos end-pos)
9359 (vhdl-insert-keyword "NATURE ")
9360 (when (setq name (vhdl-template-field "name" nil t start (point)))
9361 (vhdl-insert-keyword " IS ")
9362 (let ((definition
9363 (upcase
9364 (or (vhdl-template-field
9365 "across type | ARRAY | RECORD")
9366 ""))))
9367 (cond ((equal definition "")
9368 (insert ";"))
9369 ((equal definition "ARRAY")
453cfeb3 9370 (delete-region (point) (progn (forward-word -1) (point)))
5eabfe72
KH
9371 (vhdl-template-array 'nature t))
9372 ((equal definition "RECORD")
9373 (setq mid-pos (point-marker))
453cfeb3 9374 (delete-region (point) (progn (forward-word -1) (point)))
5eabfe72
KH
9375 (vhdl-template-record 'nature name t))
9376 (t
9377 (vhdl-insert-keyword " ACROSS ")
9378 (vhdl-template-field "through type")
9379 (vhdl-insert-keyword " THROUGH ")
9380 (vhdl-template-field "reference name")
9381 (vhdl-insert-keyword " REFERENCE;")))
9382 (when mid-pos
9383 (setq end-pos (point-marker))
9384 (goto-char mid-pos)
9385 (end-of-line))
9386 (vhdl-comment-insert-inline)
9387 (when end-pos (goto-char end-pos))))))
9388
9389(defun vhdl-template-next ()
9390 "Insert a next statement."
d2ddb974 9391 (interactive)
3dcb36b7
JB
9392 (let ((start (point)))
9393 (vhdl-insert-keyword "NEXT ")
9394 (if (vhdl-template-field "[loop label]" nil t start (point))
9395 (let ((position (point)))
9396 (vhdl-insert-keyword " WHEN ")
9397 (when vhdl-conditions-in-parenthesis (insert "("))
9398 (if (vhdl-template-field "[condition]" nil t)
9399 (when vhdl-conditions-in-parenthesis (insert ")"))
9400 (delete-region position (point))))
9401 (delete-char -1))
5eabfe72
KH
9402 (insert ";")))
9403
9404(defun vhdl-template-others ()
9405 "Insert an others aggregate."
9406 (interactive)
3dcb36b7
JB
9407 (let ((start (point)))
9408 (if (or (= (preceding-char) ?\() (not vhdl-template-invoked-by-hook))
9409 (progn (unless vhdl-template-invoked-by-hook (insert "("))
9410 (vhdl-insert-keyword "OTHERS => '")
9411 (when (vhdl-template-field "value" nil t start (point))
9412 (insert "')")))
9413 (vhdl-insert-keyword "OTHERS "))))
d2ddb974 9414
5eabfe72 9415(defun vhdl-template-package (&optional kind)
d2ddb974
KH
9416 "Insert a package specification or body."
9417 (interactive)
5eabfe72
KH
9418 (let ((margin (current-indentation))
9419 (start (point))
9420 name body position)
d2ddb974 9421 (vhdl-insert-keyword "PACKAGE ")
5eabfe72
KH
9422 (setq body (if kind (eq kind 'body)
9423 (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b)))
3dcb36b7
JB
9424 (when body
9425 (vhdl-insert-keyword "BODY ")
9426 (when (save-excursion
9427 (vhdl-prepare-search-1
9428 (vhdl-re-search-backward "\\<package \\(\\w+\\) is\\>" nil t)))
9429 (insert (setq name (match-string 1)))))
9430 (when (or name
9431 (setq name (vhdl-template-field "name" nil t start (point))))
5eabfe72
KH
9432 (vhdl-insert-keyword " IS\n")
9433 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
9434 (indent-to (+ margin vhdl-basic-offset))
9435 (setq position (point))
9436 (insert "\n")
9437 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
9438 (indent-to margin)
9439 (vhdl-insert-keyword "END ")
9440 (unless (vhdl-standard-p '87)
9441 (vhdl-insert-keyword (concat "PACKAGE " (and body "BODY "))))
9442 (insert (or name "") ";")
9443 (goto-char position))))
d2ddb974 9444
5eabfe72
KH
9445(defun vhdl-template-package-decl ()
9446 "Insert a package specification."
d2ddb974 9447 (interactive)
5eabfe72 9448 (vhdl-template-package 'decl))
d2ddb974 9449
5eabfe72
KH
9450(defun vhdl-template-package-body ()
9451 "Insert a package body."
d2ddb974 9452 (interactive)
5eabfe72 9453 (vhdl-template-package 'body))
d2ddb974 9454
5eabfe72
KH
9455(defun vhdl-template-port ()
9456 "Insert a port declaration, or port map in instantiation statements."
d2ddb974 9457 (interactive)
3dcb36b7
JB
9458 (let ((start (point)))
9459 (vhdl-prepare-search-1
5eabfe72
KH
9460 (cond
9461 ((and (save-excursion ; entity declaration
9462 (re-search-backward "^\\(entity\\|end\\)\\>" nil t))
9463 (equal "ENTITY" (upcase (match-string 1))))
9464 (vhdl-template-port-list nil))
9465 ((or (save-excursion
9466 (or (beginning-of-line)
9467 (looking-at "^\\s-*\\w+\\s-*:\\s-*\\w+")))
3dcb36b7 9468 (equal 'statement-cont (caar (vhdl-get-syntactic-context))))
5eabfe72
KH
9469 (vhdl-insert-keyword "PORT ")
9470 (vhdl-template-map start))
9471 (t (vhdl-template-port-list nil))))))
9472
9473(defun vhdl-template-procedural ()
9474 "Insert a procedural."
9475 (interactive)
9476 (let ((margin (current-indentation))
9477 (start (point))
9478 (case-fold-search t)
9479 label)
9480 (vhdl-insert-keyword "PROCEDURAL ")
9481 (when (memq vhdl-optional-labels '(process all))
9482 (goto-char start)
9483 (insert ": ")
9484 (goto-char start)
9485 (setq label (vhdl-template-field "[label]" nil t))
9486 (unless label (delete-char 2))
9487 (forward-word 1)
9488 (forward-char 1))
9489 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "IS"))
3dcb36b7 9490 (insert "\n")
5eabfe72
KH
9491 (vhdl-template-begin-end "PROCEDURAL" label margin)
9492 (vhdl-comment-block)))
9493
9494(defun vhdl-template-procedure (&optional kind)
9495 "Insert a procedure declaration or body."
9496 (interactive)
9497 (let ((margin (current-indentation))
9498 (start (point))
9499 name)
9500 (vhdl-insert-keyword "PROCEDURE ")
9501 (when (setq name (vhdl-template-field "name" nil t start (point)))
9502 (vhdl-template-argument-list)
9503 (if (if kind (eq kind 'body)
9504 (eq (vhdl-decision-query nil "(d)eclaration or (b)ody?") ?b))
9505 (progn (vhdl-insert-keyword " IS")
9506 (when vhdl-auto-align
3dcb36b7
JB
9507 (vhdl-align-region-groups start (point) 1))
9508 (end-of-line) (insert "\n")
5eabfe72
KH
9509 (vhdl-template-begin-end
9510 (unless (vhdl-standard-p '87) "PROCEDURE")
9511 name margin)
9512 (vhdl-comment-block))
9513 (insert ";")
3dcb36b7 9514 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1))
5eabfe72
KH
9515 (end-of-line)))))
9516
9517(defun vhdl-template-procedure-decl ()
9518 "Insert a procedure declaration."
9519 (interactive)
9520 (vhdl-template-procedure 'decl))
d2ddb974 9521
5eabfe72
KH
9522(defun vhdl-template-procedure-body ()
9523 "Insert a procedure body."
9524 (interactive)
9525 (vhdl-template-procedure 'body))
9526
9527(defun vhdl-template-process (&optional kind)
9528 "Insert a process."
9529 (interactive)
9530 (let ((margin (current-indentation))
9531 (start (point))
fda91268 9532 (reset-kind vhdl-reset-kind)
5eabfe72
KH
9533 label seq input-signals clock reset final-pos)
9534 (setq seq (if kind (eq kind 'seq)
9535 (eq (vhdl-decision-query
9536 "process" "(c)ombinational or (s)equential?" t) ?s)))
9537 (vhdl-insert-keyword "PROCESS ")
9538 (when (memq vhdl-optional-labels '(process all))
9539 (goto-char start)
9540 (insert ": ")
9541 (goto-char start)
9542 (setq label (vhdl-template-field "[label]" nil t))
9543 (unless label (delete-char 2))
9544 (forward-word 1)
9545 (forward-char 1))
9546 (insert "(")
9547 (if (not seq)
9548 (unless (setq input-signals
9549 (vhdl-template-field "[sensitivity list]" ")" t))
9550 (setq input-signals "")
9551 (delete-char -2))
9552 (setq clock (or (and (not (equal "" vhdl-clock-name))
9553 (progn (insert vhdl-clock-name) vhdl-clock-name))
9554 (vhdl-template-field "clock name") "<clock>"))
fda91268
RZ
9555 (when (eq reset-kind 'query)
9556 (setq reset-kind
9557 (if (eq (vhdl-decision-query
9558 "" "(a)synchronous or (s)ynchronous reset?" t) ?a)
9559 'async
9560 'sync)))
9561 (when (eq reset-kind 'async)
5eabfe72
KH
9562 (insert ", ")
9563 (setq reset (or (and (not (equal "" vhdl-reset-name))
9564 (progn (insert vhdl-reset-name) vhdl-reset-name))
9565 (vhdl-template-field "reset name") "<reset>")))
9566 (insert ")"))
9567 (unless (vhdl-standard-p '87) (vhdl-insert-keyword " IS"))
3dcb36b7 9568 (insert "\n")
5eabfe72 9569 (vhdl-template-begin-end "PROCESS" label margin)
fda91268 9570 (when seq (setq reset (vhdl-template-seq-process clock reset reset-kind)))
5eabfe72
KH
9571 (when vhdl-prompt-for-comments
9572 (setq final-pos (point-marker))
3dcb36b7
JB
9573 (vhdl-prepare-search-2
9574 (when (and (vhdl-re-search-backward "\\<begin\\>" nil t)
9575 (vhdl-re-search-backward "\\<process\\>" nil t))
5eabfe72
KH
9576 (end-of-line -0)
9577 (if (bobp)
9578 (progn (insert "\n") (forward-line -1))
9579 (insert "\n"))
9580 (indent-to margin)
9581 (insert "-- purpose: ")
9582 (if (not (vhdl-template-field "[description]" nil t))
9583 (vhdl-line-kill-entire)
9584 (insert "\n")
9585 (indent-to margin)
9586 (insert "-- type : ")
9587 (insert (if seq "sequential" "combinational") "\n")
9588 (indent-to margin)
9589 (insert "-- inputs : ")
9590 (if (not seq)
9591 (insert input-signals)
9592 (insert clock ", ")
9593 (when reset (insert reset ", "))
9594 (unless (vhdl-template-field "[signal names]" nil t)
9595 (delete-char -2)))
9596 (insert "\n")
9597 (indent-to margin)
9598 (insert "-- outputs: ")
9599 (vhdl-template-field "[signal names]" nil t))))
9600 (goto-char final-pos))))
9601
9602(defun vhdl-template-process-comb ()
9603 "Insert a combinational process."
9604 (interactive)
9605 (vhdl-template-process 'comb))
9606
9607(defun vhdl-template-process-seq ()
9608 "Insert a sequential process."
9609 (interactive)
9610 (vhdl-template-process 'seq))
9611
9612(defun vhdl-template-quantity ()
9613 "Insert a quantity declaration."
9614 (interactive)
9615 (if (vhdl-in-argument-list-p)
9616 (let ((start (point)))
9617 (vhdl-insert-keyword "QUANTITY ")
9618 (when (vhdl-template-field "names" nil t start (point))
9619 (insert " : ")
9620 (vhdl-template-field "[IN | OUT]" " " t)
9621 (vhdl-template-field "type")
9622 (insert ";")
9623 (vhdl-comment-insert-inline)))
9624 (let ((char (vhdl-decision-query
9625 "quantity" "(f)ree, (b)ranch, or (s)ource quantity?" t)))
9626 (cond ((eq char ?f) (vhdl-template-quantity-free))
9627 ((eq char ?b) (vhdl-template-quantity-branch))
9628 ((eq char ?s) (vhdl-template-quantity-source))
9629 (t (vhdl-template-undo (point) (point)))))))
9630
9631(defun vhdl-template-quantity-free ()
9632 "Insert a free quantity declaration."
9633 (interactive)
9634 (vhdl-insert-keyword "QUANTITY ")
9635 (vhdl-template-field "names")
9636 (insert " : ")
9637 (vhdl-template-field "type")
9638 (let ((position (point)))
9639 (insert " := ")
9640 (unless (vhdl-template-field "[initialization]" nil t)
9641 (delete-region position (point)))
9642 (insert ";")
9643 (vhdl-comment-insert-inline)))
9644
9645(defun vhdl-template-quantity-branch ()
9646 "Insert a branch quantity declaration."
9647 (interactive)
9648 (let (position)
9649 (vhdl-insert-keyword "QUANTITY ")
9650 (when (vhdl-template-field "[across names]" " " t)
9651 (vhdl-insert-keyword "ACROSS "))
9652 (when (vhdl-template-field "[through names]" " " t)
9653 (vhdl-insert-keyword "THROUGH "))
9654 (vhdl-template-field "plus terminal name")
9655 (setq position (point))
9656 (vhdl-insert-keyword " TO ")
9657 (unless (vhdl-template-field "[minus terminal name]" nil t)
9658 (delete-region position (point)))
9659 (insert ";")
9660 (vhdl-comment-insert-inline)))
9661
9662(defun vhdl-template-quantity-source ()
9663 "Insert a source quantity declaration."
9664 (interactive)
9665 (vhdl-insert-keyword "QUANTITY ")
9666 (vhdl-template-field "names")
9667 (insert " : ")
9668 (vhdl-template-field "type" " ")
9669 (if (eq (vhdl-decision-query nil "(s)pectrum or (n)oise?") ?n)
9670 (progn (vhdl-insert-keyword "NOISE ")
9671 (vhdl-template-field "power expression"))
9672 (vhdl-insert-keyword "SPECTRUM ")
9673 (vhdl-template-field "magnitude expression" ", ")
9674 (vhdl-template-field "phase expression"))
9675 (insert ";")
9676 (vhdl-comment-insert-inline))
9677
9678(defun vhdl-template-record (kind &optional name secondary)
d2ddb974
KH
9679 "Insert a record type declaration."
9680 (interactive)
9681 (let ((margin (current-column))
9682 (start (point))
9683 (first t))
9684 (vhdl-insert-keyword "RECORD\n")
9685 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
9686 (when (or (vhdl-template-field "element names"
9687 nil (not secondary) start (point))
9688 secondary)
9689 (while (or first (vhdl-template-field "[element names]" nil t))
9690 (insert " : ")
9691 (vhdl-template-field (if (eq kind 'type) "type" "nature") ";")
9692 (vhdl-comment-insert-inline)
9693 (insert "\n")
d2ddb974 9694 (indent-to (+ margin vhdl-basic-offset))
5eabfe72 9695 (setq first nil))
453cfeb3 9696 (delete-region (line-beginning-position) (point))
d2ddb974 9697 (indent-to margin)
5eabfe72
KH
9698 (vhdl-insert-keyword "END RECORD")
9699 (unless (vhdl-standard-p '87) (and name (insert " " name)))
9700 (insert ";")
3dcb36b7 9701 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1)))))
d2ddb974 9702
5eabfe72
KH
9703(defun vhdl-template-report ()
9704 "Insert a report statement."
9705 (interactive)
9706 (let ((start (point)))
9707 (vhdl-insert-keyword "REPORT ")
9708 (if (equal "\"\"" (vhdl-template-field
9709 "string expression" nil t start (point) t))
d355a0b7 9710 (delete-char -2)
5eabfe72
KH
9711 (setq start (point))
9712 (vhdl-insert-keyword " SEVERITY ")
9713 (unless (vhdl-template-field "[NOTE | WARNING | ERROR | FAILURE]" nil t)
9714 (delete-region start (point)))
9715 (insert ";"))))
9716
9717(defun vhdl-template-return ()
d2ddb974
KH
9718 "Insert a return statement."
9719 (interactive)
3dcb36b7
JB
9720 (let ((start (point)))
9721 (vhdl-insert-keyword "RETURN ")
9722 (unless (vhdl-template-field "[expression]" nil t start (point))
9723 (delete-char -1))
9724 (insert ";")))
d2ddb974 9725
5eabfe72 9726(defun vhdl-template-selected-signal-asst ()
d2ddb974
KH
9727 "Insert a selected signal assignment."
9728 (interactive)
5eabfe72
KH
9729 (let ((margin (current-indentation))
9730 (start (point))
9731 (choices t))
d2ddb974 9732 (let ((position (point)))
5eabfe72 9733 (vhdl-insert-keyword " SELECT ")
d2ddb974
KH
9734 (goto-char position))
9735 (vhdl-insert-keyword "WITH ")
5eabfe72
KH
9736 (when (vhdl-template-field "selector expression"
9737 nil t start (+ (point) 7))
9738 (forward-word 1)
9739 (delete-char 1)
d2ddb974
KH
9740 (insert "\n")
9741 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
9742 (vhdl-template-field "target signal" " <= ")
9743; (vhdl-template-field "[GUARDED] [TRANSPORT]")
d2ddb974
KH
9744 (insert "\n")
9745 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
9746 (vhdl-template-field "waveform")
9747 (vhdl-insert-keyword " WHEN ")
9748 (vhdl-template-field "choices" ",")
9749 (insert "\n")
9750 (indent-to (+ margin vhdl-basic-offset))
9751 (while (and choices (vhdl-template-field "[waveform]" nil t))
d2ddb974 9752 (vhdl-insert-keyword " WHEN ")
5eabfe72
KH
9753 (if (setq choices (vhdl-template-field "[choices]" "," t))
9754 (progn (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
9755 (vhdl-insert-keyword "OTHERS")))
9756 (when choices
d2ddb974
KH
9757 (fixup-whitespace)
9758 (delete-char -2))
9759 (insert ";")
3dcb36b7 9760 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1)))))
d2ddb974 9761
5eabfe72 9762(defun vhdl-template-signal ()
d2ddb974
KH
9763 "Insert a signal declaration."
9764 (interactive)
5eabfe72
KH
9765 (let ((start (point))
9766 (in-arglist (vhdl-in-argument-list-p)))
9767 (vhdl-insert-keyword "SIGNAL ")
9768 (when (vhdl-template-field "names" nil t start (point))
d2ddb974 9769 (insert " : ")
5eabfe72
KH
9770 (when in-arglist (vhdl-template-field "[IN | OUT | INOUT]" " " t))
9771 (vhdl-template-field "type")
d2ddb974 9772 (if in-arglist
5eabfe72
KH
9773 (progn (insert ";")
9774 (vhdl-comment-insert-inline))
d2ddb974
KH
9775 (let ((position (point)))
9776 (insert " := ")
5eabfe72
KH
9777 (unless (vhdl-template-field "[initialization]" nil t)
9778 (delete-region position (point)))
9779 (insert ";")
9780 (vhdl-comment-insert-inline))))))
9781
9782(defun vhdl-template-subnature ()
9783 "Insert a subnature declaration."
9784 (interactive)
9785 (let ((start (point))
9786 position)
9787 (vhdl-insert-keyword "SUBNATURE ")
9788 (when (vhdl-template-field "name" nil t start (point))
9789 (vhdl-insert-keyword " IS ")
9790 (vhdl-template-field "nature" " (")
9791 (if (vhdl-template-field "[index range]" nil t)
9792 (insert ")")
9793 (delete-char -2))
9794 (setq position (point))
9795 (vhdl-insert-keyword " TOLERANCE ")
9796 (if (equal "\"\"" (vhdl-template-field "[string expression]"
9797 nil t nil nil t))
9798 (delete-region position (point))
9799 (vhdl-insert-keyword " ACROSS ")
9800 (vhdl-template-field "string expression" nil nil nil nil t)
9801 (vhdl-insert-keyword " THROUGH"))
9802 (insert ";")
9803 (vhdl-comment-insert-inline))))
9804
9805(defun vhdl-template-subprogram-body ()
9806 "Insert a subprogram body."
9807 (interactive)
9808 (if (eq (vhdl-decision-query nil "(p)rocedure or (f)unction?" t) ?f)
9809 (vhdl-template-function-body)
9810 (vhdl-template-procedure-body)))
d2ddb974 9811
5eabfe72
KH
9812(defun vhdl-template-subprogram-decl ()
9813 "Insert a subprogram declaration."
9814 (interactive)
9815 (if (eq (vhdl-decision-query nil "(p)rocedure or (f)unction?" t) ?f)
9816 (vhdl-template-function-decl)
9817 (vhdl-template-procedure-decl)))
9818
9819(defun vhdl-template-subtype ()
d2ddb974
KH
9820 "Insert a subtype declaration."
9821 (interactive)
5eabfe72
KH
9822 (let ((start (point)))
9823 (vhdl-insert-keyword "SUBTYPE ")
9824 (when (vhdl-template-field "name" nil t start (point))
9825 (vhdl-insert-keyword " IS ")
9826 (vhdl-template-field "type" " ")
9827 (unless
9828 (vhdl-template-field "[RANGE value range | ( index range )]" nil t)
d2ddb974 9829 (delete-char -1))
5eabfe72
KH
9830 (insert ";")
9831 (vhdl-comment-insert-inline))))
d2ddb974 9832
5eabfe72
KH
9833(defun vhdl-template-terminal ()
9834 "Insert a terminal declaration."
d2ddb974 9835 (interactive)
5eabfe72
KH
9836 (let ((start (point)))
9837 (vhdl-insert-keyword "TERMINAL ")
9838 (when (vhdl-template-field "names" nil t start (point))
9839 (insert " : ")
9840 (vhdl-template-field "nature")
9841 (insert ";")
9842 (vhdl-comment-insert-inline))))
d2ddb974 9843
5eabfe72
KH
9844(defun vhdl-template-type ()
9845 "Insert a type declaration."
9846 (interactive)
9847 (let ((start (point))
9848 name mid-pos end-pos)
9849 (vhdl-insert-keyword "TYPE ")
9850 (when (setq name (vhdl-template-field "name" nil t start (point)))
9851 (vhdl-insert-keyword " IS ")
9852 (let ((definition
9853 (upcase
9854 (or (vhdl-template-field
9855 "[scalar type | ARRAY | RECORD | ACCESS | FILE]" nil t)
9856 ""))))
9857 (cond ((equal definition "")
d355a0b7 9858 (delete-char -4)
5eabfe72
KH
9859 (insert ";"))
9860 ((equal definition "ARRAY")
453cfeb3 9861 (delete-region (point) (progn (forward-word -1) (point)))
5eabfe72
KH
9862 (vhdl-template-array 'type t))
9863 ((equal definition "RECORD")
9864 (setq mid-pos (point-marker))
453cfeb3 9865 (delete-region (point) (progn (forward-word -1) (point)))
5eabfe72
KH
9866 (vhdl-template-record 'type name t))
9867 ((equal definition "ACCESS")
9868 (insert " ")
9869 (vhdl-template-field "type" ";"))
9870 ((equal definition "FILE")
9871 (vhdl-insert-keyword " OF ")
9872 (vhdl-template-field "type" ";"))
9873 (t (insert ";")))
9874 (when mid-pos
9875 (setq end-pos (point-marker))
9876 (goto-char mid-pos)
9877 (end-of-line))
9878 (vhdl-comment-insert-inline)
9879 (when end-pos (goto-char end-pos))))))
9880
9881(defun vhdl-template-use ()
d2ddb974
KH
9882 "Insert a use clause."
9883 (interactive)
3dcb36b7
JB
9884 (let ((start (point)))
9885 (vhdl-prepare-search-1
5eabfe72
KH
9886 (vhdl-insert-keyword "USE ")
9887 (when (save-excursion (beginning-of-line) (looking-at "^\\s-*use\\>"))
9888 (vhdl-insert-keyword "..ALL;")
9889 (backward-char 6)
9890 (when (vhdl-template-field "library name" nil t start (+ (point) 6))
9891 (forward-char 1)
9892 (vhdl-template-field "package name")
9893 (forward-char 5))))))
9894
9895(defun vhdl-template-variable ()
d2ddb974
KH
9896 "Insert a variable declaration."
9897 (interactive)
5eabfe72 9898 (let ((start (point))
5eabfe72 9899 (in-arglist (vhdl-in-argument-list-p)))
3dcb36b7 9900 (vhdl-prepare-search-2
5eabfe72 9901 (if (or (save-excursion
fda91268
RZ
9902 (progn (vhdl-beginning-of-block)
9903 (looking-at "\\s-*\\(\\w+\\s-*:\\s-*\\)?\\<\\(\\<function\\|procedure\\|process\\|procedural\\)\\>")))
5eabfe72
KH
9904 (save-excursion (backward-word 1) (looking-at "\\<shared\\>")))
9905 (vhdl-insert-keyword "VARIABLE ")
fda91268
RZ
9906 (if (vhdl-standard-p '87)
9907 (error "ERROR: Not within sequential block")
9908 (vhdl-insert-keyword "SHARED VARIABLE "))))
5eabfe72 9909 (when (vhdl-template-field "names" nil t start (point))
d2ddb974 9910 (insert " : ")
5eabfe72
KH
9911 (when in-arglist (vhdl-template-field "[IN | OUT | INOUT]" " " t))
9912 (vhdl-template-field "type")
d2ddb974 9913 (if in-arglist
5eabfe72
KH
9914 (progn (insert ";")
9915 (vhdl-comment-insert-inline))
d2ddb974
KH
9916 (let ((position (point)))
9917 (insert " := ")
5eabfe72
KH
9918 (unless (vhdl-template-field "[initialization]" nil t)
9919 (delete-region position (point)))
9920 (insert ";")
9921 (vhdl-comment-insert-inline))))))
d2ddb974 9922
5eabfe72 9923(defun vhdl-template-wait ()
d2ddb974
KH
9924 "Insert a wait statement."
9925 (interactive)
9926 (vhdl-insert-keyword "WAIT ")
5eabfe72
KH
9927 (unless (vhdl-template-field
9928 "[ON sensitivity list] [UNTIL condition] [FOR time expression]"
9929 nil t)
9930 (delete-char -1))
9931 (insert ";"))
d2ddb974 9932
5eabfe72 9933(defun vhdl-template-when ()
d2ddb974
KH
9934 "Indent correctly if within a case statement."
9935 (interactive)
9936 (let ((position (point))
5eabfe72 9937 margin)
3dcb36b7 9938 (vhdl-prepare-search-2
5eabfe72 9939 (if (and (= (current-column) (current-indentation))
3dcb36b7 9940 (vhdl-re-search-forward "\\<end\\>" nil t)
5eabfe72
KH
9941 (looking-at "\\s-*\\<case\\>"))
9942 (progn
9943 (setq margin (current-indentation))
9944 (goto-char position)
9945 (delete-horizontal-space)
9946 (indent-to (+ margin vhdl-basic-offset)))
9947 (goto-char position)))
9948 (vhdl-insert-keyword "WHEN ")))
9949
9950(defun vhdl-template-while-loop ()
9951 "Insert a while loop."
d2ddb974 9952 (interactive)
5eabfe72
KH
9953 (let* ((margin (current-indentation))
9954 (start (point))
9955 label)
9956 (if (not (eq vhdl-optional-labels 'all))
9957 (vhdl-insert-keyword "WHILE ")
9958 (vhdl-insert-keyword ": WHILE ")
9959 (goto-char start)
9960 (setq label (vhdl-template-field "[label]" nil t))
9961 (unless label (delete-char 2))
9962 (forward-word 1)
9963 (forward-char 1))
9964 (when vhdl-conditions-in-parenthesis (insert "("))
9965 (when (vhdl-template-field "condition" nil t start (point))
9966 (when vhdl-conditions-in-parenthesis (insert ")"))
d2ddb974
KH
9967 (vhdl-insert-keyword " LOOP\n\n")
9968 (indent-to margin)
9969 (vhdl-insert-keyword "END LOOP")
5eabfe72 9970 (insert (if label (concat " " label ";") ";"))
d2ddb974 9971 (forward-line -1)
5eabfe72 9972 (indent-to (+ margin vhdl-basic-offset)))))
d2ddb974 9973
5eabfe72 9974(defun vhdl-template-with ()
d2ddb974
KH
9975 "Insert a with statement (i.e. selected signal assignment)."
9976 (interactive)
3dcb36b7
JB
9977 (vhdl-prepare-search-1
9978 (if (and (save-excursion (vhdl-re-search-backward "\\(\\<limit\\>\\|;\\)"))
9979 (equal ";" (match-string 1)))
9980 (vhdl-template-selected-signal-asst)
9981 (vhdl-insert-keyword "WITH "))))
5eabfe72
KH
9982
9983;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9984;; Special templates
9985
9986(defun vhdl-template-clocked-wait ()
9987 "Insert a wait statement for rising/falling clock edge."
9988 (interactive)
9989 (let ((start (point))
9990 clock)
9991 (vhdl-insert-keyword "WAIT UNTIL ")
9992 (when (setq clock
9993 (or (and (not (equal "" vhdl-clock-name))
9994 (progn (insert vhdl-clock-name) vhdl-clock-name))
9995 (vhdl-template-field "clock name" nil t start (point))))
9996 (insert "'event")
9997 (vhdl-insert-keyword " AND ")
9998 (insert clock)
9999 (insert
10000 " = " (if vhdl-clock-rising-edge vhdl-one-string vhdl-zero-string) ";")
10001 (vhdl-comment-insert-inline
10002 (concat (if vhdl-clock-rising-edge "rising" "falling")
10003 " clock edge")))))
10004
fda91268 10005(defun vhdl-template-seq-process (clock reset reset-kind)
5eabfe72
KH
10006 "Insert a template for the body of a sequential process."
10007 (let ((margin (current-indentation))
10008 position)
d2ddb974 10009 (vhdl-insert-keyword "IF ")
fda91268
RZ
10010 (when vhdl-conditions-in-parenthesis (insert "("))
10011 (when (eq reset-kind 'async)
5eabfe72
KH
10012 (insert reset " = "
10013 (if vhdl-reset-active-high vhdl-one-string vhdl-zero-string))
fda91268 10014 (when vhdl-conditions-in-parenthesis (insert ")"))
5eabfe72
KH
10015 (vhdl-insert-keyword " THEN")
10016 (vhdl-comment-insert-inline
10017 (concat "asynchronous reset (active "
10018 (if vhdl-reset-active-high "high" "low") ")"))
10019 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
10020 (setq position (point))
10021 (insert "\n") (indent-to margin)
fda91268
RZ
10022 (vhdl-insert-keyword "ELSIF ")
10023 (when vhdl-conditions-in-parenthesis (insert "(")))
5eabfe72
KH
10024 (if (eq vhdl-clock-edge-condition 'function)
10025 (insert (if vhdl-clock-rising-edge "rising" "falling")
10026 "_edge(" clock ")")
10027 (insert clock "'event")
10028 (vhdl-insert-keyword " AND ")
10029 (insert clock " = "
10030 (if vhdl-clock-rising-edge vhdl-one-string vhdl-zero-string)))
fda91268 10031 (when vhdl-conditions-in-parenthesis (insert ")"))
5eabfe72
KH
10032 (vhdl-insert-keyword " THEN")
10033 (vhdl-comment-insert-inline
10034 (concat (if vhdl-clock-rising-edge "rising" "falling") " clock edge"))
10035 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
fda91268 10036 (when (eq reset-kind 'sync)
5eabfe72 10037 (vhdl-insert-keyword "IF ")
fda91268 10038 (when vhdl-conditions-in-parenthesis (insert "("))
5eabfe72
KH
10039 (setq reset (or (and (not (equal "" vhdl-reset-name))
10040 (progn (insert vhdl-reset-name) vhdl-reset-name))
10041 (vhdl-template-field "reset name") "<reset>"))
10042 (insert " = "
10043 (if vhdl-reset-active-high vhdl-one-string vhdl-zero-string))
fda91268 10044 (when vhdl-conditions-in-parenthesis (insert ")"))
5eabfe72
KH
10045 (vhdl-insert-keyword " THEN")
10046 (vhdl-comment-insert-inline
10047 (concat "synchronous reset (active "
10048 (if vhdl-reset-active-high "high" "low") ")"))
10049 (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset)))
10050 (setq position (point))
10051 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
10052 (vhdl-insert-keyword "ELSE")
10053 (insert "\n") (indent-to (+ margin (* 2 vhdl-basic-offset)))
10054 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
10055 (vhdl-insert-keyword "END IF;"))
fda91268 10056 (when (eq reset-kind 'none)
5eabfe72
KH
10057 (setq position (point)))
10058 (insert "\n") (indent-to margin)
d2ddb974 10059 (vhdl-insert-keyword "END IF;")
5eabfe72
KH
10060 (goto-char position)
10061 reset))
d2ddb974 10062
5eabfe72
KH
10063(defun vhdl-template-standard-package (library package)
10064 "Insert specification of a standard package. Include a library
10065specification, if not already there."
3dcb36b7
JB
10066 (let ((margin (current-indentation)))
10067 (unless (equal library "std")
10068 (unless (or (save-excursion
10069 (vhdl-prepare-search-1
10070 (and (not (bobp))
10071 (re-search-backward
10072 (concat "^\\s-*\\(\\(library\\)\\s-+\\(\\w+\\s-*,\\s-*\\)*"
10073 library "\\|end\\)\\>") nil t)
10074 (match-string 2))))
10075 (equal (downcase library) "work"))
10076 (vhdl-insert-keyword "LIBRARY ")
0a2e512a
RF
10077 (insert library ";")
10078 (when package
10079 (insert "\n")
fda91268
RZ
10080 (indent-to margin))))
10081 (when package
10082 (vhdl-insert-keyword "USE ")
10083 (insert library "." package)
10084 (vhdl-insert-keyword ".ALL;"))))
d2ddb974 10085
5eabfe72
KH
10086(defun vhdl-template-package-numeric-bit ()
10087 "Insert specification of `numeric_bit' package."
d2ddb974 10088 (interactive)
5eabfe72 10089 (vhdl-template-standard-package "ieee" "numeric_bit"))
d2ddb974 10090
5eabfe72
KH
10091(defun vhdl-template-package-numeric-std ()
10092 "Insert specification of `numeric_std' package."
d2ddb974 10093 (interactive)
5eabfe72 10094 (vhdl-template-standard-package "ieee" "numeric_std"))
d2ddb974 10095
5eabfe72
KH
10096(defun vhdl-template-package-std-logic-1164 ()
10097 "Insert specification of `std_logic_1164' package."
10098 (interactive)
10099 (vhdl-template-standard-package "ieee" "std_logic_1164"))
d2ddb974 10100
5eabfe72
KH
10101(defun vhdl-template-package-std-logic-arith ()
10102 "Insert specification of `std_logic_arith' package."
10103 (interactive)
10104 (vhdl-template-standard-package "ieee" "std_logic_arith"))
10105
10106(defun vhdl-template-package-std-logic-misc ()
10107 "Insert specification of `std_logic_misc' package."
10108 (interactive)
10109 (vhdl-template-standard-package "ieee" "std_logic_misc"))
10110
10111(defun vhdl-template-package-std-logic-signed ()
10112 "Insert specification of `std_logic_signed' package."
10113 (interactive)
10114 (vhdl-template-standard-package "ieee" "std_logic_signed"))
d2ddb974 10115
5eabfe72
KH
10116(defun vhdl-template-package-std-logic-textio ()
10117 "Insert specification of `std_logic_textio' package."
10118 (interactive)
10119 (vhdl-template-standard-package "ieee" "std_logic_textio"))
10120
10121(defun vhdl-template-package-std-logic-unsigned ()
10122 "Insert specification of `std_logic_unsigned' package."
10123 (interactive)
10124 (vhdl-template-standard-package "ieee" "std_logic_unsigned"))
10125
10126(defun vhdl-template-package-textio ()
10127 "Insert specification of `textio' package."
10128 (interactive)
10129 (vhdl-template-standard-package "std" "textio"))
10130
fda91268
RZ
10131(defun vhdl-template-package-fundamental-constants ()
10132 "Insert specification of `fundamental_constants' package."
10133 (interactive)
10134 (vhdl-template-standard-package "ieee" "fundamental_constants"))
10135
10136(defun vhdl-template-package-material-constants ()
10137 "Insert specification of `material_constants' package."
10138 (interactive)
10139 (vhdl-template-standard-package "ieee" "material_constants"))
10140
10141(defun vhdl-template-package-energy-systems ()
10142 "Insert specification of `energy_systems' package."
10143 (interactive)
10144 (vhdl-template-standard-package "ieee" "energy_systems"))
10145
10146(defun vhdl-template-package-electrical-systems ()
10147 "Insert specification of `electrical_systems' package."
10148 (interactive)
10149 (vhdl-template-standard-package "ieee" "electrical_systems"))
10150
10151(defun vhdl-template-package-mechanical-systems ()
10152 "Insert specification of `mechanical_systems' package."
10153 (interactive)
10154 (vhdl-template-standard-package "ieee" "mechanical_systems"))
10155
10156(defun vhdl-template-package-radiant-systems ()
10157 "Insert specification of `radiant_systems' package."
10158 (interactive)
10159 (vhdl-template-standard-package "ieee" "radiant_systems"))
10160
10161(defun vhdl-template-package-thermal-systems ()
10162 "Insert specification of `thermal_systems' package."
10163 (interactive)
10164 (vhdl-template-standard-package "ieee" "thermal_systems"))
10165
10166(defun vhdl-template-package-fluidic-systems ()
10167 "Insert specification of `fluidic_systems' package."
10168 (interactive)
10169 (vhdl-template-standard-package "ieee" "fluidic_systems"))
10170
10171(defun vhdl-template-package-math-complex ()
10172 "Insert specification of `math_complex' package."
10173 (interactive)
10174 (vhdl-template-standard-package "ieee" "math_complex"))
10175
10176(defun vhdl-template-package-math-real ()
10177 "Insert specification of `math_real' package."
10178 (interactive)
10179 (vhdl-template-standard-package "ieee" "math_real"))
10180
5eabfe72
KH
10181(defun vhdl-template-directive (directive)
10182 "Insert directive."
10183 (unless (= (current-indentation) (current-column))
10184 (delete-horizontal-space)
10185 (insert " "))
10186 (insert "-- pragma " directive))
10187
10188(defun vhdl-template-directive-translate-on ()
10189 "Insert directive 'translate_on'."
10190 (interactive)
10191 (vhdl-template-directive "translate_on"))
10192
10193(defun vhdl-template-directive-translate-off ()
10194 "Insert directive 'translate_off'."
10195 (interactive)
10196 (vhdl-template-directive "translate_off"))
10197
10198(defun vhdl-template-directive-synthesis-on ()
10199 "Insert directive 'synthesis_on'."
10200 (interactive)
10201 (vhdl-template-directive "synthesis_on"))
10202
10203(defun vhdl-template-directive-synthesis-off ()
10204 "Insert directive 'synthesis_off'."
10205 (interactive)
10206 (vhdl-template-directive "synthesis_off"))
10207
3dcb36b7
JB
10208;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10209;; Header and footer templates
10210
10211(defun vhdl-template-header (&optional file-title)
10212 "Insert a VHDL file header."
10213 (interactive)
10214 (unless (equal vhdl-file-header "")
10215 (let (pos)
10216 (save-excursion
10217 (goto-char (point-min))
10218 (vhdl-insert-string-or-file vhdl-file-header)
10219 (setq pos (point-marker)))
10220 (vhdl-template-replace-header-keywords
10221 (point-min-marker) pos file-title))))
10222
10223(defun vhdl-template-footer ()
10224 "Insert a VHDL file footer."
10225 (interactive)
10226 (unless (equal vhdl-file-footer "")
10227 (let (pos)
10228 (save-excursion
10229 (goto-char (point-max))
10230 (setq pos (point-marker))
10231 (vhdl-insert-string-or-file vhdl-file-footer)
10232 (unless (= (preceding-char) ?\n)
10233 (insert "\n")))
10234 (vhdl-template-replace-header-keywords pos (point-max-marker)))))
10235
10236(defun vhdl-template-replace-header-keywords (beg end &optional file-title
10237 is-model)
10238 "Replace keywords in header and footer."
10239 (let ((project-title (or (nth 0 (aget vhdl-project-alist vhdl-project)) ""))
10240 (project-desc (or (nth 9 (aget vhdl-project-alist vhdl-project)) ""))
10241 pos)
10242 (vhdl-prepare-search-2
10243 (save-excursion
10244 (goto-char beg)
10245 (while (search-forward "<projectdesc>" end t)
10246 (replace-match project-desc t t))
10247 (goto-char beg)
10248 (while (search-forward "<filename>" end t)
10249 (replace-match (buffer-name) t t))
10250 (goto-char beg)
10251 (while (search-forward "<copyright>" end t)
10252 (replace-match vhdl-copyright-string t t))
10253 (goto-char beg)
10254 (while (search-forward "<author>" end t)
10255 (replace-match "" t t)
10256 (insert (user-full-name))
10257 (when user-mail-address (insert " <" user-mail-address ">")))
10258 (goto-char beg)
fda91268
RZ
10259 (while (search-forward "<authorfull>" end t)
10260 (replace-match (user-full-name) t t))
10261 (goto-char beg)
3dcb36b7
JB
10262 (while (search-forward "<login>" end t)
10263 (replace-match (user-login-name) t t))
10264 (goto-char beg)
10265 (while (search-forward "<project>" end t)
10266 (replace-match project-title t t))
10267 (goto-char beg)
10268 (while (search-forward "<company>" end t)
10269 (replace-match vhdl-company-name t t))
10270 (goto-char beg)
10271 (while (search-forward "<platform>" end t)
10272 (replace-match vhdl-platform-spec t t))
10273 (goto-char beg)
10274 (while (search-forward "<standard>" end t)
10275 (replace-match
10276 (concat "VHDL" (cond ((vhdl-standard-p '87) "'87")
fda91268 10277 ((vhdl-standard-p '93) "'93/02"))
3dcb36b7
JB
10278 (when (vhdl-standard-p 'ams) ", VHDL-AMS")
10279 (when (vhdl-standard-p 'math) ", Math Packages")) t t))
10280 (goto-char beg)
10281 ;; Replace <RCS> with $, so that RCS for the source is
10282 ;; not over-enthusiastic with replacements
10283 (while (search-forward "<RCS>" end t)
10284 (replace-match "$" nil t))
10285 (goto-char beg)
10286 (while (search-forward "<date>" end t)
10287 (replace-match "" t t)
10288 (vhdl-template-insert-date))
10289 (goto-char beg)
10290 (while (search-forward "<year>" end t)
10291 (replace-match (format-time-string "%Y" nil) t t))
10292 (goto-char beg)
10293 (when file-title
10294 (while (search-forward "<title string>" end t)
10295 (replace-match file-title t t))
10296 (goto-char beg))
10297 (let (string)
10298 (while
10299 (re-search-forward "<\\(\\(\\w\\|\\s_\\)*\\) string>" end t)
10300 (setq string (read-string (concat (match-string 1) ": ")))
10301 (replace-match string t t)))
10302 (goto-char beg)
10303 (when (and (not is-model) (search-forward "<cursor>" end t))
10304 (replace-match "" t t)
10305 (setq pos (point))))
10306 (when pos (goto-char pos))
10307 (unless is-model
10308 (when (or (not project-title) (equal project-title ""))
10309 (message "You can specify a project title in user option `vhdl-project-alist'"))
10310 (when (or (not project-desc) (equal project-desc ""))
10311 (message "You can specify a project description in user option `vhdl-project-alist'"))
10312 (when (equal vhdl-platform-spec "")
10313 (message "You can specify a platform in user option `vhdl-platform-spec'"))
10314 (when (equal vhdl-company-name "")
10315 (message "You can specify a company name in user option `vhdl-company-name'"))))))
10316
5eabfe72
KH
10317;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10318;; Comment templates and functions
10319
10320(defun vhdl-comment-indent ()
10321 "Indent comments."
10322 (let* ((position (point))
10323 (col
10324 (progn
10325 (forward-line -1)
10326 (if (re-search-forward "--" position t)
10327 (- (current-column) 2) ; existing comment at bol stays there
10328 (goto-char position)
10329 (skip-chars-backward " \t")
10330 (max comment-column ; else indent to comment column
10331 (1+ (current-column))))))) ; except leave at least one space
10332 (goto-char position)
10333 col))
10334
10335(defun vhdl-comment-insert ()
d2ddb974 10336 "Start a comment at the end of the line.
5eabfe72
KH
10337If on line with code, indent at least `comment-column'.
10338If starting after end-comment-column, start a new line."
d2ddb974 10339 (interactive)
5eabfe72
KH
10340 (when (> (current-column) end-comment-column) (newline-and-indent))
10341 (if (or (looking-at "\\s-*$") ; end of line
d2ddb974
KH
10342 (and (not unread-command-events) ; called with key binding or menu
10343 (not (end-of-line))))
5eabfe72
KH
10344 (let (margin)
10345 (while (= (preceding-char) ?-) (delete-char -1))
d2ddb974 10346 (setq margin (current-column))
5eabfe72
KH
10347 (delete-horizontal-space)
10348 (if (bolp)
10349 (progn (indent-to margin) (insert "--"))
d2ddb974 10350 (insert " ")
5eabfe72
KH
10351 (indent-to comment-column)
10352 (insert "--"))
d2ddb974 10353 (if (not unread-command-events) (insert " ")))
5eabfe72 10354 ;; else code following current point implies commenting out code
d2ddb974
KH
10355 (let (next-input code)
10356 (while (= (preceding-char) ?-) (delete-char -2))
10357 (while (= (setq next-input (read-char)) 13) ; CR
5eabfe72 10358 (insert "--") ; or have a space after it?
d2ddb974
KH
10359 (forward-char -2)
10360 (forward-line 1)
10361 (message "Enter CR if commenting out a line of code.")
5eabfe72 10362 (setq code t))
3dcb36b7 10363 (unless code
5eabfe72 10364 (insert "--")) ; hardwire to 1 space or use vhdl-basic-offset?
d2ddb974 10365 (setq unread-command-events
5eabfe72 10366 (list (vhdl-character-to-event next-input)))))) ; pushback the char
d2ddb974 10367
5eabfe72 10368(defun vhdl-comment-display (&optional line-exists)
d2ddb974
KH
10369 "Add 2 comment lines at the current indent, making a display comment."
10370 (interactive)
5eabfe72 10371 (let ((margin (current-indentation)))
3dcb36b7 10372 (unless line-exists (vhdl-comment-display-line))
5eabfe72
KH
10373 (insert "\n") (indent-to margin)
10374 (insert "\n") (indent-to margin)
10375 (vhdl-comment-display-line)
10376 (end-of-line -0)
10377 (insert "-- ")))
10378
10379(defun vhdl-comment-display-line ()
d2ddb974
KH
10380 "Displays one line of dashes."
10381 (interactive)
10382 (while (= (preceding-char) ?-) (delete-char -2))
fda91268 10383 (insert "--")
d2ddb974
KH
10384 (let* ((col (current-column))
10385 (len (- end-comment-column col)))
fda91268 10386 (insert-char vhdl-comment-display-line-char len)))
d2ddb974 10387
5eabfe72
KH
10388(defun vhdl-comment-append-inline ()
10389 "Append empty inline comment to current line."
10390 (interactive)
10391 (end-of-line)
10392 (delete-horizontal-space)
10393 (insert " ")
10394 (indent-to comment-column)
10395 (insert "-- "))
10396
10397(defun vhdl-comment-insert-inline (&optional string always-insert)
10398 "Insert inline comment."
10399 (when (or (and string (or vhdl-self-insert-comments always-insert))
10400 (and (not string) vhdl-prompt-for-comments))
10401 (let ((position (point)))
10402 (insert " ")
10403 (indent-to comment-column)
10404 (insert "-- ")
3dcb36b7
JB
10405 (if (not (or (and string (progn (insert string) t))
10406 (vhdl-template-field "[comment]" nil t)))
10407 (delete-region position (point))
d355a0b7
SM
10408 (while (= (preceding-char) ?\ ) (delete-char -1))
10409 ;; (when (> (current-column) end-comment-column)
10410 ;; (setq position (point-marker))
10411 ;; (re-search-backward "-- ")
10412 ;; (insert "\n")
10413 ;; (indent-to comment-column)
10414 ;; (goto-char position))
3dcb36b7 10415 ))))
5eabfe72
KH
10416
10417(defun vhdl-comment-block ()
10418 "Insert comment for code block."
10419 (when vhdl-prompt-for-comments
3dcb36b7
JB
10420 (let ((final-pos (point-marker)))
10421 (vhdl-prepare-search-2
5eabfe72 10422 (when (and (re-search-backward "^\\s-*begin\\>" nil t)
3dcb36b7 10423 (re-search-backward "\\<\\(architecture\\|block\\|function\\|procedure\\|process\\|procedural\\)\\>" nil t))
5eabfe72
KH
10424 (let (margin)
10425 (back-to-indentation)
10426 (setq margin (current-column))
10427 (end-of-line -0)
10428 (if (bobp)
10429 (progn (insert "\n") (forward-line -1))
10430 (insert "\n"))
10431 (indent-to margin)
10432 (insert "-- purpose: ")
10433 (unless (vhdl-template-field "[description]" nil t)
10434 (vhdl-line-kill-entire)))))
10435 (goto-char final-pos))))
d2ddb974
KH
10436
10437(defun vhdl-comment-uncomment-region (beg end &optional arg)
5eabfe72 10438 "Comment out region if not commented out, uncomment otherwise."
d2ddb974 10439 (interactive "r\nP")
5eabfe72
KH
10440 (save-excursion
10441 (goto-char (1- end))
10442 (end-of-line)
10443 (setq end (point-marker))
10444 (goto-char beg)
10445 (beginning-of-line)
10446 (setq beg (point))
fda91268 10447 (if (looking-at (concat "\\s-*" comment-start))
3dcb36b7 10448 (comment-region beg end '(4))
5eabfe72
KH
10449 (comment-region beg end))))
10450
10451(defun vhdl-comment-uncomment-line (&optional arg)
10452 "Comment out line if not commented out, uncomment otherwise."
d2ddb974 10453 (interactive "p")
5eabfe72
KH
10454 (save-excursion
10455 (beginning-of-line)
10456 (let ((position (point)))
10457 (forward-line (or arg 1))
10458 (vhdl-comment-uncomment-region position (point)))))
d2ddb974 10459
5eabfe72
KH
10460(defun vhdl-comment-kill-region (beg end)
10461 "Kill comments in region."
10462 (interactive "r")
10463 (save-excursion
10464 (goto-char end)
10465 (setq end (point-marker))
10466 (goto-char beg)
10467 (beginning-of-line)
10468 (while (< (point) end)
10469 (if (looking-at "^\\(\\s-*--.*\n\\)")
10470 (progn (delete-region (match-beginning 1) (match-end 1)))
10471 (beginning-of-line 2)))))
10472
10473(defun vhdl-comment-kill-inline-region (beg end)
10474 "Kill inline comments in region."
10475 (interactive "r")
10476 (save-excursion
10477 (goto-char end)
10478 (setq end (point-marker))
10479 (goto-char beg)
10480 (beginning-of-line)
10481 (while (< (point) end)
fda91268 10482 (when (looking-at "^.*[^ \t\n\r\f-]+\\(\\s-*--.*\\)$")
5eabfe72
KH
10483 (delete-region (match-beginning 1) (match-end 1)))
10484 (beginning-of-line 2))))
10485
10486;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10487;; Subtemplates
10488
10489(defun vhdl-template-begin-end (construct name margin &optional empty-lines)
d2ddb974
KH
10490 "Insert a begin ... end pair with optional name after the end.
10491Point is left between them."
5eabfe72 10492 (let (position)
5eabfe72 10493 (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n"))
d2ddb974
KH
10494 (indent-to margin)
10495 (vhdl-insert-keyword "BEGIN")
5eabfe72
KH
10496 (when (and (or construct name) vhdl-self-insert-comments)
10497 (insert " --")
10498 (when construct (insert " ") (vhdl-insert-keyword construct))
10499 (when name (insert " " name)))
d2ddb974 10500 (insert "\n")
5eabfe72 10501 (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n"))
d2ddb974 10502 (indent-to (+ margin vhdl-basic-offset))
5eabfe72
KH
10503 (setq position (point))
10504 (insert "\n")
10505 (when (or empty-lines (eq vhdl-insert-empty-lines 'all)) (insert "\n"))
d2ddb974
KH
10506 (indent-to margin)
10507 (vhdl-insert-keyword "END")
5eabfe72
KH
10508 (when construct (insert " ") (vhdl-insert-keyword construct))
10509 (insert (if name (concat " " name) "") ";")
10510 (goto-char position)))
d2ddb974 10511
5eabfe72 10512(defun vhdl-template-argument-list (&optional is-function)
d2ddb974
KH
10513 "Read from user a procedure or function argument list."
10514 (insert " (")
d2ddb974 10515 (let ((margin (current-column))
5eabfe72
KH
10516 (start (point))
10517 (end-pos (point))
10518 not-empty interface semicolon-pos)
3dcb36b7 10519 (unless vhdl-argument-list-indent
5eabfe72
KH
10520 (setq margin (+ (current-indentation) vhdl-basic-offset))
10521 (insert "\n")
10522 (indent-to margin))
10523 (setq interface (vhdl-template-field
10524 (concat "[CONSTANT | SIGNAL"
10525 (unless is-function " | VARIABLE") "]") " " t))
10526 (while (vhdl-template-field "[names]" nil t)
10527 (setq not-empty t)
10528 (insert " : ")
3dcb36b7 10529 (unless is-function
5eabfe72
KH
10530 (if (and interface (equal (upcase interface) "CONSTANT"))
10531 (vhdl-insert-keyword "IN ")
10532 (vhdl-template-field "[IN | OUT | INOUT]" " " t)))
10533 (vhdl-template-field "type")
10534 (setq semicolon-pos (point))
10535 (insert ";")
10536 (vhdl-comment-insert-inline)
10537 (setq end-pos (point))
10538 (insert "\n")
10539 (indent-to margin)
10540 (setq interface (vhdl-template-field
10541 (concat "[CONSTANT | SIGNAL"
10542 (unless is-function " | VARIABLE") "]") " " t)))
10543 (delete-region end-pos (point))
10544 (when semicolon-pos (goto-char semicolon-pos))
10545 (if not-empty
10546 (progn (delete-char 1) (insert ")"))
d355a0b7 10547 (delete-char -2))))
5eabfe72
KH
10548
10549(defun vhdl-template-generic-list (optional &optional no-value)
d2ddb974 10550 "Read from user a generic spec argument list."
5eabfe72 10551 (let (margin
d2ddb974 10552 (start (point)))
5eabfe72
KH
10553 (vhdl-insert-keyword "GENERIC (")
10554 (setq margin (current-column))
3dcb36b7 10555 (unless vhdl-argument-list-indent
5eabfe72
KH
10556 (let ((position (point)))
10557 (back-to-indentation)
10558 (setq margin (+ (current-column) vhdl-basic-offset))
10559 (goto-char position)
10560 (insert "\n")
10561 (indent-to margin)))
10562 (let ((vhdl-generics (vhdl-template-field
10563 (concat (and optional "[") "name"
10564 (and no-value "s") (and optional "]"))
10565 nil optional)))
10566 (if (not vhdl-generics)
d2ddb974 10567 (if optional
5eabfe72 10568 (progn (vhdl-line-kill-entire) (end-of-line -0)
3dcb36b7 10569 (unless vhdl-argument-list-indent
5eabfe72
KH
10570 (vhdl-line-kill-entire) (end-of-line -0)))
10571 (vhdl-template-undo start (point))
d2ddb974
KH
10572 nil )
10573 (insert " : ")
5eabfe72
KH
10574 (let (semicolon-pos end-pos)
10575 (while vhdl-generics
10576 (vhdl-template-field "type")
10577 (if no-value
10578 (progn (setq semicolon-pos (point))
10579 (insert ";"))
10580 (insert " := ")
10581 (unless (vhdl-template-field "[value]" nil t)
10582 (delete-char -4))
10583 (setq semicolon-pos (point))
10584 (insert ";"))
10585 (vhdl-comment-insert-inline)
10586 (setq end-pos (point))
10587 (insert "\n")
10588 (indent-to margin)
10589 (setq vhdl-generics (vhdl-template-field
10590 (concat "[name" (and no-value "s") "]")
10591 " : " t)))
10592 (delete-region end-pos (point))
10593 (goto-char semicolon-pos)
10594 (insert ")")
10595 (end-of-line)
3dcb36b7 10596 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1))
5eabfe72
KH
10597 t)))))
10598
10599(defun vhdl-template-port-list (optional)
10600 "Read from user a port spec argument list."
10601 (let ((start (point))
10602 margin vhdl-ports object)
10603 (vhdl-insert-keyword "PORT (")
10604 (setq margin (current-column))
3dcb36b7 10605 (unless vhdl-argument-list-indent
5eabfe72
KH
10606 (let ((position (point)))
10607 (back-to-indentation)
10608 (setq margin (+ (current-column) vhdl-basic-offset))
10609 (goto-char position)
10610 (insert "\n")
10611 (indent-to margin)))
10612 (when (vhdl-standard-p 'ams)
10613 (setq object (vhdl-template-field "[SIGNAL | TERMINAL | QUANTITY]"
10614 " " t)))
10615 (setq vhdl-ports (vhdl-template-field
10616 (concat (and optional "[") "names" (and optional "]"))
10617 nil optional))
10618 (if (not vhdl-ports)
10619 (if optional
10620 (progn (vhdl-line-kill-entire) (end-of-line -0)
3dcb36b7 10621 (unless vhdl-argument-list-indent
5eabfe72
KH
10622 (vhdl-line-kill-entire) (end-of-line -0)))
10623 (vhdl-template-undo start (point))
10624 nil)
10625 (insert " : ")
10626 (let (semicolon-pos end-pos)
10627 (while vhdl-ports
10628 (cond ((or (null object) (equal "SIGNAL" (upcase object)))
10629 (vhdl-template-field "IN | OUT | INOUT" " "))
10630 ((equal "QUANTITY" (upcase object))
10631 (vhdl-template-field "[IN | OUT]" " " t)))
10632 (vhdl-template-field
10633 (if (and object (equal "TERMINAL" (upcase object)))
10634 "nature" "type"))
10635 (setq semicolon-pos (point))
10636 (insert ";")
10637 (vhdl-comment-insert-inline)
10638 (setq end-pos (point))
10639 (insert "\n")
10640 (indent-to margin)
10641 (when (vhdl-standard-p 'ams)
10642 (setq object (vhdl-template-field "[SIGNAL | TERMINAL | QUANTITY]"
10643 " " t)))
10644 (setq vhdl-ports (vhdl-template-field "[names]" " : " t)))
10645 (delete-region end-pos (point))
10646 (goto-char semicolon-pos)
10647 (insert ")")
10648 (end-of-line)
3dcb36b7 10649 (when vhdl-auto-align (vhdl-align-region-groups start end-pos 1))
5eabfe72
KH
10650 t))))
10651
10652(defun vhdl-template-generate-body (margin label)
10653 "Insert body for generate template."
10654 (vhdl-insert-keyword " GENERATE")
3dcb36b7
JB
10655; (if (not (vhdl-standard-p '87))
10656; (vhdl-template-begin-end "GENERATE" label margin)
10657 (insert "\n\n")
10658 (indent-to margin)
10659 (vhdl-insert-keyword "END GENERATE ")
10660 (insert label ";")
10661 (end-of-line 0)
10662 (indent-to (+ margin vhdl-basic-offset)))
5eabfe72
KH
10663
10664(defun vhdl-template-insert-date ()
d2ddb974
KH
10665 "Insert date in appropriate format."
10666 (interactive)
5eabfe72
KH
10667 (insert
10668 (cond
3dcb36b7 10669 ;; 'american, 'european, 'scientific kept for backward compatibility
5eabfe72
KH
10670 ((eq vhdl-date-format 'american) (format-time-string "%m/%d/%Y" nil))
10671 ((eq vhdl-date-format 'european) (format-time-string "%d.%m.%Y" nil))
10672 ((eq vhdl-date-format 'scientific) (format-time-string "%Y/%m/%d" nil))
10673 (t (format-time-string vhdl-date-format nil)))))
10674
10675;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10676;; Help functions
10677
10678(defun vhdl-electric-space (count)
10679 "Expand abbreviations and self-insert space(s), do indent-new-comment-line
10680if in comment and past end-comment-column."
10681 (interactive "p")
10682 (cond ((vhdl-in-comment-p)
10683 (self-insert-command count)
10684 (cond ((>= (current-column) (+ 2 end-comment-column))
3dcb36b7 10685 (backward-char 1)
fda91268 10686 (skip-chars-backward "^ \t\n\r\f")
5eabfe72 10687 (indent-new-comment-line)
fda91268 10688 (skip-chars-forward "^ \t\n\r\f")
5eabfe72
KH
10689 (forward-char 1))
10690 ((>= (current-column) end-comment-column)
10691 (indent-new-comment-line))
10692 (t nil)))
10693 ((or (and (>= (preceding-char) ?a) (<= (preceding-char) ?z))
10694 (and (>= (preceding-char) ?A) (<= (preceding-char) ?Z)))
3dcb36b7
JB
10695 (vhdl-prepare-search-1
10696 (or (expand-abbrev) (vhdl-fix-case-word -1)))
5eabfe72
KH
10697 (self-insert-command count))
10698 (t (self-insert-command count))))
10699
10700(defun vhdl-template-field (prompt &optional follow-string optional
10701 begin end is-string default)
10702 "Prompt for string and insert it in buffer with optional FOLLOW-STRING.
10703If OPTIONAL is nil, the prompt is left if an empty string is inserted. If
10704an empty string is inserted, return nil and call `vhdl-template-undo' for
10705the region between BEGIN and END. IS-STRING indicates whether a string
10706with double-quotes is to be inserted. DEFAULT specifies a default string."
10707 (let ((position (point))
10708 string)
10709 (insert "<" prompt ">")
10710 (setq string
10711 (condition-case ()
10712 (read-from-minibuffer (concat prompt ": ")
10713 (or (and is-string '("\"\"" . 2)) default)
10714 vhdl-minibuffer-local-map)
10715 (quit (if (and optional begin end)
10716 (progn (beep) "")
10717 (keyboard-quit)))))
10718 (when (or (not (equal string "")) optional)
10719 (delete-region position (point)))
10720 (when (and (equal string "") optional begin end)
10721 (vhdl-template-undo begin end)
10722 (message "Template aborted"))
3dcb36b7 10723 (unless (equal string "")
5eabfe72
KH
10724 (insert string)
10725 (vhdl-fix-case-region-1 position (point) vhdl-upper-case-keywords
3dcb36b7
JB
10726 vhdl-keywords-regexp)
10727 (vhdl-fix-case-region-1 position (point) vhdl-upper-case-types
10728 vhdl-types-regexp)
10729 (vhdl-fix-case-region-1 position (point) vhdl-upper-case-attributes
10730 (concat "'" vhdl-attributes-regexp))
10731 (vhdl-fix-case-region-1 position (point) vhdl-upper-case-enum-values
fda91268
RZ
10732 vhdl-enum-values-regexp)
10733 (vhdl-fix-case-region-1 position (point) vhdl-upper-case-constants
10734 vhdl-constants-regexp))
5eabfe72
KH
10735 (when (or (not (equal string "")) (not optional))
10736 (insert (or follow-string "")))
10737 (if (equal string "") nil string)))
10738
10739(defun vhdl-decision-query (string prompt &optional optional)
10740 "Query a decision from the user."
10741 (let ((start (point)))
10742 (when string (vhdl-insert-keyword (concat string " ")))
274f1353 10743 (message "%s" (or prompt ""))
5eabfe72
KH
10744 (let ((char (read-char)))
10745 (delete-region start (point))
10746 (if (and optional (eq char ?\r))
10747 (progn (insert " ")
10748 (unexpand-abbrev)
3dcb36b7 10749 (throw 'abort "ERROR: Template aborted"))
5eabfe72 10750 char))))
d2ddb974
KH
10751
10752(defun vhdl-insert-keyword (keyword)
5eabfe72
KH
10753 "Insert KEYWORD and adjust case."
10754 (insert (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword))))
d2ddb974
KH
10755
10756(defun vhdl-case-keyword (keyword)
5eabfe72
KH
10757 "Adjust case of KEYWORD."
10758 (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword)))
d2ddb974
KH
10759
10760(defun vhdl-case-word (num)
a4c6cfad 10761 "Adjust case of following NUM words."
5eabfe72
KH
10762 (if vhdl-upper-case-keywords (upcase-word num) (downcase-word num)))
10763
10764(defun vhdl-minibuffer-tab (&optional prefix-arg)
97610156 10765 "If preceding character is part of a word or a paren then hippie-expand,
3dcb36b7 10766else insert tab (used for word completion in VHDL minibuffer)."
5eabfe72 10767 (interactive "P")
3dcb36b7
JB
10768 (cond
10769 ;; expand word
10770 ((= (char-syntax (preceding-char)) ?w)
10771 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
10772 (case-replace nil)
10773 (hippie-expand-only-buffers
10774 (or (and (boundp 'hippie-expand-only-buffers)
10775 hippie-expand-only-buffers)
10776 '(vhdl-mode))))
10777 (vhdl-expand-abbrev prefix-arg)))
10778 ;; expand parenthesis
10779 ((or (= (preceding-char) ?\() (= (preceding-char) ?\)))
10780 (let ((case-fold-search (not vhdl-word-completion-case-sensitive))
10781 (case-replace nil))
10782 (vhdl-expand-paren prefix-arg)))
10783 ;; insert tab
10784 (t (insert-tab))))
5eabfe72
KH
10785
10786(defun vhdl-template-search-prompt ()
10787 "Search for left out template prompts and query again."
10788 (interactive)
3dcb36b7
JB
10789 (vhdl-prepare-search-2
10790 (when (or (re-search-forward
10791 (concat "<\\(" vhdl-template-prompt-syntax "\\)>") nil t)
10792 (re-search-backward
10793 (concat "<\\(" vhdl-template-prompt-syntax "\\)>") nil t))
10794 (let ((string (match-string 1)))
10795 (replace-match "")
10796 (vhdl-template-field string)))))
5eabfe72
KH
10797
10798(defun vhdl-template-undo (begin end)
10799 "Undo aborted template by deleting region and unexpanding the keyword."
10800 (cond (vhdl-template-invoked-by-hook
10801 (goto-char end)
10802 (insert " ")
10803 (delete-region begin end)
10804 (unexpand-abbrev))
10805 (t (delete-region begin end))))
10806
10807(defun vhdl-insert-string-or-file (string)
10808 "Insert STRING or file contents if STRING is an existing file name."
10809 (unless (equal string "")
3dcb36b7
JB
10810 (let ((file-name
10811 (progn (string-match "^\\([^\n]+\\)" string)
10812 (vhdl-resolve-env-variable (match-string 1 string)))))
10813 (if (file-exists-p file-name)
10814 (forward-char (cadr (insert-file-contents file-name)))
10815 (insert string)))))
10816
10817(defun vhdl-beginning-of-block ()
10818 "Move cursor to the beginning of the enclosing block."
10819 (let (pos)
fda91268
RZ
10820 (vhdl-prepare-search-2
10821 (save-excursion
10822 (beginning-of-line)
10823 ;; search backward for block beginning or end
10824 (while (or (while (and (setq pos (re-search-backward "^\\s-*\\(\\(end\\)\\|\\(\\(impure\\|pure\\)[ \t\n\r\f]+\\)?\\(function\\|procedure\\)\\|\\(for\\)\\|\\(architecture\\|component\\|configuration\\|entity\\|package\\(\\s-+body\\)?\\|type[ \t\n\r\f]+\\w+[ \t\n\r\f]+is[ \t\n\r\f]+\\(record\\|protected\\(\\s-+body\\)?\\)\\|units\\)\\|\\(\\w+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?\\(postponed[ \t\n\r\f]+\\)?\\(block\\|case\\|for\\|if\\|procedural\\|process\\|while\\|loop\\)\\)\\>" nil t))
10825 ;; not consider subprogram declarations
10826 (or (and (match-string 5)
10827 (save-match-data
10828 (save-excursion
10829 (goto-char (match-end 5))
10830 (forward-word 1)
10831 (vhdl-forward-syntactic-ws)
10832 (when (looking-at "(")
10833 (forward-sexp))
10834 (re-search-forward "\\<is\\>\\|\\(;\\)" nil t))
10835 (match-string 1)))
10836 ;; not consider configuration specifications
10837 (and (match-string 6)
10838 (save-match-data
10839 (save-excursion
10840 (vhdl-end-of-block)
10841 (beginning-of-line)
10842 (not (looking-at "^\\s-*end\\s-+\\(for\\|generate\\|loop\\)\\>"))))))))
10843 (match-string 2))
10844 ;; skip subblock if block end found
10845 (vhdl-beginning-of-block))))
3dcb36b7
JB
10846 (when pos (goto-char pos))))
10847
10848(defun vhdl-end-of-block ()
10849 "Move cursor to the end of the enclosing block."
10850 (let (pos)
fda91268
RZ
10851 (vhdl-prepare-search-2
10852 (save-excursion
10853 (end-of-line)
10854 ;; search forward for block beginning or end
10855 (while (or (while (and (setq pos (re-search-forward "^\\s-*\\(\\(end\\)\\|\\(\\(impure\\|pure\\)[ \t\n\r\f]+\\)?\\(function\\|procedure\\)\\|\\(for\\)\\|\\(architecture\\|component\\|configuration\\|entity\\|package\\(\\s-+body\\)?\\|type[ \t\n\r\f]+\\w+[ \t\n\r\f]+is[ \t\n\r\f]+\\(record\\|protected\\(\\s-+body\\)?\\)\\|units\\)\\|\\(\\w+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?\\(postponed[ \t\n\r\f]+\\)?\\(block\\|case\\|for\\|if\\|procedural\\|process\\|while\\|loop\\)\\)\\>" nil t))
10856 ;; not consider subprogram declarations
10857 (or (and (match-string 5)
10858 (save-match-data
10859 (save-excursion (re-search-forward "\\<is\\>\\|\\(;\\)" nil t))
10860 (match-string 1)))
10861 ;; not consider configuration specifications
10862 (and (match-string 6)
10863 (save-match-data
10864 (save-excursion
10865 (vhdl-end-of-block)
10866 (beginning-of-line)
10867 (not (looking-at "^\\s-*end\\s-+\\(for\\|generate\\|loop\\)\\>"))))))))
10868 (not (match-string 2)))
10869 ;; skip subblock if block beginning found
10870 (vhdl-end-of-block))))
3dcb36b7 10871 (when pos (goto-char pos))))
5eabfe72
KH
10872
10873(defun vhdl-sequential-statement-p ()
10874 "Check if point is within sequential statement part."
3dcb36b7
JB
10875 (let ((start (point)))
10876 (save-excursion
10877 (vhdl-prepare-search-2
10878 ;; is sequential statement if ...
10879 (and (re-search-backward "^\\s-*begin\\>" nil t)
10880 ;; ... point is between "begin" and "end" of ...
10881 (progn (vhdl-end-of-block)
10882 (< start (point)))
10883 ;; ... a sequential block
10884 (progn (vhdl-beginning-of-block)
fda91268 10885 (looking-at "^\\s-*\\(\\(\\w+[ \t\n\r\f]+\\)?\\(function\\|procedure\\)\\|\\(\\w+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?\\(\\w+[ \t\n\r\f]+\\)?\\(procedural\\|process\\)\\)\\>")))))))
5eabfe72
KH
10886
10887(defun vhdl-in-argument-list-p ()
10888 "Check if within an argument list."
10889 (save-excursion
3dcb36b7
JB
10890 (vhdl-prepare-search-2
10891 (or (string-match "arglist"
10892 (format "%s" (caar (vhdl-get-syntactic-context))))
10893 (progn (beginning-of-line)
10894 (looking-at "^\\s-*\\(generic\\|port\\|\\(\\(impure\\|pure\\)\\s-+\\|\\)function\\|procedure\\)\\>\\s-*\\(\\w+\\s-*\\)?("))))))
5eabfe72
KH
10895
10896;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10897;; Abbrev hooks
10898
10899(defun vhdl-hooked-abbrev (func)
10900 "Do function, if syntax says abbrev is a keyword, invoked by hooked abbrev,
a4c6cfad 10901but not if inside a comment or quote."
3dcb36b7 10902 (if (or (vhdl-in-literal)
5eabfe72
KH
10903 (save-excursion
10904 (forward-word -1)
10905 (and (looking-at "\\<end\\>") (not (looking-at "\\<end;")))))
10906 (progn
10907 (insert " ")
10908 (unexpand-abbrev)
fda91268
RZ
10909 (backward-word 1)
10910 (vhdl-case-word 1)
10911 (delete-char 1))
5eabfe72
KH
10912 (if (not vhdl-electric-mode)
10913 (progn
10914 (insert " ")
10915 (unexpand-abbrev)
10916 (backward-word 1)
10917 (vhdl-case-word 1)
10918 (delete-char 1))
1ba983e8 10919 (let ((invoke-char last-command-event)
5eabfe72
KH
10920 (abbrev-mode -1)
10921 (vhdl-template-invoked-by-hook t))
10922 (let ((caught (catch 'abort
10923 (funcall func))))
29a4e67d 10924 (when (stringp caught) (message "%s" caught)))
5eabfe72
KH
10925 (when (= invoke-char ?-) (setq abbrev-start-location (point)))
10926 ;; delete CR which is still in event queue
4bcb9c95 10927 (if (fboundp 'enqueue-eval-event)
5eabfe72
KH
10928 (enqueue-eval-event 'delete-char -1)
10929 (setq unread-command-events ; push back a delete char
10930 (list (vhdl-character-to-event ?\177))))))))
10931
10932(defun vhdl-template-alias-hook ()
10933 (vhdl-hooked-abbrev 'vhdl-template-alias))
10934(defun vhdl-template-architecture-hook ()
10935 (vhdl-hooked-abbrev 'vhdl-template-architecture))
10936(defun vhdl-template-assert-hook ()
10937 (vhdl-hooked-abbrev 'vhdl-template-assert))
10938(defun vhdl-template-attribute-hook ()
10939 (vhdl-hooked-abbrev 'vhdl-template-attribute))
10940(defun vhdl-template-block-hook ()
10941 (vhdl-hooked-abbrev 'vhdl-template-block))
10942(defun vhdl-template-break-hook ()
10943 (vhdl-hooked-abbrev 'vhdl-template-break))
10944(defun vhdl-template-case-hook ()
10945 (vhdl-hooked-abbrev 'vhdl-template-case))
10946(defun vhdl-template-component-hook ()
10947 (vhdl-hooked-abbrev 'vhdl-template-component))
10948(defun vhdl-template-instance-hook ()
10949 (vhdl-hooked-abbrev 'vhdl-template-instance))
10950(defun vhdl-template-conditional-signal-asst-hook ()
10951 (vhdl-hooked-abbrev 'vhdl-template-conditional-signal-asst))
10952(defun vhdl-template-configuration-hook ()
10953 (vhdl-hooked-abbrev 'vhdl-template-configuration))
10954(defun vhdl-template-constant-hook ()
10955 (vhdl-hooked-abbrev 'vhdl-template-constant))
10956(defun vhdl-template-disconnect-hook ()
10957 (vhdl-hooked-abbrev 'vhdl-template-disconnect))
10958(defun vhdl-template-display-comment-hook ()
10959 (vhdl-hooked-abbrev 'vhdl-comment-display))
10960(defun vhdl-template-else-hook ()
10961 (vhdl-hooked-abbrev 'vhdl-template-else))
10962(defun vhdl-template-elsif-hook ()
10963 (vhdl-hooked-abbrev 'vhdl-template-elsif))
10964(defun vhdl-template-entity-hook ()
10965 (vhdl-hooked-abbrev 'vhdl-template-entity))
10966(defun vhdl-template-exit-hook ()
10967 (vhdl-hooked-abbrev 'vhdl-template-exit))
10968(defun vhdl-template-file-hook ()
10969 (vhdl-hooked-abbrev 'vhdl-template-file))
10970(defun vhdl-template-for-hook ()
10971 (vhdl-hooked-abbrev 'vhdl-template-for))
10972(defun vhdl-template-function-hook ()
10973 (vhdl-hooked-abbrev 'vhdl-template-function))
10974(defun vhdl-template-generic-hook ()
10975 (vhdl-hooked-abbrev 'vhdl-template-generic))
10976(defun vhdl-template-group-hook ()
10977 (vhdl-hooked-abbrev 'vhdl-template-group))
10978(defun vhdl-template-library-hook ()
10979 (vhdl-hooked-abbrev 'vhdl-template-library))
10980(defun vhdl-template-limit-hook ()
10981 (vhdl-hooked-abbrev 'vhdl-template-limit))
10982(defun vhdl-template-if-hook ()
10983 (vhdl-hooked-abbrev 'vhdl-template-if))
10984(defun vhdl-template-bare-loop-hook ()
10985 (vhdl-hooked-abbrev 'vhdl-template-bare-loop))
10986(defun vhdl-template-map-hook ()
10987 (vhdl-hooked-abbrev 'vhdl-template-map))
10988(defun vhdl-template-nature-hook ()
10989 (vhdl-hooked-abbrev 'vhdl-template-nature))
10990(defun vhdl-template-next-hook ()
10991 (vhdl-hooked-abbrev 'vhdl-template-next))
3dcb36b7
JB
10992(defun vhdl-template-others-hook ()
10993 (vhdl-hooked-abbrev 'vhdl-template-others))
5eabfe72
KH
10994(defun vhdl-template-package-hook ()
10995 (vhdl-hooked-abbrev 'vhdl-template-package))
10996(defun vhdl-template-port-hook ()
10997 (vhdl-hooked-abbrev 'vhdl-template-port))
10998(defun vhdl-template-procedural-hook ()
10999 (vhdl-hooked-abbrev 'vhdl-template-procedural))
11000(defun vhdl-template-procedure-hook ()
11001 (vhdl-hooked-abbrev 'vhdl-template-procedure))
11002(defun vhdl-template-process-hook ()
11003 (vhdl-hooked-abbrev 'vhdl-template-process))
11004(defun vhdl-template-quantity-hook ()
11005 (vhdl-hooked-abbrev 'vhdl-template-quantity))
11006(defun vhdl-template-report-hook ()
11007 (vhdl-hooked-abbrev 'vhdl-template-report))
11008(defun vhdl-template-return-hook ()
11009 (vhdl-hooked-abbrev 'vhdl-template-return))
11010(defun vhdl-template-selected-signal-asst-hook ()
11011 (vhdl-hooked-abbrev 'vhdl-template-selected-signal-asst))
11012(defun vhdl-template-signal-hook ()
11013 (vhdl-hooked-abbrev 'vhdl-template-signal))
11014(defun vhdl-template-subnature-hook ()
11015 (vhdl-hooked-abbrev 'vhdl-template-subnature))
11016(defun vhdl-template-subtype-hook ()
11017 (vhdl-hooked-abbrev 'vhdl-template-subtype))
11018(defun vhdl-template-terminal-hook ()
11019 (vhdl-hooked-abbrev 'vhdl-template-terminal))
11020(defun vhdl-template-type-hook ()
11021 (vhdl-hooked-abbrev 'vhdl-template-type))
11022(defun vhdl-template-use-hook ()
11023 (vhdl-hooked-abbrev 'vhdl-template-use))
11024(defun vhdl-template-variable-hook ()
11025 (vhdl-hooked-abbrev 'vhdl-template-variable))
11026(defun vhdl-template-wait-hook ()
11027 (vhdl-hooked-abbrev 'vhdl-template-wait))
11028(defun vhdl-template-when-hook ()
11029 (vhdl-hooked-abbrev 'vhdl-template-when))
11030(defun vhdl-template-while-loop-hook ()
11031 (vhdl-hooked-abbrev 'vhdl-template-while-loop))
11032(defun vhdl-template-with-hook ()
11033 (vhdl-hooked-abbrev 'vhdl-template-with))
11034(defun vhdl-template-and-hook ()
11035 (vhdl-hooked-abbrev 'vhdl-template-and))
11036(defun vhdl-template-or-hook ()
11037 (vhdl-hooked-abbrev 'vhdl-template-or))
11038(defun vhdl-template-nand-hook ()
11039 (vhdl-hooked-abbrev 'vhdl-template-nand))
11040(defun vhdl-template-nor-hook ()
11041 (vhdl-hooked-abbrev 'vhdl-template-nor))
11042(defun vhdl-template-xor-hook ()
11043 (vhdl-hooked-abbrev 'vhdl-template-xor))
11044(defun vhdl-template-xnor-hook ()
11045 (vhdl-hooked-abbrev 'vhdl-template-xnor))
11046(defun vhdl-template-not-hook ()
11047 (vhdl-hooked-abbrev 'vhdl-template-not))
11048
11049(defun vhdl-template-default-hook ()
11050 (vhdl-hooked-abbrev 'vhdl-template-default))
11051(defun vhdl-template-default-indent-hook ()
11052 (vhdl-hooked-abbrev 'vhdl-template-default-indent))
11053
11054;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11055;; Template insertion from completion list
11056
11057(defun vhdl-template-insert-construct (name)
11058 "Insert the built-in construct template with NAME."
11059 (interactive
11060 (list (let ((completion-ignore-case t))
11061 (completing-read "Construct name: "
11062 vhdl-template-construct-alist nil t))))
11063 (vhdl-template-insert-fun
3dcb36b7 11064 (cadr (assoc name vhdl-template-construct-alist))))
5eabfe72
KH
11065
11066(defun vhdl-template-insert-package (name)
11067 "Insert the built-in package template with NAME."
11068 (interactive
11069 (list (let ((completion-ignore-case t))
11070 (completing-read "Package name: "
11071 vhdl-template-package-alist nil t))))
11072 (vhdl-template-insert-fun
3dcb36b7 11073 (cadr (assoc name vhdl-template-package-alist))))
5eabfe72
KH
11074
11075(defun vhdl-template-insert-directive (name)
11076 "Insert the built-in directive template with NAME."
11077 (interactive
11078 (list (let ((completion-ignore-case t))
11079 (completing-read "Directive name: "
11080 vhdl-template-directive-alist nil t))))
11081 (vhdl-template-insert-fun
3dcb36b7 11082 (cadr (assoc name vhdl-template-directive-alist))))
5eabfe72
KH
11083
11084(defun vhdl-template-insert-fun (fun)
11085 "Call FUN to insert a built-in template."
11086 (let ((caught (catch 'abort (when fun (funcall fun)))))
29a4e67d 11087 (when (stringp caught) (message "%s" caught))))
5eabfe72
KH
11088
11089
11090;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11091;;; Models
11092;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11093
11094(defun vhdl-model-insert (model-name)
11095 "Insert the user model with name MODEL-NAME."
11096 (interactive
11097 (let ((completion-ignore-case t))
11098 (list (completing-read "Model name: " vhdl-model-alist))))
3dcb36b7 11099 (indent-according-to-mode)
5eabfe72
KH
11100 (let ((start (point-marker))
11101 (margin (current-indentation))
5eabfe72 11102 model position prompt string end)
3dcb36b7 11103 (vhdl-prepare-search-2
5eabfe72
KH
11104 (when (setq model (assoc model-name vhdl-model-alist))
11105 ;; insert model
11106 (beginning-of-line)
11107 (delete-horizontal-space)
11108 (goto-char start)
11109 (vhdl-insert-string-or-file (nth 1 model))
11110 (setq end (point-marker))
11111 ;; indent code
11112 (goto-char start)
11113 (beginning-of-line)
11114 (while (< (point) end)
11115 (unless (looking-at "^$")
11116 (insert-char ? margin))
11117 (beginning-of-line 2))
11118 (goto-char start)
11119 ;; insert clock
11120 (unless (equal "" vhdl-clock-name)
11121 (while (re-search-forward "<clock>" end t)
11122 (replace-match vhdl-clock-name)))
11123 (goto-char start)
11124 ;; insert reset
11125 (unless (equal "" vhdl-reset-name)
11126 (while (re-search-forward "<reset>" end t)
11127 (replace-match vhdl-reset-name)))
3dcb36b7
JB
11128 ;; replace header prompts
11129 (vhdl-template-replace-header-keywords start end nil t)
5eabfe72 11130 (goto-char start)
3dcb36b7 11131 ;; query other prompts
5eabfe72
KH
11132 (while (re-search-forward
11133 (concat "<\\(" vhdl-template-prompt-syntax "\\)>") end t)
11134 (unless (equal "cursor" (match-string 1))
11135 (setq position (match-beginning 1))
11136 (setq prompt (match-string 1))
11137 (replace-match "")
11138 (setq string (vhdl-template-field prompt nil t))
a5a08b1f 11139 ;; replace occurrences of same prompt
5eabfe72
KH
11140 (while (re-search-forward (concat "<\\(" prompt "\\)>") end t)
11141 (replace-match (or string "")))
11142 (goto-char position)))
11143 (goto-char start)
11144 ;; goto final position
11145 (if (re-search-forward "<cursor>" end t)
11146 (replace-match "")
11147 (goto-char end))))))
11148
11149(defun vhdl-model-defun ()
11150 "Define help and hook functions for user models."
11151 (let ((model-alist vhdl-model-alist)
11152 model-name model-keyword)
11153 (while model-alist
11154 ;; define functions for user models that can be invoked from menu and key
11155 ;; bindings and which themselves call `vhdl-model-insert' with the model
11156 ;; name as argument
11157 (setq model-name (nth 0 (car model-alist)))
d4a5b644
GM
11158 (eval `(defun ,(vhdl-function-name "vhdl-model" model-name) ()
11159 ,(concat "Insert model for \"" model-name "\".")
11160 (interactive)
11161 (vhdl-model-insert ,model-name)))
5eabfe72
KH
11162 ;; define hooks for user models that are invoked from keyword abbrevs
11163 (setq model-keyword (nth 3 (car model-alist)))
11164 (unless (equal model-keyword "")
d4a5b644
GM
11165 (eval `(defun
11166 ,(vhdl-function-name
11167 "vhdl-model" model-name "hook") ()
11168 (vhdl-hooked-abbrev
11169 ',(vhdl-function-name "vhdl-model" model-name)))))
5eabfe72
KH
11170 (setq model-alist (cdr model-alist)))))
11171
11172(vhdl-model-defun)
11173
11174
11175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11176;;; Port translation
11177;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11178
11179(defvar vhdl-port-list nil
3dcb36b7 11180 "Variable to hold last port map parsed.")
333f9019 11181;; structure: (parenthesized expression means list of such entries)
3dcb36b7
JB
11182;; (ent-name
11183;; ((generic-names) generic-type generic-init generic-comment group-comment)
11184;; ((port-names) port-object port-direct port-type port-comment group-comment)
11185;; (lib-name pack-key))
5eabfe72
KH
11186
11187(defun vhdl-parse-string (string &optional optional)
3dcb36b7 11188 "Check that the text following point matches the regexp in STRING."
5eabfe72 11189 (if (looking-at string)
fda91268
RZ
11190 (progn (goto-char (match-end 0))
11191 (when (vhdl-in-literal)
11192 (end-of-line))
11193 (point))
5eabfe72 11194 (unless optional
3dcb36b7
JB
11195 (throw 'parse (format "ERROR: Syntax error near line %s, expecting \"%s\""
11196 (vhdl-current-line) string)))
5eabfe72
KH
11197 nil))
11198
0a2e512a 11199(defun vhdl-replace-string (regexp-cons string &optional adjust-case)
5eabfe72 11200 "Replace STRING from car of REGEXP-CONS to cdr of REGEXP-CONS."
3dcb36b7 11201 (vhdl-prepare-search-1
5eabfe72 11202 (if (string-match (car regexp-cons) string)
0a2e512a
RF
11203 (if adjust-case
11204 (funcall vhdl-file-name-case
11205 (replace-match (cdr regexp-cons) t nil string))
11206 (replace-match (cdr regexp-cons) t nil string))
5eabfe72
KH
11207 string)))
11208
3dcb36b7
JB
11209(defun vhdl-parse-group-comment ()
11210 "Parse comment and empty lines between groups of lines."
11211 (let ((start (point))
11212 string)
11213 (vhdl-forward-comment (point-max))
11214 (setq string (buffer-substring-no-properties start (point)))
0a2e512a 11215 (vhdl-forward-syntactic-ws)
3dcb36b7
JB
11216 ;; strip off leading blanks and first newline
11217 (while (string-match "^\\(\\s-+\\)" string)
11218 (setq string (concat (substring string 0 (match-beginning 1))
11219 (substring string (match-end 1)))))
11220 (if (and (not (equal string "")) (equal (substring string 0 1) "\n"))
11221 (substring string 1)
11222 string)))
11223
11224(defun vhdl-paste-group-comment (string indent)
11225 "Paste comment and empty lines from STRING between groups of lines
11226with INDENT."
11227 (let ((pos (point-marker)))
11228 (when (> indent 0)
11229 (while (string-match "^\\(--\\)" string)
11230 (setq string (concat (substring string 0 (match-beginning 1))
11231 (make-string indent ? )
11232 (substring string (match-beginning 1))))))
11233 (beginning-of-line)
11234 (insert string)
11235 (goto-char pos)))
11236
11237(defvar vhdl-port-flattened nil
11238 "Indicates whether a port has been flattened.")
11239
11240(defun vhdl-port-flatten (&optional as-alist)
0a2e512a
RF
11241 "Flatten port list so that only one generic/port exists per line.
11242This operation is performed on an internally stored port and is only
11243reflected in a subsequent paste operation."
5eabfe72
KH
11244 (interactive)
11245 (if (not vhdl-port-list)
3dcb36b7 11246 (error "ERROR: No port has been read")
0a2e512a 11247 (message "Flattening port for next paste...")
5eabfe72
KH
11248 (let ((new-vhdl-port-list (list (car vhdl-port-list)))
11249 (old-vhdl-port-list (cdr vhdl-port-list))
11250 old-port-list new-port-list old-port new-port names)
11251 ;; traverse port list and flatten entries
3dcb36b7 11252 (while (cdr old-vhdl-port-list)
5eabfe72
KH
11253 (setq old-port-list (car old-vhdl-port-list))
11254 (setq new-port-list nil)
11255 (while old-port-list
11256 (setq old-port (car old-port-list))
11257 (setq names (car old-port))
11258 (while names
3dcb36b7
JB
11259 (setq new-port (cons (if as-alist (car names) (list (car names)))
11260 (cdr old-port)))
5eabfe72
KH
11261 (setq new-port-list (append new-port-list (list new-port)))
11262 (setq names (cdr names)))
11263 (setq old-port-list (cdr old-port-list)))
11264 (setq old-vhdl-port-list (cdr old-vhdl-port-list))
11265 (setq new-vhdl-port-list (append new-vhdl-port-list
11266 (list new-port-list))))
3dcb36b7
JB
11267 (setq vhdl-port-list
11268 (append new-vhdl-port-list (list old-vhdl-port-list))
11269 vhdl-port-flattened t)
0a2e512a 11270 (message "Flattening port for next paste...done"))))
5eabfe72 11271
3dcb36b7
JB
11272(defvar vhdl-port-reversed-direction nil
11273 "Indicates whether port directions are reversed.")
11274
11275(defun vhdl-port-reverse-direction ()
0a2e512a
RF
11276 "Reverse direction for all ports (useful in testbenches).
11277This operation is performed on an internally stored port and is only
11278reflected in a subsequent paste operation."
3dcb36b7
JB
11279 (interactive)
11280 (if (not vhdl-port-list)
11281 (error "ERROR: No port has been read")
0a2e512a 11282 (message "Reversing port directions for next paste...")
3dcb36b7
JB
11283 (let ((port-list (nth 2 vhdl-port-list))
11284 port-dir-car port-dir)
11285 ;; traverse port list and reverse directions
11286 (while port-list
11287 (setq port-dir-car (cddr (car port-list))
11288 port-dir (car port-dir-car))
11289 (setcar port-dir-car
11290 (cond ((equal port-dir "in") "out")
fda91268 11291 ((equal port-dir "IN") "OUT")
3dcb36b7 11292 ((equal port-dir "out") "in")
fda91268 11293 ((equal port-dir "OUT") "IN")
3dcb36b7
JB
11294 (t port-dir)))
11295 (setq port-list (cdr port-list)))
11296 (setq vhdl-port-reversed-direction (not vhdl-port-reversed-direction))
0a2e512a 11297 (message "Reversing port directions for next paste...done"))))
3dcb36b7 11298
5eabfe72
KH
11299(defun vhdl-port-copy ()
11300 "Get generic and port information from an entity or component declaration."
11301 (interactive)
5eabfe72 11302 (save-excursion
3dcb36b7
JB
11303 (let (parse-error end-of-list
11304 decl-type name generic-list port-list context-clause
11305 object names direct type init comment group-comment)
11306 (vhdl-prepare-search-2
5eabfe72
KH
11307 (setq
11308 parse-error
11309 (catch 'parse
11310 ;; check if within entity or component declaration
3dcb36b7 11311 (end-of-line)
5eabfe72
KH
11312 (when (or (not (re-search-backward
11313 "^\\s-*\\(component\\|entity\\|end\\)\\>" nil t))
3dcb36b7
JB
11314 (equal "END" (upcase (match-string 1))))
11315 (throw 'parse "ERROR: Not within an entity or component declaration"))
11316 (setq decl-type (downcase (match-string-no-properties 1)))
5eabfe72 11317 (forward-word 1)
3dcb36b7
JB
11318 (vhdl-parse-string "\\s-+\\(\\w+\\)\\(\\s-+is\\>\\)?")
11319 (setq name (match-string-no-properties 1))
11320 (message "Reading port of %s \"%s\"..." decl-type name)
5eabfe72
KH
11321 (vhdl-forward-syntactic-ws)
11322 ;; parse generic clause
fda91268 11323 (when (vhdl-parse-string "generic[ \t\n\r\f]*(" t)
3dcb36b7
JB
11324 ;; parse group comment and spacing
11325 (setq group-comment (vhdl-parse-group-comment))
fda91268 11326 (setq end-of-list (vhdl-parse-string ")[ \t\n\r\f]*;[ \t\n\r\f]*" t))
5eabfe72 11327 (while (not end-of-list)
0a2e512a 11328 ;; parse names (accept extended identifiers)
fda91268 11329 (vhdl-parse-string "\\(\\\\[^\\]+\\\\\\|\\w+\\)[ \t\n\r\f]*")
3dcb36b7 11330 (setq names (list (match-string-no-properties 1)))
fda91268 11331 (while (vhdl-parse-string ",[ \t\n\r\f]*\\(\\\\[^\\]+\\\\\\|\\w+\\)[ \t\n\r\f]*" t)
3dcb36b7
JB
11332 (setq names
11333 (append names (list (match-string-no-properties 1)))))
5eabfe72 11334 ;; parse type
fda91268 11335 (vhdl-parse-string ":[ \t\n\r\f]*\\([^():;\n]+\\)")
3dcb36b7 11336 (setq type (match-string-no-properties 1))
fda91268
RZ
11337 (when (vhdl-in-comment-p) ; if stuck in comment
11338 (setq type (concat type (and (vhdl-parse-string ".*")
11339 (match-string-no-properties 0)))))
5eabfe72
KH
11340 (setq comment nil)
11341 (while (looking-at "(")
11342 (setq type
11343 (concat type
3dcb36b7 11344 (buffer-substring-no-properties
5eabfe72
KH
11345 (point) (progn (forward-sexp) (point)))
11346 (and (vhdl-parse-string "\\([^():;\n]*\\)" t)
3dcb36b7 11347 (match-string-no-properties 1)))))
5eabfe72
KH
11348 ;; special case: closing parenthesis is on separate line
11349 (when (and type (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" type))
11350 (setq comment (substring type (match-beginning 2)))
11351 (setq type (substring type 0 (match-beginning 1))))
3dcb36b7 11352 ;; strip of trailing group-comment
5eabfe72
KH
11353 (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
11354 (setq type (substring type 0 (match-end 1)))
11355 ;; parse initialization expression
11356 (setq init nil)
fda91268 11357 (when (vhdl-parse-string ":=[ \t\n\r\f]*" t)
5eabfe72 11358 (vhdl-parse-string "\\([^();\n]*\\)")
3dcb36b7 11359 (setq init (match-string-no-properties 1))
5eabfe72
KH
11360 (while (looking-at "(")
11361 (setq init
11362 (concat init
3dcb36b7 11363 (buffer-substring-no-properties
5eabfe72
KH
11364 (point) (progn (forward-sexp) (point)))
11365 (and (vhdl-parse-string "\\([^();\n]*\\)" t)
3dcb36b7 11366 (match-string-no-properties 1))))))
5eabfe72
KH
11367 ;; special case: closing parenthesis is on separate line
11368 (when (and init (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" init))
11369 (setq comment (substring init (match-beginning 2)))
11370 (setq init (substring init 0 (match-beginning 1)))
11371 (vhdl-forward-syntactic-ws))
11372 (skip-chars-forward " \t")
11373 ;; parse inline comment, special case: as above, no initial.
11374 (unless comment
11375 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
3dcb36b7 11376 (match-string-no-properties 1))))
5eabfe72
KH
11377 (vhdl-forward-syntactic-ws)
11378 (setq end-of-list (vhdl-parse-string ")" t))
3dcb36b7 11379 (vhdl-parse-string "\\s-*;\\s-*")
5eabfe72
KH
11380 ;; parse inline comment
11381 (unless comment
11382 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
3dcb36b7 11383 (match-string-no-properties 1))))
5eabfe72 11384 ;; save everything in list
3dcb36b7
JB
11385 (setq generic-list (append generic-list
11386 (list (list names type init
11387 comment group-comment))))
11388 ;; parse group comment and spacing
11389 (setq group-comment (vhdl-parse-group-comment))))
5eabfe72 11390 ;; parse port clause
fda91268 11391 (when (vhdl-parse-string "port[ \t\n\r\f]*(" t)
3dcb36b7
JB
11392 ;; parse group comment and spacing
11393 (setq group-comment (vhdl-parse-group-comment))
fda91268 11394 (setq end-of-list (vhdl-parse-string ")[ \t\n\r\f]*;[ \t\n\r\f]*" t))
5eabfe72
KH
11395 (while (not end-of-list)
11396 ;; parse object
11397 (setq object
fda91268 11398 (and (vhdl-parse-string "\\<\\(signal\\|quantity\\|terminal\\)\\>[ \t\n\r\f]*" t)
3dcb36b7
JB
11399 (match-string-no-properties 1)))
11400 ;; parse names (accept extended identifiers)
fda91268 11401 (vhdl-parse-string "\\(\\\\[^\\]+\\\\\\|\\w+\\)[ \t\n\r\f]*")
3dcb36b7 11402 (setq names (list (match-string-no-properties 1)))
fda91268 11403 (while (vhdl-parse-string ",[ \t\n\r\f]*\\(\\\\[^\\]+\\\\\\|\\w+\\)[ \t\n\r\f]*" t)
3dcb36b7 11404 (setq names (append names (list (match-string-no-properties 1)))))
5eabfe72 11405 ;; parse direction
fda91268 11406 (vhdl-parse-string ":[ \t\n\r\f]*")
5eabfe72 11407 (setq direct
fda91268 11408 (and (vhdl-parse-string "\\<\\(in\\|out\\|inout\\|buffer\\|linkage\\)\\>[ \t\n\r\f]+" t)
3dcb36b7 11409 (match-string-no-properties 1)))
5eabfe72
KH
11410 ;; parse type
11411 (vhdl-parse-string "\\([^();\n]+\\)")
3dcb36b7 11412 (setq type (match-string-no-properties 1))
fda91268
RZ
11413 (when (vhdl-in-comment-p) ; if stuck in comment
11414 (setq type (concat type (and (vhdl-parse-string ".*")
11415 (match-string-no-properties 0)))))
5eabfe72
KH
11416 (setq comment nil)
11417 (while (looking-at "(")
11418 (setq type (concat type
3dcb36b7 11419 (buffer-substring-no-properties
5eabfe72
KH
11420 (point) (progn (forward-sexp) (point)))
11421 (and (vhdl-parse-string "\\([^();\n]*\\)" t)
3dcb36b7 11422 (match-string-no-properties 1)))))
5eabfe72 11423 ;; special case: closing parenthesis is on separate line
3dcb36b7 11424 (when (and type (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" type))
5eabfe72
KH
11425 (setq comment (substring type (match-beginning 2)))
11426 (setq type (substring type 0 (match-beginning 1))))
3dcb36b7 11427 ;; strip of trailing group-comment
5eabfe72
KH
11428 (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
11429 (setq type (substring type 0 (match-end 1)))
11430 (vhdl-forward-syntactic-ws)
11431 (setq end-of-list (vhdl-parse-string ")" t))
3dcb36b7 11432 (vhdl-parse-string "\\s-*;\\s-*")
5eabfe72
KH
11433 ;; parse inline comment
11434 (unless comment
11435 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
3dcb36b7 11436 (match-string-no-properties 1))))
5eabfe72 11437 ;; save everything in list
3dcb36b7
JB
11438 (setq port-list (append port-list
11439 (list (list names object direct type
11440 comment group-comment))))
11441 ;; parse group comment and spacing
11442 (setq group-comment (vhdl-parse-group-comment))))
11443; (vhdl-parse-string "end\\>")
11444 ;; parse context clause
11445 (setq context-clause (vhdl-scan-context-clause))
11446; ;; add surrounding package to context clause
11447; (when (and (equal decl-type "component")
11448; (re-search-backward "^\\s-*package\\s-+\\(\\w+\\)" nil t))
11449; (setq context-clause
11450; (append context-clause
11451; (list (cons (vhdl-work-library)
11452; (match-string-no-properties 1))))))
11453 (message "Reading port of %s \"%s\"...done" decl-type name)
5eabfe72
KH
11454 nil)))
11455 ;; finish parsing
11456 (if parse-error
11457 (error parse-error)
3dcb36b7
JB
11458 (setq vhdl-port-list (list name generic-list port-list context-clause)
11459 vhdl-port-reversed-direction nil
11460 vhdl-port-flattened nil)))))
11461
11462(defun vhdl-port-paste-context-clause (&optional exclude-pack-name)
11463 "Paste a context clause."
11464 (let ((margin (current-indentation))
11465 (clause-list (nth 3 vhdl-port-list))
11466 clause)
11467 (while clause-list
11468 (setq clause (car clause-list))
11469 (unless (or (and exclude-pack-name (equal (downcase (cdr clause))
11470 (downcase exclude-pack-name)))
11471 (save-excursion
11472 (re-search-backward
11473 (concat "^\\s-*use\\s-+" (car clause)
11474 "\." (cdr clause) "\\>") nil t)))
11475 (vhdl-template-standard-package (car clause) (cdr clause))
11476 (insert "\n"))
11477 (setq clause-list (cdr clause-list)))))
5eabfe72
KH
11478
11479(defun vhdl-port-paste-generic (&optional no-init)
11480 "Paste a generic clause."
11481 (let ((margin (current-indentation))
3dcb36b7
JB
11482 (generic-list (nth 1 vhdl-port-list))
11483 list-margin start names generic)
5eabfe72 11484 ;; paste generic clause
3dcb36b7 11485 (when generic-list
5eabfe72
KH
11486 (setq start (point))
11487 (vhdl-insert-keyword "GENERIC (")
11488 (unless vhdl-argument-list-indent
11489 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
11490 (setq list-margin (current-column))
3dcb36b7
JB
11491 (while generic-list
11492 (setq generic (car generic-list))
11493 ;; paste group comment and spacing
11494 (when (memq vhdl-include-group-comments '(decl always))
11495 (vhdl-paste-group-comment (nth 4 generic) list-margin))
5eabfe72 11496 ;; paste names
5eabfe72
KH
11497 (setq names (nth 0 generic))
11498 (while names
11499 (insert (car names))
11500 (setq names (cdr names))
11501 (when names (insert ", ")))
11502 ;; paste type
11503 (insert " : " (nth 1 generic))
11504 ;; paste initialization
11505 (when (and (not no-init) (nth 2 generic))
11506 (insert " := " (nth 2 generic)))
3dcb36b7 11507 (unless (cdr generic-list) (insert ")"))
5eabfe72
KH
11508 (insert ";")
11509 ;; paste comment
11510 (when (and vhdl-include-port-comments (nth 3 generic))
11511 (vhdl-comment-insert-inline (nth 3 generic) t))
3dcb36b7
JB
11512 (setq generic-list (cdr generic-list))
11513 (when generic-list (insert "\n") (indent-to list-margin)))
5eabfe72 11514 ;; align generic clause
3dcb36b7 11515 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1 t)))))
5eabfe72
KH
11516
11517(defun vhdl-port-paste-port ()
11518 "Paste a port clause."
11519 (let ((margin (current-indentation))
3dcb36b7
JB
11520 (port-list (nth 2 vhdl-port-list))
11521 list-margin start names port)
5eabfe72 11522 ;; paste port clause
3dcb36b7 11523 (when port-list
5eabfe72
KH
11524 (setq start (point))
11525 (vhdl-insert-keyword "PORT (")
11526 (unless vhdl-argument-list-indent
11527 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
11528 (setq list-margin (current-column))
3dcb36b7
JB
11529 (while port-list
11530 (setq port (car port-list))
11531 ;; paste group comment and spacing
11532 (when (memq vhdl-include-group-comments '(decl always))
11533 (vhdl-paste-group-comment (nth 5 port) list-margin))
5eabfe72
KH
11534 ;; paste object
11535 (when (nth 1 port) (insert (nth 1 port) " "))
11536 ;; paste names
11537 (setq names (nth 0 port))
11538 (while names
11539 (insert (car names))
11540 (setq names (cdr names))
11541 (when names (insert ", ")))
11542 ;; paste direction
11543 (insert " : ")
11544 (when (nth 2 port) (insert (nth 2 port) " "))
11545 ;; paste type
11546 (insert (nth 3 port))
3dcb36b7 11547 (unless (cdr port-list) (insert ")"))
5eabfe72
KH
11548 (insert ";")
11549 ;; paste comment
11550 (when (and vhdl-include-port-comments (nth 4 port))
11551 (vhdl-comment-insert-inline (nth 4 port) t))
3dcb36b7
JB
11552 (setq port-list (cdr port-list))
11553 (when port-list (insert "\n") (indent-to list-margin)))
5eabfe72 11554 ;; align port clause
3dcb36b7 11555 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1)))))
5eabfe72 11556
3dcb36b7 11557(defun vhdl-port-paste-declaration (kind &optional no-indent)
5eabfe72 11558 "Paste as an entity or component declaration."
3dcb36b7 11559 (unless no-indent (indent-according-to-mode))
5eabfe72
KH
11560 (let ((margin (current-indentation))
11561 (name (nth 0 vhdl-port-list)))
11562 (vhdl-insert-keyword (if (eq kind 'entity) "ENTITY " "COMPONENT "))
11563 (insert name)
3dcb36b7
JB
11564 (when (or (eq kind 'entity) (not (vhdl-standard-p '87)))
11565 (vhdl-insert-keyword " IS"))
11566 ;; paste generic and port clause
5eabfe72
KH
11567 (when (nth 1 vhdl-port-list)
11568 (insert "\n")
11569 (when (and (memq vhdl-insert-empty-lines '(unit all)) (eq kind 'entity))
11570 (insert "\n"))
11571 (indent-to (+ margin vhdl-basic-offset))
11572 (vhdl-port-paste-generic (eq kind 'component)))
11573 (when (nth 2 vhdl-port-list)
11574 (insert "\n")
11575 (when (and (memq vhdl-insert-empty-lines '(unit all))
11576 (eq kind 'entity))
11577 (insert "\n"))
11578 (indent-to (+ margin vhdl-basic-offset)))
11579 (vhdl-port-paste-port)
11580 (insert "\n")
11581 (when (and (memq vhdl-insert-empty-lines '(unit all)) (eq kind 'entity))
11582 (insert "\n"))
11583 (indent-to margin)
11584 (vhdl-insert-keyword "END")
11585 (if (eq kind 'entity)
11586 (progn
11587 (unless (vhdl-standard-p '87) (vhdl-insert-keyword " ENTITY"))
11588 (insert " " name))
11589 (vhdl-insert-keyword " COMPONENT")
11590 (unless (vhdl-standard-p '87) (insert " " name)))
11591 (insert ";")))
11592
3dcb36b7 11593(defun vhdl-port-paste-entity (&optional no-indent)
5eabfe72
KH
11594 "Paste as an entity declaration."
11595 (interactive)
11596 (if (not vhdl-port-list)
3dcb36b7
JB
11597 (error "ERROR: No port read")
11598 (message "Pasting port as entity \"%s\"..." (car vhdl-port-list))
11599 (vhdl-port-paste-declaration 'entity no-indent)
11600 (message "Pasting port as entity \"%s\"...done" (car vhdl-port-list))))
5eabfe72 11601
3dcb36b7 11602(defun vhdl-port-paste-component (&optional no-indent)
5eabfe72
KH
11603 "Paste as a component declaration."
11604 (interactive)
11605 (if (not vhdl-port-list)
3dcb36b7
JB
11606 (error "ERROR: No port read")
11607 (message "Pasting port as component \"%s\"..." (car vhdl-port-list))
11608 (vhdl-port-paste-declaration 'component no-indent)
11609 (message "Pasting port as component \"%s\"...done" (car vhdl-port-list))))
5eabfe72
KH
11610
11611(defun vhdl-port-paste-generic-map (&optional secondary no-constants)
11612 "Paste as a generic map."
11613 (interactive)
3dcb36b7 11614 (unless secondary (indent-according-to-mode))
5eabfe72
KH
11615 (let ((margin (current-indentation))
11616 list-margin start generic
3dcb36b7
JB
11617 (generic-list (nth 1 vhdl-port-list)))
11618 (when generic-list
5eabfe72
KH
11619 (setq start (point))
11620 (vhdl-insert-keyword "GENERIC MAP (")
11621 (if (not vhdl-association-list-with-formals)
11622 ;; paste list of actual generics
3dcb36b7
JB
11623 (while generic-list
11624 (insert (if no-constants
11625 (car (nth 0 (car generic-list)))
11626 (or (nth 2 (car generic-list)) " ")))
11627 (setq generic-list (cdr generic-list))
0a2e512a
RF
11628 (insert (if generic-list ", " ")"))
11629 (when (and (not generic-list) secondary
11630 (null (nth 2 vhdl-port-list)))
11631 (insert ";")))
5eabfe72 11632 (unless vhdl-argument-list-indent
3dcb36b7 11633 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
5eabfe72 11634 (setq list-margin (current-column))
3dcb36b7
JB
11635 (while generic-list
11636 (setq generic (car generic-list))
11637 ;; paste group comment and spacing
11638 (when (eq vhdl-include-group-comments 'always)
11639 (vhdl-paste-group-comment (nth 4 generic) list-margin))
5eabfe72
KH
11640 ;; paste formal and actual generic
11641 (insert (car (nth 0 generic)) " => "
11642 (if no-constants
11643 (car (nth 0 generic))
11644 (or (nth 2 generic) "")))
3dcb36b7
JB
11645 (setq generic-list (cdr generic-list))
11646 (insert (if generic-list "," ")"))
0a2e512a
RF
11647 (when (and (not generic-list) secondary
11648 (null (nth 2 vhdl-port-list)))
11649 (insert ";"))
5eabfe72 11650 ;; paste comment
3dcb36b7
JB
11651 (when (or vhdl-include-type-comments
11652 (and vhdl-include-port-comments (nth 3 generic)))
11653 (vhdl-comment-insert-inline
11654 (concat
11655 (when vhdl-include-type-comments
11656 (concat "[" (nth 1 generic) "] "))
11657 (when vhdl-include-port-comments (nth 3 generic))) t))
11658 (when generic-list (insert "\n") (indent-to list-margin)))
5eabfe72
KH
11659 ;; align generic map
11660 (when vhdl-auto-align
3dcb36b7 11661 (vhdl-align-region-groups start (point) 1 t))))))
5eabfe72
KH
11662
11663(defun vhdl-port-paste-port-map ()
11664 "Paste as a port map."
11665 (let ((margin (current-indentation))
11666 list-margin start port
3dcb36b7
JB
11667 (port-list (nth 2 vhdl-port-list)))
11668 (when port-list
5eabfe72
KH
11669 (setq start (point))
11670 (vhdl-insert-keyword "PORT MAP (")
11671 (if (not vhdl-association-list-with-formals)
11672 ;; paste list of actual ports
3dcb36b7 11673 (while port-list
5eabfe72 11674 (insert (vhdl-replace-string vhdl-actual-port-name
3dcb36b7
JB
11675 (car (nth 0 (car port-list)))))
11676 (setq port-list (cdr port-list))
0a2e512a 11677 (insert (if port-list ", " ")")))
5eabfe72 11678 (unless vhdl-argument-list-indent
3dcb36b7 11679 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
5eabfe72 11680 (setq list-margin (current-column))
3dcb36b7
JB
11681 (while port-list
11682 (setq port (car port-list))
11683 ;; paste group comment and spacing
11684 (when (eq vhdl-include-group-comments 'always)
11685 (vhdl-paste-group-comment (nth 5 port) list-margin))
5eabfe72
KH
11686 ;; paste formal and actual port
11687 (insert (car (nth 0 port)) " => ")
11688 (insert (vhdl-replace-string vhdl-actual-port-name
11689 (car (nth 0 port))))
3dcb36b7
JB
11690 (setq port-list (cdr port-list))
11691 (insert (if port-list "," ");"))
5eabfe72 11692 ;; paste comment
fda91268 11693 (when (or (and vhdl-include-direction-comments (nth 2 port))
3dcb36b7 11694 vhdl-include-type-comments
5eabfe72
KH
11695 (and vhdl-include-port-comments (nth 4 port)))
11696 (vhdl-comment-insert-inline
11697 (concat
3dcb36b7
JB
11698 (cond ((and vhdl-include-direction-comments
11699 vhdl-include-type-comments)
11700 (concat "[" (format "%-4s" (concat (nth 2 port) " "))
11701 (nth 3 port) "] "))
11702 ((and vhdl-include-direction-comments (nth 2 port))
11703 (format "%-6s" (concat "[" (nth 2 port) "] ")))
11704 (vhdl-include-direction-comments " ")
11705 (vhdl-include-type-comments
11706 (concat "[" (nth 3 port) "] ")))
11707 (when vhdl-include-port-comments (nth 4 port))) t))
11708 (when port-list (insert "\n") (indent-to list-margin)))
5eabfe72
KH
11709 ;; align port clause
11710 (when vhdl-auto-align
3dcb36b7 11711 (vhdl-align-region-groups start (point) 1))))))
5eabfe72 11712
3dcb36b7 11713(defun vhdl-port-paste-instance (&optional name no-indent title)
5eabfe72
KH
11714 "Paste as an instantiation."
11715 (interactive)
11716 (if (not vhdl-port-list)
3dcb36b7 11717 (error "ERROR: No port read")
5eabfe72
KH
11718 (let ((orig-vhdl-port-list vhdl-port-list))
11719 ;; flatten local copy of port list (must be flat for port mapping)
11720 (vhdl-port-flatten)
3dcb36b7
JB
11721 (unless no-indent (indent-according-to-mode))
11722 (let ((margin (current-indentation)))
5eabfe72 11723 ;; paste instantiation
3dcb36b7
JB
11724 (cond (name
11725 (insert name))
11726 ((equal (cdr vhdl-instance-name) "")
11727 (setq name (vhdl-template-field "instance name")))
11728 ((string-match "\%d" (cdr vhdl-instance-name))
11729 (let ((n 1))
11730 (while (save-excursion
11731 (setq name (format (vhdl-replace-string
11732 vhdl-instance-name
11733 (nth 0 vhdl-port-list)) n))
11734 (goto-char (point-min))
11735 (vhdl-re-search-forward name nil t))
11736 (setq n (1+ n)))
11737 (insert name)))
11738 (t (insert (vhdl-replace-string vhdl-instance-name
11739 (nth 0 vhdl-port-list)))))
11740 (message "Pasting port as instantiation \"%s\"..." name)
11741 (insert ": ")
11742 (when title
11743 (save-excursion
11744 (beginning-of-line)
11745 (indent-to vhdl-basic-offset)
11746 (insert "-- instance \"" name "\"\n")))
11747 (if (not (vhdl-use-direct-instantiation))
5eabfe72
KH
11748 (insert (nth 0 vhdl-port-list))
11749 (vhdl-insert-keyword "ENTITY ")
3dcb36b7 11750 (insert (vhdl-work-library) "." (nth 0 vhdl-port-list)))
5eabfe72
KH
11751 (when (nth 1 vhdl-port-list)
11752 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
11753 (vhdl-port-paste-generic-map t t))
11754 (when (nth 2 vhdl-port-list)
11755 (insert "\n") (indent-to (+ margin vhdl-basic-offset))
11756 (vhdl-port-paste-port-map))
0a2e512a
RF
11757 (unless (or (nth 1 vhdl-port-list) (nth 2 vhdl-port-list))
11758 (insert ";"))
3dcb36b7
JB
11759 (message "Pasting port as instantiation \"%s\"...done" name))
11760 (setq vhdl-port-list orig-vhdl-port-list))))
11761
11762(defun vhdl-port-paste-constants (&optional no-indent)
11763 "Paste generics as constants."
11764 (interactive)
11765 (if (not vhdl-port-list)
11766 (error "ERROR: No port read")
11767 (let ((orig-vhdl-port-list vhdl-port-list))
11768 (message "Pasting port as constants...")
11769 ;; flatten local copy of port list (must be flat for constant initial.)
11770 (vhdl-port-flatten)
11771 (unless no-indent (indent-according-to-mode))
11772 (let ((margin (current-indentation))
11773 start generic name
11774 (generic-list (nth 1 vhdl-port-list)))
11775 (when generic-list
11776 (setq start (point))
11777 (while generic-list
11778 (setq generic (car generic-list))
11779 ;; paste group comment and spacing
11780 (when (memq vhdl-include-group-comments '(decl always))
11781 (vhdl-paste-group-comment (nth 4 generic) margin))
11782 (vhdl-insert-keyword "CONSTANT ")
11783 ;; paste generic constants
11784 (setq name (nth 0 generic))
11785 (when name
11786 (insert (car name))
11787 ;; paste type
11788 (insert " : " (nth 1 generic))
11789 ;; paste initialization
11790 (when (nth 2 generic)
11791 (insert " := " (nth 2 generic)))
11792 (insert ";")
11793 ;; paste comment
11794 (when (and vhdl-include-port-comments (nth 3 generic))
11795 (vhdl-comment-insert-inline (nth 3 generic) t))
11796 (setq generic-list (cdr generic-list))
11797 (when generic-list (insert "\n") (indent-to margin))))
11798 ;; align signal list
11799 (when vhdl-auto-align
11800 (vhdl-align-region-groups start (point) 1))))
11801 (message "Pasting port as constants...done")
5eabfe72
KH
11802 (setq vhdl-port-list orig-vhdl-port-list))))
11803
3dcb36b7 11804(defun vhdl-port-paste-signals (&optional initialize no-indent)
5eabfe72
KH
11805 "Paste ports as internal signals."
11806 (interactive)
11807 (if (not vhdl-port-list)
3dcb36b7 11808 (error "ERROR: No port read")
5eabfe72 11809 (message "Pasting port as signals...")
3dcb36b7 11810 (unless no-indent (indent-according-to-mode))
5eabfe72
KH
11811 (let ((margin (current-indentation))
11812 start port names
3dcb36b7
JB
11813 (port-list (nth 2 vhdl-port-list)))
11814 (when port-list
5eabfe72 11815 (setq start (point))
3dcb36b7
JB
11816 (while port-list
11817 (setq port (car port-list))
11818 ;; paste group comment and spacing
11819 (when (memq vhdl-include-group-comments '(decl always))
11820 (vhdl-paste-group-comment (nth 5 port) margin))
5eabfe72
KH
11821 ;; paste object
11822 (if (nth 1 port)
11823 (insert (nth 1 port) " ")
11824 (vhdl-insert-keyword "SIGNAL "))
11825 ;; paste actual port signals
11826 (setq names (nth 0 port))
11827 (while names
11828 (insert (vhdl-replace-string vhdl-actual-port-name (car names)))
11829 (setq names (cdr names))
11830 (when names (insert ", ")))
11831 ;; paste type
11832 (insert " : " (nth 3 port))
11833 ;; paste initialization (inputs only)
fda91268
RZ
11834 (when (and initialize (nth 2 port) (equal "IN" (upcase (nth 2 port))))
11835 (insert " := "
11836 (cond ((string-match "integer" (nth 3 port)) "0")
11837 ((string-match "natural" (nth 3 port)) "0")
11838 ((string-match "positive" (nth 3 port)) "0")
11839 ((string-match "real" (nth 3 port)) "0.0")
11840 ((string-match "(.+)" (nth 3 port)) "(others => '0')")
11841 (t "'0'"))))
5eabfe72
KH
11842 (insert ";")
11843 ;; paste comment
fda91268 11844 (when (or (and vhdl-include-direction-comments (nth 2 port))
3dcb36b7
JB
11845 (and vhdl-include-port-comments (nth 4 port)))
11846 (vhdl-comment-insert-inline
11847 (concat
11848 (cond ((and vhdl-include-direction-comments (nth 2 port))
11849 (format "%-6s" (concat "[" (nth 2 port) "] ")))
11850 (vhdl-include-direction-comments " "))
11851 (when vhdl-include-port-comments (nth 4 port))) t))
11852 (setq port-list (cdr port-list))
11853 (when port-list (insert "\n") (indent-to margin)))
5eabfe72 11854 ;; align signal list
3dcb36b7 11855 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1))))
5eabfe72
KH
11856 (message "Pasting port as signals...done")))
11857
3dcb36b7
JB
11858(defun vhdl-port-paste-initializations (&optional no-indent)
11859 "Paste ports as signal initializations."
5eabfe72
KH
11860 (interactive)
11861 (if (not vhdl-port-list)
3dcb36b7 11862 (error "ERROR: No port read")
5eabfe72 11863 (let ((orig-vhdl-port-list vhdl-port-list))
3dcb36b7
JB
11864 (message "Pasting port as initializations...")
11865 ;; flatten local copy of port list (must be flat for signal initial.)
5eabfe72 11866 (vhdl-port-flatten)
3dcb36b7 11867 (unless no-indent (indent-according-to-mode))
5eabfe72 11868 (let ((margin (current-indentation))
3dcb36b7
JB
11869 start port name
11870 (port-list (nth 2 vhdl-port-list)))
11871 (when port-list
5eabfe72 11872 (setq start (point))
3dcb36b7
JB
11873 (while port-list
11874 (setq port (car port-list))
11875 ;; paste actual port signal (inputs only)
11876 (when (equal "IN" (upcase (nth 2 port)))
11877 (setq name (car (nth 0 port)))
11878 (insert (vhdl-replace-string vhdl-actual-port-name name))
5eabfe72 11879 ;; paste initialization
fda91268
RZ
11880 (insert " <= "
11881 (cond ((string-match "integer" (nth 3 port)) "0")
11882 ((string-match "natural" (nth 3 port)) "0")
11883 ((string-match "positive" (nth 3 port)) "0")
11884 ((string-match "real" (nth 3 port)) "0.0")
11885 ((string-match "(.+)" (nth 3 port)) "(others => '0')")
11886 (t "'0'"))
11887 ";"))
3dcb36b7
JB
11888 (setq port-list (cdr port-list))
11889 (when (and port-list
11890 (equal "IN" (upcase (nth 2 (car port-list)))))
11891 (insert "\n") (indent-to margin)))
11892 ;; align signal list
11893 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1))))
11894 (message "Pasting port as initializations...done")
5eabfe72
KH
11895 (setq vhdl-port-list orig-vhdl-port-list))))
11896
11897(defun vhdl-port-paste-testbench ()
3dcb36b7 11898 "Paste as a bare-bones testbench."
5eabfe72
KH
11899 (interactive)
11900 (if (not vhdl-port-list)
3dcb36b7 11901 (error "ERROR: No port read")
5eabfe72
KH
11902 (let ((case-fold-search t)
11903 (ent-name (vhdl-replace-string vhdl-testbench-entity-name
11904 (nth 0 vhdl-port-list)))
11905 (source-buffer (current-buffer))
3dcb36b7
JB
11906 arch-name config-name ent-file-name arch-file-name
11907 ent-buffer arch-buffer position)
5eabfe72 11908 ;; open entity file
3dcb36b7 11909 (unless (eq vhdl-testbench-create-files 'none)
5eabfe72 11910 (setq ent-file-name
0a2e512a
RF
11911 (concat (vhdl-replace-string vhdl-testbench-entity-file-name
11912 ent-name t)
11913 "." (file-name-extension (buffer-file-name))))
3dcb36b7 11914 (if (file-exists-p ent-file-name)
5eabfe72 11915 (if (y-or-n-p
3dcb36b7
JB
11916 (concat "File \"" ent-file-name "\" exists; overwrite? "))
11917 (progn (find-file ent-file-name)
11918 (erase-buffer)
11919 (set-buffer-modified-p nil))
11920 (if (eq vhdl-testbench-create-files 'separate)
11921 (setq ent-file-name nil)
11922 (error "ERROR: Pasting port as testbench...aborted")))
11923 (find-file ent-file-name)))
11924 (unless (and (eq vhdl-testbench-create-files 'separate)
11925 (null ent-file-name))
11926 ;; paste entity header
11927 (if vhdl-testbench-include-header
11928 (progn (vhdl-template-header
11929 (concat "Testbench for design \""
11930 (nth 0 vhdl-port-list) "\""))
11931 (goto-char (point-max)))
11932 (vhdl-comment-display-line) (insert "\n\n"))
11933 ;; paste std_logic_1164 package
11934 (when vhdl-testbench-include-library
11935 (vhdl-template-package-std-logic-1164)
11936 (insert "\n\n") (vhdl-comment-display-line) (insert "\n\n"))
11937 ;; paste entity declaration
11938 (vhdl-insert-keyword "ENTITY ")
5eabfe72
KH
11939 (insert ent-name)
11940 (vhdl-insert-keyword " IS")
3dcb36b7 11941 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
5eabfe72 11942 (insert "\n")
3dcb36b7
JB
11943 (vhdl-insert-keyword "END ")
11944 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ENTITY "))
11945 (insert ent-name ";")
11946 (insert "\n\n")
11947 (vhdl-comment-display-line) (insert "\n"))
11948 ;; get architecture name
11949 (setq arch-name (if (equal (cdr vhdl-testbench-architecture-name) "")
11950 (read-from-minibuffer "architecture name: "
11951 nil vhdl-minibuffer-local-map)
11952 (vhdl-replace-string vhdl-testbench-architecture-name
11953 (nth 0 vhdl-port-list))))
11954 (message "Pasting port as testbench \"%s(%s)\"..." ent-name arch-name)
11955 ;; open architecture file
11956 (if (not (eq vhdl-testbench-create-files 'separate))
5eabfe72 11957 (insert "\n")
3dcb36b7
JB
11958 (setq ent-buffer (current-buffer))
11959 (setq arch-file-name
0a2e512a
RF
11960 (concat (vhdl-replace-string vhdl-testbench-architecture-file-name
11961 (concat ent-name " " arch-name) t)
11962 "." (file-name-extension (buffer-file-name))))
3dcb36b7
JB
11963 (when (and (file-exists-p arch-file-name)
11964 (not (y-or-n-p (concat "File \"" arch-file-name
11965 "\" exists; overwrite? "))))
11966 (error "ERROR: Pasting port as testbench...aborted"))
11967 (find-file arch-file-name)
11968 (erase-buffer)
11969 (set-buffer-modified-p nil)
11970 ;; paste architecture header
11971 (if vhdl-testbench-include-header
11972 (progn (vhdl-template-header
11973 (concat "Testbench architecture for design \""
11974 (nth 0 vhdl-port-list) "\""))
11975 (goto-char (point-max)))
11976 (vhdl-comment-display-line) (insert "\n\n")))
11977 ;; paste architecture body
11978 (vhdl-insert-keyword "ARCHITECTURE ")
11979 (insert arch-name)
11980 (vhdl-insert-keyword " OF ")
11981 (insert ent-name)
11982 (vhdl-insert-keyword " IS")
11983 (insert "\n\n") (indent-to vhdl-basic-offset)
11984 ;; paste component declaration
11985 (unless (vhdl-use-direct-instantiation)
11986 (vhdl-port-paste-component t)
11987 (insert "\n\n") (indent-to vhdl-basic-offset))
11988 ;; paste constants
11989 (when (nth 1 vhdl-port-list)
11990 (insert "-- component generics\n") (indent-to vhdl-basic-offset)
11991 (vhdl-port-paste-constants t)
11992 (insert "\n\n") (indent-to vhdl-basic-offset))
11993 ;; paste internal signals
11994 (insert "-- component ports\n") (indent-to vhdl-basic-offset)
11995 (vhdl-port-paste-signals vhdl-testbench-initialize-signals t)
11996 (insert "\n")
11997 ;; paste custom declarations
11998 (unless (equal "" vhdl-testbench-declarations)
5eabfe72 11999 (insert "\n")
fda91268
RZ
12000 (setq position (point))
12001 (vhdl-insert-string-or-file vhdl-testbench-declarations)
12002 (vhdl-indent-region position (point)))
3dcb36b7
JB
12003 (setq position (point))
12004 (insert "\n\n")
12005 (vhdl-comment-display-line) (insert "\n")
12006 (when vhdl-testbench-include-configuration
12007 (setq config-name (vhdl-replace-string
12008 vhdl-testbench-configuration-name
12009 (concat ent-name " " arch-name)))
12010 (insert "\n")
12011 (vhdl-insert-keyword "CONFIGURATION ") (insert config-name)
12012 (vhdl-insert-keyword " OF ") (insert ent-name)
12013 (vhdl-insert-keyword " IS\n")
12014 (indent-to vhdl-basic-offset)
12015 (vhdl-insert-keyword "FOR ") (insert arch-name "\n")
12016 (indent-to vhdl-basic-offset)
12017 (vhdl-insert-keyword "END FOR;\n")
12018 (vhdl-insert-keyword "END ") (insert config-name ";\n\n")
12019 (vhdl-comment-display-line) (insert "\n"))
12020 (goto-char position)
12021 (vhdl-template-begin-end
12022 (unless (vhdl-standard-p '87) "ARCHITECTURE") arch-name 0 t)
12023 ;; paste instantiation
12024 (insert "-- component instantiation\n") (indent-to vhdl-basic-offset)
12025 (vhdl-port-paste-instance
12026 (vhdl-replace-string vhdl-testbench-dut-name (nth 0 vhdl-port-list)) t)
12027 (insert "\n")
12028 ;; paste custom statements
12029 (unless (equal "" vhdl-testbench-statements)
12030 (insert "\n")
fda91268
RZ
12031 (setq position (point))
12032 (vhdl-insert-string-or-file vhdl-testbench-statements)
12033 (vhdl-indent-region position (point)))
3dcb36b7
JB
12034 (insert "\n")
12035 (indent-to vhdl-basic-offset)
12036 (unless (eq vhdl-testbench-create-files 'none)
12037 (setq arch-buffer (current-buffer))
12038 (when ent-buffer (set-buffer ent-buffer) (save-buffer))
12039 (set-buffer arch-buffer) (save-buffer))
29a4e67d 12040 (message "%s"
3dcb36b7
JB
12041 (concat (format "Pasting port as testbench \"%s(%s)\"...done"
12042 ent-name arch-name)
12043 (and ent-file-name
12044 (format "\n File created: \"%s\"" ent-file-name))
12045 (and arch-file-name
12046 (format "\n File created: \"%s\"" arch-file-name)))))))
5eabfe72
KH
12047
12048
12049;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 12050;;; Subprogram interface translation
5eabfe72
KH
12051;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12052
3dcb36b7
JB
12053(defvar vhdl-subprog-list nil
12054 "Variable to hold last subprogram interface parsed.")
333f9019 12055;; structure: (parenthesized expression means list of such entries)
3dcb36b7
JB
12056;; (subprog-name kind
12057;; ((names) object direct type init comment group-comment)
12058;; return-type return-comment group-comment)
5eabfe72 12059
3dcb36b7
JB
12060(defvar vhdl-subprog-flattened nil
12061 "Indicates whether an subprogram interface has been flattened.")
5eabfe72 12062
3dcb36b7
JB
12063(defun vhdl-subprog-flatten ()
12064 "Flatten interface list so that only one parameter exists per line."
12065 (interactive)
12066 (if (not vhdl-subprog-list)
12067 (error "ERROR: No subprogram interface has been read")
12068 (message "Flattening subprogram interface...")
12069 (let ((old-subprog-list (nth 2 vhdl-subprog-list))
12070 new-subprog-list old-subprog new-subprog names)
12071 ;; traverse parameter list and flatten entries
12072 (while old-subprog-list
12073 (setq old-subprog (car old-subprog-list))
12074 (setq names (car old-subprog))
12075 (while names
12076 (setq new-subprog (cons (list (car names)) (cdr old-subprog)))
12077 (setq new-subprog-list (append new-subprog-list (list new-subprog)))
12078 (setq names (cdr names)))
12079 (setq old-subprog-list (cdr old-subprog-list)))
12080 (setq vhdl-subprog-list
12081 (list (nth 0 vhdl-subprog-list) (nth 1 vhdl-subprog-list)
12082 new-subprog-list (nth 3 vhdl-subprog-list)
12083 (nth 4 vhdl-subprog-list) (nth 5 vhdl-subprog-list))
12084 vhdl-subprog-flattened t)
12085 (message "Flattening subprogram interface...done"))))
12086
12087(defun vhdl-subprog-copy ()
12088 "Get interface information from a subprogram specification."
12089 (interactive)
12090 (save-excursion
12091 (let (parse-error pos end-of-list
12092 name kind param-list object names direct type init
12093 comment group-comment
12094 return-type return-comment return-group-comment)
12095 (vhdl-prepare-search-2
12096 (setq
12097 parse-error
12098 (catch 'parse
12099 ;; check if within function declaration
12100 (setq pos (point))
12101 (end-of-line)
fda91268
RZ
12102 (when (looking-at "[ \t\n\r\f]*\\((\\|;\\|is\\>\\)") (goto-char (match-end 0)))
12103 (unless (and (re-search-backward "^\\s-*\\(\\(procedure\\)\\|\\(\\(pure\\|impure\\)\\s-+\\)?function\\)\\s-+\\(\"?\\w+\"?\\)[ \t\n\r\f]*\\(\\((\\)\\|;\\|is\\>\\)" nil t)
3dcb36b7
JB
12104 (goto-char (match-end 0))
12105 (save-excursion (backward-char)
12106 (forward-sexp)
12107 (<= pos (point))))
12108 (throw 'parse "ERROR: Not within a subprogram specification"))
12109 (setq name (match-string-no-properties 5))
12110 (setq kind (if (match-string 2) 'procedure 'function))
12111 (setq end-of-list (not (match-string 7)))
12112 (message "Reading interface of subprogram \"%s\"..." name)
12113 ;; parse parameter list
12114 (setq group-comment (vhdl-parse-group-comment))
12115 (setq end-of-list (or end-of-list
fda91268 12116 (vhdl-parse-string ")[ \t\n\r\f]*\\(;\\|\\(is\\|return\\)\\>\\)" t)))
3dcb36b7
JB
12117 (while (not end-of-list)
12118 ;; parse object
12119 (setq object
fda91268 12120 (and (vhdl-parse-string "\\(constant\\|signal\\|variable\\|file\\|quantity\\|terminal\\)[ \t\n\r\f]*" t)
3dcb36b7
JB
12121 (match-string-no-properties 1)))
12122 ;; parse names (accept extended identifiers)
fda91268 12123 (vhdl-parse-string "\\(\\\\[^\\]+\\\\\\|\\w+\\)[ \t\n\r\f]*")
3dcb36b7 12124 (setq names (list (match-string-no-properties 1)))
fda91268 12125 (while (vhdl-parse-string ",[ \t\n\r\f]*\\(\\\\[^\\]+\\\\\\|\\w+\\)[ \t\n\r\f]*" t)
3dcb36b7
JB
12126 (setq names (append names (list (match-string-no-properties 1)))))
12127 ;; parse direction
fda91268 12128 (vhdl-parse-string ":[ \t\n\r\f]*")
3dcb36b7 12129 (setq direct
fda91268 12130 (and (vhdl-parse-string "\\(in\\|out\\|inout\\|buffer\\|linkage\\)[ \t\n\r\f]+" t)
3dcb36b7
JB
12131 (match-string-no-properties 1)))
12132 ;; parse type
12133 (vhdl-parse-string "\\([^():;\n]+\\)")
12134 (setq type (match-string-no-properties 1))
12135 (setq comment nil)
12136 (while (looking-at "(")
12137 (setq type
12138 (concat type
12139 (buffer-substring-no-properties
12140 (point) (progn (forward-sexp) (point)))
12141 (and (vhdl-parse-string "\\([^():;\n]*\\)" t)
12142 (match-string-no-properties 1)))))
12143 ;; special case: closing parenthesis is on separate line
12144 (when (and type (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" type))
12145 (setq comment (substring type (match-beginning 2)))
12146 (setq type (substring type 0 (match-beginning 1))))
12147 ;; strip off trailing group-comment
12148 (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
12149 (setq type (substring type 0 (match-end 1)))
12150 ;; parse initialization expression
12151 (setq init nil)
fda91268 12152 (when (vhdl-parse-string ":=[ \t\n\r\f]*" t)
3dcb36b7
JB
12153 (vhdl-parse-string "\\([^();\n]*\\)")
12154 (setq init (match-string-no-properties 1))
12155 (while (looking-at "(")
12156 (setq init
12157 (concat init
12158 (buffer-substring-no-properties
12159 (point) (progn (forward-sexp) (point)))
12160 (and (vhdl-parse-string "\\([^();\n]*\\)" t)
12161 (match-string-no-properties 1))))))
12162 ;; special case: closing parenthesis is on separate line
12163 (when (and init (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" init))
12164 (setq comment (substring init (match-beginning 2)))
12165 (setq init (substring init 0 (match-beginning 1)))
12166 (vhdl-forward-syntactic-ws))
12167 (skip-chars-forward " \t")
12168 ;; parse inline comment, special case: as above, no initial.
12169 (unless comment
12170 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
12171 (match-string-no-properties 1))))
12172 (vhdl-forward-syntactic-ws)
12173 (setq end-of-list (vhdl-parse-string ")\\s-*" t))
12174 ;; parse inline comment
12175 (unless comment
12176 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
12177 (match-string-no-properties 1))))
12178 (setq return-group-comment (vhdl-parse-group-comment))
12179 (vhdl-parse-string "\\(;\\|\\(is\\|\\(return\\)\\)\\>\\)\\s-*")
12180 ;; parse return type
12181 (when (match-string 3)
fda91268 12182 (vhdl-parse-string "[ \t\n\r\f]*\\(.+\\)[ \t\n\r\f]*\\(;\\|is\\>\\)\\s-*")
3dcb36b7
JB
12183 (setq return-type (match-string-no-properties 1))
12184 (when (and return-type
12185 (string-match "\\(\\s-*--\\s-*\\)\\(.*\\)" return-type))
12186 (setq return-comment (substring return-type (match-beginning 2)))
12187 (setq return-type (substring return-type 0 (match-beginning 1))))
12188 ;; strip of trailing group-comment
12189 (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" return-type)
12190 (setq return-type (substring return-type 0 (match-end 1)))
12191 ;; parse return comment
12192 (unless return-comment
12193 (setq return-comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
12194 (match-string-no-properties 1)))))
12195 ;; parse inline comment
12196 (unless comment
12197 (setq comment (and (vhdl-parse-string "--\\s-*\\([^\n]*\\)" t)
12198 (match-string-no-properties 1))))
12199 ;; save everything in list
12200 (setq param-list (append param-list
12201 (list (list names object direct type init
12202 comment group-comment))))
12203 ;; parse group comment and spacing
12204 (setq group-comment (vhdl-parse-group-comment)))
12205 (message "Reading interface of subprogram \"%s\"...done" name)
12206 nil)))
12207 ;; finish parsing
12208 (if parse-error
12209 (error parse-error)
12210 (setq vhdl-subprog-list
12211 (list name kind param-list return-type return-comment
12212 return-group-comment)
12213 vhdl-subprog-flattened nil)))))
12214
12215(defun vhdl-subprog-paste-specification (kind)
12216 "Paste as a subprogram specification."
12217 (indent-according-to-mode)
12218 (let ((margin (current-column))
12219 (param-list (nth 2 vhdl-subprog-list))
12220 list-margin start names param)
12221 ;; paste keyword and name
12222 (vhdl-insert-keyword
12223 (if (eq (nth 1 vhdl-subprog-list) 'procedure) "PROCEDURE " "FUNCTION "))
12224 (insert (nth 0 vhdl-subprog-list))
12225 (if (not param-list)
12226 (if (eq kind 'decl) (insert ";") (vhdl-insert-keyword " is"))
12227 (setq start (point))
12228 ;; paste parameter list
12229 (insert " (")
12230 (unless vhdl-argument-list-indent
12231 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
12232 (setq list-margin (current-column))
12233 (while param-list
12234 (setq param (car param-list))
12235 ;; paste group comment and spacing
12236 (when (memq vhdl-include-group-comments (list kind 'always))
12237 (vhdl-paste-group-comment (nth 6 param) list-margin))
12238 ;; paste object
12239 (when (nth 1 param) (insert (nth 1 param) " "))
12240 ;; paste names
12241 (setq names (nth 0 param))
12242 (while names
12243 (insert (car names))
12244 (setq names (cdr names))
12245 (when names (insert ", ")))
12246 ;; paste direction
12247 (insert " : ")
12248 (when (nth 2 param) (insert (nth 2 param) " "))
12249 ;; paste type
12250 (insert (nth 3 param))
12251 ;; paste initialization
12252 (when (nth 4 param) (insert " := " (nth 4 param)))
12253 ;; terminate line
12254 (if (cdr param-list)
12255 (insert ";")
12256 (insert ")")
12257 (when (null (nth 3 vhdl-subprog-list))
12258 (if (eq kind 'decl) (insert ";") (vhdl-insert-keyword " is"))))
12259 ;; paste comment
12260 (when (and vhdl-include-port-comments (nth 5 param))
12261 (vhdl-comment-insert-inline (nth 5 param) t))
12262 (setq param-list (cdr param-list))
12263 (when param-list (insert "\n") (indent-to list-margin)))
12264 (when (nth 3 vhdl-subprog-list)
12265 (insert "\n") (indent-to list-margin)
12266 ;; paste group comment and spacing
12267 (when (memq vhdl-include-group-comments (list kind 'always))
12268 (vhdl-paste-group-comment (nth 5 vhdl-subprog-list) list-margin))
12269 ;; paste return type
12270 (insert "return " (nth 3 vhdl-subprog-list))
0a2e512a 12271 (if (eq kind 'decl) (insert ";") (vhdl-insert-keyword " is"))
3dcb36b7
JB
12272 (when (and vhdl-include-port-comments (nth 4 vhdl-subprog-list))
12273 (vhdl-comment-insert-inline (nth 4 vhdl-subprog-list) t)))
12274 ;; align parameter list
12275 (when vhdl-auto-align (vhdl-align-region-groups start (point) 1 t)))
12276 ;; paste body
12277 (when (eq kind 'body)
12278 (insert "\n")
12279 (vhdl-template-begin-end
12280 (unless (vhdl-standard-p '87)
12281 (if (eq (nth 1 vhdl-subprog-list) 'procedure) "PROCEDURE" "FUNCTION"))
12282 (nth 0 vhdl-subprog-list) margin))))
12283
12284(defun vhdl-subprog-paste-declaration ()
12285 "Paste as a subprogram declaration."
12286 (interactive)
12287 (if (not vhdl-subprog-list)
12288 (error "ERROR: No subprogram interface read")
12289 (message "Pasting interface as subprogram declaration \"%s\"..."
12290 (car vhdl-subprog-list))
12291 ;; paste specification
12292 (vhdl-subprog-paste-specification 'decl)
12293 (message "Pasting interface as subprogram declaration \"%s\"...done"
12294 (car vhdl-subprog-list))))
12295
12296(defun vhdl-subprog-paste-body ()
12297 "Paste as a subprogram body."
12298 (interactive)
12299 (if (not vhdl-subprog-list)
12300 (error "ERROR: No subprogram interface read")
12301 (message "Pasting interface as subprogram body \"%s\"..."
12302 (car vhdl-subprog-list))
12303 ;; paste specification and body
12304 (vhdl-subprog-paste-specification 'body)
12305 (message "Pasting interface as subprogram body \"%s\"...done"
12306 (car vhdl-subprog-list))))
12307
12308(defun vhdl-subprog-paste-call ()
12309 "Paste as a subprogram call."
12310 (interactive)
12311 (if (not vhdl-subprog-list)
12312 (error "ERROR: No subprogram interface read")
12313 (let ((orig-vhdl-subprog-list vhdl-subprog-list)
12314 param-list margin list-margin param start)
12315 ;; flatten local copy of interface list (must be flat for parameter mapping)
12316 (vhdl-subprog-flatten)
12317 (setq param-list (nth 2 vhdl-subprog-list))
12318 (indent-according-to-mode)
12319 (setq margin (current-indentation))
12320 (message "Pasting interface as subprogram call \"%s\"..."
12321 (car vhdl-subprog-list))
12322 ;; paste name
12323 (insert (nth 0 vhdl-subprog-list))
12324 (if (not param-list)
12325 (insert ";")
12326 (setq start (point))
12327 ;; paste parameter list
12328 (insert " (")
12329 (unless vhdl-argument-list-indent
12330 (insert "\n") (indent-to (+ margin vhdl-basic-offset)))
12331 (setq list-margin (current-column))
12332 (while param-list
12333 (setq param (car param-list))
12334 ;; paste group comment and spacing
12335 (when (eq vhdl-include-group-comments 'always)
12336 (vhdl-paste-group-comment (nth 6 param) list-margin))
12337 ;; paste formal port
12338 (insert (car (nth 0 param)) " => ")
12339 (setq param-list (cdr param-list))
12340 (insert (if param-list "," ");"))
12341 ;; paste comment
12342 (when (and vhdl-include-port-comments (nth 5 param))
12343 (vhdl-comment-insert-inline (nth 5 param)))
12344 (when param-list (insert "\n") (indent-to list-margin)))
12345 ;; align parameter list
12346 (when vhdl-auto-align
12347 (vhdl-align-region-groups start (point) 1)))
12348 (message "Pasting interface as subprogram call \"%s\"...done"
12349 (car vhdl-subprog-list))
12350 (setq vhdl-subprog-list orig-vhdl-subprog-list))))
12351
12352
12353;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12354;;; Miscellaneous
12355;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12356
12357;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12358;; Hippie expand customization
12359
12360(defvar vhdl-expand-upper-case nil)
12361
12362(defun vhdl-try-expand-abbrev (old)
12363 "Try expanding abbreviations from `vhdl-abbrev-list'."
12364 (unless old
12365 (he-init-string (he-dabbrev-beg) (point))
5eabfe72
KH
12366 (setq he-expand-list
12367 (let ((abbrev-list vhdl-abbrev-list)
12368 (sel-abbrev-list '()))
12369 (while abbrev-list
12370 (when (or (not (stringp (car abbrev-list)))
12371 (string-match
12372 (concat "^" he-search-string) (car abbrev-list)))
12373 (setq sel-abbrev-list
12374 (cons (car abbrev-list) sel-abbrev-list)))
12375 (setq abbrev-list (cdr abbrev-list)))
12376 (nreverse sel-abbrev-list))))
12377 (while (and he-expand-list
12378 (or (not (stringp (car he-expand-list)))
12379 (he-string-member (car he-expand-list) he-tried-table t)))
12380; (equal (car he-expand-list) he-search-string)))
12381 (unless (stringp (car he-expand-list))
12382 (setq vhdl-expand-upper-case (car he-expand-list)))
12383 (setq he-expand-list (cdr he-expand-list)))
12384 (if (null he-expand-list)
12385 (progn (when old (he-reset-string))
12386 nil)
12387 (he-substitute-string
12388 (if vhdl-expand-upper-case
12389 (upcase (car he-expand-list))
12390 (car he-expand-list))
12391 t)
12392 (setq he-expand-list (cdr he-expand-list))
12393 t))
12394
12395(defun vhdl-he-list-beg ()
12396 "Also looks at the word before `(' in order to better match parenthesized
12397expressions (e.g. for index ranges of types and signals)."
12398 (save-excursion
12399 (condition-case ()
12400 (progn (backward-up-list 1)
12401 (skip-syntax-backward "w_")) ; crashes in `viper-mode'
12402 (error ()))
12403 (point)))
12404
12405;; override `he-list-beg' from `hippie-exp'
12406(unless (and (boundp 'viper-mode) viper-mode)
5eabfe72
KH
12407 (defalias 'he-list-beg 'vhdl-he-list-beg))
12408
12409;; function for expanding abbrevs and dabbrevs
fda91268
RZ
12410(defalias 'vhdl-expand-abbrev (make-hippie-expand-function
12411 '(try-expand-dabbrev
12412 try-expand-dabbrev-all-buffers
12413 vhdl-try-expand-abbrev)))
5eabfe72
KH
12414
12415;; function for expanding parenthesis
fda91268
RZ
12416(defalias 'vhdl-expand-paren (make-hippie-expand-function
12417 '(try-expand-list
12418 try-expand-list-all-buffers)))
5eabfe72
KH
12419
12420;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12421;; Case fixing
d2ddb974
KH
12422
12423(defun vhdl-fix-case-region-1 (beg end upper-case word-regexp &optional count)
a4c6cfad
JB
12424 "Convert all words matching WORD-REGEXP in region to lower or upper case,
12425depending on parameter UPPER-CASE."
3dcb36b7 12426 (let ((case-replace nil)
5eabfe72 12427 (last-update 0))
3dcb36b7 12428 (vhdl-prepare-search-2
5eabfe72
KH
12429 (save-excursion
12430 (goto-char end)
12431 (setq end (point-marker))
12432 (goto-char beg)
12433 (while (re-search-forward word-regexp end t)
3dcb36b7 12434 (or (vhdl-in-literal)
5eabfe72
KH
12435 (if upper-case
12436 (upcase-word -1)
12437 (downcase-word -1)))
3dcb36b7 12438 (when (and count vhdl-progress-interval (not noninteractive)
5eabfe72
KH
12439 (< vhdl-progress-interval
12440 (- (nth 1 (current-time)) last-update)))
12441 (message "Fixing case... (%2d%s)"
fda91268 12442 (+ (* count 20) (/ (* 20 (- (point) beg)) (- end beg)))
5eabfe72
KH
12443 "%")
12444 (setq last-update (nth 1 (current-time)))))
3dcb36b7 12445 (goto-char end)))))
d2ddb974
KH
12446
12447(defun vhdl-fix-case-region (beg end &optional arg)
12448 "Convert all VHDL words in region to lower or upper case, depending on
3dcb36b7 12449options vhdl-upper-case-{keywords,types,attributes,enum-values}."
d2ddb974
KH
12450 (interactive "r\nP")
12451 (vhdl-fix-case-region-1
5eabfe72 12452 beg end vhdl-upper-case-keywords vhdl-keywords-regexp 0)
d2ddb974 12453 (vhdl-fix-case-region-1
5eabfe72 12454 beg end vhdl-upper-case-types vhdl-types-regexp 1)
d2ddb974 12455 (vhdl-fix-case-region-1
5eabfe72
KH
12456 beg end vhdl-upper-case-attributes (concat "'" vhdl-attributes-regexp) 2)
12457 (vhdl-fix-case-region-1
3dcb36b7 12458 beg end vhdl-upper-case-enum-values vhdl-enum-values-regexp 3)
fda91268
RZ
12459 (vhdl-fix-case-region-1
12460 beg end vhdl-upper-case-constants vhdl-constants-regexp 4)
3dcb36b7 12461 (when vhdl-progress-interval (message "Fixing case...done")))
d2ddb974 12462
5eabfe72
KH
12463(defun vhdl-fix-case-buffer ()
12464 "Convert all VHDL words in buffer to lower or upper case, depending on
3dcb36b7 12465options vhdl-upper-case-{keywords,types,attributes,enum-values}."
d2ddb974 12466 (interactive)
5eabfe72
KH
12467 (vhdl-fix-case-region (point-min) (point-max)))
12468
3dcb36b7
JB
12469(defun vhdl-fix-case-word (&optional arg)
12470 "Convert word after cursor to upper case if necessary."
12471 (interactive "p")
12472 (save-excursion
12473 (when arg (backward-word 1))
12474 (vhdl-prepare-search-1
12475 (when (and vhdl-upper-case-keywords
12476 (looking-at vhdl-keywords-regexp))
12477 (upcase-word 1))
12478 (when (and vhdl-upper-case-types
12479 (looking-at vhdl-types-regexp))
12480 (upcase-word 1))
12481 (when (and vhdl-upper-case-attributes
12482 (looking-at vhdl-attributes-regexp))
12483 (upcase-word 1))
12484 (when (and vhdl-upper-case-enum-values
12485 (looking-at vhdl-enum-values-regexp))
fda91268
RZ
12486 (upcase-word 1))
12487 (when (and vhdl-upper-case-constants
12488 (looking-at vhdl-constants-regexp))
3dcb36b7
JB
12489 (upcase-word 1)))))
12490
5eabfe72
KH
12491;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12492;; Line handling functions
d2ddb974
KH
12493
12494(defun vhdl-current-line ()
12495 "Return the line number of the line containing point."
12496 (save-restriction
12497 (widen)
9b026d9f 12498 (1+ (count-lines (point-min) (point-at-bol)))))
d2ddb974 12499
5eabfe72 12500(defun vhdl-line-kill-entire (&optional arg)
d2ddb974 12501 "Delete entire line."
5eabfe72
KH
12502 (interactive "p")
12503 (beginning-of-line)
12504 (kill-line (or arg 1)))
12505
12506(defun vhdl-line-kill (&optional arg)
12507 "Kill current line."
12508 (interactive "p")
12509 (vhdl-line-kill-entire arg))
12510
12511(defun vhdl-line-copy (&optional arg)
12512 "Copy current line."
12513 (interactive "p")
12514 (save-excursion
9b026d9f 12515 (let ((position (point-at-bol)))
5eabfe72
KH
12516 (forward-line (or arg 1))
12517 (copy-region-as-kill position (point)))))
12518
12519(defun vhdl-line-yank ()
12520 "Yank entire line."
d2ddb974 12521 (interactive)
5eabfe72
KH
12522 (beginning-of-line)
12523 (yank))
d2ddb974 12524
5eabfe72
KH
12525(defun vhdl-line-expand (&optional prefix-arg)
12526 "Hippie-expand current line."
12527 (interactive "P")
de82e29b 12528 (require 'hippie-exp)
5eabfe72
KH
12529 (let ((case-fold-search t) (case-replace nil)
12530 (hippie-expand-try-functions-list
12531 '(try-expand-line try-expand-line-all-buffers)))
12532 (hippie-expand prefix-arg)))
12533
12534(defun vhdl-line-transpose-next (&optional arg)
12535 "Interchange this line with next line."
12536 (interactive "p")
12537 (forward-line 1)
12538 (transpose-lines (or arg 1))
12539 (forward-line -1))
12540
12541(defun vhdl-line-transpose-previous (&optional arg)
12542 "Interchange this line with previous line."
12543 (interactive "p")
12544 (forward-line 1)
12545 (transpose-lines (- 0 (or arg 0)))
12546 (forward-line -1))
12547
12548(defun vhdl-line-open ()
d2ddb974
KH
12549 "Open a new line and indent."
12550 (interactive)
5eabfe72
KH
12551 (end-of-line -0)
12552 (newline-and-indent))
d2ddb974 12553
3dcb36b7
JB
12554(defun vhdl-delete-indentation ()
12555 "Join lines. That is, call `delete-indentation' with `fill-prefix' so that
12556it works within comments too."
12557 (interactive)
12558 (let ((fill-prefix "-- "))
12559 (delete-indentation)))
d2ddb974 12560
5eabfe72 12561;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 12562;; Move functions
d2ddb974 12563
3dcb36b7
JB
12564(defun vhdl-forward-same-indent ()
12565 "Move forward to next line with same indent."
12566 (interactive)
12567 (let ((pos (point))
12568 (indent (current-indentation)))
12569 (beginning-of-line 2)
12570 (while (and (not (eobp))
12571 (or (looking-at "^\\s-*\\(--.*\\)?$")
12572 (> (current-indentation) indent)))
12573 (beginning-of-line 2))
12574 (if (= (current-indentation) indent)
12575 (back-to-indentation)
12576 (message "No following line with same indent found in this block")
12577 (goto-char pos)
12578 nil)))
5eabfe72 12579
3dcb36b7
JB
12580(defun vhdl-backward-same-indent ()
12581 "Move backward to previous line with same indent."
12582 (interactive)
12583 (let ((pos (point))
12584 (indent (current-indentation)))
12585 (beginning-of-line -0)
12586 (while (and (not (bobp))
12587 (or (looking-at "^\\s-*\\(--.*\\)?$")
12588 (> (current-indentation) indent)))
12589 (beginning-of-line -0))
12590 (if (= (current-indentation) indent)
12591 (back-to-indentation)
12592 (message "No preceding line with same indent found in this block")
12593 (goto-char pos)
12594 nil)))
5eabfe72
KH
12595
12596;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7
JB
12597;; Statistics
12598
12599(defun vhdl-statistics-buffer ()
12600 "Get some file statistics."
12601 (interactive)
12602 (let ((no-stats 0)
12603 (no-code-lines 0)
fda91268
RZ
12604 (no-empty-lines 0)
12605 (no-comm-lines 0)
12606 (no-comments 0)
3dcb36b7
JB
12607 (no-lines (count-lines (point-min) (point-max))))
12608 (save-excursion
12609 ;; count statements
12610 (goto-char (point-min))
12611 (while (re-search-forward "\\(--.*\n\\|\"[^\"\n]*[\"\n]\\)\\|;" nil t)
12612 (if (match-string 1)
12613 (goto-char (match-end 1))
12614 (setq no-stats (1+ no-stats))))
12615 ;; count code lines
12616 (goto-char (point-min))
12617 (while (not (eobp))
12618 (unless (looking-at "^\\s-*\\(--.*\\)?$")
12619 (setq no-code-lines (1+ no-code-lines)))
fda91268
RZ
12620 (beginning-of-line 2))
12621 ;; count empty lines
12622 (goto-char (point-min))
12623 (while (and (re-search-forward "^\\s-*$" nil t)
12624 (not (eq (point) (point-max))))
12625 (if (match-string 1)
12626 (goto-char (match-end 1))
12627 (setq no-empty-lines (1+ no-empty-lines))
12628 (unless (eq (point) (point-max))
12629 (forward-char))))
12630 ;; count comment-only lines
12631 (goto-char (point-min))
12632 (while (re-search-forward "^\\s-*--.*" nil t)
12633 (if (match-string 1)
12634 (goto-char (match-end 1))
12635 (setq no-comm-lines (1+ no-comm-lines))))
12636 ;; count comments
12637 (goto-char (point-min))
12638 (while (re-search-forward "--.*" nil t)
12639 (if (match-string 1)
12640 (goto-char (match-end 1))
12641 (setq no-comments (1+ no-comments)))))
3dcb36b7
JB
12642 ;; print results
12643 (message "\n\
12644File statistics: \"%s\"\n\
12645---------------------\n\
fda91268
RZ
12646# statements : %5d\n\
12647# code lines : %5d\n\
12648# empty lines : %5d\n\
12649# comment lines : %5d\n\
12650# comments : %5d\n\
12651# total lines : %5d\n\ "
12652 (buffer-file-name) no-stats no-code-lines no-empty-lines
12653 no-comm-lines no-comments no-lines)
0a2e512a 12654 (unless vhdl-emacs-21 (vhdl-show-messages))))
3dcb36b7 12655
5eabfe72 12656;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 12657;; Help functions
d2ddb974 12658
3dcb36b7
JB
12659(defun vhdl-re-search-forward (regexp &optional bound noerror count)
12660 "Like `re-search-forward', but does not match within literals."
12661 (let (pos)
12662 (save-excursion
12663 (while (and (setq pos (re-search-forward regexp bound noerror count))
12664 (vhdl-in-literal))))
12665 (when pos (goto-char pos))
12666 pos))
12667
12668(defun vhdl-re-search-backward (regexp &optional bound noerror count)
12669 "Like `re-search-backward', but does not match within literals."
12670 (let (pos)
12671 (save-excursion
12672 (while (and (setq pos (re-search-backward regexp bound noerror count))
12673 (vhdl-in-literal))))
12674 (when pos (goto-char pos))
12675 pos))
5eabfe72 12676
d2ddb974 12677
3dcb36b7
JB
12678;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12679;;; Project
12680;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12681
12682(defun vhdl-set-project (name)
12683 "Set current project to NAME."
12684 (interactive
12685 (list (let ((completion-ignore-case t))
12686 (completing-read "Project name: " vhdl-project-alist nil t))))
12687 (cond ((equal name "")
12688 (setq vhdl-project nil)
12689 (message "Current VHDL project: None"))
12690 ((assoc name vhdl-project-alist)
12691 (setq vhdl-project name)
12692 (message "Current VHDL project: \"%s\"" name))
12693 (t
12694 (vhdl-warning (format "Unknown VHDL project: \"%s\"" name))))
12695 (vhdl-speedbar-update-current-project))
12696
0a2e512a
RF
12697(defun vhdl-set-default-project ()
12698 "Set current project as default on startup."
12699 (interactive)
12700 (customize-set-variable 'vhdl-project vhdl-project)
12701 (customize-save-customized))
12702
3dcb36b7
JB
12703(defun vhdl-toggle-project (name token indent)
12704 "Set current project to NAME or unset if NAME is current project."
12705 (vhdl-set-project (if (equal name vhdl-project) "" name)))
12706
12707(defun vhdl-export-project (file-name)
12708 "Write project setup for current project."
12709 (interactive
12710 (let ((name (vhdl-resolve-env-variable
12711 (vhdl-replace-string
12712 (cons "\\(.*\\) \\(.*\\)" (car vhdl-project-file-name))
12713 (concat (subst-char-in-string
12714 ? ?_ (or (vhdl-project-p)
12715 (error "ERROR: No current project")))
12716 " " (user-login-name))))))
12717 (list (read-file-name
12718 "Write project file: "
12719 (when (file-name-absolute-p name) "") nil nil name))))
12720 (setq file-name (abbreviate-file-name file-name))
12721 (let ((orig-buffer (current-buffer)))
12722 (unless (file-exists-p (file-name-directory file-name))
12723 (make-directory (file-name-directory file-name) t))
12724 (if (not (file-writable-p file-name))
12725 (error "ERROR: File not writable: \"%s\"" file-name)
12726 (set-buffer (find-file-noselect file-name t t))
12727 (erase-buffer)
12728 (insert ";; -*- Emacs-Lisp -*-\n\n"
12729 ";;; " (file-name-nondirectory file-name)
12730 " - project setup file for Emacs VHDL Mode " vhdl-version "\n\n"
12731 ";; Project : " vhdl-project "\n"
12732 ";; Saved : " (format-time-string "%Y-%m-%d %T ")
12733 (user-login-name) "\n\n\n"
12734 ";; project name\n"
12735 "(setq vhdl-project \"" vhdl-project "\")\n\n"
12736 ";; project setup\n"
12737 "(aput 'vhdl-project-alist vhdl-project\n'")
12738 (pp (aget vhdl-project-alist vhdl-project) (current-buffer))
12739 (insert ")\n")
12740 (save-buffer)
12741 (kill-buffer (current-buffer))
12742 (set-buffer orig-buffer))))
12743
12744(defun vhdl-import-project (file-name &optional auto not-make-current)
12745 "Read project setup and set current project."
12746 (interactive
12747 (let ((name (vhdl-resolve-env-variable
12748 (vhdl-replace-string
12749 (cons "\\(.*\\) \\(.*\\)" (car vhdl-project-file-name))
12750 (concat "" " " (user-login-name))))))
12751 (list (read-file-name
12752 "Read project file: " (when (file-name-absolute-p name) "") nil t
12753 (file-name-directory name)))))
12754 (when (file-exists-p file-name)
12755 (condition-case ()
12756 (let ((current-project vhdl-project))
12757 (load-file file-name)
12758 (when (/= (length (aget vhdl-project-alist vhdl-project t)) 10)
12759 (adelete 'vhdl-project-alist vhdl-project)
0a2e512a 12760 (error ""))
3dcb36b7
JB
12761 (when not-make-current
12762 (setq vhdl-project current-project))
12763 (vhdl-update-mode-menu)
12764 (vhdl-speedbar-refresh)
12765 (unless not-make-current
12766 (message "Current VHDL project: \"%s\"%s"
12767 vhdl-project (if auto " (auto-loaded)" ""))))
12768 (error (vhdl-warning
12769 (format "ERROR: Invalid project setup file: \"%s\"" file-name))))))
12770
12771(defun vhdl-duplicate-project ()
12772 "Duplicate setup of current project."
5eabfe72 12773 (interactive)
3dcb36b7
JB
12774 (let ((new-name (read-from-minibuffer "New project name: "))
12775 (project-entry (aget vhdl-project-alist vhdl-project t)))
12776 (setq vhdl-project-alist
12777 (append vhdl-project-alist
12778 (list (cons new-name project-entry))))
12779 (vhdl-update-mode-menu)))
12780
12781(defun vhdl-auto-load-project ()
12782 "Automatically load project setup at startup."
12783 (let ((file-name-list vhdl-project-file-name)
12784 file-list list-length)
12785 (while file-name-list
12786 (setq file-list
12787 (append file-list
12788 (file-expand-wildcards
12789 (vhdl-resolve-env-variable
12790 (vhdl-replace-string
12791 (cons "\\(.*\\) \\(.*\\)" (car file-name-list))
12792 (concat "\*" " " (user-login-name)))))))
12793 (setq list-length (or list-length (length file-list)))
12794 (setq file-name-list (cdr file-name-list)))
12795 (while file-list
12796 (vhdl-import-project (expand-file-name (car file-list)) t
12797 (not (> list-length 0)))
12798 (setq list-length (1- list-length))
12799 (setq file-list (cdr file-list)))))
12800
12801;; automatically load project setup when idle after startup
12802(when (memq 'startup vhdl-project-auto-load)
12803 (if noninteractive
12804 (vhdl-auto-load-project)
12805 (vhdl-run-when-idle .1 nil 'vhdl-auto-load-project)))
5eabfe72
KH
12806
12807
12808;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12809;;; Hideshow
12810;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12811;; (using `hideshow.el')
d2ddb974 12812
3dcb36b7
JB
12813(defconst vhdl-hs-start-regexp
12814 (concat
12815 "\\(^\\)\\s-*\\("
12816 ;; generic/port clause
fda91268 12817 "\\(generic\\|port\\)[ \t\n\r\f]*(\\|"
3dcb36b7
JB
12818 ;; component
12819 "component\\>\\|"
12820 ;; component instantiation
fda91268
RZ
12821 "\\(\\w\\|\\s_\\)+[ \t\n\r\f]*:[ \t\n\r\f]*"
12822 "\\(\\(component\\|configuration\\|entity\\)[ \t\n\r\f]+\\)?"
12823 "\\(\\w\\|\\s_\\)+\\([ \t\n\r\f]*(\\(\\w\\|\\s_\\)+)\\)?[ \t\n\r\f]*"
12824 "\\(generic\\|port\\)[ \t\n\r\f]+map[ \t\n\r\f]*(\\|"
3dcb36b7
JB
12825 ;; subprogram
12826 "\\(function\\|procedure\\)\\>\\|"
12827 ;; process, block
fda91268 12828 "\\(\\(\\w\\|\\s_\\)+[ \t\n\r\f]*:[ \t\n\r\f]*\\)?\\(process\\|block\\)\\>\\|"
3dcb36b7
JB
12829 ;; configuration declaration
12830 "configuration\\>"
12831 "\\)")
12832 "Regexp to match start of construct to hide.")
12833
12834(defun vhdl-hs-forward-sexp-func (count)
a4c6cfad 12835 "Find end of construct to hide (for hideshow). Only searches forward."
3dcb36b7
JB
12836 (let ((pos (point)))
12837 (vhdl-prepare-search-2
12838 (beginning-of-line)
12839 (cond
12840 ;; generic/port clause
fda91268 12841 ((looking-at "^\\s-*\\(generic\\|port\\)[ \t\n\r\f]*(")
3dcb36b7
JB
12842 (goto-char (match-end 0))
12843 (backward-char)
12844 (forward-sexp))
12845 ;; component declaration
12846 ((looking-at "^\\s-*component\\>")
12847 (re-search-forward "^\\s-*end\\s-+component\\>" nil t))
12848 ;; component instantiation
12849 ((looking-at
12850 (concat
fda91268
RZ
12851 "^\\s-*\\w+\\s-*:[ \t\n\r\f]*"
12852 "\\(\\(component\\|configuration\\|entity\\)[ \t\n\r\f]+\\)?"
12853 "\\w+\\(\\s-*(\\w+)\\)?[ \t\n\r\f]*"
12854 "\\(generic\\|port\\)\\s-+map[ \t\n\r\f]*("))
3dcb36b7
JB
12855 (goto-char (match-end 0))
12856 (backward-char)
12857 (forward-sexp)
12858 (setq pos (point))
12859 (vhdl-forward-syntactic-ws)
fda91268 12860 (when (looking-at "port\\s-+map[ \t\n\r\f]*(")
3dcb36b7
JB
12861 (goto-char (match-end 0))
12862 (backward-char)
12863 (forward-sexp)
12864 (setq pos (point)))
12865 (goto-char pos))
12866 ;; subprogram declaration/body
12867 ((looking-at "^\\s-*\\(function\\|procedure\\)\\s-+\\(\\w+\\|\".+\"\\)")
12868 (goto-char (match-end 0))
12869 (vhdl-forward-syntactic-ws)
12870 (when (looking-at "(")
12871 (forward-sexp))
12872 (while (and (re-search-forward "\\(;\\)\\|\\(\\<is\\>\\)" nil t)
12873 (vhdl-in-literal)))
12874 ;; subprogram body
12875 (when (match-string 2)
12876 (re-search-forward "^\\s-*\\<begin\\>" nil t)
12877 (backward-word 1)
12878 (vhdl-forward-sexp)))
12879 ;; block (recursive)
12880 ((looking-at "^\\s-*\\w+\\s-*:\\s-*block\\>")
12881 (goto-char (match-end 0))
12882 (while (and (re-search-forward "^\\s-*\\(\\(\\w+\\s-*:\\s-*block\\>\\)\\|\\(end\\s-+block\\>\\)\\)" nil t)
12883 (match-beginning 2))
12884 (vhdl-hs-forward-sexp-func count)))
12885 ;; process
12886 ((looking-at "^\\s-*\\(\\w+\\s-*:\\s-*\\)?process\\>")
12887 (re-search-forward "^\\s-*end\\s-+process\\>" nil t))
12888 ;; configuration declaration
12889 ((looking-at "^\\s-*configuration\\>")
12890 (forward-word 4)
12891 (vhdl-forward-sexp))
12892 (t (goto-char pos))))))
5eabfe72
KH
12893
12894(defun vhdl-hideshow-init ()
12895 "Initialize `hideshow'."
3dcb36b7
JB
12896 (when vhdl-hideshow-menu
12897 (vhdl-hs-minor-mode 1)))
12898
12899(defun vhdl-hs-minor-mode (&optional arg)
12900 "Toggle hideshow minor mode and update menu bar."
12901 (interactive "P")
12902 (require 'hideshow)
12903 ;; check for hideshow version 5.x
12904 (if (not (boundp 'hs-block-start-mdata-select))
12905 (vhdl-warning-when-idle "Install included `hideshow.el' patch first (see INSTALL file)")
12906 ;; initialize hideshow
12907 (unless (assoc 'vhdl-mode hs-special-modes-alist)
12908 (setq hs-special-modes-alist
12909 (cons (list 'vhdl-mode vhdl-hs-start-regexp nil "--\\( \\|$\\)"
12910 'vhdl-hs-forward-sexp-func nil)
12911 hs-special-modes-alist)))
175069ef 12912 (if (featurep 'xemacs) (make-local-hook 'hs-minor-mode-hook))
3dcb36b7 12913 (if vhdl-hide-all-init
175069ef
SM
12914 (add-hook 'hs-minor-mode-hook 'hs-hide-all nil t)
12915 (remove-hook 'hs-minor-mode-hook 'hs-hide-all t))
3dcb36b7 12916 (hs-minor-mode arg)
56eb0904 12917 (force-mode-line-update))) ; hack to update menu bar
5eabfe72
KH
12918
12919
12920;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12921;;; Font locking
12922;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
12923;; (using `font-lock.el')
12924
5eabfe72 12925;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7 12926;; Help functions
5eabfe72
KH
12927
12928(defun vhdl-within-translate-off ()
12929 "Return point if within translate-off region, else nil."
12930 (and (save-excursion
12931 (re-search-backward
12932 "^\\s-*--\\s-*pragma\\s-*translate_\\(on\\|off\\)\\s-*\n" nil t))
12933 (equal "off" (match-string 1))
12934 (point)))
12935
12936(defun vhdl-start-translate-off (limit)
12937 "Return point before translate-off pragma if before LIMIT, else nil."
12938 (when (re-search-forward
12939 "^\\s-*--\\s-*pragma\\s-*translate_off\\s-*\n" limit t)
12940 (match-beginning 0)))
12941
12942(defun vhdl-end-translate-off (limit)
12943 "Return point after translate-on pragma if before LIMIT, else nil."
12944 (re-search-forward "^\\s-*--\\s-*pragma\\s-*translate_on\\s-*\n" limit t))
12945
12946(defun vhdl-match-translate-off (limit)
12947 "Match a translate-off block, setting match-data and returning t, else nil."
12948 (when (< (point) limit)
12949 (let ((start (or (vhdl-within-translate-off)
12950 (vhdl-start-translate-off limit)))
12951 (case-fold-search t))
12952 (when start
12953 (let ((end (or (vhdl-end-translate-off limit) limit)))
12954 (set-match-data (list start end))
12955 (goto-char end))))))
12956
12957(defun vhdl-font-lock-match-item (limit)
a4c6cfad 12958 "Match, and move over, any declaration item after point. Adapted from
5eabfe72
KH
12959`font-lock-match-c-style-declaration-item-and-skip-to-next'."
12960 (condition-case nil
12961 (save-restriction
12962 (narrow-to-region (point-min) limit)
12963 ;; match item
3dcb36b7 12964 (when (looking-at "\\s-*\\([a-zA-Z]\\w*\\)")
5eabfe72
KH
12965 (save-match-data
12966 (goto-char (match-end 1))
12967 ;; move to next item
0a2e512a
RF
12968 (if (looking-at "\\(\\s-*,\\)")
12969 (goto-char (match-end 1))
5eabfe72
KH
12970 (end-of-line) t))))
12971 (error t)))
12972
12973;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
12974;; Syntax definitions
12975
5eabfe72
KH
12976(defconst vhdl-font-lock-syntactic-keywords
12977 '(("\\(\'\\).\\(\'\\)" (1 (7 . ?\')) (2 (7 . ?\'))))
12978 "Mark single quotes as having string quote syntax in 'c' instances.")
12979
d2ddb974
KH
12980(defvar vhdl-font-lock-keywords nil
12981 "Regular expressions to highlight in VHDL Mode.")
12982
3dcb36b7
JB
12983(defvar vhdl-font-lock-keywords-0
12984 ;; set in `vhdl-font-lock-init' because dependent on user options
d2ddb974 12985 "For consideration as a value of `vhdl-font-lock-keywords'.
5eabfe72 12986This does highlighting of template prompts and directives (pragmas).")
d2ddb974 12987
5eabfe72 12988(defvar vhdl-font-lock-keywords-1 nil
3dcb36b7 12989 ;; set in `vhdl-font-lock-init' because dependent on user options
5eabfe72
KH
12990 "For consideration as a value of `vhdl-font-lock-keywords'.
12991This does highlighting of keywords and standard identifiers.")
12992
12993(defconst vhdl-font-lock-keywords-2
d2ddb974
KH
12994 (list
12995 ;; highlight names of units, subprograms, and components when declared
12996 (list
12997 (concat
12998 "^\\s-*\\("
3dcb36b7
JB
12999 "architecture\\|configuration\\|entity\\|package\\(\\s-+body\\)?\\|"
13000 "\\(\\(impure\\|pure\\)\\s-+\\)?function\\|procedure\\|component"
d2ddb974 13001 "\\)\\s-+\\(\\w+\\)")
5eabfe72
KH
13002 5 'font-lock-function-name-face)
13003
13004 ;; highlight entity names of architectures and configurations
13005 (list
13006 "^\\s-*\\(architecture\\|configuration\\)\\s-+\\w+\\s-+of\\s-+\\(\\w+\\)"
13007 2 'font-lock-function-name-face)
d2ddb974
KH
13008
13009 ;; highlight labels of common constructs
13010 (list
13011 (concat
fda91268 13012 "^\\s-*\\(\\w+\\)\\s-*:[ \t\n\r\f]*\\(\\("
3dcb36b7
JB
13013 "assert\\|block\\|case\\|exit\\|for\\|if\\|loop\\|next\\|null\\|"
13014 "postponed\\|process\\|"
5eabfe72
KH
13015 (when (vhdl-standard-p 'ams) "procedural\\|")
13016 "with\\|while"
0a2e512a 13017 "\\)\\>\\|\\w+\\s-*\\(([^\n]*)\\|\\.\\w+\\)*\\s-*<=\\)")
d2ddb974
KH
13018 1 'font-lock-function-name-face)
13019
5eabfe72 13020 ;; highlight label and component name of component instantiations
d2ddb974 13021 (list
5eabfe72 13022 (concat
fda91268
RZ
13023 "^\\s-*\\(\\w+\\)\\s-*:[ \t\n\r\f]*\\(\\w+\\)[ \t\n\r\f]*"
13024 "\\(--[^\n]*[ \t\n\r\f]+\\)*\\(generic\\|port\\)\\s-+map\\>")
3dcb36b7
JB
13025 '(1 font-lock-function-name-face) '(2 font-lock-function-name-face))
13026
13027 ;; highlight label and instantiated unit of component instantiations
13028 (list
13029 (concat
fda91268 13030 "^\\s-*\\(\\w+\\)\\s-*:[ \t\n\r\f]*"
3dcb36b7
JB
13031 "\\(component\\|configuration\\|entity\\)\\s-+"
13032 "\\(\\w+\\)\\(\\.\\(\\w+\\)\\)?\\(\\s-*(\\(\\w+\\))\\)?")
13033 '(1 font-lock-function-name-face) '(3 font-lock-function-name-face)
13034 '(5 font-lock-function-name-face nil t)
13035 '(7 font-lock-function-name-face nil t))
d2ddb974
KH
13036
13037 ;; highlight names and labels at end of constructs
13038 (list
13039 (concat
5eabfe72
KH
13040 "^\\s-*end\\s-+\\(\\("
13041 "architecture\\|block\\|case\\|component\\|configuration\\|entity\\|"
3dcb36b7
JB
13042 "for\\|function\\|generate\\|if\\|loop\\|package\\(\\s-+body\\)?\\|"
13043 "procedure\\|\\(postponed\\s-+\\)?process\\|"
5eabfe72
KH
13044 (when (vhdl-standard-p 'ams) "procedural\\|")
13045 "units"
3dcb36b7 13046 "\\)\\s-+\\)?\\(\\w*\\)")
5eabfe72
KH
13047 5 'font-lock-function-name-face)
13048
13049 ;; highlight labels in exit and next statements
13050 (list
13051 (concat
13052 "^\\s-*\\(\\w+\\s-*:\\s-*\\)?\\(exit\\|next\\)\\s-+\\(\\w*\\)")
13053 3 'font-lock-function-name-face)
13054
13055 ;; highlight entity name in attribute specifications
13056 (list
13057 (concat
13058 "^\\s-*attribute\\s-+\\w+\\s-+of\\s-+\\(\\w+\\(,\\s-*\\w+\\)*\\)\\s-*:")
13059 1 'font-lock-function-name-face)
13060
3dcb36b7
JB
13061 ;; highlight labels in block and component specifications
13062 (list
13063 (concat
13064 "^\\s-*for\\s-+\\(\\w+\\(,\\s-*\\w+\\)*\\)\\>\\s-*"
fda91268 13065 "\\(:[ \t\n\r\f]*\\(\\w+\\)\\|[^i \t]\\)")
3dcb36b7
JB
13066 '(1 font-lock-function-name-face) '(4 font-lock-function-name-face nil t))
13067
13068 ;; highlight names in library clauses
13069 (list "^\\s-*library\\>"
13070 '(vhdl-font-lock-match-item nil nil (1 font-lock-function-name-face)))
13071
13072 ;; highlight names in use clauses
5eabfe72
KH
13073 (list
13074 (concat
3dcb36b7
JB
13075 "\\<use\\s-+\\(\\(entity\\|configuration\\)\\s-+\\)?"
13076 "\\(\\w+\\)\\(\\.\\(\\w+\\)\\)?\\((\\(\\w+\\))\\)?")
13077 '(3 font-lock-function-name-face) '(5 font-lock-function-name-face nil t)
13078 '(7 font-lock-function-name-face nil t))
5eabfe72
KH
13079
13080 ;; highlight attribute name in attribute declarations/specifications
13081 (list
13082 (concat
13083 "^\\s-*attribute\\s-+\\(\\w+\\)")
0a2e512a 13084 1 'vhdl-font-lock-attribute-face)
5eabfe72
KH
13085
13086 ;; highlight type/nature name in (sub)type/(sub)nature declarations
13087 (list
13088 (concat
fda91268
RZ
13089 "^\\s-*\\(\\(sub\\)?\\(nature\\|type\\)\\|end\\s-+\\(record\\|protected\\)\\)\\s-+\\(\\w+\\)")
13090 5 'font-lock-type-face)
5eabfe72
KH
13091
13092 ;; highlight signal/variable/constant declaration names
13093 (list "\\(:[^=]\\)"
13094 '(vhdl-font-lock-match-item
13095 (progn (goto-char (match-beginning 1))
13096 (skip-syntax-backward " ")
13097 (skip-syntax-backward "w_")
13098 (skip-syntax-backward " ")
13099 (while (= (preceding-char) ?,)
13100 (backward-char 1)
13101 (skip-syntax-backward " ")
13102 (skip-syntax-backward "w_")
13103 (skip-syntax-backward " ")))
13104; (skip-chars-backward "^-(\n\";")
13105 (goto-char (match-end 1)) (1 font-lock-variable-name-face)))
13106
3dcb36b7
JB
13107 ;; highlight formal parameters in component instantiations and subprogram
13108 ;; calls
13109 (list "\\(=>\\)"
13110 '(vhdl-font-lock-match-item
13111 (progn (goto-char (match-beginning 1))
13112 (skip-syntax-backward " ")
13113 (while (= (preceding-char) ?\)) (backward-sexp))
13114 (skip-syntax-backward "w_")
13115 (skip-syntax-backward " ")
0a2e512a 13116 (when (memq (preceding-char) '(?n ?N ?|))
3dcb36b7
JB
13117 (goto-char (point-max))))
13118 (goto-char (match-end 1)) (1 font-lock-variable-name-face)))
13119
13120 ;; highlight alias/group/quantity declaration names and for-loop/-generate
13121 ;; variables
13122 (list "\\<\\(alias\\|for\\|group\\|quantity\\)\\s-+\\w+\\s-+\\(across\\|in\\|is\\)\\>"
5eabfe72
KH
13123 '(vhdl-font-lock-match-item
13124 (progn (goto-char (match-end 1)) (match-beginning 2))
13125 nil (1 font-lock-variable-name-face)))
d2ddb974 13126 )
5eabfe72
KH
13127 "For consideration as a value of `vhdl-font-lock-keywords'.
13128This does context sensitive highlighting of names and labels.")
d2ddb974 13129
5eabfe72 13130(defvar vhdl-font-lock-keywords-3 nil
3dcb36b7 13131 ;; set in `vhdl-font-lock-init' because dependent on user options
d2ddb974 13132 "For consideration as a value of `vhdl-font-lock-keywords'.
5eabfe72
KH
13133This does highlighting of words with special syntax.")
13134
13135(defvar vhdl-font-lock-keywords-4 nil
3dcb36b7 13136 ;; set in `vhdl-font-lock-init' because dependent on user options
d2ddb974 13137 "For consideration as a value of `vhdl-font-lock-keywords'.
5eabfe72 13138This does highlighting of additional reserved words.")
d2ddb974 13139
5eabfe72
KH
13140(defconst vhdl-font-lock-keywords-5
13141 ;; background highlight translate-off regions
0a2e512a 13142 '((vhdl-match-translate-off (0 vhdl-font-lock-translate-off-face append)))
5eabfe72
KH
13143 "For consideration as a value of `vhdl-font-lock-keywords'.
13144This does background highlighting of translate-off regions.")
13145
13146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
13147;; Font and color definitions
13148
0a2e512a 13149(defvar vhdl-font-lock-prompt-face 'vhdl-font-lock-prompt-face
d2ddb974
KH
13150 "Face name to use for prompts.")
13151
0a2e512a 13152(defvar vhdl-font-lock-attribute-face 'vhdl-font-lock-attribute-face
5eabfe72
KH
13153 "Face name to use for standardized attributes.")
13154
0a2e512a 13155(defvar vhdl-font-lock-enumvalue-face 'vhdl-font-lock-enumvalue-face
5eabfe72 13156 "Face name to use for standardized enumeration values.")
d2ddb974 13157
0a2e512a 13158(defvar vhdl-font-lock-function-face 'vhdl-font-lock-function-face
5eabfe72 13159 "Face name to use for standardized functions and packages.")
d2ddb974 13160
0a2e512a 13161(defvar vhdl-font-lock-directive-face 'vhdl-font-lock-directive-face
5eabfe72 13162 "Face name to use for directives.")
d2ddb974 13163
0a2e512a 13164(defvar vhdl-font-lock-reserved-words-face 'vhdl-font-lock-reserved-words-face
5eabfe72 13165 "Face name to use for additional reserved words.")
d2ddb974 13166
0a2e512a 13167(defvar vhdl-font-lock-translate-off-face 'vhdl-font-lock-translate-off-face
5eabfe72 13168 "Face name to use for translate-off regions.")
d2ddb974 13169
5eabfe72
KH
13170;; face names to use for words with special syntax.
13171(let ((syntax-alist vhdl-special-syntax-alist)
13172 name)
13173 (while syntax-alist
0a2e512a
RF
13174 (setq name (vhdl-function-name
13175 "vhdl-font-lock" (nth 0 (car syntax-alist)) "face"))
d4a5b644
GM
13176 (eval `(defvar ,name ',name
13177 ,(concat "Face name to use for "
13178 (nth 0 (car syntax-alist)) ".")))
5eabfe72
KH
13179 (setq syntax-alist (cdr syntax-alist))))
13180
3dcb36b7 13181(defgroup vhdl-highlight-faces nil
5eabfe72
KH
13182 "Faces for highlighting."
13183 :group 'vhdl-highlight)
d2ddb974 13184
3dcb36b7
JB
13185;; add faces used from `font-lock'
13186(custom-add-to-group
13187 'vhdl-highlight-faces 'font-lock-comment-face 'custom-face)
13188(custom-add-to-group
13189 'vhdl-highlight-faces 'font-lock-string-face 'custom-face)
13190(custom-add-to-group
13191 'vhdl-highlight-faces 'font-lock-keyword-face 'custom-face)
13192(custom-add-to-group
13193 'vhdl-highlight-faces 'font-lock-type-face 'custom-face)
13194(custom-add-to-group
13195 'vhdl-highlight-faces 'font-lock-function-name-face 'custom-face)
13196(custom-add-to-group
13197 'vhdl-highlight-faces 'font-lock-variable-name-face 'custom-face)
13198
0a2e512a 13199(defface vhdl-font-lock-prompt-face
f47877ee 13200 '((((min-colors 88) (class color) (background light))
ea81d57e 13201 (:foreground "Red1" :bold t))
f47877ee 13202 (((class color) (background light)) (:foreground "Red" :bold t))
3dcb36b7 13203 (((class color) (background dark)) (:foreground "Pink" :bold t))
d2ddb974 13204 (t (:inverse-video t)))
5eabfe72 13205 "Font lock mode face used to highlight prompts."
fa6674e3 13206 :group 'vhdl-highlight-faces)
d2ddb974 13207
0a2e512a 13208(defface vhdl-font-lock-attribute-face
5eabfe72
KH
13209 '((((class color) (background light)) (:foreground "Orchid"))
13210 (((class color) (background dark)) (:foreground "LightSteelBlue"))
3dcb36b7 13211 (t (:italic t :bold t)))
5eabfe72 13212 "Font lock mode face used to highlight standardized attributes."
fa6674e3 13213 :group 'vhdl-highlight-faces)
d2ddb974 13214
0a2e512a 13215(defface vhdl-font-lock-enumvalue-face
3dcb36b7 13216 '((((class color) (background light)) (:foreground "SaddleBrown"))
5eabfe72 13217 (((class color) (background dark)) (:foreground "BurlyWood"))
3dcb36b7 13218 (t (:italic t :bold t)))
5eabfe72 13219 "Font lock mode face used to highlight standardized enumeration values."
fa6674e3 13220 :group 'vhdl-highlight-faces)
d2ddb974 13221
0a2e512a 13222(defface vhdl-font-lock-function-face
3dcb36b7 13223 '((((class color) (background light)) (:foreground "Cyan4"))
5eabfe72 13224 (((class color) (background dark)) (:foreground "Orchid1"))
3dcb36b7 13225 (t (:italic t :bold t)))
5eabfe72 13226 "Font lock mode face used to highlight standardized functions and packages."
fa6674e3 13227 :group 'vhdl-highlight-faces)
d2ddb974 13228
0a2e512a 13229(defface vhdl-font-lock-directive-face
5eabfe72
KH
13230 '((((class color) (background light)) (:foreground "CadetBlue"))
13231 (((class color) (background dark)) (:foreground "Aquamarine"))
3dcb36b7 13232 (t (:italic t :bold t)))
5eabfe72 13233 "Font lock mode face used to highlight directives."
fa6674e3 13234 :group 'vhdl-highlight-faces)
d2ddb974 13235
0a2e512a 13236(defface vhdl-font-lock-reserved-words-face
3dcb36b7 13237 '((((class color) (background light)) (:foreground "Orange" :bold t))
5bb5087f 13238 (((min-colors 88) (class color) (background dark))
ea81d57e 13239 (:foreground "Yellow1" :bold t))
3dcb36b7 13240 (((class color) (background dark)) (:foreground "Yellow" :bold t))
d2ddb974 13241 (t ()))
5eabfe72 13242 "Font lock mode face used to highlight additional reserved words."
fa6674e3 13243 :group 'vhdl-highlight-faces)
d2ddb974 13244
0a2e512a 13245(defface vhdl-font-lock-translate-off-face
5eabfe72
KH
13246 '((((class color) (background light)) (:background "LightGray"))
13247 (((class color) (background dark)) (:background "DimGray"))
d2ddb974 13248 (t ()))
5eabfe72 13249 "Font lock mode face used to background highlight translate-off regions."
fa6674e3 13250 :group 'vhdl-highlight-faces)
d2ddb974 13251
5eabfe72
KH
13252;; font lock mode faces used to highlight words with special syntax.
13253(let ((syntax-alist vhdl-special-syntax-alist))
13254 (while syntax-alist
0a2e512a
RF
13255 (eval `(defface ,(vhdl-function-name
13256 "vhdl-font-lock" (caar syntax-alist) "face")
d4a5b644
GM
13257 '((((class color) (background light))
13258 (:foreground ,(nth 2 (car syntax-alist))))
13259 (((class color) (background dark))
13260 (:foreground ,(nth 3 (car syntax-alist))))
13261 (t ()))
13262 ,(concat "Font lock mode face used to highlight "
13263 (nth 0 (car syntax-alist)) ".")
fa6674e3 13264 :group 'vhdl-highlight-faces))
5eabfe72
KH
13265 (setq syntax-alist (cdr syntax-alist))))
13266
13267;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
13268;; Font lock initialization
13269
13270(defun vhdl-font-lock-init ()
5eabfe72 13271 "Initialize fontification."
0a2e512a 13272 ;; highlight template prompts and directives
3dcb36b7
JB
13273 (setq vhdl-font-lock-keywords-0
13274 (list (list (concat "\\(^\\|[ \t(.']\\)\\(<"
13275 vhdl-template-prompt-syntax ">\\)")
0a2e512a 13276 2 'vhdl-font-lock-prompt-face t)
3dcb36b7
JB
13277 (list (concat "--\\s-*"
13278 vhdl-directive-keywords-regexp "\\s-+\\(.*\\)$")
0a2e512a
RF
13279 2 'vhdl-font-lock-directive-face t)
13280 ;; highlight c-preprocessor directives
13281 (list "^#[ \t]*\\(\\w+\\)\\([ \t]+\\(\\w+\\)\\)?"
13282 '(1 font-lock-builtin-face)
13283 '(3 font-lock-variable-name-face nil t))))
5eabfe72
KH
13284 ;; highlight keywords and standardized types, attributes, enumeration
13285 ;; values, and subprograms
13286 (setq vhdl-font-lock-keywords-1
13287 (list
0a2e512a
RF
13288 (list (concat "'" vhdl-attributes-regexp)
13289 1 'vhdl-font-lock-attribute-face)
5eabfe72 13290 (list vhdl-types-regexp 1 'font-lock-type-face)
0a2e512a
RF
13291 (list vhdl-functions-regexp 1 'vhdl-font-lock-function-face)
13292 (list vhdl-packages-regexp 1 'vhdl-font-lock-function-face)
13293 (list vhdl-enum-values-regexp 1 'vhdl-font-lock-enumvalue-face)
fda91268 13294 (list vhdl-constants-regexp 1 'font-lock-constant-face)
5eabfe72
KH
13295 (list vhdl-keywords-regexp 1 'font-lock-keyword-face)))
13296 ;; highlight words with special syntax.
13297 (setq vhdl-font-lock-keywords-3
13298 (let ((syntax-alist vhdl-special-syntax-alist)
13299 keywords)
13300 (while syntax-alist
13301 (setq keywords
13302 (cons
fda91268 13303 (list (concat "\\(" (nth 1 (car syntax-alist)) "\\)") 1
5eabfe72 13304 (vhdl-function-name
fda91268
RZ
13305 "vhdl-font-lock" (nth 0 (car syntax-alist)) "face")
13306 (nth 4 (car syntax-alist)))
5eabfe72
KH
13307 keywords))
13308 (setq syntax-alist (cdr syntax-alist)))
13309 keywords))
13310 ;; highlight additional reserved words
13311 (setq vhdl-font-lock-keywords-4
0a2e512a
RF
13312 (list (list vhdl-reserved-words-regexp 1
13313 'vhdl-font-lock-reserved-words-face)))
5eabfe72 13314 ;; highlight everything together
d2ddb974 13315 (setq vhdl-font-lock-keywords
5eabfe72
KH
13316 (append
13317 vhdl-font-lock-keywords-0
13318 (when vhdl-highlight-keywords vhdl-font-lock-keywords-1)
13319 (when (or vhdl-highlight-forbidden-words
13320 vhdl-highlight-verilog-keywords) vhdl-font-lock-keywords-4)
13321 (when vhdl-highlight-special-words vhdl-font-lock-keywords-3)
13322 (when vhdl-highlight-names vhdl-font-lock-keywords-2)
13323 (when vhdl-highlight-translate-off vhdl-font-lock-keywords-5))))
13324
13325;; initialize fontification for VHDL Mode
13326(vhdl-font-lock-init)
13327
13328(defun vhdl-fontify-buffer ()
13329 "Re-initialize fontification and fontify buffer."
13330 (interactive)
13331 (setq font-lock-defaults
cf38dd42
SM
13332 `(vhdl-font-lock-keywords
13333 nil ,(not vhdl-highlight-case-sensitive) ((?\_ . "w"))
13334 beginning-of-line))
5eabfe72
KH
13335 (when (fboundp 'font-lock-unset-defaults)
13336 (font-lock-unset-defaults)) ; not implemented in XEmacs
0a2e512a 13337 (font-lock-set-defaults)
3dcb36b7
JB
13338 (font-lock-mode nil)
13339 (font-lock-mode t))
5eabfe72
KH
13340
13341;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7877f373 13342;; Initialization for PostScript printing
5eabfe72
KH
13343
13344(defun vhdl-ps-print-settings ()
7877f373 13345 "Initialize custom face and page settings for PostScript printing."
5eabfe72
KH
13346 ;; define custom face settings
13347 (unless (or (not vhdl-print-customize-faces)
d2ddb974
KH
13348 ps-print-color-p)
13349 (set (make-local-variable 'ps-bold-faces)
0a2e512a
RF
13350 '(font-lock-keyword-face
13351 font-lock-type-face
13352 vhdl-font-lock-attribute-face
13353 vhdl-font-lock-enumvalue-face
13354 vhdl-font-lock-directive-face))
d2ddb974
KH
13355 (set (make-local-variable 'ps-italic-faces)
13356 '(font-lock-comment-face
0a2e512a
RF
13357 font-lock-function-name-face
13358 font-lock-type-face
13359 vhdl-font-lock-attribute-face
13360 vhdl-font-lock-enumvalue-face
13361 vhdl-font-lock-directive-face))
d2ddb974
KH
13362 (set (make-local-variable 'ps-underlined-faces)
13363 '(font-lock-string-face))
5eabfe72 13364 (setq ps-always-build-face-reference t))
d2ddb974
KH
13365 ;; define page settings, so that a line containing 79 characters (default)
13366 ;; fits into one column
5eabfe72
KH
13367 (when vhdl-print-two-column
13368 (set (make-local-variable 'ps-landscape-mode) t)
13369 (set (make-local-variable 'ps-number-of-columns) 2)
13370 (set (make-local-variable 'ps-font-size) 7.0)
13371 (set (make-local-variable 'ps-header-title-font-size) 10.0)
13372 (set (make-local-variable 'ps-header-font-size) 9.0)
13373 (set (make-local-variable 'ps-header-offset) 12.0)
13374 (when (eq ps-paper-type 'letter)
13375 (set (make-local-variable 'ps-inter-column) 40.0)
13376 (set (make-local-variable 'ps-left-margin) 40.0)
13377 (set (make-local-variable 'ps-right-margin) 40.0))))
13378
13379(defun vhdl-ps-print-init ()
7877f373 13380 "Initialize PostScript printing."
f8246027 13381 (if (featurep 'xemacs)
3dcb36b7
JB
13382 (when (boundp 'ps-print-color-p)
13383 (vhdl-ps-print-settings))
175069ef
SM
13384 (if (featurep 'xemacs) (make-local-hook 'ps-print-hook))
13385 (add-hook 'ps-print-hook 'vhdl-ps-print-settings nil t)))
5eabfe72
KH
13386
13387
13388;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13389;;; Hierarchy browser (using `speedbar.el')
13390;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13391;; Allows displaying the hierarchy of all VHDL design units contained in a
13392;; directory by using the speedbar.
13393
13394;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13395;; Variables
13396
13397(defvar vhdl-entity-alist nil
3dcb36b7
JB
13398 "Cache with entities and corresponding architectures for each
13399project/directory.")
333f9019 13400;; structure: (parenthesized expression means list of such entries)
3dcb36b7
JB
13401;; (cache-key
13402;; (ent-key ent-name ent-file ent-line
13403;; (arch-key arch-name arch-file arch-line
13404;; (inst-key inst-name inst-file inst-line inst-comp-name inst-ent-key
0a2e512a
RF
13405;; inst-arch-key inst-conf-key inst-lib-key inst-path)
13406;; (lib-name pack-key))
13407;; mra-key (lib-name pack-key))
3dcb36b7
JB
13408
13409(defvar vhdl-config-alist nil
13410 "Cache with configurations for each project/directory.")
333f9019 13411;; structure: (parenthesized expression means list of such entries)
3dcb36b7
JB
13412;; (cache-key
13413;; (conf-key conf-name conf-file conf-line ent-key arch-key
13414;; (inst-key inst-comp-name inst-ent-key inst-arch-key
0a2e512a 13415;; inst-conf-key inst-lib-key)
3dcb36b7 13416;; (lib-name pack-key)))
5eabfe72
KH
13417
13418(defvar vhdl-package-alist nil
3dcb36b7 13419 "Cache with packages for each project/directory.")
333f9019 13420;; structure: (parenthesized expression means list of such entries)
3dcb36b7
JB
13421;; (cache-key
13422;; (pack-key pack-name pack-file pack-line
13423;; (comp-key comp-name comp-file comp-line)
13424;; (func-key func-name func-file func-line)
13425;; (lib-name pack-key)
13426;; pack-body-file pack-body-line
13427;; (func-key func-name func-body-file func-body-line)
13428;; (lib-name pack-key)))
5eabfe72
KH
13429
13430(defvar vhdl-ent-inst-alist nil
3dcb36b7 13431 "Cache with instantiated entities for each project/directory.")
333f9019 13432;; structure: (parenthesized expression means list of such entries)
3dcb36b7 13433;; (cache-key (inst-ent-key))
5eabfe72 13434
3dcb36b7
JB
13435(defvar vhdl-file-alist nil
13436 "Cache with design units in each file for each project/directory.")
333f9019 13437;; structure: (parenthesized expression means list of such entries)
3dcb36b7
JB
13438;; (cache-key
13439;; (file-name (ent-list) (arch-list) (arch-ent-list) (conf-list)
0a2e512a 13440;; (pack-list) (pack-body-list) (inst-list) (inst-ent-list))
5eabfe72 13441
3dcb36b7
JB
13442(defvar vhdl-directory-alist nil
13443 "Cache with source directories for each project.")
333f9019 13444;; structure: (parenthesized expression means list of such entries)
3dcb36b7 13445;; (cache-key (directory))
5eabfe72 13446
3dcb36b7 13447(defvar vhdl-speedbar-shown-unit-alist nil
5eabfe72
KH
13448 "Alist of design units simultaneously open in the current speedbar for each
13449directory and project.")
13450
3dcb36b7
JB
13451(defvar vhdl-speedbar-shown-project-list nil
13452 "List of projects simultaneously open in the current speedbar.")
5eabfe72 13453
3dcb36b7
JB
13454(defvar vhdl-updated-project-list nil
13455 "List of projects and directories with updated files.")
13456
13457(defvar vhdl-modified-file-list nil
13458 "List of modified files to be rescanned for hierarchy updating.")
13459
13460(defvar vhdl-speedbar-hierarchy-depth 0
13461 "Depth of instantiation hierarchy to display.")
13462
13463(defvar vhdl-speedbar-show-projects nil
13464 "Non-nil means project hierarchy is displayed in speedbar, directory
13465hierarchy otherwise.")
13466
13467(defun vhdl-get-end-of-unit ()
13468 "Return position of end of current unit."
13469 (let ((pos (point)))
13470 (save-excursion
13471 (while (and (re-search-forward "^[ \t]*\\(architecture\\|configuration\\|entity\\|package\\)\\>" nil 1)
13472 (save-excursion
13473 (goto-char (match-beginning 0))
13474 (vhdl-backward-syntactic-ws)
13475 (and (/= (preceding-char) ?\;) (not (bobp))))))
13476 (re-search-backward "^[ \t]*end\\>" pos 1)
13477 (point))))
13478
13479(defun vhdl-match-string-downcase (num &optional string)
13480 "Like `match-string-no-properties' with down-casing."
13481 (let ((match (match-string-no-properties num string)))
13482 (and match (downcase match))))
5eabfe72 13483
5eabfe72
KH
13484
13485;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13486;; Scan functions
13487
3dcb36b7 13488(defun vhdl-scan-context-clause ()
97610156 13489 "Scan the context clause that precedes a design unit."
3dcb36b7
JB
13490 (let (lib-alist)
13491 (save-excursion
13492 (when (re-search-backward "^[ \t]*\\(architecture\\|configuration\\|entity\\|package\\)\\>" nil t)
13493 (while (and (re-search-backward "^[ \t]*\\(end\\|use\\)\\>" nil t)
13494 (equal "USE" (upcase (match-string 1))))
fda91268 13495 (when (looking-at "^[ \t]*use[ \t\n\r\f]*\\(\\w+\\)\\.\\(\\w+\\)\\.\\w+")
3dcb36b7
JB
13496 (setq lib-alist (cons (cons (match-string-no-properties 1)
13497 (vhdl-match-string-downcase 2))
13498 lib-alist))))))
13499 lib-alist))
13500
13501(defun vhdl-scan-directory-contents (name &optional project update num-string
13502 non-final)
a4c6cfad 13503 "Scan contents of VHDL files in directory or file pattern NAME."
3dcb36b7 13504 (string-match "\\(.*[/\\]\\)\\(.*\\)" name)
5eabfe72
KH
13505; (unless (file-directory-p (match-string 1 name))
13506; (message "No such directory: \"%s\"" (match-string 1 name)))
3dcb36b7
JB
13507 (let* ((dir-name (match-string 1 name))
13508 (file-pattern (match-string 2 name))
13509 (is-directory (= 0 (length file-pattern)))
5eabfe72 13510 (file-list
3dcb36b7
JB
13511 (if update
13512 (list name)
13513 (if is-directory
13514 (vhdl-get-source-files t dir-name)
13515 (vhdl-directory-files
13516 dir-name t (wildcard-to-regexp file-pattern)))))
13517 (key (or project dir-name))
13518 (file-exclude-regexp
13519 (or (nth 3 (aget vhdl-project-alist project)) ""))
13520 (limit-design-file-size (nth 0 vhdl-speedbar-scan-limit))
13521 (limit-hier-file-size (nth 0 (nth 1 vhdl-speedbar-scan-limit)))
13522 (limit-hier-inst-no (nth 1 (nth 1 vhdl-speedbar-scan-limit)))
13523 ent-alist conf-alist pack-alist ent-inst-list file-alist
13524 tmp-list tmp-entry no-files files-exist big-files)
13525 (when (or project update)
13526 (setq ent-alist (aget vhdl-entity-alist key t)
13527 conf-alist (aget vhdl-config-alist key t)
13528 pack-alist (aget vhdl-package-alist key t)
13529 ent-inst-list (car (aget vhdl-ent-inst-alist key t))
13530 file-alist (aget vhdl-file-alist key t)))
5eabfe72
KH
13531 (when (and (not is-directory) (null file-list))
13532 (message "No such file: \"%s\"" name))
3dcb36b7
JB
13533 (setq files-exist file-list)
13534 (when file-list
13535 (setq no-files (length file-list))
13536 (message "Scanning %s %s\"%s\"..."
13537 (if is-directory "directory" "files") (or num-string "") name)
13538 ;; exclude files
13539 (unless (equal file-exclude-regexp "")
13540 (let ((case-fold-search nil)
13541 file-tmp-list)
13542 (while file-list
13543 (unless (string-match file-exclude-regexp (car file-list))
13544 (setq file-tmp-list (cons (car file-list) file-tmp-list)))
13545 (setq file-list (cdr file-list)))
13546 (setq file-list (nreverse file-tmp-list))))
13547 ;; do for all files
13548 (while file-list
13549 (unless noninteractive
5eabfe72
KH
13550 (message "Scanning %s %s\"%s\"... (%2d%s)"
13551 (if is-directory "directory" "files")
13552 (or num-string "") name
3dcb36b7
JB
13553 (/ (* 100 (- no-files (length file-list))) no-files) "%"))
13554 (let ((file-name (abbreviate-file-name (car file-list)))
13555 ent-list arch-list arch-ent-list conf-list
13556 pack-list pack-body-list inst-list inst-ent-list)
13557 ;; scan file
13558 (vhdl-visit-file
13559 file-name nil
13560 (vhdl-prepare-search-2
13561 (save-excursion
13562 ;; scan for design units
13563 (if (and limit-design-file-size
13564 (< limit-design-file-size (buffer-size)))
13565 (progn (message "WARNING: Scan limit (design units: file size) reached in file:\n \"%s\"" file-name)
13566 (setq big-files t))
13567 ;; scan for entities
13568 (goto-char (point-min))
fda91268 13569 (while (re-search-forward "^[ \t]*entity[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t)
3dcb36b7
JB
13570 (let* ((ent-name (match-string-no-properties 1))
13571 (ent-key (downcase ent-name))
13572 (ent-entry (aget ent-alist ent-key t))
3dcb36b7
JB
13573 (lib-alist (vhdl-scan-context-clause)))
13574 (if (nth 1 ent-entry)
13575 (vhdl-warning-when-idle
13576 "Entity declared twice (used 1.): \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)"
13577 ent-name (nth 1 ent-entry) (nth 2 ent-entry)
13578 file-name (vhdl-current-line))
13579 (setq ent-list (cons ent-key ent-list))
13580 (aput 'ent-alist ent-key
13581 (list ent-name file-name (vhdl-current-line)
0a2e512a
RF
13582 (nth 3 ent-entry) (nth 4 ent-entry)
13583 lib-alist)))))
3dcb36b7
JB
13584 ;; scan for architectures
13585 (goto-char (point-min))
fda91268 13586 (while (re-search-forward "^[ \t]*architecture[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+of[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t)
3dcb36b7
JB
13587 (let* ((arch-name (match-string-no-properties 1))
13588 (arch-key (downcase arch-name))
13589 (ent-name (match-string-no-properties 2))
13590 (ent-key (downcase ent-name))
13591 (ent-entry (aget ent-alist ent-key t))
13592 (arch-alist (nth 3 ent-entry))
13593 (arch-entry (aget arch-alist arch-key t))
13594 (lib-arch-alist (vhdl-scan-context-clause)))
13595 (if arch-entry
13596 (vhdl-warning-when-idle
13597 "Architecture declared twice (used 1.): \"%s\" of \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)"
13598 arch-name ent-name (nth 1 arch-entry)
13599 (nth 2 arch-entry) file-name (vhdl-current-line))
13600 (setq arch-list (cons arch-key arch-list)
13601 arch-ent-list (cons ent-key arch-ent-list))
13602 (aput 'arch-alist arch-key
13603 (list arch-name file-name (vhdl-current-line) nil
13604 lib-arch-alist))
13605 (aput 'ent-alist ent-key
13606 (list (or (nth 0 ent-entry) ent-name)
13607 (nth 1 ent-entry) (nth 2 ent-entry)
13608 (vhdl-sort-alist arch-alist)
0a2e512a 13609 arch-key (nth 5 ent-entry))))))
3dcb36b7
JB
13610 ;; scan for configurations
13611 (goto-char (point-min))
fda91268 13612 (while (re-search-forward "^[ \t]*configuration[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+of[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t)
3dcb36b7
JB
13613 (let* ((conf-name (match-string-no-properties 1))
13614 (conf-key (downcase conf-name))
13615 (conf-entry (aget conf-alist conf-key t))
13616 (ent-name (match-string-no-properties 2))
13617 (ent-key (downcase ent-name))
13618 (lib-alist (vhdl-scan-context-clause))
13619 (conf-line (vhdl-current-line))
13620 (end-of-unit (vhdl-get-end-of-unit))
13621 arch-key comp-conf-list inst-key-list
13622 inst-comp-key inst-ent-key inst-arch-key
13623 inst-conf-key inst-lib-key)
fda91268 13624 (when (vhdl-re-search-forward "\\<for[ \t\n\r\f]+\\(\\w+\\)")
3dcb36b7
JB
13625 (setq arch-key (vhdl-match-string-downcase 1)))
13626 (if conf-entry
13627 (vhdl-warning-when-idle
13628 "Configuration declared twice (used 1.): \"%s\" of \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)"
13629 conf-name ent-name (nth 1 conf-entry)
13630 (nth 2 conf-entry) file-name conf-line)
13631 (setq conf-list (cons conf-key conf-list))
13632 ;; scan for subconfigurations and subentities
fda91268 13633 (while (re-search-forward "^[ \t]*for[ \t\n\r\f]+\\(\\w+\\([ \t\n\r\f]*,[ \t\n\r\f]*\\w+\\)*\\)[ \t\n\r\f]*:[ \t\n\r\f]*\\(\\w+\\)[ \t\n\r\f]+" end-of-unit t)
3dcb36b7
JB
13634 (setq inst-comp-key (vhdl-match-string-downcase 3)
13635 inst-key-list (split-string
13636 (vhdl-match-string-downcase 1)
fda91268 13637 "[ \t\n\r\f]*,[ \t\n\r\f]*"))
3dcb36b7 13638 (vhdl-forward-syntactic-ws)
fda91268 13639 (when (looking-at "use[ \t\n\r\f]+\\(\\(entity\\)\\|configuration\\)[ \t\n\r\f]+\\(\\w+\\)\\.\\(\\w+\\)[ \t\n\r\f]*\\((\\(\\w+\\))\\)?")
3dcb36b7
JB
13640 (setq
13641 inst-lib-key (vhdl-match-string-downcase 3)
13642 inst-ent-key (and (match-string 2)
13643 (vhdl-match-string-downcase 4))
13644 inst-arch-key (and (match-string 2)
13645 (vhdl-match-string-downcase 6))
13646 inst-conf-key (and (not (match-string 2))
13647 (vhdl-match-string-downcase 4)))
13648 (while inst-key-list
13649 (setq comp-conf-list
13650 (cons (list (car inst-key-list)
13651 inst-comp-key inst-ent-key
13652 inst-arch-key inst-conf-key
13653 inst-lib-key)
13654 comp-conf-list))
13655 (setq inst-key-list (cdr inst-key-list)))))
13656 (aput 'conf-alist conf-key
13657 (list conf-name file-name conf-line ent-key
13658 arch-key comp-conf-list lib-alist)))))
13659 ;; scan for packages
13660 (goto-char (point-min))
fda91268 13661 (while (re-search-forward "^[ \t]*package[ \t\n\r\f]+\\(body[ \t\n\r\f]+\\)?\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t)
3dcb36b7
JB
13662 (let* ((pack-name (match-string-no-properties 2))
13663 (pack-key (downcase pack-name))
13664 (is-body (match-string-no-properties 1))
13665 (pack-entry (aget pack-alist pack-key t))
13666 (pack-line (vhdl-current-line))
13667 (end-of-unit (vhdl-get-end-of-unit))
13668 comp-name func-name comp-alist func-alist lib-alist)
13669 (if (if is-body (nth 6 pack-entry) (nth 1 pack-entry))
13670 (vhdl-warning-when-idle
13671 "Package%s declared twice (used 1.): \"%s\"\n 1. in \"%s\" (line %d)\n 2. in \"%s\" (line %d)"
13672 (if is-body " body" "") pack-name
13673 (if is-body (nth 6 pack-entry) (nth 1 pack-entry))
13674 (if is-body (nth 7 pack-entry) (nth 2 pack-entry))
13675 file-name (vhdl-current-line))
13676 ;; scan for context clauses
13677 (setq lib-alist (vhdl-scan-context-clause))
13678 ;; scan for component and subprogram declarations/bodies
fda91268 13679 (while (re-search-forward "^[ \t]*\\(component\\|function\\|procedure\\)[ \t\n\r\f]+\\(\\w+\\|\".*\"\\)" end-of-unit t)
3dcb36b7
JB
13680 (if (equal (upcase (match-string 1)) "COMPONENT")
13681 (setq comp-name (match-string-no-properties 2)
13682 comp-alist
13683 (cons (list (downcase comp-name) comp-name
13684 file-name (vhdl-current-line))
13685 comp-alist))
13686 (setq func-name (match-string-no-properties 2)
13687 func-alist
13688 (cons (list (downcase func-name) func-name
13689 file-name (vhdl-current-line))
13690 func-alist))))
13691 (setq func-alist (nreverse func-alist))
13692 (setq comp-alist (nreverse comp-alist))
13693 (if is-body
13694 (setq pack-body-list (cons pack-key pack-body-list))
13695 (setq pack-list (cons pack-key pack-list)))
13696 (aput
13697 'pack-alist pack-key
13698 (if is-body
13699 (list (or (nth 0 pack-entry) pack-name)
13700 (nth 1 pack-entry) (nth 2 pack-entry)
13701 (nth 3 pack-entry) (nth 4 pack-entry)
13702 (nth 5 pack-entry)
13703 file-name pack-line func-alist lib-alist)
13704 (list pack-name file-name pack-line
13705 comp-alist func-alist lib-alist
13706 (nth 6 pack-entry) (nth 7 pack-entry)
13707 (nth 8 pack-entry) (nth 9 pack-entry))))))))
13708 ;; scan for hierarchy
13709 (if (and limit-hier-file-size
13710 (< limit-hier-file-size (buffer-size)))
13711 (progn (message "WARNING: Scan limit (hierarchy: file size) reached in file:\n \"%s\"" file-name)
13712 (setq big-files t))
13713 ;; scan for architectures
13714 (goto-char (point-min))
fda91268 13715 (while (re-search-forward "^[ \t]*architecture[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+of[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t)
3dcb36b7
JB
13716 (let* ((ent-name (match-string-no-properties 2))
13717 (ent-key (downcase ent-name))
13718 (arch-name (match-string-no-properties 1))
13719 (arch-key (downcase arch-name))
13720 (ent-entry (aget ent-alist ent-key t))
13721 (arch-alist (nth 3 ent-entry))
13722 (arch-entry (aget arch-alist arch-key t))
13723 (beg-of-unit (point))
13724 (end-of-unit (vhdl-get-end-of-unit))
13725 (inst-no 0)
0a2e512a 13726 inst-alist inst-path)
3dcb36b7
JB
13727 ;; scan for contained instantiations
13728 (while (and (re-search-forward
fda91268
RZ
13729 (concat "^[ \t]*\\(\\w+\\)[ \t\n\r\f]*:[ \t\n\r\f]*\\("
13730 "\\(\\w+\\)[ \t\n\r\f]+\\(--[^\n]*\n[ \t\n\r\f]*\\)*\\(generic\\|port\\)[ \t\n\r\f]+map\\>\\|"
13731 "component[ \t\n\r\f]+\\(\\w+\\)\\|"
13732 "\\(\\(entity\\)\\|configuration\\)[ \t\n\r\f]+\\(\\(\\w+\\)\\.\\)?\\(\\w+\\)\\([ \t\n\r\f]*(\\(\\w+\\))\\)?\\|"
0a2e512a 13733 "\\(\\(for\\|if\\)\\>[^;:]+\\<generate\\>\\|block\\>\\)\\)\\|"
fda91268 13734 "\\(^[ \t]*end[ \t\n\r\f]+\\(generate\\|block\\)\\>\\)") end-of-unit t)
3dcb36b7
JB
13735 (or (not limit-hier-inst-no)
13736 (<= (setq inst-no (1+ inst-no))
13737 limit-hier-inst-no)))
0a2e512a
RF
13738 (cond
13739 ;; block/generate beginning found
13740 ((match-string 14)
13741 (setq inst-path
13742 (cons (match-string-no-properties 1) inst-path)))
13743 ;; block/generate end found
13744 ((match-string 16)
13745 (setq inst-path (cdr inst-path)))
13746 ;; instantiation found
13747 (t
13748 (let* ((inst-name (match-string-no-properties 1))
13749 (inst-key (downcase inst-name))
13750 (inst-comp-name
13751 (or (match-string-no-properties 3)
13752 (match-string-no-properties 6)))
13753 (inst-ent-key
13754 (or (and (match-string 8)
13755 (vhdl-match-string-downcase 11))
13756 (and inst-comp-name
13757 (downcase inst-comp-name))))
13758 (inst-arch-key (vhdl-match-string-downcase 13))
13759 (inst-conf-key
13760 (and (not (match-string 8))
13761 (vhdl-match-string-downcase 11)))
13762 (inst-lib-key (vhdl-match-string-downcase 10)))
13763 (goto-char (match-end 1))
13764 (setq inst-list (cons inst-key inst-list)
13765 inst-ent-list
13766 (cons inst-ent-key inst-ent-list))
13767 (setq inst-alist
13768 (append
13769 inst-alist
13770 (list (list inst-key inst-name file-name
13771 (vhdl-current-line) inst-comp-name
13772 inst-ent-key inst-arch-key
13773 inst-conf-key inst-lib-key
13774 (reverse inst-path)))))))))
3dcb36b7
JB
13775 ;; scan for contained configuration specifications
13776 (goto-char beg-of-unit)
13777 (while (re-search-forward
fda91268
RZ
13778 (concat "^[ \t]*for[ \t\n\r\f]+\\(\\w+\\([ \t\n\r\f]*,[ \t\n\r\f]*\\w+\\)*\\)[ \t\n\r\f]*:[ \t\n\r\f]*\\(\\w+\\)[ \t\n\r\f]+\\(--[^\n]*\n[ \t\n\r\f]*\\)*"
13779 "use[ \t\n\r\f]+\\(\\(entity\\)\\|configuration\\)[ \t\n\r\f]+\\(\\(\\w+\\)\\.\\)?\\(\\w+\\)\\([ \t\n\r\f]*(\\(\\w+\\))\\)?") end-of-unit t)
0a2e512a 13780 (let* ((inst-comp-name (match-string-no-properties 3))
3dcb36b7
JB
13781 (inst-ent-key
13782 (and (match-string 6)
13783 (vhdl-match-string-downcase 9)))
13784 (inst-arch-key (vhdl-match-string-downcase 11))
13785 (inst-conf-key
13786 (and (not (match-string 6))
13787 (vhdl-match-string-downcase 9)))
13788 (inst-lib-key (vhdl-match-string-downcase 8))
13789 (inst-key-list
13790 (split-string (vhdl-match-string-downcase 1)
fda91268 13791 "[ \t\n\r\f]*,[ \t\n\r\f]*"))
3dcb36b7
JB
13792 (tmp-inst-alist inst-alist)
13793 inst-entry)
13794 (while tmp-inst-alist
13795 (when (and (or (equal "all" (car inst-key-list))
13796 (member (nth 0 (car tmp-inst-alist))
13797 inst-key-list))
13798 (equal
13799 (downcase
13800 (or (nth 4 (car tmp-inst-alist)) ""))
13801 (downcase inst-comp-name)))
13802 (setq inst-entry (car tmp-inst-alist))
13803 (setq inst-ent-list
13804 (cons (or inst-ent-key (nth 5 inst-entry))
13805 (vhdl-delete
13806 (nth 5 inst-entry) inst-ent-list)))
13807 (setq inst-entry
13808 (list (nth 0 inst-entry) (nth 1 inst-entry)
13809 (nth 2 inst-entry) (nth 3 inst-entry)
13810 (nth 4 inst-entry)
13811 (or inst-ent-key (nth 5 inst-entry))
13812 (or inst-arch-key (nth 6 inst-entry))
13813 inst-conf-key inst-lib-key))
13814 (setcar tmp-inst-alist inst-entry))
13815 (setq tmp-inst-alist (cdr tmp-inst-alist)))))
13816 ;; save in cache
13817 (aput 'arch-alist arch-key
13818 (list (nth 0 arch-entry) (nth 1 arch-entry)
13819 (nth 2 arch-entry) inst-alist
13820 (nth 4 arch-entry)))
13821 (aput 'ent-alist ent-key
13822 (list (nth 0 ent-entry) (nth 1 ent-entry)
13823 (nth 2 ent-entry) (vhdl-sort-alist arch-alist)
0a2e512a 13824 (nth 4 ent-entry) (nth 5 ent-entry)))
3dcb36b7
JB
13825 (when (and limit-hier-inst-no
13826 (> inst-no limit-hier-inst-no))
13827 (message "WARNING: Scan limit (hierarchy: instances per architecture) reached in file:\n \"%s\"" file-name)
13828 (setq big-files t))
13829 (goto-char end-of-unit))))
13830 ;; remember design units for this file
13831 (aput 'file-alist file-name
13832 (list ent-list arch-list arch-ent-list conf-list
13833 pack-list pack-body-list inst-list inst-ent-list))
13834 (setq ent-inst-list (append inst-ent-list ent-inst-list))))))
13835 (setq file-list (cdr file-list))))
13836 (when (or (and (not project) files-exist)
13837 (and project (not non-final)))
13838 ;; consistency checks:
13839 ;; check whether each architecture has a corresponding entity
13840 (setq tmp-list ent-alist)
13841 (while tmp-list
13842 (when (null (nth 2 (car tmp-list)))
13843 (setq tmp-entry (car (nth 4 (car tmp-list))))
13844 (vhdl-warning-when-idle
13845 "Architecture of non-existing entity: \"%s\" of \"%s\"\n in \"%s\" (line %d)"
13846 (nth 1 tmp-entry) (nth 1 (car tmp-list)) (nth 2 tmp-entry)
13847 (nth 3 tmp-entry)))
13848 (setq tmp-list (cdr tmp-list)))
13849 ;; check whether configuration has a corresponding entity/architecture
13850 (setq tmp-list conf-alist)
13851 (while tmp-list
13852 (if (setq tmp-entry (aget ent-alist (nth 4 (car tmp-list)) t))
13853 (unless (aget (nth 3 tmp-entry) (nth 5 (car tmp-list)) t)
13854 (setq tmp-entry (car tmp-list))
13855 (vhdl-warning-when-idle
13856 "Configuration of non-existing architecture: \"%s\" of \"%s(%s)\"\n in \"%s\" (line %d)"
13857 (nth 1 tmp-entry) (nth 4 tmp-entry) (nth 5 tmp-entry)
13858 (nth 2 tmp-entry) (nth 3 tmp-entry)))
13859 (setq tmp-entry (car tmp-list))
13860 (vhdl-warning-when-idle
13861 "Configuration of non-existing entity: \"%s\" of \"%s\"\n in \"%s\" (line %d)"
13862 (nth 1 tmp-entry) (nth 4 tmp-entry)
13863 (nth 2 tmp-entry) (nth 3 tmp-entry)))
13864 (setq tmp-list (cdr tmp-list)))
13865 ;; check whether each package body has a package declaration
13866 (setq tmp-list pack-alist)
13867 (while tmp-list
13868 (when (null (nth 2 (car tmp-list)))
13869 (setq tmp-entry (car tmp-list))
13870 (vhdl-warning-when-idle
13871 "Package body of non-existing package: \"%s\"\n in \"%s\" (line %d)"
13872 (nth 1 tmp-entry) (nth 7 tmp-entry) (nth 8 tmp-entry)))
13873 (setq tmp-list (cdr tmp-list)))
13874 ;; sort lists
13875 (setq ent-alist (vhdl-sort-alist ent-alist))
13876 (setq conf-alist (vhdl-sort-alist conf-alist))
13877 (setq pack-alist (vhdl-sort-alist pack-alist))
13878 ;; remember updated directory/project
13879 (add-to-list 'vhdl-updated-project-list (or project dir-name)))
13880 ;; clear directory alists
13881 (unless project
13882 (adelete 'vhdl-entity-alist key)
13883 (adelete 'vhdl-config-alist key)
13884 (adelete 'vhdl-package-alist key)
13885 (adelete 'vhdl-ent-inst-alist key)
13886 (adelete 'vhdl-file-alist key))
13887 ;; put directory contents into cache
13888 (aput 'vhdl-entity-alist key ent-alist)
13889 (aput 'vhdl-config-alist key conf-alist)
13890 (aput 'vhdl-package-alist key pack-alist)
13891 (aput 'vhdl-ent-inst-alist key (list ent-inst-list))
13892 (aput 'vhdl-file-alist key file-alist)
13893 ;; final messages
13894 (message "Scanning %s %s\"%s\"...done"
13895 (if is-directory "directory" "files") (or num-string "") name)
13896 (unless project (message "Scanning directory...done"))
13897 (when big-files
13898 (vhdl-warning-when-idle "Scanning is incomplete.\n --> see user option `vhdl-speedbar-scan-limit'"))
13899 ;; save cache when scanned non-interactively
13900 (when (or (not project) (not non-final))
13901 (when (and noninteractive vhdl-speedbar-save-cache)
13902 (vhdl-save-cache key)))
13903 t))
5eabfe72 13904
3dcb36b7 13905(defun vhdl-scan-project-contents (project)
5eabfe72
KH
13906 "Scan the contents of all VHDL files found in the directories and files
13907of PROJECT."
3dcb36b7
JB
13908 (let ((dir-list (or (nth 2 (aget vhdl-project-alist project)) '("")))
13909 (default-dir (vhdl-resolve-env-variable
13910 (nth 1 (aget vhdl-project-alist project))))
13911 (file-exclude-regexp
13912 (or (nth 3 (aget vhdl-project-alist project)) ""))
13913 dir-list-tmp dir dir-name num-dir act-dir recursive)
13914 ;; clear project alists
13915 (adelete 'vhdl-entity-alist project)
13916 (adelete 'vhdl-config-alist project)
13917 (adelete 'vhdl-package-alist project)
13918 (adelete 'vhdl-ent-inst-alist project)
13919 (adelete 'vhdl-file-alist project)
13920 ;; expand directory names by default-directory
13921 (message "Collecting source files...")
13922 (while dir-list
13923 (setq dir (vhdl-resolve-env-variable (car dir-list)))
13924 (string-match "\\(\\(-r \\)?\\)\\(.*\\)" dir)
13925 (setq recursive (match-string 1 dir)
13926 dir-name (match-string 3 dir))
13927 (setq dir-list-tmp
13928 (cons (concat recursive
13929 (if (file-name-absolute-p dir-name) "" default-dir)
13930 dir-name)
13931 dir-list-tmp))
13932 (setq dir-list (cdr dir-list)))
13933 ;; resolve path wildcards
5eabfe72
KH
13934 (setq dir-list-tmp (vhdl-resolve-paths dir-list-tmp))
13935 ;; expand directories
13936 (while dir-list-tmp
13937 (setq dir (car dir-list-tmp))
13938 ;; get subdirectories
3dcb36b7 13939 (if (string-match "-r \\(.*[/\\]\\)" dir)
5eabfe72
KH
13940 (setq dir-list (append dir-list (vhdl-get-subdirs
13941 (match-string 1 dir))))
13942 (setq dir-list (append dir-list (list dir))))
13943 (setq dir-list-tmp (cdr dir-list-tmp)))
3dcb36b7
JB
13944 ;; exclude files
13945 (unless (equal file-exclude-regexp "")
13946 (let ((case-fold-search nil))
13947 (while dir-list
13948 (unless (string-match file-exclude-regexp (car dir-list))
13949 (setq dir-list-tmp (cons (car dir-list) dir-list-tmp)))
13950 (setq dir-list (cdr dir-list)))
13951 (setq dir-list (nreverse dir-list-tmp))))
13952 (message "Collecting source files...done")
13953 ;; scan for design units for each directory in DIR-LIST
13954 (setq dir-list-tmp nil
13955 num-dir (length dir-list)
5eabfe72
KH
13956 act-dir 1)
13957 (while dir-list
3dcb36b7
JB
13958 (setq dir-name (abbreviate-file-name
13959 (expand-file-name (car dir-list))))
13960 (vhdl-scan-directory-contents dir-name project nil
13961 (format "(%s/%s) " act-dir num-dir)
13962 (cdr dir-list))
13963 (add-to-list 'dir-list-tmp (file-name-directory dir-name))
5eabfe72
KH
13964 (setq dir-list (cdr dir-list)
13965 act-dir (1+ act-dir)))
3dcb36b7
JB
13966 (aput 'vhdl-directory-alist project (list (nreverse dir-list-tmp)))
13967 (message "Scanning project \"%s\"...done" project)))
13968
13969(defun vhdl-update-file-contents (file-name)
13970 "Update hierarchy information by contents of current buffer."
13971 (setq file-name (abbreviate-file-name file-name))
13972 (let* ((dir-name (file-name-directory file-name))
13973 (directory-alist vhdl-directory-alist)
13974 updated)
13975 (while directory-alist
13976 (when (member dir-name (nth 1 (car directory-alist)))
13977 (let* ((vhdl-project (nth 0 (car directory-alist)))
13978 (project (vhdl-project-p))
13979 (ent-alist (aget vhdl-entity-alist (or project dir-name) t))
13980 (conf-alist (aget vhdl-config-alist (or project dir-name) t))
13981 (pack-alist (aget vhdl-package-alist (or project dir-name) t))
13982 (ent-inst-list (car (aget vhdl-ent-inst-alist
13983 (or project dir-name) t)))
13984 (file-alist (aget vhdl-file-alist (or project dir-name) t))
13985 (file-entry (aget file-alist file-name t))
13986 (ent-list (nth 0 file-entry))
13987 (arch-list (nth 1 file-entry))
13988 (arch-ent-list (nth 2 file-entry))
13989 (conf-list (nth 3 file-entry))
13990 (pack-list (nth 4 file-entry))
13991 (pack-body-list (nth 5 file-entry))
13992 (inst-ent-list (nth 7 file-entry))
13993 (cache-key (or project dir-name))
13994 arch-alist key ent-key entry)
13995 ;; delete design units previously contained in this file:
13996 ;; entities
13997 (while ent-list
13998 (setq key (car ent-list)
13999 entry (aget ent-alist key t))
14000 (when (equal file-name (nth 1 entry))
14001 (if (nth 3 entry)
14002 (aput 'ent-alist key
14003 (list (nth 0 entry) nil nil (nth 3 entry) nil))
14004 (adelete 'ent-alist key)))
14005 (setq ent-list (cdr ent-list)))
14006 ;; architectures
14007 (while arch-list
14008 (setq key (car arch-list)
14009 ent-key (car arch-ent-list)
14010 entry (aget ent-alist ent-key t)
14011 arch-alist (nth 3 entry))
14012 (when (equal file-name (nth 1 (aget arch-alist key t)))
14013 (adelete 'arch-alist key)
14014 (if (or (nth 1 entry) arch-alist)
14015 (aput 'ent-alist ent-key
14016 (list (nth 0 entry) (nth 1 entry) (nth 2 entry)
0a2e512a 14017 arch-alist (nth 4 entry) (nth 5 entry)))
3dcb36b7
JB
14018 (adelete 'ent-alist ent-key)))
14019 (setq arch-list (cdr arch-list)
14020 arch-ent-list (cdr arch-ent-list)))
14021 ;; configurations
14022 (while conf-list
14023 (setq key (car conf-list))
14024 (when (equal file-name (nth 1 (aget conf-alist key t)))
14025 (adelete 'conf-alist key))
14026 (setq conf-list (cdr conf-list)))
14027 ;; package declarations
14028 (while pack-list
14029 (setq key (car pack-list)
14030 entry (aget pack-alist key t))
14031 (when (equal file-name (nth 1 entry))
14032 (if (nth 6 entry)
14033 (aput 'pack-alist key
14034 (list (nth 0 entry) nil nil nil nil nil
14035 (nth 6 entry) (nth 7 entry) (nth 8 entry)
14036 (nth 9 entry)))
14037 (adelete 'pack-alist key)))
14038 (setq pack-list (cdr pack-list)))
14039 ;; package bodies
14040 (while pack-body-list
14041 (setq key (car pack-body-list)
14042 entry (aget pack-alist key t))
14043 (when (equal file-name (nth 6 entry))
14044 (if (nth 1 entry)
14045 (aput 'pack-alist key
14046 (list (nth 0 entry) (nth 1 entry) (nth 2 entry)
14047 (nth 3 entry) (nth 4 entry) (nth 5 entry)
14048 nil nil nil nil))
14049 (adelete 'pack-alist key)))
14050 (setq pack-body-list (cdr pack-body-list)))
14051 ;; instantiated entities
14052 (while inst-ent-list
14053 (setq ent-inst-list
14054 (vhdl-delete (car inst-ent-list) ent-inst-list))
14055 (setq inst-ent-list (cdr inst-ent-list)))
14056 ;; update caches
14057 (vhdl-aput 'vhdl-entity-alist cache-key ent-alist)
14058 (vhdl-aput 'vhdl-config-alist cache-key conf-alist)
14059 (vhdl-aput 'vhdl-package-alist cache-key pack-alist)
14060 (vhdl-aput 'vhdl-ent-inst-alist cache-key (list ent-inst-list))
14061 ;; scan file
14062 (vhdl-scan-directory-contents file-name project t)
14063 (when (or (and vhdl-speedbar-show-projects project)
14064 (and (not vhdl-speedbar-show-projects) (not project)))
14065 (vhdl-speedbar-refresh project))
14066 (setq updated t)))
14067 (setq directory-alist (cdr directory-alist)))
14068 updated))
14069
14070(defun vhdl-update-hierarchy ()
14071 "Update directory and hierarchy information in speedbar."
14072 (let ((file-list (reverse vhdl-modified-file-list))
14073 updated)
14074 (when (and vhdl-speedbar-update-on-saving file-list)
14075 (while file-list
14076 (setq updated
14077 (or (vhdl-update-file-contents (car file-list))
14078 updated))
14079 (setq file-list (cdr file-list)))
14080 (setq vhdl-modified-file-list nil)
0a2e512a 14081 (vhdl-speedbar-update-current-unit)
3dcb36b7
JB
14082 (when updated (message "Updating hierarchy...done")))))
14083
333f9019 14084;; structure (parenthesized expression means list of such entries)
3dcb36b7
JB
14085;; (inst-key inst-file-marker comp-ent-key comp-ent-file-marker
14086;; comp-arch-key comp-arch-file-marker comp-conf-key comp-conf-file-marker
14087;; comp-lib-name level)
14088(defun vhdl-get-hierarchy (ent-alist conf-alist ent-key arch-key conf-key
14089 conf-inst-alist level indent
14090 &optional include-top ent-hier)
14091 "Get instantiation hierarchy beginning in architecture ARCH-KEY of
14092entity ENT-KEY."
14093 (let* ((ent-entry (aget ent-alist ent-key t))
14094 (arch-entry (if arch-key (aget (nth 3 ent-entry) arch-key t)
14095 (cdar (last (nth 3 ent-entry)))))
14096 (inst-alist (nth 3 arch-entry))
14097 inst-entry inst-ent-entry inst-arch-entry inst-conf-entry comp-entry
14098 hier-list subcomp-list tmp-list inst-key inst-comp-name
14099 inst-ent-key inst-arch-key inst-conf-key inst-lib-key)
5eabfe72 14100 (when (= level 0) (message "Extract design hierarchy..."))
3dcb36b7
JB
14101 (when include-top
14102 (setq level (1+ level)))
14103 (when (member ent-key ent-hier)
14104 (error "ERROR: Instantiation loop detected, component instantiates itself: \"%s\"" ent-key))
14105 ;; check configured architecture (already checked during scanning)
14106; (unless (or (null conf-inst-alist) (assoc arch-key (nth 3 ent-entry)))
14107; (vhdl-warning-when-idle "Configuration for non-existing architecture used: \"%s\"" conf-key))
14108 ;; process all instances
14109 (while inst-alist
14110 (setq inst-entry (car inst-alist)
14111 inst-key (nth 0 inst-entry)
14112 inst-comp-name (nth 4 inst-entry)
14113 inst-conf-key (nth 7 inst-entry))
14114 ;; search entry in configuration's instantiations list
14115 (setq tmp-list conf-inst-alist)
14116 (while (and tmp-list
14117 (not (and (member (nth 0 (car tmp-list))
14118 (list "all" inst-key))
14119 (equal (nth 1 (car tmp-list))
14120 (downcase (or inst-comp-name ""))))))
14121 (setq tmp-list (cdr tmp-list)))
14122 (setq inst-conf-key (or (nth 4 (car tmp-list)) inst-conf-key))
14123 (setq inst-conf-entry (aget conf-alist inst-conf-key t))
14124 (when (and inst-conf-key (not inst-conf-entry))
14125 (vhdl-warning-when-idle "Configuration not found: \"%s\"" inst-conf-key))
14126 ;; determine entity
14127 (setq inst-ent-key
14128 (or (nth 2 (car tmp-list)) ; from configuration
14129 (nth 3 inst-conf-entry) ; from subconfiguration
14130 (nth 3 (aget conf-alist (nth 7 inst-entry) t))
14131 ; from configuration spec.
14132 (nth 5 inst-entry))) ; from direct instantiation
14133 (setq inst-ent-entry (aget ent-alist inst-ent-key t))
14134 ;; determine architecture
14135 (setq inst-arch-key
0a2e512a
RF
14136 (or (nth 3 (car tmp-list)) ; from configuration
14137 (nth 4 inst-conf-entry) ; from subconfiguration
14138 (nth 6 inst-entry) ; from direct instantiation
3dcb36b7 14139 (nth 4 (aget conf-alist (nth 7 inst-entry)))
0a2e512a
RF
14140 ; from configuration spec.
14141 (nth 4 inst-ent-entry) ; MRA
14142 (caar (nth 3 inst-ent-entry)))) ; first alphabetically
3dcb36b7
JB
14143 (setq inst-arch-entry (aget (nth 3 inst-ent-entry) inst-arch-key t))
14144 ;; set library
14145 (setq inst-lib-key
0a2e512a
RF
14146 (or (nth 5 (car tmp-list)) ; from configuration
14147 (nth 8 inst-entry))) ; from direct instantiation
3dcb36b7
JB
14148 ;; gather information for this instance
14149 (setq comp-entry
14150 (list (nth 1 inst-entry)
14151 (cons (nth 2 inst-entry) (nth 3 inst-entry))
14152 (or (nth 0 inst-ent-entry) (nth 4 inst-entry))
14153 (cons (nth 1 inst-ent-entry) (nth 2 inst-ent-entry))
14154 (or (nth 0 inst-arch-entry) inst-arch-key)
14155 (cons (nth 1 inst-arch-entry) (nth 2 inst-arch-entry))
14156 (or (nth 0 inst-conf-entry) inst-conf-key)
14157 (cons (nth 1 inst-conf-entry) (nth 2 inst-conf-entry))
14158 inst-lib-key level))
14159 ;; get subcomponent hierarchy
14160 (setq subcomp-list (vhdl-get-hierarchy
14161 ent-alist conf-alist
14162 inst-ent-key inst-arch-key inst-conf-key
14163 (nth 5 inst-conf-entry)
14164 (1+ level) indent nil (cons ent-key ent-hier)))
14165 ;; add to list
14166 (setq hier-list (append hier-list (list comp-entry) subcomp-list))
14167 (setq inst-alist (cdr inst-alist)))
14168 (when include-top
5eabfe72 14169 (setq hier-list
3dcb36b7
JB
14170 (cons (list nil nil (nth 0 ent-entry)
14171 (cons (nth 1 ent-entry) (nth 2 ent-entry))
14172 (nth 0 arch-entry)
14173 (cons (nth 1 arch-entry) (nth 2 arch-entry))
14174 nil nil
14175 nil (1- level))
14176 hier-list)))
14177 (when (or (= level 0) (and include-top (= level 1))) (message ""))
5eabfe72
KH
14178 hier-list))
14179
3dcb36b7
JB
14180(defun vhdl-get-instantiations (ent-key indent)
14181 "Get all instantiations of entity ENT-KEY."
14182 (let ((ent-alist (aget vhdl-entity-alist (vhdl-speedbar-line-key indent) t))
5eabfe72
KH
14183 arch-alist inst-alist ent-inst-list
14184 ent-entry arch-entry inst-entry)
14185 (while ent-alist
14186 (setq ent-entry (car ent-alist))
3dcb36b7 14187 (setq arch-alist (nth 4 ent-entry))
5eabfe72
KH
14188 (while arch-alist
14189 (setq arch-entry (car arch-alist))
3dcb36b7 14190 (setq inst-alist (nth 4 arch-entry))
5eabfe72
KH
14191 (while inst-alist
14192 (setq inst-entry (car inst-alist))
3dcb36b7 14193 (when (equal ent-key (nth 5 inst-entry))
5eabfe72 14194 (setq ent-inst-list
3dcb36b7
JB
14195 (cons (list (nth 1 inst-entry)
14196 (cons (nth 2 inst-entry) (nth 3 inst-entry))
14197 (nth 1 ent-entry)
14198 (cons (nth 2 ent-entry) (nth 3 ent-entry))
14199 (nth 1 arch-entry)
14200 (cons (nth 2 arch-entry) (nth 3 arch-entry)))
14201 ent-inst-list)))
5eabfe72
KH
14202 (setq inst-alist (cdr inst-alist)))
14203 (setq arch-alist (cdr arch-alist)))
14204 (setq ent-alist (cdr ent-alist)))
14205 (nreverse ent-inst-list)))
14206
14207;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3dcb36b7
JB
14208;; Caching in file
14209
14210(defun vhdl-save-caches ()
14211 "Save all updated hierarchy caches to file."
14212 (interactive)
14213 (condition-case nil
14214 (when vhdl-speedbar-save-cache
14215 ;; update hierarchy
14216 (vhdl-update-hierarchy)
14217 (let ((project-list vhdl-updated-project-list))
14218 (message "Saving hierarchy caches...")
14219 ;; write updated project caches
14220 (while project-list
14221 (vhdl-save-cache (car project-list))
14222 (setq project-list (cdr project-list)))
14223 (message "Saving hierarchy caches...done")))
b65d82ca 14224 (error (progn (vhdl-warning "ERROR: An error occurred while saving the hierarchy caches")
3dcb36b7
JB
14225 (sit-for 2)))))
14226
14227(defun vhdl-save-cache (key)
14228 "Save current hierarchy cache to file."
14229 (let* ((orig-buffer (current-buffer))
14230 (vhdl-project key)
14231 (project (vhdl-project-p))
14232 (default-directory key)
14233 (directory (abbreviate-file-name (vhdl-default-directory)))
14234 (file-name (vhdl-resolve-env-variable
14235 (vhdl-replace-string
14236 (cons "\\(.*\\) \\(.*\\)" vhdl-speedbar-cache-file-name)
14237 (concat
14238 (subst-char-in-string ? ?_ (or project "dir"))
14239 " " (user-login-name)))))
14240 (file-dir-name (expand-file-name file-name directory))
14241 (cache-key (or project directory))
14242 (key (if project "project" "directory")))
14243 (unless (file-exists-p (file-name-directory file-dir-name))
14244 (make-directory (file-name-directory file-dir-name) t))
14245 (if (not (file-writable-p file-dir-name))
14246 (progn (vhdl-warning (format "File not writable: \"%s\""
14247 (abbreviate-file-name file-dir-name)))
14248 (sit-for 2))
14249 (message "Saving cache: \"%s\"" file-dir-name)
14250 (set-buffer (find-file-noselect file-dir-name t t))
14251 (erase-buffer)
14252 (insert ";; -*- Emacs-Lisp -*-\n\n"
14253 ";;; " (file-name-nondirectory file-name)
14254 " - design hierarchy cache file for Emacs VHDL Mode "
14255 vhdl-version "\n")
14256 (insert "\n;; " (if project "Project " "Directory") " : ")
14257 (if project (insert project) (prin1 directory (current-buffer)))
14258 (insert "\n;; Saved : " (format-time-string "%Y-%m-%d %T ")
14259 (user-login-name) "\n\n"
14260 "\n;; version number\n"
14261 "(setq vhdl-cache-version \"" vhdl-version "\")\n"
14262 "\n;; " (if project "project" "directory") " name"
14263 "\n(setq " key " ")
14264 (prin1 (or project directory) (current-buffer))
14265 (insert ")\n")
14266 (when (member 'hierarchy vhdl-speedbar-save-cache)
14267 (insert "\n;; entity and architecture cache\n"
14268 "(aput 'vhdl-entity-alist " key " '")
14269 (print (aget vhdl-entity-alist cache-key t) (current-buffer))
14270 (insert ")\n\n;; configuration cache\n"
14271 "(aput 'vhdl-config-alist " key " '")
14272 (print (aget vhdl-config-alist cache-key t) (current-buffer))
14273 (insert ")\n\n;; package cache\n"
14274 "(aput 'vhdl-package-alist " key " '")
14275 (print (aget vhdl-package-alist cache-key t) (current-buffer))
14276 (insert ")\n\n;; instantiated entities cache\n"
14277 "(aput 'vhdl-ent-inst-alist " key " '")
14278 (print (aget vhdl-ent-inst-alist cache-key t) (current-buffer))
14279 (insert ")\n\n;; design units per file cache\n"
14280 "(aput 'vhdl-file-alist " key " '")
14281 (print (aget vhdl-file-alist cache-key t) (current-buffer))
14282 (when project
14283 (insert ")\n\n;; source directories in project cache\n"
14284 "(aput 'vhdl-directory-alist " key " '")
14285 (print (aget vhdl-directory-alist cache-key t) (current-buffer)))
14286 (insert ")\n"))
14287 (when (member 'display vhdl-speedbar-save-cache)
14288 (insert "\n;; shown design units cache\n"
14289 "(aput 'vhdl-speedbar-shown-unit-alist " key " '")
14290 (print (aget vhdl-speedbar-shown-unit-alist cache-key t)
14291 (current-buffer))
14292 (insert ")\n"))
14293 (setq vhdl-updated-project-list
14294 (delete cache-key vhdl-updated-project-list))
14295 (save-buffer)
14296 (kill-buffer (current-buffer))
14297 (set-buffer orig-buffer))))
14298
14299(defun vhdl-load-cache (key)
14300 "Load hierarchy cache information from file."
14301 (let* ((vhdl-project key)
14302 (default-directory key)
14303 (directory (vhdl-default-directory))
14304 (file-name (vhdl-resolve-env-variable
14305 (vhdl-replace-string
14306 (cons "\\(.*\\) \\(.*\\)" vhdl-speedbar-cache-file-name)
14307 (concat
14308 (subst-char-in-string ? ?_ (or (vhdl-project-p) "dir"))
14309 " " (user-login-name)))))
14310 (file-dir-name (expand-file-name file-name directory))
14311 vhdl-cache-version)
14312 (unless (memq 'vhdl-save-caches kill-emacs-hook)
14313 (add-hook 'kill-emacs-hook 'vhdl-save-caches))
14314 (when (file-exists-p file-dir-name)
14315 (condition-case ()
14316 (progn (load-file file-dir-name)
14317 (string< (mapconcat
027a4b6b 14318 (lambda (a) (format "%3d" (string-to-number a)))
0a2e512a 14319 (split-string "3.33" "\\.") "")
3dcb36b7 14320 (mapconcat
027a4b6b 14321 (lambda (a) (format "%3d" (string-to-number a)))
3dcb36b7
JB
14322 (split-string vhdl-cache-version "\\.") "")))
14323 (error (progn (vhdl-warning (format "ERROR: Corrupted cache file: \"%s\"" file-dir-name))
14324 nil))))))
14325
14326(defun vhdl-require-hierarchy-info ()
14327 "Make sure that hierarchy information is available. Load cache or scan files
14328if required."
14329 (if (vhdl-project-p)
14330 (unless (or (assoc vhdl-project vhdl-file-alist)
14331 (vhdl-load-cache vhdl-project))
14332 (vhdl-scan-project-contents vhdl-project))
14333 (let ((directory (abbreviate-file-name default-directory)))
14334 (unless (or (assoc directory vhdl-file-alist)
14335 (vhdl-load-cache directory))
14336 (vhdl-scan-directory-contents directory)))))
14337
14338;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14339;; Add hierarchy browser functionality to speedbar
5eabfe72
KH
14340
14341(defvar vhdl-speedbar-key-map nil
14342 "Keymap used when in the VHDL hierarchy browser mode.")
14343
3dcb36b7 14344(defvar vhdl-speedbar-menu-items nil
5eabfe72
KH
14345 "Additional menu-items to add to speedbar frame.")
14346
14347(defun vhdl-speedbar-initialize ()
14348 "Initialize speedbar."
14349 ;; general settings
14350; (set (make-local-variable 'speedbar-tag-hierarchy-method) nil)
14351 ;; VHDL file extensions (extracted from `auto-mode-alist')
14352 (let ((mode-alist auto-mode-alist))
14353 (while mode-alist
3dcb36b7
JB
14354 (when (eq (cdar mode-alist) 'vhdl-mode)
14355 (speedbar-add-supported-extension (caar mode-alist)))
5eabfe72
KH
14356 (setq mode-alist (cdr mode-alist))))
14357 ;; hierarchy browser settings
14358 (when (boundp 'speedbar-mode-functions-list)
3dcb36b7 14359 ;; special functions
5eabfe72 14360 (speedbar-add-mode-functions-list
3dcb36b7 14361 '("vhdl directory"
5eabfe72 14362 (speedbar-item-info . vhdl-speedbar-item-info)
7752250e 14363 (speedbar-line-directory . speedbar-files-line-path)))
3dcb36b7
JB
14364 (speedbar-add-mode-functions-list
14365 '("vhdl project"
14366 (speedbar-item-info . vhdl-speedbar-item-info)
7752250e 14367 (speedbar-line-directory . vhdl-speedbar-line-project)))
3dcb36b7 14368 ;; keymap
5eabfe72
KH
14369 (unless vhdl-speedbar-key-map
14370 (setq vhdl-speedbar-key-map (speedbar-make-specialized-keymap))
14371 (define-key vhdl-speedbar-key-map "e" 'speedbar-edit-line)
14372 (define-key vhdl-speedbar-key-map "\C-m" 'speedbar-edit-line)
14373 (define-key vhdl-speedbar-key-map "+" 'speedbar-expand-line)
3dcb36b7
JB
14374 (define-key vhdl-speedbar-key-map "=" 'speedbar-expand-line)
14375 (define-key vhdl-speedbar-key-map "-" 'vhdl-speedbar-contract-level)
14376 (define-key vhdl-speedbar-key-map "_" 'vhdl-speedbar-contract-all)
14377 (define-key vhdl-speedbar-key-map "C" 'vhdl-speedbar-port-copy)
14378 (define-key vhdl-speedbar-key-map "P" 'vhdl-speedbar-place-component)
0a2e512a
RF
14379 (define-key vhdl-speedbar-key-map "F" 'vhdl-speedbar-configuration)
14380 (define-key vhdl-speedbar-key-map "A" 'vhdl-speedbar-select-mra)
3dcb36b7
JB
14381 (define-key vhdl-speedbar-key-map "K" 'vhdl-speedbar-make-design)
14382 (define-key vhdl-speedbar-key-map "R" 'vhdl-speedbar-rescan-hierarchy)
14383 (define-key vhdl-speedbar-key-map "S" 'vhdl-save-caches)
14384 (let ((key 0))
14385 (while (<= key 9)
14386 (define-key vhdl-speedbar-key-map (int-to-string key)
14387 `(lambda () (interactive) (vhdl-speedbar-set-depth ,key)))
14388 (setq key (1+ key)))))
20367d28 14389 (define-key speedbar-mode-map "h"
5eabfe72 14390 (lambda () (interactive)
3dcb36b7 14391 (speedbar-change-initial-expansion-list "vhdl directory")))
20367d28 14392 (define-key speedbar-mode-map "H"
3dcb36b7
JB
14393 (lambda () (interactive)
14394 (speedbar-change-initial-expansion-list "vhdl project")))
14395 ;; menu
14396 (unless vhdl-speedbar-menu-items
14397 (setq
14398 vhdl-speedbar-menu-items
14399 `(["Edit" speedbar-edit-line t]
14400 ["Expand" speedbar-expand-line
14401 (save-excursion (beginning-of-line) (looking-at "[0-9]+: *.\\+. "))]
14402 ["Contract" vhdl-speedbar-contract-level t]
14403 ["Expand All" vhdl-speedbar-expand-all t]
14404 ["Contract All" vhdl-speedbar-contract-all t]
14405 ,(let ((key 0) (menu-list '("Hierarchy Depth")))
14406 (while (<= key 9)
14407 (setq menu-list
14408 (cons `[,(if (= key 0) "All" (int-to-string key))
14409 (vhdl-speedbar-set-depth ,key)
14410 :style radio
14411 :selected (= vhdl-speedbar-hierarchy-depth ,key)
14412 :keys ,(int-to-string key)]
14413 menu-list))
14414 (setq key (1+ key)))
14415 (nreverse menu-list))
14416 "--"
14417 ["Copy Port/Subprogram" vhdl-speedbar-port-copy
14418 (or (vhdl-speedbar-check-unit 'entity)
14419 (vhdl-speedbar-check-unit 'subprogram))]
14420 ["Place Component" vhdl-speedbar-place-component
14421 (vhdl-speedbar-check-unit 'entity)]
0a2e512a
RF
14422 ["Generate Configuration" vhdl-speedbar-configuration
14423 (vhdl-speedbar-check-unit 'architecture)]
14424 ["Select as MRA" vhdl-speedbar-select-mra
14425 (vhdl-speedbar-check-unit 'architecture)]
3dcb36b7
JB
14426 ["Make" vhdl-speedbar-make-design
14427 (save-excursion (beginning-of-line) (looking-at "[0-9]+: *[[<]"))]
14428 ["Generate Makefile" vhdl-speedbar-generate-makefile
14429 (save-excursion (beginning-of-line) (looking-at "[0-9]+:"))]
14430 ["Rescan Directory" vhdl-speedbar-rescan-hierarchy
14431 :active (save-excursion (beginning-of-line) (looking-at "[0-9]+:"))
f8246027 14432 ,(if (featurep 'xemacs) :active :visible) (not vhdl-speedbar-show-projects)]
3dcb36b7
JB
14433 ["Rescan Project" vhdl-speedbar-rescan-hierarchy
14434 :active (save-excursion (beginning-of-line) (looking-at "[0-9]+:"))
f8246027 14435 ,(if (featurep 'xemacs) :active :visible) vhdl-speedbar-show-projects]
3dcb36b7
JB
14436 ["Save Caches" vhdl-save-caches vhdl-updated-project-list])))
14437 ;; hook-ups
14438 (speedbar-add-expansion-list
14439 '("vhdl directory" vhdl-speedbar-menu-items vhdl-speedbar-key-map
14440 vhdl-speedbar-display-directory))
14441 (speedbar-add-expansion-list
14442 '("vhdl project" vhdl-speedbar-menu-items vhdl-speedbar-key-map
14443 vhdl-speedbar-display-projects))
5eabfe72 14444 (setq speedbar-stealthy-function-list
3dcb36b7
JB
14445 (append
14446 '(("vhdl directory" vhdl-speedbar-update-current-unit)
14447 ("vhdl project" vhdl-speedbar-update-current-project
14448 vhdl-speedbar-update-current-unit)
14449; ("files" (lambda () (setq speedbar-ignored-path-regexp
14450; (speedbar-extension-list-to-regex
14451; speedbar-ignored-path-expressions))))
14452 )
14453 speedbar-stealthy-function-list))
14454 (when (eq vhdl-speedbar-display-mode 'directory)
14455 (setq speedbar-initial-expansion-list-name "vhdl directory"))
14456 (when (eq vhdl-speedbar-display-mode 'project)
14457 (setq speedbar-initial-expansion-list-name "vhdl project"))
14458 (add-hook 'speedbar-timer-hook 'vhdl-update-hierarchy)))
5eabfe72
KH
14459
14460(defun vhdl-speedbar (&optional arg)
14461 "Open/close speedbar."
d2ddb974 14462 (interactive)
5eabfe72 14463 (if (not (fboundp 'speedbar))
3dcb36b7
JB
14464 (error "WARNING: Speedbar is not available or not installed")
14465 (condition-case ()
5eabfe72 14466 (speedbar-frame-mode arg)
3dcb36b7 14467 (error (error "WARNING: An error occurred while opening speedbar")))))
5eabfe72
KH
14468
14469;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14470;; Display functions
14471
3dcb36b7
JB
14472(defvar vhdl-speedbar-last-selected-project nil
14473 "Name of last selected project.")
14474
5eabfe72
KH
14475;; macros must be defined in the file they are used (copied from `speedbar.el')
14476(defmacro speedbar-with-writable (&rest forms)
14477 "Allow the buffer to be writable and evaluate FORMS."
14478 (list 'let '((inhibit-read-only t))
14479 (cons 'progn forms)))
14480(put 'speedbar-with-writable 'lisp-indent-function 0)
14481
3dcb36b7 14482(defun vhdl-speedbar-display-directory (directory depth &optional rescan)
5eabfe72 14483 "Display directory and hierarchy information in speedbar."
3dcb36b7 14484 (setq vhdl-speedbar-show-projects nil)
f8262222
RS
14485 (setq speedbar-ignored-directory-regexp
14486 (speedbar-extension-list-to-regex speedbar-ignored-directory-expressions))
5eabfe72
KH
14487 (setq directory (abbreviate-file-name (file-name-as-directory directory)))
14488 (setq speedbar-last-selected-file nil)
14489 (speedbar-with-writable
3dcb36b7
JB
14490 (condition-case nil
14491 (progn
14492 ;; insert directory path
14493 (speedbar-directory-buttons directory depth)
14494 ;; insert subdirectories
14495 (vhdl-speedbar-insert-dirs (speedbar-file-lists directory) depth)
14496 ;; scan and insert hierarchy of current directory
14497 (vhdl-speedbar-insert-dir-hierarchy directory depth
14498 speedbar-power-click)
14499 ;; expand subdirectories
14500 (when (= depth 0) (vhdl-speedbar-expand-dirs directory)))
14501 (error (vhdl-warning-when-idle "ERROR: Invalid hierarchy information, unable to display correctly")))))
14502
14503(defun vhdl-speedbar-display-projects (project depth &optional rescan)
14504 "Display projects and hierarchy information in speedbar."
14505 (setq vhdl-speedbar-show-projects t)
f8262222 14506 (setq speedbar-ignored-directory-regexp ".")
3dcb36b7
JB
14507 (setq speedbar-last-selected-file nil)
14508 (setq vhdl-speedbar-last-selected-project nil)
14509 (speedbar-with-writable
14510 (condition-case nil
14511 ;; insert projects
14512 (vhdl-speedbar-insert-projects)
14513 (error (vhdl-warning-when-idle "ERROR: Invalid hierarchy information, unable to display correctly"))))
14514 (setq speedbar-full-text-cache nil)) ; prevent caching
14515
14516(defun vhdl-speedbar-insert-projects ()
14517 "Insert all projects in speedbar."
14518 (vhdl-speedbar-make-title-line "Projects:")
14519 (let ((project-alist (if vhdl-project-sort
14520 (vhdl-sort-alist (copy-alist vhdl-project-alist))
14521 vhdl-project-alist))
14522 (vhdl-speedbar-update-current-unit nil))
14523 ;; insert projects
14524 (while project-alist
14525 (speedbar-make-tag-line
14526 'angle ?+ 'vhdl-speedbar-expand-project
14527 (caar project-alist) (caar project-alist)
14528 'vhdl-toggle-project (caar project-alist) 'speedbar-directory-face 0)
14529 (setq project-alist (cdr project-alist)))
14530 (setq project-alist vhdl-project-alist)
14531 ;; expand projects
14532 (while project-alist
14533 (when (member (caar project-alist) vhdl-speedbar-shown-project-list)
14534 (goto-char (point-min))
14535 (when (re-search-forward
14536 (concat "^\\([0-9]+:\\s-*<\\)[+]>\\s-+" (caar project-alist) "$") nil t)
14537 (goto-char (match-end 1))
14538 (speedbar-do-function-pointer)))
14539 (setq project-alist (cdr project-alist))))
14540; (vhdl-speedbar-update-current-project)
14541; (vhdl-speedbar-update-current-unit nil t)
14542 )
14543
14544(defun vhdl-speedbar-insert-project-hierarchy (project indent &optional rescan)
a4c6cfad 14545 "Insert hierarchy of PROJECT. Rescan directories if RESCAN is non-nil,
3dcb36b7
JB
14546otherwise use cached data."
14547 (when (or rescan (and (not (assoc project vhdl-file-alist))
14548 (not (vhdl-load-cache project))))
14549 (vhdl-scan-project-contents project))
14550 ;; insert design hierarchy
14551 (vhdl-speedbar-insert-hierarchy
14552 (aget vhdl-entity-alist project t)
14553 (aget vhdl-config-alist project t)
14554 (aget vhdl-package-alist project t)
14555 (car (aget vhdl-ent-inst-alist project t)) indent)
14556 (insert (int-to-string indent) ":\n")
14557 (put-text-property (- (point) 3) (1- (point)) 'invisible t)
14558 (put-text-property (1- (point)) (point) 'invisible nil)
14559 ;; expand design units
14560 (vhdl-speedbar-expand-units project))
14561
14562(defun vhdl-speedbar-insert-dir-hierarchy (directory depth &optional rescan)
14563 "Insert hierarchy of DIRECTORY. Rescan directory if RESCAN is non-nil,
14564otherwise use cached data."
14565 (when (or rescan (and (not (assoc directory vhdl-file-alist))
14566 (not (vhdl-load-cache directory))))
14567 (vhdl-scan-directory-contents directory))
14568 ;; insert design hierarchy
14569 (vhdl-speedbar-insert-hierarchy
14570 (aget vhdl-entity-alist directory t)
14571 (aget vhdl-config-alist directory t)
14572 (aget vhdl-package-alist directory t)
14573 (car (aget vhdl-ent-inst-alist directory t)) depth)
14574 ;; expand design units
14575 (vhdl-speedbar-expand-units directory)
14576 (aput 'vhdl-directory-alist directory (list (list directory))))
14577
14578(defun vhdl-speedbar-insert-hierarchy (ent-alist conf-alist pack-alist
5eabfe72 14579 ent-inst-list depth)
3dcb36b7
JB
14580 "Insert hierarchy of ENT-ALIST, CONF-ALIST, and PACK-ALIST."
14581 (if (not (or ent-alist conf-alist pack-alist))
14582 (vhdl-speedbar-make-title-line "No VHDL design units!" depth)
14583 (let (ent-entry conf-entry pack-entry)
5eabfe72
KH
14584 ;; insert entities
14585 (when ent-alist (vhdl-speedbar-make-title-line "Entities:" depth))
14586 (while ent-alist
14587 (setq ent-entry (car ent-alist))
14588 (speedbar-make-tag-line
14589 'bracket ?+ 'vhdl-speedbar-expand-entity (nth 0 ent-entry)
3dcb36b7
JB
14590 (nth 1 ent-entry) 'vhdl-speedbar-find-file
14591 (cons (nth 2 ent-entry) (nth 3 ent-entry))
0a2e512a 14592 'vhdl-speedbar-entity-face depth)
3dcb36b7
JB
14593 (unless (nth 2 ent-entry)
14594 (end-of-line 0) (insert "!") (forward-char 1))
14595 (unless (member (nth 0 ent-entry) ent-inst-list)
5eabfe72
KH
14596 (end-of-line 0) (insert " (top)") (forward-char 1))
14597 (setq ent-alist (cdr ent-alist)))
3dcb36b7
JB
14598 ;; insert configurations
14599 (when conf-alist (vhdl-speedbar-make-title-line "Configurations:" depth))
14600 (while conf-alist
14601 (setq conf-entry (car conf-alist))
14602 (speedbar-make-tag-line
14603 'bracket ?+ 'vhdl-speedbar-expand-config (nth 0 conf-entry)
14604 (nth 1 conf-entry) 'vhdl-speedbar-find-file
14605 (cons (nth 2 conf-entry) (nth 3 conf-entry))
0a2e512a 14606 'vhdl-speedbar-configuration-face depth)
3dcb36b7 14607 (setq conf-alist (cdr conf-alist)))
5eabfe72
KH
14608 ;; insert packages
14609 (when pack-alist (vhdl-speedbar-make-title-line "Packages:" depth))
14610 (while pack-alist
14611 (setq pack-entry (car pack-alist))
14612 (vhdl-speedbar-make-pack-line
3dcb36b7
JB
14613 (nth 0 pack-entry) (nth 1 pack-entry)
14614 (cons (nth 2 pack-entry) (nth 3 pack-entry))
14615 (cons (nth 7 pack-entry) (nth 8 pack-entry))
5eabfe72
KH
14616 depth)
14617 (setq pack-alist (cdr pack-alist))))))
14618
5eabfe72 14619(defun vhdl-speedbar-rescan-hierarchy ()
3dcb36b7 14620 "Rescan hierarchy for the directory or project under the cursor."
d2ddb974 14621 (interactive)
3dcb36b7
JB
14622 (let (key path)
14623 (cond
14624 ;; current project
14625 (vhdl-speedbar-show-projects
14626 (setq key (vhdl-speedbar-line-project))
14627 (vhdl-scan-project-contents key))
14628 ;; top-level directory
14629 ((save-excursion (beginning-of-line) (looking-at "[^0-9]"))
14630 (re-search-forward "[0-9]+:" nil t)
14631 (vhdl-scan-directory-contents
7752250e 14632 (abbreviate-file-name (speedbar-line-directory))))
3dcb36b7 14633 ;; current directory
7752250e 14634 (t (setq path (speedbar-line-directory))
3dcb36b7
JB
14635 (string-match "^\\(.+[/\\]\\)" path)
14636 (vhdl-scan-directory-contents
14637 (abbreviate-file-name (match-string 1 path)))))
14638 (vhdl-speedbar-refresh key)))
5eabfe72
KH
14639
14640(defun vhdl-speedbar-expand-dirs (directory)
14641 "Expand subdirectories in DIRECTORY according to
14642 `speedbar-shown-directories'."
14643 ;; (nicked from `speedbar-default-directory-list')
3dcb36b7
JB
14644 (let ((sf (cdr (reverse speedbar-shown-directories)))
14645 (vhdl-speedbar-update-current-unit nil))
5eabfe72
KH
14646 (setq speedbar-shown-directories
14647 (list (expand-file-name default-directory)))
14648 (while sf
14649 (when (speedbar-goto-this-file (car sf))
14650 (beginning-of-line)
14651 (when (looking-at "[0-9]+:\\s-*<")
14652 (goto-char (match-end 0))
3dcb36b7
JB
14653 (speedbar-do-function-pointer)))
14654 (setq sf (cdr sf))))
14655 (vhdl-speedbar-update-current-unit nil t))
14656
14657(defun vhdl-speedbar-expand-units (key)
14658 "Expand design units in directory/project KEY according to
14659`vhdl-speedbar-shown-unit-alist'."
14660 (let ((unit-alist (aget vhdl-speedbar-shown-unit-alist key t))
14661 (vhdl-speedbar-update-current-unit nil)
14662 vhdl-updated-project-list)
14663 (adelete 'vhdl-speedbar-shown-unit-alist key)
14664 (vhdl-prepare-search-1
14665 (while unit-alist ; expand units
14666 (vhdl-speedbar-goto-this-unit key (caar unit-alist))
14667 (beginning-of-line)
14668 (let ((arch-alist (nth 1 (car unit-alist)))
14669 position)
14670 (when (looking-at "^[0-9]+:\\s-*\\[")
14671 (goto-char (match-end 0))
14672 (setq position (point))
14673 (speedbar-do-function-pointer)
14674 (select-frame speedbar-frame)
14675 (while arch-alist ; expand architectures
14676 (goto-char position)
14677 (when (re-search-forward
14678 (concat "^[0-9]+:\\s-*\\(\\[\\|{.}\\s-+"
14679 (car arch-alist) "\\>\\)") nil t)
14680 (beginning-of-line)
14681 (when (looking-at "^[0-9]+:\\s-*{")
14682 (goto-char (match-end 0))
14683 (speedbar-do-function-pointer)
14684 (select-frame speedbar-frame)))
14685 (setq arch-alist (cdr arch-alist))))
14686 (setq unit-alist (cdr unit-alist))))))
14687 (vhdl-speedbar-update-current-unit nil t))
14688
14689(defun vhdl-speedbar-contract-level ()
14690 "Contract current level in current directory/project."
14691 (interactive)
14692 (when (or (save-excursion
14693 (beginning-of-line) (looking-at "^[0-9]:\\s-*[[{<]-"))
14694 (and (save-excursion
14695 (beginning-of-line) (looking-at "^\\([0-9]+\\):"))
14696 (re-search-backward
14697 (format "^[0-%d]:\\s-*[[{<]-"
027a4b6b 14698 (max (1- (string-to-number (match-string 1))) 0)) nil t)))
3dcb36b7
JB
14699 (goto-char (match-end 0))
14700 (speedbar-do-function-pointer)
14701 (speedbar-center-buffer-smartly)))
14702
14703(defun vhdl-speedbar-contract-all ()
14704 "Contract all expanded design units in current directory/project."
14705 (interactive)
14706 (if (and vhdl-speedbar-show-projects
14707 (save-excursion (beginning-of-line) (looking-at "^0:")))
14708 (progn (setq vhdl-speedbar-shown-project-list nil)
14709 (vhdl-speedbar-refresh))
14710 (let ((key (vhdl-speedbar-line-key)))
14711 (adelete 'vhdl-speedbar-shown-unit-alist key)
14712 (vhdl-speedbar-refresh (and vhdl-speedbar-show-projects key))
14713 (when (memq 'display vhdl-speedbar-save-cache)
14714 (add-to-list 'vhdl-updated-project-list key)))))
14715
14716(defun vhdl-speedbar-expand-all ()
14717 "Expand all design units in current directory/project."
14718 (interactive)
14719 (let* ((key (vhdl-speedbar-line-key))
14720 (ent-alist (aget vhdl-entity-alist key t))
14721 (conf-alist (aget vhdl-config-alist key t))
14722 (pack-alist (aget vhdl-package-alist key t))
14723 arch-alist unit-alist subunit-alist)
14724 (add-to-list 'vhdl-speedbar-shown-project-list key)
14725 (while ent-alist
14726 (setq arch-alist (nth 4 (car ent-alist)))
14727 (setq subunit-alist nil)
14728 (while arch-alist
14729 (setq subunit-alist (cons (caar arch-alist) subunit-alist))
14730 (setq arch-alist (cdr arch-alist)))
14731 (setq unit-alist (cons (list (caar ent-alist) subunit-alist) unit-alist))
14732 (setq ent-alist (cdr ent-alist)))
14733 (while conf-alist
14734 (setq unit-alist (cons (list (caar conf-alist)) unit-alist))
14735 (setq conf-alist (cdr conf-alist)))
14736 (while pack-alist
14737 (setq unit-alist (cons (list (caar pack-alist)) unit-alist))
14738 (setq pack-alist (cdr pack-alist)))
14739 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist)
14740 (vhdl-speedbar-refresh)
14741 (when (memq 'display vhdl-speedbar-save-cache)
14742 (add-to-list 'vhdl-updated-project-list key))))
14743
14744(defun vhdl-speedbar-expand-project (text token indent)
14745 "Expand/contract the project under the cursor."
14746 (cond
14747 ((string-match "+" text) ; expand project
14748 (speedbar-change-expand-button-char ?-)
14749 (unless (member token vhdl-speedbar-shown-project-list)
14750 (setq vhdl-speedbar-shown-project-list
14751 (cons token vhdl-speedbar-shown-project-list)))
14752 (speedbar-with-writable
14753 (save-excursion
14754 (end-of-line) (forward-char 1)
14755 (vhdl-speedbar-insert-project-hierarchy token (1+ indent)
14756 speedbar-power-click))))
14757 ((string-match "-" text) ; contract project
14758 (speedbar-change-expand-button-char ?+)
14759 (setq vhdl-speedbar-shown-project-list
14760 (delete token vhdl-speedbar-shown-project-list))
14761 (speedbar-delete-subblock indent))
14762 (t (error "Nothing to display")))
14763 (when (equal (selected-frame) speedbar-frame)
14764 (speedbar-center-buffer-smartly)))
5eabfe72
KH
14765
14766(defun vhdl-speedbar-expand-entity (text token indent)
14767 "Expand/contract the entity under the cursor."
14768 (cond
14769 ((string-match "+" text) ; expand entity
3dcb36b7
JB
14770 (let* ((key (vhdl-speedbar-line-key indent))
14771 (ent-alist (aget vhdl-entity-alist key t))
14772 (ent-entry (aget ent-alist token t))
14773 (arch-alist (nth 3 ent-entry))
5eabfe72 14774 (inst-alist (vhdl-get-instantiations token indent))
0a2e512a
RF
14775 (subpack-alist (nth 5 ent-entry))
14776 (multiple-arch (> (length arch-alist) 1))
3dcb36b7
JB
14777 arch-entry inst-entry)
14778 (if (not (or arch-alist inst-alist subpack-alist))
5eabfe72
KH
14779 (speedbar-change-expand-button-char ??)
14780 (speedbar-change-expand-button-char ?-)
3dcb36b7
JB
14781 ;; add entity to `vhdl-speedbar-shown-unit-alist'
14782 (let* ((unit-alist (aget vhdl-speedbar-shown-unit-alist key t)))
14783 (aput 'unit-alist token nil)
14784 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist))
5eabfe72 14785 (speedbar-with-writable
3dcb36b7
JB
14786 (save-excursion
14787 (end-of-line) (forward-char 1)
14788 ;; insert architectures
14789 (when arch-alist
14790 (vhdl-speedbar-make-title-line "Architectures:" (1+ indent)))
14791 (while arch-alist
14792 (setq arch-entry (car arch-alist))
14793 (speedbar-make-tag-line
14794 'curly ?+ 'vhdl-speedbar-expand-architecture
14795 (cons token (nth 0 arch-entry))
14796 (nth 1 arch-entry) 'vhdl-speedbar-find-file
14797 (cons (nth 2 arch-entry) (nth 3 arch-entry))
0a2e512a
RF
14798 'vhdl-speedbar-architecture-face (1+ indent))
14799 (when (and multiple-arch
14800 (equal (nth 0 arch-entry) (nth 4 ent-entry)))
14801 (end-of-line 0) (insert " (mra)") (forward-char 1))
3dcb36b7
JB
14802 (setq arch-alist (cdr arch-alist)))
14803 ;; insert instantiations
14804 (when inst-alist
14805 (vhdl-speedbar-make-title-line "Instantiated as:" (1+ indent)))
14806 (while inst-alist
14807 (setq inst-entry (car inst-alist))
14808 (vhdl-speedbar-make-inst-line
14809 (nth 0 inst-entry) (nth 1 inst-entry) (nth 2 inst-entry)
14810 (nth 3 inst-entry) (nth 4 inst-entry) (nth 5 inst-entry)
14811 nil nil nil (1+ indent) 0 " in ")
14812 (setq inst-alist (cdr inst-alist)))
14813 ;; insert required packages
14814 (vhdl-speedbar-insert-subpackages
14815 subpack-alist (1+ indent) indent)))
14816 (when (memq 'display vhdl-speedbar-save-cache)
14817 (add-to-list 'vhdl-updated-project-list key))
14818 (vhdl-speedbar-update-current-unit t t))))
5eabfe72
KH
14819 ((string-match "-" text) ; contract entity
14820 (speedbar-change-expand-button-char ?+)
3dcb36b7
JB
14821 ;; remove entity from `vhdl-speedbar-shown-unit-alist'
14822 (let* ((key (vhdl-speedbar-line-key indent))
14823 (unit-alist (aget vhdl-speedbar-shown-unit-alist key t)))
14824 (adelete 'unit-alist token)
14825 (if unit-alist
14826 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist)
14827 (adelete 'vhdl-speedbar-shown-unit-alist key))
14828 (speedbar-delete-subblock indent)
14829 (when (memq 'display vhdl-speedbar-save-cache)
14830 (add-to-list 'vhdl-updated-project-list key))))
14831 (t (error "Nothing to display")))
14832 (when (equal (selected-frame) speedbar-frame)
14833 (speedbar-center-buffer-smartly)))
5eabfe72
KH
14834
14835(defun vhdl-speedbar-expand-architecture (text token indent)
14836 "Expand/contract the architecture under the cursor."
14837 (cond
14838 ((string-match "+" text) ; expand architecture
3dcb36b7
JB
14839 (let* ((key (vhdl-speedbar-line-key (1- indent)))
14840 (ent-alist (aget vhdl-entity-alist key t))
14841 (conf-alist (aget vhdl-config-alist key t))
14842 (hier-alist (vhdl-get-hierarchy
14843 ent-alist conf-alist (car token) (cdr token) nil nil
14844 0 (1- indent)))
14845 (ent-entry (aget ent-alist (car token) t))
14846 (arch-entry (aget (nth 3 ent-entry) (cdr token) t))
14847 (subpack-alist (nth 4 arch-entry))
14848 entry)
14849 (if (not (or hier-alist subpack-alist))
14850 (speedbar-change-expand-button-char ??)
14851 (speedbar-change-expand-button-char ?-)
14852 ;; add architecture to `vhdl-speedbar-shown-unit-alist'
14853 (let* ((unit-alist (aget vhdl-speedbar-shown-unit-alist key t))
14854 (arch-alist (nth 0 (aget unit-alist (car token) t))))
14855 (aput 'unit-alist (car token) (list (cons (cdr token) arch-alist)))
14856 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist))
14857 (speedbar-with-writable
14858 (save-excursion
14859 (end-of-line) (forward-char 1)
14860 ;; insert instance hierarchy
14861 (when hier-alist
14862 (vhdl-speedbar-make-title-line "Subcomponent hierarchy:"
14863 (1+ indent)))
14864 (while hier-alist
14865 (setq entry (car hier-alist))
14866 (when (or (= vhdl-speedbar-hierarchy-depth 0)
14867 (< (nth 9 entry) vhdl-speedbar-hierarchy-depth))
14868 (vhdl-speedbar-make-inst-line
14869 (nth 0 entry) (nth 1 entry) (nth 2 entry) (nth 3 entry)
14870 (nth 4 entry) (nth 5 entry) (nth 6 entry) (nth 7 entry)
14871 (nth 8 entry) (1+ indent) (1+ (nth 9 entry)) ": "))
14872 (setq hier-alist (cdr hier-alist)))
14873 ;; insert required packages
14874 (vhdl-speedbar-insert-subpackages
14875 subpack-alist (1+ indent) (1- indent))))
14876 (when (memq 'display vhdl-speedbar-save-cache)
14877 (add-to-list 'vhdl-updated-project-list key))
14878 (vhdl-speedbar-update-current-unit t t))))
14879 ((string-match "-" text) ; contract architecture
14880 (speedbar-change-expand-button-char ?+)
14881 ;; remove architecture from `vhdl-speedbar-shown-unit-alist'
14882 (let* ((key (vhdl-speedbar-line-key (1- indent)))
14883 (unit-alist (aget vhdl-speedbar-shown-unit-alist key t))
14884 (arch-alist (nth 0 (aget unit-alist (car token) t))))
14885 (aput 'unit-alist (car token) (list (delete (cdr token) arch-alist)))
14886 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist)
14887 (speedbar-delete-subblock indent)
14888 (when (memq 'display vhdl-speedbar-save-cache)
14889 (add-to-list 'vhdl-updated-project-list key))))
14890 (t (error "Nothing to display")))
14891 (when (equal (selected-frame) speedbar-frame)
14892 (speedbar-center-buffer-smartly)))
14893
14894(defun vhdl-speedbar-expand-config (text token indent)
14895 "Expand/contract the configuration under the cursor."
14896 (cond
14897 ((string-match "+" text) ; expand configuration
14898 (let* ((key (vhdl-speedbar-line-key indent))
14899 (conf-alist (aget vhdl-config-alist key t))
14900 (conf-entry (aget conf-alist token))
14901 (ent-alist (aget vhdl-entity-alist key t))
14902 (hier-alist (vhdl-get-hierarchy
14903 ent-alist conf-alist (nth 3 conf-entry)
14904 (nth 4 conf-entry) token (nth 5 conf-entry)
14905 0 indent t))
14906 (subpack-alist (nth 6 conf-entry))
14907 entry)
14908 (if (not (or hier-alist subpack-alist))
5eabfe72
KH
14909 (speedbar-change-expand-button-char ??)
14910 (speedbar-change-expand-button-char ?-)
3dcb36b7
JB
14911 ;; add configuration to `vhdl-speedbar-shown-unit-alist'
14912 (let* ((unit-alist (aget vhdl-speedbar-shown-unit-alist key t)))
14913 (aput 'unit-alist token nil)
14914 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist))
5eabfe72
KH
14915 (speedbar-with-writable
14916 (save-excursion
14917 (end-of-line) (forward-char 1)
14918 ;; insert instance hierarchy
14919 (when hier-alist
3dcb36b7 14920 (vhdl-speedbar-make-title-line "Design hierarchy:" (1+ indent)))
5eabfe72 14921 (while hier-alist
3dcb36b7
JB
14922 (setq entry (car hier-alist))
14923 (when (or (= vhdl-speedbar-hierarchy-depth 0)
14924 (<= (nth 9 entry) vhdl-speedbar-hierarchy-depth))
5eabfe72 14925 (vhdl-speedbar-make-inst-line
3dcb36b7
JB
14926 (nth 0 entry) (nth 1 entry) (nth 2 entry) (nth 3 entry)
14927 (nth 4 entry) (nth 5 entry) (nth 6 entry) (nth 7 entry)
14928 (nth 8 entry) (1+ indent) (nth 9 entry) ": "))
14929 (setq hier-alist (cdr hier-alist)))
14930 ;; insert required packages
14931 (vhdl-speedbar-insert-subpackages
14932 subpack-alist (1+ indent) indent)))
14933 (when (memq 'display vhdl-speedbar-save-cache)
14934 (add-to-list 'vhdl-updated-project-list key))
14935 (vhdl-speedbar-update-current-unit t t))))
14936 ((string-match "-" text) ; contract configuration
5eabfe72 14937 (speedbar-change-expand-button-char ?+)
3dcb36b7
JB
14938 ;; remove configuration from `vhdl-speedbar-shown-unit-alist'
14939 (let* ((key (vhdl-speedbar-line-key indent))
14940 (unit-alist (aget vhdl-speedbar-shown-unit-alist key t)))
14941 (adelete 'unit-alist token)
14942 (if unit-alist
14943 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist)
14944 (adelete 'vhdl-speedbar-shown-unit-alist key))
14945 (speedbar-delete-subblock indent)
14946 (when (memq 'display vhdl-speedbar-save-cache)
14947 (add-to-list 'vhdl-updated-project-list key))))
14948 (t (error "Nothing to display")))
14949 (when (equal (selected-frame) speedbar-frame)
14950 (speedbar-center-buffer-smartly)))
14951
14952(defun vhdl-speedbar-expand-package (text token indent)
14953 "Expand/contract the package under the cursor."
14954 (cond
14955 ((string-match "+" text) ; expand package
14956 (let* ((key (vhdl-speedbar-line-key indent))
14957 (pack-alist (aget vhdl-package-alist key t))
14958 (pack-entry (aget pack-alist token t))
14959 (comp-alist (nth 3 pack-entry))
14960 (func-alist (nth 4 pack-entry))
14961 (func-body-alist (nth 8 pack-entry))
14962 (subpack-alist (append (nth 5 pack-entry) (nth 9 pack-entry)))
14963 comp-entry func-entry func-body-entry)
14964 (if (not (or comp-alist func-alist subpack-alist))
14965 (speedbar-change-expand-button-char ??)
14966 (speedbar-change-expand-button-char ?-)
14967 ;; add package to `vhdl-speedbar-shown-unit-alist'
14968 (let* ((unit-alist (aget vhdl-speedbar-shown-unit-alist key t)))
14969 (aput 'unit-alist token nil)
14970 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist))
14971 (speedbar-with-writable
14972 (save-excursion
14973 (end-of-line) (forward-char 1)
14974 ;; insert components
14975 (when comp-alist
14976 (vhdl-speedbar-make-title-line "Components:" (1+ indent)))
14977 (while comp-alist
14978 (setq comp-entry (car comp-alist))
14979 (speedbar-make-tag-line
14980 nil nil nil
14981 (cons token (nth 0 comp-entry))
14982 (nth 1 comp-entry) 'vhdl-speedbar-find-file
14983 (cons (nth 2 comp-entry) (nth 3 comp-entry))
0a2e512a 14984 'vhdl-speedbar-entity-face (1+ indent))
3dcb36b7
JB
14985 (setq comp-alist (cdr comp-alist)))
14986 ;; insert subprograms
14987 (when func-alist
14988 (vhdl-speedbar-make-title-line "Subprograms:" (1+ indent)))
14989 (while func-alist
14990 (setq func-entry (car func-alist)
14991 func-body-entry (aget func-body-alist (car func-entry) t))
14992 (when (nth 2 func-entry)
14993 (vhdl-speedbar-make-subprogram-line
14994 (nth 1 func-entry)
14995 (cons (nth 2 func-entry) (nth 3 func-entry))
14996 (cons (nth 1 func-body-entry) (nth 2 func-body-entry))
14997 (1+ indent)))
14998 (setq func-alist (cdr func-alist)))
14999 ;; insert required packages
15000 (vhdl-speedbar-insert-subpackages
15001 subpack-alist (1+ indent) indent)))
15002 (when (memq 'display vhdl-speedbar-save-cache)
15003 (add-to-list 'vhdl-updated-project-list key))
15004 (vhdl-speedbar-update-current-unit t t))))
15005 ((string-match "-" text) ; contract package
15006 (speedbar-change-expand-button-char ?+)
15007 ;; remove package from `vhdl-speedbar-shown-unit-alist'
15008 (let* ((key (vhdl-speedbar-line-key indent))
15009 (unit-alist (aget vhdl-speedbar-shown-unit-alist key t)))
15010 (adelete 'unit-alist token)
15011 (if unit-alist
15012 (aput 'vhdl-speedbar-shown-unit-alist key unit-alist)
15013 (adelete 'vhdl-speedbar-shown-unit-alist key))
15014 (speedbar-delete-subblock indent)
15015 (when (memq 'display vhdl-speedbar-save-cache)
15016 (add-to-list 'vhdl-updated-project-list key))))
15017 (t (error "Nothing to display")))
15018 (when (equal (selected-frame) speedbar-frame)
15019 (speedbar-center-buffer-smartly)))
15020
15021(defun vhdl-speedbar-insert-subpackages (subpack-alist indent dir-indent)
15022 "Insert required packages."
15023 (let* ((pack-alist (aget vhdl-package-alist
15024 (vhdl-speedbar-line-key dir-indent) t))
15025 pack-key lib-name pack-entry)
15026 (when subpack-alist
15027 (vhdl-speedbar-make-title-line "Packages Used:" indent))
15028 (while subpack-alist
15029 (setq pack-key (cdar subpack-alist)
15030 lib-name (caar subpack-alist))
15031 (setq pack-entry (aget pack-alist pack-key t))
15032 (vhdl-speedbar-make-subpack-line
15033 (or (nth 0 pack-entry) pack-key) lib-name
0a2e512a
RF
15034 (cons (nth 1 pack-entry) (nth 2 pack-entry))
15035 (cons (nth 6 pack-entry) (nth 7 pack-entry)) indent)
3dcb36b7 15036 (setq subpack-alist (cdr subpack-alist)))))
5eabfe72
KH
15037
15038;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15039;; Display help functions
15040
3dcb36b7
JB
15041(defvar vhdl-speedbar-update-current-unit t
15042 "Non-nil means to run `vhdl-speedbar-update-current-unit'.")
15043
15044(defun vhdl-speedbar-update-current-project ()
15045 "Highlight project that is currently active."
15046 (when (and vhdl-speedbar-show-projects
15047 (not (equal vhdl-speedbar-last-selected-project vhdl-project))
15048 (and (boundp 'speedbar-frame)
15049 (frame-live-p speedbar-frame)))
15050 (let ((last-frame (selected-frame))
15051 (project-alist vhdl-project-alist)
15052 pos)
15053 (select-frame speedbar-frame)
15054 (speedbar-with-writable
15055 (save-excursion
15056 (while project-alist
15057 (goto-char (point-min))
15058 (when (re-search-forward
15059 (concat "<.> \\(" (caar project-alist) "\\)$") nil t)
15060 (put-text-property (match-beginning 1) (match-end 1) 'face
15061 (if (equal (caar project-alist) vhdl-project)
15062 'speedbar-selected-face
15063 'speedbar-directory-face))
15064 (when (equal (caar project-alist) vhdl-project)
15065 (setq pos (1- (match-beginning 1)))))
15066 (setq project-alist (cdr project-alist))))
15067 (when pos (goto-char pos)))
15068 (select-frame last-frame)
15069 (setq vhdl-speedbar-last-selected-project vhdl-project)))
15070 t)
15071
15072(defun vhdl-speedbar-update-current-unit (&optional no-position always)
5eabfe72
KH
15073 "Highlight all design units that are contained in the current file.
15074NO-POSITION non-nil means do not re-position cursor."
15075 (let ((last-frame (selected-frame))
3dcb36b7
JB
15076 (project-list vhdl-speedbar-shown-project-list)
15077 file-alist pos file-name)
5eabfe72 15078 ;; get current file name
3dcb36b7
JB
15079 (if (fboundp 'speedbar-select-attached-frame)
15080 (speedbar-select-attached-frame)
15081 (select-frame speedbar-attached-frame))
5eabfe72 15082 (setq file-name (abbreviate-file-name (or (buffer-file-name) "")))
3dcb36b7
JB
15083 (when (and vhdl-speedbar-update-current-unit
15084 (or always (not (equal file-name speedbar-last-selected-file))))
15085 (if vhdl-speedbar-show-projects
15086 (while project-list
15087 (setq file-alist (append file-alist (aget vhdl-file-alist
15088 (car project-list) t)))
15089 (setq project-list (cdr project-list)))
15090 (setq file-alist (aget vhdl-file-alist
15091 (abbreviate-file-name default-directory) t)))
5eabfe72
KH
15092 (select-frame speedbar-frame)
15093 (set-buffer speedbar-buffer)
15094 (speedbar-with-writable
3dcb36b7 15095 (vhdl-prepare-search-1
5eabfe72
KH
15096 (save-excursion
15097 ;; unhighlight last units
3dcb36b7 15098 (let* ((file-entry (aget file-alist speedbar-last-selected-file t)))
5eabfe72 15099 (vhdl-speedbar-update-units
3dcb36b7 15100 "\\[.\\] " (nth 0 file-entry)
0a2e512a 15101 speedbar-last-selected-file 'vhdl-speedbar-entity-face)
5eabfe72 15102 (vhdl-speedbar-update-units
3dcb36b7 15103 "{.} " (nth 1 file-entry)
0a2e512a 15104 speedbar-last-selected-file 'vhdl-speedbar-architecture-face)
5eabfe72 15105 (vhdl-speedbar-update-units
3dcb36b7 15106 "\\[.\\] " (nth 3 file-entry)
0a2e512a 15107 speedbar-last-selected-file 'vhdl-speedbar-configuration-face)
5eabfe72 15108 (vhdl-speedbar-update-units
3dcb36b7 15109 "[]>] " (nth 4 file-entry)
0a2e512a 15110 speedbar-last-selected-file 'vhdl-speedbar-package-face)
5eabfe72 15111 (vhdl-speedbar-update-units
3dcb36b7 15112 "\\[.\\].+(" '("body")
0a2e512a 15113 speedbar-last-selected-file 'vhdl-speedbar-package-face)
3dcb36b7
JB
15114 (vhdl-speedbar-update-units
15115 "> " (nth 6 file-entry)
0a2e512a 15116 speedbar-last-selected-file 'vhdl-speedbar-instantiation-face))
5eabfe72 15117 ;; highlight current units
3dcb36b7
JB
15118 (let* ((file-entry (aget file-alist file-name t)))
15119 (setq
15120 pos (vhdl-speedbar-update-units
15121 "\\[.\\] " (nth 0 file-entry)
0a2e512a 15122 file-name 'vhdl-speedbar-entity-selected-face pos)
3dcb36b7
JB
15123 pos (vhdl-speedbar-update-units
15124 "{.} " (nth 1 file-entry)
0a2e512a 15125 file-name 'vhdl-speedbar-architecture-selected-face pos)
3dcb36b7
JB
15126 pos (vhdl-speedbar-update-units
15127 "\\[.\\] " (nth 3 file-entry)
0a2e512a 15128 file-name 'vhdl-speedbar-configuration-selected-face pos)
3dcb36b7
JB
15129 pos (vhdl-speedbar-update-units
15130 "[]>] " (nth 4 file-entry)
0a2e512a 15131 file-name 'vhdl-speedbar-package-selected-face pos)
3dcb36b7
JB
15132 pos (vhdl-speedbar-update-units
15133 "\\[.\\].+(" '("body")
0a2e512a 15134 file-name 'vhdl-speedbar-package-selected-face pos)
3dcb36b7
JB
15135 pos (vhdl-speedbar-update-units
15136 "> " (nth 6 file-entry)
0a2e512a 15137 file-name 'vhdl-speedbar-instantiation-selected-face pos))))))
5eabfe72 15138 ;; move speedbar so the first highlighted unit is visible
3dcb36b7
JB
15139 (when (and pos (not no-position))
15140 (goto-char pos)
15141 (speedbar-center-buffer-smartly)
5eabfe72
KH
15142 (speedbar-position-cursor-on-line))
15143 (setq speedbar-last-selected-file file-name))
15144 (select-frame last-frame)
15145 t))
15146
3dcb36b7
JB
15147(defun vhdl-speedbar-update-units (text unit-list file-name face
15148 &optional pos)
5eabfe72 15149 "Help function to highlight design units."
3dcb36b7
JB
15150 (while unit-list
15151 (goto-char (point-min))
15152 (while (re-search-forward
15153 (concat text "\\(" (car unit-list) "\\)\\>") nil t)
15154 (when (equal file-name (car (get-text-property
15155 (match-beginning 1) 'speedbar-token)))
15156 (setq pos (or pos (point-marker)))
15157 (put-text-property (match-beginning 1) (match-end 1) 'face face)))
15158 (setq unit-list (cdr unit-list)))
15159 pos)
5eabfe72
KH
15160
15161(defun vhdl-speedbar-make-inst-line (inst-name inst-file-marker
3dcb36b7
JB
15162 ent-name ent-file-marker
15163 arch-name arch-file-marker
15164 conf-name conf-file-marker
15165 lib-name depth offset delimiter)
5eabfe72 15166 "Insert instantiation entry."
3dcb36b7
JB
15167 (let ((start (point))
15168 visible-start)
5eabfe72
KH
15169 (insert (int-to-string depth) ":")
15170 (put-text-property start (point) 'invisible t)
3dcb36b7
JB
15171 (setq visible-start (point))
15172 (insert-char ? (* depth speedbar-indentation-width))
15173 (while (> offset 0)
15174 (insert "|")
15175 (insert-char (if (= offset 1) ?- ? ) (1- speedbar-indentation-width))
15176 (setq offset (1- offset)))
15177 (put-text-property visible-start (point) 'invisible nil)
5eabfe72 15178 (setq start (point))
3dcb36b7
JB
15179 (insert ">")
15180 (speedbar-make-button start (point) nil nil nil)
15181 (setq visible-start (point))
15182 (insert " ")
5eabfe72 15183 (setq start (point))
3dcb36b7
JB
15184 (if (not inst-name)
15185 (insert "(top)")
15186 (insert inst-name)
15187 (speedbar-make-button
0a2e512a 15188 start (point) 'vhdl-speedbar-instantiation-face 'speedbar-highlight-face
3dcb36b7
JB
15189 'vhdl-speedbar-find-file inst-file-marker))
15190 (insert delimiter)
15191 (when ent-name
5eabfe72 15192 (setq start (point))
3dcb36b7 15193 (insert ent-name)
5eabfe72 15194 (speedbar-make-button
0a2e512a 15195 start (point) 'vhdl-speedbar-entity-face 'speedbar-highlight-face
3dcb36b7
JB
15196 'vhdl-speedbar-find-file ent-file-marker)
15197 (when arch-name
15198 (insert " (")
15199 (setq start (point))
15200 (insert arch-name)
15201 (speedbar-make-button
0a2e512a 15202 start (point) 'vhdl-speedbar-architecture-face 'speedbar-highlight-face
3dcb36b7
JB
15203 'vhdl-speedbar-find-file arch-file-marker)
15204 (insert ")"))
15205 (when conf-name
15206 (insert " (")
15207 (setq start (point))
15208 (insert conf-name)
15209 (speedbar-make-button
0a2e512a 15210 start (point) 'vhdl-speedbar-configuration-face 'speedbar-highlight-face
3dcb36b7
JB
15211 'vhdl-speedbar-find-file conf-file-marker)
15212 (insert ")")))
15213 (when (and lib-name (not (equal lib-name (downcase (vhdl-work-library)))))
5eabfe72 15214 (setq start (point))
3dcb36b7
JB
15215 (insert " (" lib-name ")")
15216 (put-text-property (+ 2 start) (1- (point)) 'face
0a2e512a 15217 'vhdl-speedbar-library-face))
5eabfe72 15218 (insert-char ?\n 1)
3dcb36b7 15219 (put-text-property visible-start (point) 'invisible nil)))
5eabfe72 15220
3dcb36b7
JB
15221(defun vhdl-speedbar-make-pack-line (pack-key pack-name pack-file-marker
15222 body-file-marker depth)
5eabfe72 15223 "Insert package entry."
3dcb36b7
JB
15224 (let ((start (point))
15225 visible-start)
5eabfe72
KH
15226 (insert (int-to-string depth) ":")
15227 (put-text-property start (point) 'invisible t)
3dcb36b7
JB
15228 (setq visible-start (point))
15229 (insert-char ? (* depth speedbar-indentation-width))
15230 (put-text-property visible-start (point) 'invisible nil)
5eabfe72 15231 (setq start (point))
3dcb36b7
JB
15232 (insert "[+]")
15233 (speedbar-make-button
15234 start (point) 'speedbar-button-face 'speedbar-highlight-face
15235 'vhdl-speedbar-expand-package pack-key)
15236 (setq visible-start (point))
15237 (insert-char ? 1 nil)
5eabfe72
KH
15238 (setq start (point))
15239 (insert pack-name)
15240 (speedbar-make-button
0a2e512a 15241 start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face
5eabfe72 15242 'vhdl-speedbar-find-file pack-file-marker)
3dcb36b7
JB
15243 (unless (car pack-file-marker)
15244 (insert "!"))
5eabfe72 15245 (when (car body-file-marker)
5eabfe72 15246 (insert " (")
5eabfe72
KH
15247 (setq start (point))
15248 (insert "body")
15249 (speedbar-make-button
0a2e512a 15250 start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face
5eabfe72 15251 'vhdl-speedbar-find-file body-file-marker)
3dcb36b7 15252 (insert ")"))
5eabfe72 15253 (insert-char ?\n 1)
3dcb36b7 15254 (put-text-property visible-start (point) 'invisible nil)))
5eabfe72 15255
3dcb36b7 15256(defun vhdl-speedbar-make-subpack-line (pack-name lib-name pack-file-marker
0a2e512a 15257 pack-body-file-marker depth)
3dcb36b7
JB
15258 "Insert used package entry."
15259 (let ((start (point))
15260 visible-start)
15261 (insert (int-to-string depth) ":")
15262 (put-text-property start (point) 'invisible t)
15263 (setq visible-start (point))
15264 (insert-char ? (* depth speedbar-indentation-width))
15265 (put-text-property visible-start (point) 'invisible nil)
15266 (setq start (point))
15267 (insert ">")
15268 (speedbar-make-button start (point) nil nil nil)
15269 (setq visible-start (point))
15270 (insert " ")
15271 (setq start (point))
15272 (insert pack-name)
15273 (speedbar-make-button
0a2e512a 15274 start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face
3dcb36b7 15275 'vhdl-speedbar-find-file pack-file-marker)
0a2e512a
RF
15276 (when (car pack-body-file-marker)
15277 (insert " (")
15278 (setq start (point))
15279 (insert "body")
15280 (speedbar-make-button
15281 start (point) 'vhdl-speedbar-package-face 'speedbar-highlight-face
15282 'vhdl-speedbar-find-file pack-body-file-marker)
15283 (insert ")"))
3dcb36b7
JB
15284 (setq start (point))
15285 (insert " (" lib-name ")")
15286 (put-text-property (+ 2 start) (1- (point)) 'face
0a2e512a 15287 'vhdl-speedbar-library-face)
3dcb36b7
JB
15288 (insert-char ?\n 1)
15289 (put-text-property visible-start (point) 'invisible nil)))
15290
15291(defun vhdl-speedbar-make-subprogram-line (func-name func-file-marker
15292 func-body-file-marker
15293 depth)
15294 "Insert subprogram entry."
15295 (let ((start (point))
15296 visible-start)
5eabfe72
KH
15297 (insert (int-to-string depth) ":")
15298 (put-text-property start (point) 'invisible t)
3dcb36b7
JB
15299 (setq visible-start (point))
15300 (insert-char ? (* depth speedbar-indentation-width))
15301 (put-text-property visible-start (point) 'invisible nil)
15302 (setq start (point))
15303 (insert ">")
15304 (speedbar-make-button start (point) nil nil nil)
15305 (setq visible-start (point))
15306 (insert " ")
5eabfe72 15307 (setq start (point))
3dcb36b7
JB
15308 (insert func-name)
15309 (speedbar-make-button
0a2e512a 15310 start (point) 'vhdl-speedbar-subprogram-face 'speedbar-highlight-face
3dcb36b7
JB
15311 'vhdl-speedbar-find-file func-file-marker)
15312 (when (car func-body-file-marker)
15313 (insert " (")
15314 (setq start (point))
15315 (insert "body")
15316 (speedbar-make-button
0a2e512a 15317 start (point) 'vhdl-speedbar-subprogram-face 'speedbar-highlight-face
3dcb36b7
JB
15318 'vhdl-speedbar-find-file func-body-file-marker)
15319 (insert ")"))
15320 (insert-char ?\n 1)
15321 (put-text-property visible-start (point) 'invisible nil)))
15322
15323(defun vhdl-speedbar-make-title-line (text &optional depth)
15324 "Insert design unit title entry."
15325 (let ((start (point))
15326 visible-start)
15327 (when depth
15328 (insert (int-to-string depth) ":")
15329 (put-text-property start (point) 'invisible t))
15330 (setq visible-start (point))
15331 (insert-char ? (* (or depth 0) speedbar-indentation-width))
5eabfe72
KH
15332 (setq start (point))
15333 (insert text)
15334 (speedbar-make-button start (point) nil nil nil nil)
15335 (insert-char ?\n 1)
3dcb36b7 15336 (put-text-property visible-start (point) 'invisible nil)))
5eabfe72
KH
15337
15338(defun vhdl-speedbar-insert-dirs (files level)
15339 "Insert subdirectories."
15340 (let ((dirs (car files)))
15341 (while dirs
15342 (speedbar-make-tag-line 'angle ?+ 'vhdl-speedbar-dired (car dirs)
15343 (car dirs) 'speedbar-dir-follow nil
15344 'speedbar-directory-face level)
15345 (setq dirs (cdr dirs)))))
15346
15347(defun vhdl-speedbar-dired (text token indent)
15348 "Speedbar click handler for directory expand button in hierarchy mode."
15349 (cond ((string-match "+" text) ; we have to expand this dir
15350 (setq speedbar-shown-directories
15351 (cons (expand-file-name
7752250e 15352 (concat (speedbar-line-directory indent) token "/"))
5eabfe72
KH
15353 speedbar-shown-directories))
15354 (speedbar-change-expand-button-char ?-)
15355 (speedbar-reset-scanners)
15356 (speedbar-with-writable
15357 (save-excursion
15358 (end-of-line) (forward-char 1)
15359 (vhdl-speedbar-insert-dirs
15360 (speedbar-file-lists
7752250e 15361 (concat (speedbar-line-directory indent) token "/"))
5eabfe72
KH
15362 (1+ indent))
15363 (speedbar-reset-scanners)
15364 (vhdl-speedbar-insert-dir-hierarchy
15365 (abbreviate-file-name
7752250e 15366 (concat (speedbar-line-directory indent) token "/"))
5eabfe72 15367 (1+ indent) speedbar-power-click)))
3dcb36b7 15368 (vhdl-speedbar-update-current-unit t t))
5eabfe72
KH
15369 ((string-match "-" text) ; we have to contract this node
15370 (speedbar-reset-scanners)
15371 (let ((oldl speedbar-shown-directories)
15372 (newl nil)
15373 (td (expand-file-name
7752250e 15374 (concat (speedbar-line-directory indent) token))))
5eabfe72
KH
15375 (while oldl
15376 (if (not (string-match (concat "^" (regexp-quote td)) (car oldl)))
15377 (setq newl (cons (car oldl) newl)))
15378 (setq oldl (cdr oldl)))
15379 (setq speedbar-shown-directories (nreverse newl)))
15380 (speedbar-change-expand-button-char ?+)
15381 (speedbar-delete-subblock indent))
3dcb36b7
JB
15382 (t (error "Nothing to display")))
15383 (when (equal (selected-frame) speedbar-frame)
15384 (speedbar-center-buffer-smartly)))
5eabfe72
KH
15385
15386(defun vhdl-speedbar-item-info ()
15387 "Derive and display information about this line item."
15388 (save-excursion
15389 (beginning-of-line)
15390 ;; skip invisible number info
3dcb36b7 15391 (when (looking-at "^[0-9]+:") (goto-char (match-end 0)))
5eabfe72 15392 (cond
3dcb36b7
JB
15393 ;; project/directory entry
15394 ((looking-at "\\s-*<[-+?]>\\s-+\\([^\n]+\\)$")
15395 (if vhdl-speedbar-show-projects
15396 (message "Project \"%s\"" (match-string-no-properties 1))
15397 (speedbar-files-item-info)))
5eabfe72 15398 ;; design unit entry
3dcb36b7
JB
15399 ((looking-at "\\(\\s-*\\([[{][-+?][]}]\\|[| -]*>\\) \\)\"?\\w")
15400 (goto-char (match-end 1))
5eabfe72
KH
15401 (let ((face (get-text-property (point) 'face)))
15402 (message
15403 "%s \"%s\" in \"%s\""
15404 ;; design unit kind
0a2e512a
RF
15405 (cond ((or (eq face 'vhdl-speedbar-entity-face)
15406 (eq face 'vhdl-speedbar-entity-selected-face))
3dcb36b7 15407 (if (equal (match-string 2) ">") "Component" "Entity"))
0a2e512a
RF
15408 ((or (eq face 'vhdl-speedbar-architecture-face)
15409 (eq face 'vhdl-speedbar-architecture-selected-face))
5eabfe72 15410 "Architecture")
0a2e512a
RF
15411 ((or (eq face 'vhdl-speedbar-configuration-face)
15412 (eq face 'vhdl-speedbar-configuration-selected-face))
5eabfe72 15413 "Configuration")
0a2e512a
RF
15414 ((or (eq face 'vhdl-speedbar-package-face)
15415 (eq face 'vhdl-speedbar-package-selected-face))
5eabfe72 15416 "Package")
0a2e512a
RF
15417 ((or (eq face 'vhdl-speedbar-instantiation-face)
15418 (eq face 'vhdl-speedbar-instantiation-selected-face))
5eabfe72 15419 "Instantiation")
0a2e512a 15420 ((eq face 'vhdl-speedbar-subprogram-face)
3dcb36b7 15421 "Subprogram")
5eabfe72
KH
15422 (t ""))
15423 ;; design unit name
15424 (buffer-substring-no-properties
3dcb36b7
JB
15425 (progn (looking-at "\"?\\(\\(\\w\\|_\\)+\\)\"?") (match-beginning 1))
15426 (match-end 1))
5eabfe72 15427 ;; file name
3dcb36b7
JB
15428 (file-relative-name
15429 (or (car (get-text-property (point) 'speedbar-token))
15430 "?")
15431 (vhdl-default-directory)))))
15432 (t (message "")))))
15433
15434(defun vhdl-speedbar-line-text ()
15435 "Calls `speedbar-line-text' and removes text properties."
15436 (let ((string (speedbar-line-text)))
15437 (set-text-properties 0 (length string) nil string)
15438 string))
5eabfe72 15439
0a2e512a
RF
15440(defun vhdl-speedbar-higher-text ()
15441 "Get speedbar-line-text of higher level."
15442 (let (depth string)
15443 (save-excursion
15444 (beginning-of-line)
15445 (looking-at "^\\([0-9]+\\):")
15446 (setq depth (string-to-number (match-string 1)))
15447 (when (re-search-backward (format "^%d: *[[<{][-+?][]>}] \\([^ \n]+\\)" (1- depth)) nil t)
15448 (setq string (match-string 1))
15449 (set-text-properties 0 (length string) nil string)
15450 string))))
15451
5eabfe72
KH
15452;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15453;; Help functions
d2ddb974 15454
3dcb36b7
JB
15455(defun vhdl-speedbar-line-key (&optional indent)
15456 "Get currently displayed directory of project name."
15457 (if vhdl-speedbar-show-projects
15458 (vhdl-speedbar-line-project)
15459 (abbreviate-file-name
7752250e 15460 (file-name-as-directory (speedbar-line-directory indent)))))
3dcb36b7
JB
15461
15462(defun vhdl-speedbar-line-project (&optional indent)
15463 "Get currently displayed project name."
15464 (and vhdl-speedbar-show-projects
15465 (save-excursion
15466 (end-of-line)
15467 (re-search-backward "^[0-9]+:\\s-*<[-+?]>\\s-+\\([^\n]+\\)$" nil t)
15468 (match-string-no-properties 1))))
15469
15470(defun vhdl-add-modified-file ()
15471 "Add file to `vhdl-modified-file-list'."
15472 (when vhdl-file-alist
15473 (add-to-list 'vhdl-modified-file-list (buffer-file-name)))
15474 nil)
5eabfe72
KH
15475
15476(defun vhdl-resolve-paths (path-list)
3dcb36b7
JB
15477 "Resolve path wildcards in PATH-LIST."
15478 (let (path-list-1 path-list-2 path-beg path-end dir)
15479 ;; eliminate non-existent directories
5eabfe72
KH
15480 (while path-list
15481 (setq dir (car path-list))
3dcb36b7
JB
15482 (string-match "\\(-r \\)?\\(\\([^?*]*[/\\]\\)*\\)" dir)
15483 (if (file-directory-p (match-string 2 dir))
15484 (setq path-list-1 (cons dir path-list-1))
15485 (vhdl-warning-when-idle "No such directory: \"%s\"" (match-string 2 dir)))
5eabfe72 15486 (setq path-list (cdr path-list)))
3dcb36b7 15487 ;; resolve path wildcards
5eabfe72
KH
15488 (while path-list-1
15489 (setq dir (car path-list-1))
3dcb36b7 15490 (if (string-match "\\(-r \\)?\\(\\([^?*]*[/\\]\\)*\\)\\([^/\\]*[?*][^/\\]*\\)\\([/\\].*\\)" dir)
5eabfe72
KH
15491 (progn
15492 (setq path-beg (match-string 1 dir)
15493 path-end (match-string 5 dir))
3dcb36b7 15494 (setq path-list-1
5eabfe72
KH
15495 (append
15496 (mapcar
15497 (function
15498 (lambda (var) (concat path-beg var path-end)))
15499 (let ((all-list (vhdl-directory-files
15500 (match-string 2 dir) t
15501 (concat "\\<" (wildcard-to-regexp
15502 (match-string 4 dir)))))
15503 dir-list)
15504 (while all-list
15505 (when (file-directory-p (car all-list))
15506 (setq dir-list (cons (car all-list) dir-list)))
15507 (setq all-list (cdr all-list)))
15508 dir-list))
3dcb36b7
JB
15509 (cdr path-list-1))))
15510 (string-match "\\(-r \\)?\\(.*\\)[/\\].*" dir)
5eabfe72 15511 (when (file-directory-p (match-string 2 dir))
3dcb36b7
JB
15512 (setq path-list-2 (cons dir path-list-2)))
15513 (setq path-list-1 (cdr path-list-1))))
15514 (nreverse path-list-2)))
5eabfe72
KH
15515
15516(defun vhdl-speedbar-goto-this-unit (directory unit)
15517 "If UNIT is displayed in DIRECTORY, goto this line and return t, else nil."
15518 (let ((dest (point)))
3dcb36b7 15519 (if (and (if vhdl-speedbar-show-projects
5eabfe72
KH
15520 (progn (goto-char (point-min)) t)
15521 (speedbar-goto-this-file directory))
15522 (re-search-forward (concat "[]}] " unit "\\>") nil t))
15523 (progn (speedbar-position-cursor-on-line)
15524 t)
15525 (goto-char dest)
15526 nil)))
15527
15528(defun vhdl-speedbar-find-file (text token indent)
3dcb36b7
JB
15529 "When user clicks on TEXT, load file with name and position in TOKEN.
15530Jump to the design unit if `vhdl-speedbar-jump-to-unit' is t or if the file
15531is already shown in a buffer."
5eabfe72 15532 (if (not (car token))
3dcb36b7
JB
15533 (error "ERROR: File cannot be found")
15534 (let ((buffer (get-file-buffer (car token))))
15535 (speedbar-find-file-in-frame (car token))
15536 (when (or vhdl-speedbar-jump-to-unit buffer)
e6ce8c42
GM
15537 (goto-char (point-min))
15538 (forward-line (1- (cdr token)))
3dcb36b7
JB
15539 (recenter))
15540 (vhdl-speedbar-update-current-unit t t)
051897ff 15541 (speedbar-set-timer dframe-update-speed)
3dcb36b7 15542 (speedbar-maybee-jump-to-attached-frame))))
5eabfe72
KH
15543
15544(defun vhdl-speedbar-port-copy ()
3dcb36b7 15545 "Copy the port of the entity/component or subprogram under the cursor."
5eabfe72 15546 (interactive)
3dcb36b7
JB
15547 (let ((is-entity (vhdl-speedbar-check-unit 'entity)))
15548 (if (not (or is-entity (vhdl-speedbar-check-unit 'subprogram)))
15549 (error "ERROR: No entity/component or subprogram under cursor")
15550 (beginning-of-line)
15551 (if (looking-at "\\([0-9]\\)+:\\s-*\\(\\[[-+?]\\]\\|>\\) \\(\\(\\w\\|\\s_\\)+\\)")
15552 (condition-case info
15553 (let ((token (get-text-property
15554 (match-beginning 3) 'speedbar-token)))
15555 (vhdl-visit-file (car token) t
e6ce8c42
GM
15556 (progn (goto-char (point-min))
15557 (forward-line (1- (cdr token)))
3dcb36b7
JB
15558 (end-of-line)
15559 (if is-entity
15560 (vhdl-port-copy)
15561 (vhdl-subprog-copy)))))
15562 (error (error "ERROR: %s not scanned successfully\n (%s)"
15563 (if is-entity "Port" "Interface") (cadr info))))
15564 (error "ERROR: No entity/component or subprogram on current line")))))
15565
15566(defun vhdl-speedbar-place-component ()
15567 "Place the entity/component under the cursor as component."
15568 (interactive)
15569 (if (not (vhdl-speedbar-check-unit 'entity))
5bb5087f 15570 (error "ERROR: No entity/component under cursor")
3dcb36b7
JB
15571 (vhdl-speedbar-port-copy)
15572 (if (fboundp 'speedbar-select-attached-frame)
15573 (speedbar-select-attached-frame)
15574 (select-frame speedbar-attached-frame))
15575 (vhdl-compose-place-component)
15576 (select-frame speedbar-frame)))
15577
0a2e512a
RF
15578(defun vhdl-speedbar-configuration ()
15579 "Generate configuration for the architecture under the cursor."
15580 (interactive)
15581 (if (not (vhdl-speedbar-check-unit 'architecture))
15582 (error "ERROR: No architecture under cursor")
15583 (let ((arch-name (vhdl-speedbar-line-text))
15584 (ent-name (vhdl-speedbar-higher-text)))
15585 (if (fboundp 'speedbar-select-attached-frame)
15586 (speedbar-select-attached-frame)
15587 (select-frame speedbar-attached-frame))
15588 (vhdl-compose-configuration ent-name arch-name))))
15589
15590(defun vhdl-speedbar-select-mra ()
15591 "Select the architecture under the cursor as MRA."
15592 (interactive)
15593 (if (not (vhdl-speedbar-check-unit 'architecture))
15594 (error "ERROR: No architecture under cursor")
15595 (let* ((arch-key (downcase (vhdl-speedbar-line-text)))
15596 (ent-key (downcase (vhdl-speedbar-higher-text)))
15597 (ent-alist (aget vhdl-entity-alist
15598 (or (vhdl-project-p) default-directory) t))
15599 (ent-entry (aget ent-alist ent-key t)))
15600 (setcar (cddr (cddr ent-entry)) arch-key) ; (nth 4 ent-entry)
15601 (speedbar-refresh))))
15602
3dcb36b7
JB
15603(defun vhdl-speedbar-make-design ()
15604 "Make (compile) design unit or directory/project under the cursor."
15605 (interactive)
15606 (if (not (save-excursion (beginning-of-line)
15607 (looking-at "[0-9]+: *\\(\\(\\[\\)\\|<\\)")))
15608 (error "ERROR: No primary design unit or directory/project under cursor")
15609 (let ((is-unit (match-string 2))
15610 (unit-name (vhdl-speedbar-line-text))
15611 (vhdl-project (vhdl-speedbar-line-project))
15612 (directory (file-name-as-directory
7752250e 15613 (or (speedbar-line-file) (speedbar-line-directory)))))
3dcb36b7
JB
15614 (if (fboundp 'speedbar-select-attached-frame)
15615 (speedbar-select-attached-frame)
15616 (select-frame speedbar-attached-frame))
15617 (let ((default-directory directory))
15618 (vhdl-make (and is-unit unit-name))))))
15619
15620(defun vhdl-speedbar-generate-makefile ()
15621 "Generate Makefile for directory/project under the cursor."
15622 (interactive)
15623 (let ((vhdl-project (vhdl-speedbar-line-project))
15624 (default-directory (file-name-as-directory
7752250e 15625 (or (speedbar-line-file) (speedbar-line-directory)))))
3dcb36b7
JB
15626 (vhdl-generate-makefile)))
15627
15628(defun vhdl-speedbar-check-unit (design-unit)
15629 "Check whether design unit under cursor corresponds to DESIGN-UNIT (or its
15630expansion function)."
15631 (save-excursion
15632 (speedbar-position-cursor-on-line)
15633 (cond ((eq design-unit 'entity)
15634 (memq (get-text-property (match-end 0) 'face)
0a2e512a
RF
15635 '(vhdl-speedbar-entity-face
15636 vhdl-speedbar-entity-selected-face)))
15637 ((eq design-unit 'architecture)
15638 (memq (get-text-property (match-end 0) 'face)
15639 '(vhdl-speedbar-architecture-face
15640 vhdl-speedbar-architecture-selected-face)))
3dcb36b7
JB
15641 ((eq design-unit 'subprogram)
15642 (eq (get-text-property (match-end 0) 'face)
0a2e512a 15643 'vhdl-speedbar-subprogram-face))
3dcb36b7
JB
15644 (t nil))))
15645
15646(defun vhdl-speedbar-set-depth (depth)
15647 "Set hierarchy display depth to DEPTH and refresh speedbar."
15648 (setq vhdl-speedbar-hierarchy-depth depth)
15649 (speedbar-refresh))
5eabfe72
KH
15650
15651;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15652;; Fontification
15653
0a2e512a 15654(defface vhdl-speedbar-entity-face
5eabfe72
KH
15655 '((((class color) (background light)) (:foreground "ForestGreen"))
15656 (((class color) (background dark)) (:foreground "PaleGreen")))
15657 "Face used for displaying entity names."
15658 :group 'speedbar-faces)
15659
0a2e512a 15660(defface vhdl-speedbar-architecture-face
f47877ee
DN
15661 '((((min-colors 88) (class color) (background light)) (:foreground "Blue1"))
15662 (((class color) (background light)) (:foreground "Blue"))
84c98ace 15663
5eabfe72
KH
15664 (((class color) (background dark)) (:foreground "LightSkyBlue")))
15665 "Face used for displaying architecture names."
15666 :group 'speedbar-faces)
d2ddb974 15667
0a2e512a 15668(defface vhdl-speedbar-configuration-face
5eabfe72
KH
15669 '((((class color) (background light)) (:foreground "DarkGoldenrod"))
15670 (((class color) (background dark)) (:foreground "Salmon")))
15671 "Face used for displaying configuration names."
15672 :group 'speedbar-faces)
15673
0a2e512a 15674(defface vhdl-speedbar-package-face
5eabfe72
KH
15675 '((((class color) (background light)) (:foreground "Grey50"))
15676 (((class color) (background dark)) (:foreground "Grey80")))
15677 "Face used for displaying package names."
15678 :group 'speedbar-faces)
15679
0a2e512a 15680(defface vhdl-speedbar-library-face
3dcb36b7
JB
15681 '((((class color) (background light)) (:foreground "Purple"))
15682 (((class color) (background dark)) (:foreground "Orchid1")))
15683 "Face used for displaying library names."
15684 :group 'speedbar-faces)
15685
0a2e512a 15686(defface vhdl-speedbar-instantiation-face
5eabfe72 15687 '((((class color) (background light)) (:foreground "Brown"))
ea81d57e 15688 (((min-colors 88) (class color) (background dark)) (:foreground "Yellow1"))
5eabfe72
KH
15689 (((class color) (background dark)) (:foreground "Yellow")))
15690 "Face used for displaying instantiation names."
15691 :group 'speedbar-faces)
15692
0a2e512a 15693(defface vhdl-speedbar-subprogram-face
3dcb36b7
JB
15694 '((((class color) (background light)) (:foreground "Orchid4"))
15695 (((class color) (background dark)) (:foreground "BurlyWood2")))
15696 "Face used for displaying subprogram names."
15697 :group 'speedbar-faces)
15698
0a2e512a 15699(defface vhdl-speedbar-entity-selected-face
5eabfe72
KH
15700 '((((class color) (background light)) (:foreground "ForestGreen" :underline t))
15701 (((class color) (background dark)) (:foreground "PaleGreen" :underline t)))
15702 "Face used for displaying entity names."
15703 :group 'speedbar-faces)
15704
0a2e512a 15705(defface vhdl-speedbar-architecture-selected-face
f47877ee
DN
15706 '((((min-colors 88) (class color) (background light)) (:foreground
15707 "Blue1" :underline t))
15708 (((class color) (background light)) (:foreground "Blue" :underline t))
5eabfe72
KH
15709 (((class color) (background dark)) (:foreground "LightSkyBlue" :underline t)))
15710 "Face used for displaying architecture names."
15711 :group 'speedbar-faces)
15712
0a2e512a 15713(defface vhdl-speedbar-configuration-selected-face
5eabfe72
KH
15714 '((((class color) (background light)) (:foreground "DarkGoldenrod" :underline t))
15715 (((class color) (background dark)) (:foreground "Salmon" :underline t)))
15716 "Face used for displaying configuration names."
15717 :group 'speedbar-faces)
15718
0a2e512a 15719(defface vhdl-speedbar-package-selected-face
5eabfe72
KH
15720 '((((class color) (background light)) (:foreground "Grey50" :underline t))
15721 (((class color) (background dark)) (:foreground "Grey80" :underline t)))
15722 "Face used for displaying package names."
15723 :group 'speedbar-faces)
15724
0a2e512a 15725(defface vhdl-speedbar-instantiation-selected-face
5eabfe72
KH
15726 '((((class color) (background light)) (:foreground "Brown" :underline t))
15727 (((class color) (background dark)) (:foreground "Yellow" :underline t)))
15728 "Face used for displaying instantiation names."
15729 :group 'speedbar-faces)
15730
3dcb36b7
JB
15731;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15732;; Initialization
15733
15734;; add speedbar
15735(when (fboundp 'speedbar)
15736 (condition-case ()
15737 (when (and vhdl-speedbar-auto-open
15738 (not (and (boundp 'speedbar-frame)
15739 (frame-live-p speedbar-frame))))
15740 (speedbar-frame-mode 1)
15741 (if (fboundp 'speedbar-select-attached-frame)
15742 (speedbar-select-attached-frame)
15743 (select-frame speedbar-attached-frame)))
15744 (error (vhdl-warning-when-idle "ERROR: An error occurred while opening speedbar"))))
15745
15746;; initialize speedbar
15747(if (not (boundp 'speedbar-frame))
15748 (add-hook 'speedbar-load-hook 'vhdl-speedbar-initialize)
15749 (vhdl-speedbar-initialize)
15750 (when speedbar-frame (vhdl-speedbar-refresh)))
15751
15752
15753;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15754;;; Structural composition
15755;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15756
15757(defun vhdl-get-components-package-name ()
15758 "Return the name of the components package."
15759 (let ((project (vhdl-project-p)))
15760 (if project
15761 (vhdl-replace-string (car vhdl-components-package-name)
15762 (subst-char-in-string ? ?_ project))
15763 (cdr vhdl-components-package-name))))
15764
15765(defun vhdl-compose-new-component ()
15766 "Create entity and architecture for new component."
15767 (interactive)
15768 (let* ((case-fold-search t)
15769 (ent-name (read-from-minibuffer "entity name: "
15770 nil vhdl-minibuffer-local-map))
15771 (arch-name
15772 (if (equal (cdr vhdl-compose-architecture-name) "")
15773 (read-from-minibuffer "architecture name: "
15774 nil vhdl-minibuffer-local-map)
15775 (vhdl-replace-string vhdl-compose-architecture-name ent-name)))
fda91268 15776 ent-file-name arch-file-name ent-buffer arch-buffer project end-pos)
3dcb36b7
JB
15777 (message "Creating component \"%s(%s)\"..." ent-name arch-name)
15778 ;; open entity file
15779 (unless (eq vhdl-compose-create-files 'none)
15780 (setq ent-file-name
0a2e512a 15781 (concat (vhdl-replace-string vhdl-entity-file-name ent-name t)
3dcb36b7
JB
15782 "." (file-name-extension (buffer-file-name))))
15783 (when (and (file-exists-p ent-file-name)
15784 (not (y-or-n-p (concat "File \"" ent-file-name
15785 "\" exists; overwrite? "))))
15786 (error "ERROR: Creating component...aborted"))
15787 (find-file ent-file-name)
15788 (erase-buffer)
15789 (set-buffer-modified-p nil))
15790 ;; insert header
15791 (if vhdl-compose-include-header
15792 (progn (vhdl-template-header)
fda91268 15793 (setq end-pos (point))
3dcb36b7
JB
15794 (goto-char (point-max)))
15795 (vhdl-comment-display-line) (insert "\n\n"))
15796 ;; insert library clause
15797 (vhdl-template-package-std-logic-1164)
15798 (when vhdl-use-components-package
15799 (insert "\n")
15800 (vhdl-template-standard-package (vhdl-work-library)
15801 (vhdl-get-components-package-name)))
15802 (insert "\n\n") (vhdl-comment-display-line) (insert "\n\n")
15803 ;; insert entity declaration
15804 (vhdl-insert-keyword "ENTITY ") (insert ent-name)
15805 (vhdl-insert-keyword " IS\n")
15806 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
15807 (indent-to vhdl-basic-offset) (vhdl-insert-keyword "GENERIC (\n")
15808 (indent-to (* 2 vhdl-basic-offset)) (insert ");\n")
15809 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
15810 (indent-to vhdl-basic-offset) (vhdl-insert-keyword "PORT (\n")
15811 (indent-to (* 2 vhdl-basic-offset)) (insert ");\n")
15812 (when (memq vhdl-insert-empty-lines '(unit all)) (insert "\n"))
15813 (vhdl-insert-keyword "END ")
15814 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ENTITY "))
15815 (insert ent-name ";\n\n")
15816 (vhdl-comment-display-line) (insert "\n")
15817 ;; open architecture file
15818 (if (not (eq vhdl-compose-create-files 'separate))
15819 (insert "\n")
fda91268 15820 (goto-char (or end-pos (point-min)))
3dcb36b7
JB
15821 (setq ent-buffer (current-buffer))
15822 (setq arch-file-name
15823 (concat (vhdl-replace-string vhdl-architecture-file-name
0a2e512a 15824 (concat ent-name " " arch-name) t)
3dcb36b7
JB
15825 "." (file-name-extension (buffer-file-name))))
15826 (when (and (file-exists-p arch-file-name)
15827 (not (y-or-n-p (concat "File \"" arch-file-name
15828 "\" exists; overwrite? "))))
15829 (error "ERROR: Creating component...aborted"))
15830 (find-file arch-file-name)
15831 (erase-buffer)
15832 (set-buffer-modified-p nil)
15833 ;; insert header
15834 (if vhdl-compose-include-header
15835 (progn (vhdl-template-header)
15836 (goto-char (point-max)))
15837 (vhdl-comment-display-line) (insert "\n\n")))
15838 ;; insert architecture body
15839 (vhdl-insert-keyword "ARCHITECTURE ") (insert arch-name)
15840 (vhdl-insert-keyword " OF ") (insert ent-name)
15841 (vhdl-insert-keyword " IS\n\n")
15842 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n")
15843 (indent-to vhdl-basic-offset) (insert "-- Internal signal declarations\n")
15844 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n\n")
15845 (unless (or vhdl-use-components-package (vhdl-use-direct-instantiation))
15846 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n")
15847 (indent-to vhdl-basic-offset) (insert "-- Component declarations\n")
15848 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n\n"))
15849 (vhdl-insert-keyword "BEGIN")
15850 (when vhdl-self-insert-comments
15851 (insert " -- ")
15852 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ARCHITECTURE "))
15853 (insert arch-name))
15854 (insert "\n\n")
15855 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n")
15856 (indent-to vhdl-basic-offset) (insert "-- Component instantiations\n")
15857 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n\n")
15858 (vhdl-insert-keyword "END ")
15859 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "ARCHITECTURE "))
15860 (insert arch-name ";\n\n")
0a2e512a 15861 ;; insert footer and save
3dcb36b7
JB
15862 (if (and vhdl-compose-include-header (not (equal vhdl-file-footer "")))
15863 (vhdl-template-footer)
15864 (vhdl-comment-display-line) (insert "\n"))
fda91268 15865 (goto-char (or end-pos (point-min)))
3dcb36b7
JB
15866 (setq arch-buffer (current-buffer))
15867 (when ent-buffer (set-buffer ent-buffer) (save-buffer))
15868 (set-buffer arch-buffer) (save-buffer)
29a4e67d 15869 (message "%s"
3dcb36b7
JB
15870 (concat (format "Creating component \"%s(%s)\"...done" ent-name arch-name)
15871 (and ent-file-name
15872 (format "\n File created: \"%s\"" ent-file-name))
15873 (and arch-file-name
15874 (format "\n File created: \"%s\"" arch-file-name))))))
15875
15876(defun vhdl-compose-place-component ()
15877 "Place new component by pasting current port as component declaration and
15878component instantiation."
15879 (interactive)
15880 (if (not vhdl-port-list)
15881 (error "ERROR: No port has been read")
15882 (save-excursion
15883 (vhdl-prepare-search-2
fda91268
RZ
15884 (unless (or (re-search-backward "^architecture[ \t\n\r\f]+\\w+[ \t\n\r\f]+of[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t)
15885 (re-search-forward "^architecture[ \t\n\r\f]+\\w+[ \t\n\r\f]+of[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t))
3dcb36b7
JB
15886 (error "ERROR: No architecture found"))
15887 (let* ((ent-name (match-string 1))
15888 (ent-file-name
0a2e512a 15889 (concat (vhdl-replace-string vhdl-entity-file-name ent-name t)
3dcb36b7
JB
15890 "." (file-name-extension (buffer-file-name))))
15891 (orig-buffer (current-buffer)))
15892 (message "Placing component \"%s\"..." (nth 0 vhdl-port-list))
15893 ;; place component declaration
15894 (unless (or vhdl-use-components-package
15895 (vhdl-use-direct-instantiation)
15896 (save-excursion
15897 (re-search-forward
15898 (concat "^\\s-*component\\s-+"
15899 (car vhdl-port-list) "\\>") nil t)))
15900 (re-search-forward "^begin\\>" nil)
15901 (beginning-of-line)
fda91268 15902 (skip-chars-backward " \t\n\r\f")
3dcb36b7
JB
15903 (insert "\n\n") (indent-to vhdl-basic-offset)
15904 (vhdl-port-paste-component t))
15905 ;; place component instantiation
15906 (re-search-forward "^end\\>" nil)
15907 (beginning-of-line)
fda91268 15908 (skip-chars-backward " \t\n\r\f")
3dcb36b7
JB
15909 (insert "\n\n") (indent-to vhdl-basic-offset)
15910 (vhdl-port-paste-instance nil t t)
15911 ;; place use clause for used packages
15912 (when (nth 3 vhdl-port-list)
15913 ;; open entity file
15914 (when (file-exists-p ent-file-name)
15915 (find-file ent-file-name))
15916 (goto-char (point-min))
fda91268 15917 (unless (re-search-forward (concat "^entity[ \t\n\r\f]+" ent-name "[ \t\n\r\f]+is\\>") nil t)
3dcb36b7
JB
15918 (error "ERROR: Entity not found: \"%s\"" ent-name))
15919 (goto-char (match-beginning 0))
15920 (if (and (save-excursion
15921 (re-search-backward "^\\(library\\|use\\)\\|end\\>" nil t))
15922 (match-string 1))
15923 (progn (goto-char (match-end 0))
15924 (beginning-of-line 2))
15925 (insert "\n")
15926 (backward-char))
15927 (vhdl-port-paste-context-clause)
15928 (switch-to-buffer orig-buffer))
15929 (message "Placing component \"%s\"...done" (nth 0 vhdl-port-list)))))))
15930
15931(defun vhdl-compose-wire-components ()
15932 "Connect components."
15933 (interactive)
15934 (save-excursion
15935 (vhdl-prepare-search-2
fda91268
RZ
15936 (unless (or (re-search-backward "^architecture[ \t\n\r\f]+\\w+[ \t\n\r\f]+of[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t)
15937 (re-search-forward "^architecture[ \t\n\r\f]+\\w+[ \t\n\r\f]+of[ \t\n\r\f]+\\(\\w+\\)[ \t\n\r\f]+is\\>" nil t))
3dcb36b7
JB
15938 (error "ERROR: No architecture found"))
15939 (let* ((ent-name (match-string 1))
15940 (ent-file-name
0a2e512a 15941 (concat (vhdl-replace-string vhdl-entity-file-name ent-name t)
3dcb36b7
JB
15942 "." (file-name-extension (buffer-file-name))))
15943 (arch-decl-pos (point-marker))
15944 (arch-stat-pos (re-search-forward "^begin\\>" nil))
15945 (arch-end-pos (re-search-forward "^end\\>" nil))
15946 (pack-name (vhdl-get-components-package-name))
15947 (pack-file-name
0a2e512a 15948 (concat (vhdl-replace-string vhdl-package-file-name pack-name t)
3dcb36b7
JB
15949 "." (file-name-extension (buffer-file-name))))
15950 inst-name comp-name comp-ent-name comp-ent-file-name has-generic
15951 port-alist generic-alist inst-alist
15952 signal-name signal-entry signal-alist local-list written-list
15953 single-in-list multi-in-list single-out-list multi-out-list
15954 constant-name constant-entry constant-alist single-list multi-list
15955 port-beg-pos port-in-pos port-out-pos port-inst-pos port-end-pos
15956 generic-beg-pos generic-pos generic-inst-pos generic-end-pos
15957 signal-beg-pos signal-pos
15958 constant-temp-pos port-temp-pos signal-temp-pos)
15959 (message "Wiring components...")
15960 ;; process all instances
15961 (goto-char arch-stat-pos)
15962 (while (re-search-forward
fda91268
RZ
15963 (concat "^[ \t]*\\(\\w+\\)[ \t\n\r\f]*:[ \t\n\r\f]*\\("
15964 "\\(component[ \t\n\r\f]+\\)?\\(\\w+\\)"
15965 "[ \t\n\r\f]+\\(--[^\n]*\n[ \t\n\r\f]*\\)*\\(\\(generic\\)\\|port\\)[ \t\n\r\f]+map\\|"
15966 "\\(\\(entity\\)\\|configuration\\)[ \t\n\r\f]+\\(\\(\\w+\\)\\.\\)?\\(\\w+\\)\\([ \t\n\r\f]*(\\(\\w+\\))\\)?"
15967 "[ \t\n\r\f]+\\(--[^\n]*\n[ \t\n\r\f]*\\)*\\(\\(generic\\)\\|port\\)[ \t\n\r\f]+map\\)[ \t\n\r\f]*(") arch-end-pos t)
3dcb36b7
JB
15968 (setq inst-name (match-string-no-properties 1)
15969 comp-name (match-string-no-properties 4)
15970 comp-ent-name (match-string-no-properties 12)
15971 has-generic (or (match-string 7) (match-string 17)))
15972 ;; get port ...
15973 (if comp-name
15974 ;; ... from component declaration
15975 (vhdl-visit-file
15976 (when vhdl-use-components-package pack-file-name) t
15977 (save-excursion
15978 (goto-char (point-min))
fda91268 15979 (unless (re-search-forward (concat "^\\s-*component[ \t\n\r\f]+" comp-name "\\>") nil t)
3dcb36b7
JB
15980 (error "ERROR: Component declaration not found: \"%s\"" comp-name))
15981 (vhdl-port-copy)))
15982 ;; ... from entity declaration (direct instantiation)
15983 (setq comp-ent-file-name
0a2e512a 15984 (concat (vhdl-replace-string vhdl-entity-file-name comp-ent-name t)
3dcb36b7
JB
15985 "." (file-name-extension (buffer-file-name))))
15986 (vhdl-visit-file
15987 comp-ent-file-name t
15988 (save-excursion
15989 (goto-char (point-min))
fda91268 15990 (unless (re-search-forward (concat "^\\s-*entity[ \t\n\r\f]+" comp-ent-name "\\>") nil t)
3dcb36b7
JB
15991 (error "ERROR: Entity declaration not found: \"%s\"" comp-ent-name))
15992 (vhdl-port-copy))))
15993 (vhdl-port-flatten t)
15994 (setq generic-alist (nth 1 vhdl-port-list)
0a2e512a
RF
15995 port-alist (nth 2 vhdl-port-list)
15996 vhdl-port-list nil)
3dcb36b7
JB
15997 (setq constant-alist nil
15998 signal-alist nil)
15999 (when has-generic
16000 ;; process all constants in generic map
16001 (vhdl-forward-syntactic-ws)
fda91268 16002 (while (vhdl-parse-string "\\(\\(\\w+\\)[ \t\n\r\f]*=>[ \t\n\r\f]*\\)?\\(\\w+\\),?" t)
3dcb36b7
JB
16003 (setq constant-name (match-string-no-properties 3))
16004 (setq constant-entry
16005 (cons constant-name
16006 (if (match-string 1)
16007 (or (aget generic-alist (match-string 2) t)
ec3ec9cc 16008 (error "ERROR: Formal generic \"%s\" mismatch for instance \"%s\"" (match-string 2) inst-name))
3dcb36b7
JB
16009 (cdar generic-alist))))
16010 (setq constant-alist (cons constant-entry constant-alist))
16011 (setq constant-name (downcase constant-name))
16012 (if (or (member constant-name single-list)
16013 (member constant-name multi-list))
16014 (progn (setq single-list (delete constant-name single-list))
16015 (add-to-list 'multi-list constant-name))
16016 (add-to-list 'single-list constant-name))
16017 (unless (match-string 1)
16018 (setq generic-alist (cdr generic-alist)))
16019 (vhdl-forward-syntactic-ws))
fda91268 16020 (vhdl-re-search-forward "\\<port\\s-+map[ \t\n\r\f]*(" nil t))
3dcb36b7
JB
16021 ;; process all signals in port map
16022 (vhdl-forward-syntactic-ws)
fda91268 16023 (while (vhdl-parse-string "\\(\\(\\w+\\)[ \t\n\r\f]*=>[ \t\n\r\f]*\\)?\\(\\w+\\),?" t)
3dcb36b7
JB
16024 (setq signal-name (match-string-no-properties 3))
16025 (setq signal-entry (cons signal-name
16026 (if (match-string 1)
16027 (or (aget port-alist (match-string 2) t)
ec3ec9cc 16028 (error "ERROR: Formal port \"%s\" mismatch for instance \"%s\"" (match-string 2) inst-name))
3dcb36b7
JB
16029 (cdar port-alist))))
16030 (setq signal-alist (cons signal-entry signal-alist))
16031 (setq signal-name (downcase signal-name))
16032 (if (equal (upcase (nth 2 signal-entry)) "IN")
16033 ;; input signal
16034 (cond
16035 ((member signal-name local-list)
16036 nil)
16037 ((or (member signal-name single-out-list)
16038 (member signal-name multi-out-list))
16039 (setq single-out-list (delete signal-name single-out-list))
16040 (setq multi-out-list (delete signal-name multi-out-list))
16041 (add-to-list 'local-list signal-name))
16042 ((member signal-name single-in-list)
16043 (setq single-in-list (delete signal-name single-in-list))
16044 (add-to-list 'multi-in-list signal-name))
16045 ((not (member signal-name multi-in-list))
16046 (add-to-list 'single-in-list signal-name)))
16047 ;; output signal
16048 (cond
16049 ((member signal-name local-list)
16050 nil)
16051 ((or (member signal-name single-in-list)
16052 (member signal-name multi-in-list))
16053 (setq single-in-list (delete signal-name single-in-list))
16054 (setq multi-in-list (delete signal-name multi-in-list))
16055 (add-to-list 'local-list signal-name))
16056 ((member signal-name single-out-list)
16057 (setq single-out-list (delete signal-name single-out-list))
16058 (add-to-list 'multi-out-list signal-name))
16059 ((not (member signal-name multi-out-list))
16060 (add-to-list 'single-out-list signal-name))))
16061 (unless (match-string 1)
16062 (setq port-alist (cdr port-alist)))
16063 (vhdl-forward-syntactic-ws))
16064 (setq inst-alist (cons (list inst-name (nreverse constant-alist)
16065 (nreverse signal-alist)) inst-alist)))
16066 ;; prepare signal insertion
16067 (vhdl-goto-marker arch-decl-pos)
16068 (forward-line 1)
fda91268 16069 (re-search-forward "^\\s-*-- Internal signal declarations[ \t\n\r\f]*-*\n" arch-stat-pos t)
3dcb36b7
JB
16070 (setq signal-pos (point-marker))
16071 (while (progn (vhdl-forward-syntactic-ws)
16072 (looking-at "signal\\>"))
16073 (beginning-of-line 2)
16074 (delete-region signal-pos (point)))
16075 (setq signal-beg-pos signal-pos)
16076 ;; open entity file
16077 (when (file-exists-p ent-file-name)
16078 (find-file ent-file-name))
16079 (goto-char (point-min))
fda91268 16080 (unless (re-search-forward (concat "^entity[ \t\n\r\f]+" ent-name "[ \t\n\r\f]+is\\>") nil t)
3dcb36b7
JB
16081 (error "ERROR: Entity not found: \"%s\"" ent-name))
16082 ;; prepare generic clause insertion
fda91268 16083 (unless (and (re-search-forward "\\(^\\s-*generic[ \t\n\r\f]*(\\)\\|^end\\>" nil t)
3dcb36b7
JB
16084 (match-string 1))
16085 (goto-char (match-beginning 0))
16086 (indent-to vhdl-basic-offset)
16087 (insert "generic ();\n\n")
16088 (backward-char 4))
16089 (backward-char)
16090 (setq generic-pos (point-marker))
16091 (forward-sexp) (end-of-line)
16092 (delete-region generic-pos (point)) (delete-char 1)
16093 (insert "(\n")
16094 (when multi-list
16095 (insert "\n")
16096 (indent-to (* 2 vhdl-basic-offset))
16097 (insert "-- global generics\n"))
16098 (setq generic-beg-pos (point-marker) generic-pos (point-marker)
16099 generic-inst-pos (point-marker) generic-end-pos (point-marker))
16100 ;; prepare port clause insertion
fda91268 16101 (unless (and (re-search-forward "\\(^\\s-*port[ \t\n\r\f]*(\\)\\|^end\\>" nil t)
3dcb36b7
JB
16102 (match-string 1))
16103 (goto-char (match-beginning 0))
16104 (indent-to vhdl-basic-offset)
16105 (insert "port ();\n\n")
16106 (backward-char 4))
16107 (backward-char)
16108 (setq port-in-pos (point-marker))
16109 (forward-sexp) (end-of-line)
16110 (delete-region port-in-pos (point)) (delete-char 1)
16111 (insert "(\n")
16112 (when (or multi-in-list multi-out-list)
16113 (insert "\n")
16114 (indent-to (* 2 vhdl-basic-offset))
16115 (insert "-- global ports\n"))
16116 (setq port-beg-pos (point-marker) port-in-pos (point-marker)
16117 port-out-pos (point-marker) port-inst-pos (point-marker)
16118 port-end-pos (point-marker))
16119 ;; insert generics, ports and signals
16120 (setq inst-alist (nreverse inst-alist))
16121 (while inst-alist
16122 (setq inst-name (nth 0 (car inst-alist))
16123 constant-alist (nth 1 (car inst-alist))
16124 signal-alist (nth 2 (car inst-alist))
16125 constant-temp-pos generic-inst-pos
16126 port-temp-pos port-inst-pos
16127 signal-temp-pos signal-pos)
16128 ;; generics
16129 (while constant-alist
16130 (setq constant-name (downcase (caar constant-alist))
16131 constant-entry (car constant-alist))
16132 (cond ((member constant-name written-list)
16133 nil)
16134 ((member constant-name multi-list)
16135 (vhdl-goto-marker generic-pos)
16136 (setq generic-end-pos
16137 (vhdl-max-marker
16138 generic-end-pos
16139 (vhdl-compose-insert-generic constant-entry)))
16140 (setq generic-pos (point-marker))
16141 (add-to-list 'written-list constant-name))
16142 (t
16143 (vhdl-goto-marker
16144 (vhdl-max-marker generic-inst-pos generic-pos))
16145 (setq generic-end-pos
16146 (vhdl-compose-insert-generic constant-entry))
16147 (setq generic-inst-pos (point-marker))
16148 (add-to-list 'written-list constant-name)))
16149 (setq constant-alist (cdr constant-alist)))
16150 (when (/= constant-temp-pos generic-inst-pos)
16151 (vhdl-goto-marker (vhdl-max-marker constant-temp-pos generic-pos))
16152 (insert "\n") (indent-to (* 2 vhdl-basic-offset))
16153 (insert "-- generics for \"" inst-name "\"\n")
16154 (vhdl-goto-marker generic-inst-pos))
16155 ;; ports and signals
16156 (while signal-alist
16157 (setq signal-name (downcase (caar signal-alist))
16158 signal-entry (car signal-alist))
16159 (cond ((member signal-name written-list)
16160 nil)
16161 ((member signal-name multi-in-list)
16162 (vhdl-goto-marker port-in-pos)
16163 (setq port-end-pos
16164 (vhdl-max-marker
16165 port-end-pos (vhdl-compose-insert-port signal-entry)))
16166 (setq port-in-pos (point-marker))
16167 (add-to-list 'written-list signal-name))
16168 ((member signal-name multi-out-list)
16169 (vhdl-goto-marker (vhdl-max-marker port-out-pos port-in-pos))
16170 (setq port-end-pos
16171 (vhdl-max-marker
16172 port-end-pos (vhdl-compose-insert-port signal-entry)))
16173 (setq port-out-pos (point-marker))
16174 (add-to-list 'written-list signal-name))
16175 ((or (member signal-name single-in-list)
16176 (member signal-name single-out-list))
16177 (vhdl-goto-marker
16178 (vhdl-max-marker
16179 port-inst-pos
16180 (vhdl-max-marker port-out-pos port-in-pos)))
16181 (setq port-end-pos (vhdl-compose-insert-port signal-entry))
16182 (setq port-inst-pos (point-marker))
16183 (add-to-list 'written-list signal-name))
16184 ((equal (upcase (nth 2 signal-entry)) "OUT")
16185 (vhdl-goto-marker signal-pos)
16186 (vhdl-compose-insert-signal signal-entry)
16187 (setq signal-pos (point-marker))
16188 (add-to-list 'written-list signal-name)))
16189 (setq signal-alist (cdr signal-alist)))
16190 (when (/= port-temp-pos port-inst-pos)
16191 (vhdl-goto-marker
16192 (vhdl-max-marker port-temp-pos
16193 (vhdl-max-marker port-in-pos port-out-pos)))
16194 (insert "\n") (indent-to (* 2 vhdl-basic-offset))
16195 (insert "-- ports to \"" inst-name "\"\n")
16196 (vhdl-goto-marker port-inst-pos))
16197 (when (/= signal-temp-pos signal-pos)
16198 (vhdl-goto-marker signal-temp-pos)
16199 (insert "\n") (indent-to vhdl-basic-offset)
16200 (insert "-- outputs of \"" inst-name "\"\n")
16201 (vhdl-goto-marker signal-pos))
16202 (setq inst-alist (cdr inst-alist)))
16203 ;; finalize generic/port clause
16204 (vhdl-goto-marker generic-end-pos) (backward-char)
16205 (when (= generic-beg-pos generic-end-pos)
16206 (insert "\n") (indent-to (* 2 vhdl-basic-offset))
16207 (insert ";") (backward-char))
16208 (insert ")")
16209 (vhdl-goto-marker port-end-pos) (backward-char)
16210 (when (= port-beg-pos port-end-pos)
16211 (insert "\n") (indent-to (* 2 vhdl-basic-offset))
16212 (insert ";") (backward-char))
16213 (insert ")")
16214 ;; align everything
16215 (when vhdl-auto-align
16216 (vhdl-goto-marker generic-beg-pos)
16217 (vhdl-align-region-groups generic-beg-pos generic-end-pos 1)
16218 (vhdl-align-region-groups port-beg-pos port-end-pos 1)
16219 (vhdl-goto-marker signal-beg-pos)
16220 (vhdl-align-region-groups signal-beg-pos signal-pos))
16221 (switch-to-buffer (marker-buffer signal-beg-pos))
16222 (message "Wiring components...done")))))
16223
16224(defun vhdl-compose-insert-generic (entry)
16225 "Insert ENTRY as generic declaration."
16226 (let (pos)
16227 (indent-to (* 2 vhdl-basic-offset))
16228 (insert (nth 0 entry) " : " (nth 1 entry))
16229 (when (nth 2 entry)
16230 (insert " := " (nth 2 entry)))
16231 (insert ";")
16232 (setq pos (point-marker))
16233 (when (and vhdl-include-port-comments (nth 3 entry))
16234 (vhdl-comment-insert-inline (nth 3 entry) t))
16235 (insert "\n")
16236 pos))
16237
16238(defun vhdl-compose-insert-port (entry)
16239 "Insert ENTRY as port declaration."
16240 (let (pos)
16241 (indent-to (* 2 vhdl-basic-offset))
16242 (insert (nth 0 entry) " : " (nth 2 entry) " " (nth 3 entry) ";")
16243 (setq pos (point-marker))
16244 (when (and vhdl-include-port-comments (nth 4 entry))
16245 (vhdl-comment-insert-inline (nth 4 entry) t))
16246 (insert "\n")
16247 pos))
16248
16249(defun vhdl-compose-insert-signal (entry)
16250 "Insert ENTRY as signal declaration."
16251 (indent-to vhdl-basic-offset)
16252 (insert "signal " (nth 0 entry) " : " (nth 3 entry) ";")
16253 (when (and vhdl-include-port-comments (nth 4 entry))
16254 (vhdl-comment-insert-inline (nth 4 entry) t))
16255 (insert "\n"))
16256
16257(defun vhdl-compose-components-package ()
16258 "Generate a package containing component declarations for all entities in the
16259current project/directory."
16260 (interactive)
16261 (vhdl-require-hierarchy-info)
16262 (let* ((project (vhdl-project-p))
16263 (pack-name (vhdl-get-components-package-name))
16264 (pack-file-name
0a2e512a 16265 (concat (vhdl-replace-string vhdl-package-file-name pack-name t)
3dcb36b7
JB
16266 "." (file-name-extension (buffer-file-name))))
16267 (ent-alist (aget vhdl-entity-alist
16268 (or project default-directory) t))
16269 (lazy-lock-minimum-size 0)
16270 clause-pos component-pos)
16271 (message "Generating components package \"%s\"..." pack-name)
16272 ;; open package file
16273 (when (and (file-exists-p pack-file-name)
16274 (not (y-or-n-p (concat "File \"" pack-file-name
16275 "\" exists; overwrite? "))))
16276 (error "ERROR: Generating components package...aborted"))
16277 (find-file pack-file-name)
16278 (erase-buffer)
16279 ;; insert header
16280 (if vhdl-compose-include-header
16281 (progn (vhdl-template-header
16282 (concat "Components package (generated by Emacs VHDL Mode "
16283 vhdl-version ")"))
16284 (goto-char (point-max)))
16285 (vhdl-comment-display-line) (insert "\n\n"))
16286 ;; insert std_logic_1164 package
16287 (vhdl-template-package-std-logic-1164)
16288 (insert "\n") (setq clause-pos (point-marker))
16289 (insert "\n") (vhdl-comment-display-line) (insert "\n\n")
16290 ;; insert package declaration
16291 (vhdl-insert-keyword "PACKAGE ") (insert pack-name)
16292 (vhdl-insert-keyword " IS\n\n")
16293 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n")
16294 (indent-to vhdl-basic-offset) (insert "-- Component declarations\n")
16295 (indent-to vhdl-basic-offset) (vhdl-comment-display-line) (insert "\n\n")
16296 (indent-to vhdl-basic-offset)
16297 (setq component-pos (point-marker))
16298 (insert "\n\n") (vhdl-insert-keyword "END ")
16299 (unless (vhdl-standard-p '87) (vhdl-insert-keyword "PACKAGE "))
16300 (insert pack-name ";\n\n")
16301 ;; insert footer
16302 (if (and vhdl-compose-include-header (not (equal vhdl-file-footer "")))
16303 (vhdl-template-footer)
16304 (vhdl-comment-display-line) (insert "\n"))
16305 ;; insert component declarations
16306 (while ent-alist
16307 (vhdl-visit-file (nth 2 (car ent-alist)) nil
e6ce8c42
GM
16308 (progn (goto-char (point-min))
16309 (forward-line (1- (nth 3 (car ent-alist))))
3dcb36b7
JB
16310 (end-of-line)
16311 (vhdl-port-copy)))
16312 (goto-char component-pos)
16313 (vhdl-port-paste-component t)
16314 (when (cdr ent-alist) (insert "\n\n") (indent-to vhdl-basic-offset))
16315 (setq component-pos (point-marker))
16316 (goto-char clause-pos)
16317 (vhdl-port-paste-context-clause pack-name)
16318 (setq clause-pos (point-marker))
16319 (setq ent-alist (cdr ent-alist)))
16320 (goto-char (point-min))
16321 (save-buffer)
16322 (message "Generating components package \"%s\"...done\n File created: \"%s\""
16323 pack-name pack-file-name)))
16324
fda91268
RZ
16325(defun vhdl-compose-configuration-architecture (ent-name arch-name ent-alist
16326 conf-alist inst-alist
0a2e512a
RF
16327 &optional insert-conf)
16328 "Generate block configuration for architecture."
16329 (let ((margin (current-indentation))
e180ab9f 16330 (beg (point-at-bol))
0a2e512a
RF
16331 ent-entry inst-entry inst-path inst-prev-path cons-key tmp-alist)
16332 ;; insert block configuration (for architecture)
16333 (vhdl-insert-keyword "FOR ") (insert arch-name "\n")
16334 (setq margin (+ margin vhdl-basic-offset))
16335 ;; process all instances
16336 (while inst-alist
16337 (setq inst-entry (car inst-alist))
16338 ;; is component?
16339 (when (nth 4 inst-entry)
16340 (setq insert-conf t)
16341 (setq inst-path (nth 9 inst-entry))
16342 ;; skip common path with previous instance
16343 (while (and inst-path (equal (car inst-path) (car inst-prev-path)))
16344 (setq inst-path (cdr inst-path)
16345 inst-prev-path (cdr inst-prev-path)))
16346 ;; insert block configuration end (for previous block/generate)
16347 (while inst-prev-path
16348 (setq margin (- margin vhdl-basic-offset))
16349 (indent-to margin)
16350 (vhdl-insert-keyword "END FOR;\n")
16351 (setq inst-prev-path (cdr inst-prev-path)))
16352 ;; insert block configuration beginning (for current block/generate)
16353 (indent-to margin)
16354 (while inst-path
16355 (setq margin (+ margin vhdl-basic-offset))
16356 (vhdl-insert-keyword "FOR ")
16357 (insert (car inst-path) "\n")
16358 (indent-to margin)
16359 (setq inst-path (cdr inst-path)))
16360 ;; insert component configuration beginning
16361 (vhdl-insert-keyword "FOR ")
16362 (insert (nth 1 inst-entry) " : " (nth 4 inst-entry) "\n")
16363 ;; find subconfiguration
16364 (setq conf-key (nth 7 inst-entry))
16365 (setq tmp-alist conf-alist)
16366 ;; use first configuration found for instance's entity
16367 (while (and tmp-alist (null conf-key))
16368 (when (equal (nth 5 inst-entry) (nth 4 (car tmp-alist)))
16369 (setq conf-key (nth 0 (car tmp-alist))))
16370 (setq tmp-alist (cdr tmp-alist)))
16371 (setq conf-entry (aget conf-alist conf-key t))
16372 ;; insert binding indication ...
16373 ;; ... with subconfiguration (if exists)
16374 (if (and vhdl-compose-configuration-use-subconfiguration conf-entry)
16375 (progn
16376 (indent-to (+ margin vhdl-basic-offset))
16377 (vhdl-insert-keyword "USE CONFIGURATION ")
16378 (insert (vhdl-work-library) "." (nth 0 conf-entry))
16379 (insert ";\n"))
16380 ;; ... with entity (if exists)
16381 (setq ent-entry (aget ent-alist (nth 5 inst-entry) t))
16382 (when ent-entry
16383 (indent-to (+ margin vhdl-basic-offset))
16384 (vhdl-insert-keyword "USE ENTITY ")
16385 (insert (vhdl-work-library) "." (nth 0 ent-entry))
16386 ;; insert architecture name (if architecture exists)
16387 (when (nth 3 ent-entry)
16388 (setq arch-name
16389 ;; choose architecture name a) from configuration,
16390 ;; b) from mra, or c) from first architecture
16391 (or (nth 0 (aget (nth 3 ent-entry)
16392 (or (nth 6 inst-entry)
16393 (nth 4 ent-entry)) t))
16394 (nth 1 (car (nth 3 ent-entry)))))
16395 (insert "(" arch-name ")"))
16396 (insert ";\n")
16397 ;; insert block configuration (for architecture of subcomponent)
16398 (when (and vhdl-compose-configuration-hierarchical
16399 (nth 3 ent-entry))
16400 (indent-to (+ margin vhdl-basic-offset))
16401 (vhdl-compose-configuration-architecture
fda91268 16402 (nth 0 ent-entry) arch-name ent-alist conf-alist
0a2e512a
RF
16403 (nth 3 (aget (nth 3 ent-entry) (downcase arch-name) t))))))
16404 ;; insert component configuration end
16405 (indent-to margin)
16406 (vhdl-insert-keyword "END FOR;\n")
16407 (setq inst-prev-path (nth 9 inst-entry)))
16408 (setq inst-alist (cdr inst-alist)))
16409 ;; insert block configuration end (for block/generate)
16410 (while inst-prev-path
16411 (setq margin (- margin vhdl-basic-offset))
16412 (indent-to margin)
16413 (vhdl-insert-keyword "END FOR;\n")
16414 (setq inst-prev-path (cdr inst-prev-path)))
16415 (indent-to (- margin vhdl-basic-offset))
16416 ;; insert block configuration end or remove beginning (for architecture)
16417 (if insert-conf
16418 (vhdl-insert-keyword "END FOR;\n")
16419 (delete-region beg (point)))))
16420
16421(defun vhdl-compose-configuration (&optional ent-name arch-name)
16422 "Generate configuration declaration."
16423 (interactive)
16424 (vhdl-require-hierarchy-info)
16425 (let ((ent-alist (aget vhdl-entity-alist
16426 (or (vhdl-project-p) default-directory) t))
16427 (conf-alist (aget vhdl-config-alist
16428 (or (vhdl-project-p) default-directory) t))
16429 (from-speedbar ent-name)
16430 inst-alist conf-name conf-file-name pos)
16431 (vhdl-prepare-search-2
16432 ;; get entity and architecture name
16433 (unless ent-name
16434 (save-excursion
16435 (unless (and (re-search-backward "^\\(architecture\\s-+\\(\\w+\\)\\s-+of\\s-+\\(\\w+\\)\\|end\\)\\>" nil t)
16436 (not (equal "END" (upcase (match-string 1))))
16437 (setq ent-name (match-string-no-properties 3))
16438 (setq arch-name (match-string-no-properties 2)))
16439 (error "ERROR: Not within an architecture"))))
16440 (setq conf-name (vhdl-replace-string
16441 vhdl-compose-configuration-name
16442 (concat ent-name " " arch-name)))
16443 (setq inst-alist
16444 (nth 3 (aget (nth 3 (aget ent-alist (downcase ent-name) t))
16445 (downcase arch-name) t))))
16446 (message "Generating configuration \"%s\"..." conf-name)
16447 (if vhdl-compose-configuration-create-file
16448 ;; open configuration file
16449 (progn
16450 (setq conf-file-name
16451 (concat (vhdl-replace-string vhdl-configuration-file-name
16452 conf-name t)
16453 "." (file-name-extension (buffer-file-name))))
16454 (when (and (file-exists-p conf-file-name)
16455 (not (y-or-n-p (concat "File \"" conf-file-name
16456 "\" exists; overwrite? "))))
16457 (error "ERROR: Creating configuration...aborted"))
16458 (find-file conf-file-name)
16459 (erase-buffer)
16460 (set-buffer-modified-p nil)
16461 ;; insert header
16462 (if vhdl-compose-include-header
16463 (progn (vhdl-template-header
16464 (concat "Configuration declaration for design \""
16465 ent-name "(" arch-name ")\""))
16466 (goto-char (point-max)))
16467 (vhdl-comment-display-line) (insert "\n\n")))
16468 ;; goto end of architecture
16469 (unless from-speedbar
16470 (re-search-forward "^end\\>" nil)
16471 (end-of-line) (insert "\n\n")
16472 (vhdl-comment-display-line) (insert "\n\n")))
16473 ;; insert library clause
16474 (setq pos (point))
16475 (vhdl-template-standard-package (vhdl-work-library) nil)
16476 (when (/= pos (point))
16477 (insert "\n\n"))
16478 ;; insert configuration
16479 (vhdl-insert-keyword "CONFIGURATION ") (insert conf-name)
16480 (vhdl-insert-keyword " OF ") (insert ent-name)
16481 (vhdl-insert-keyword " IS\n")
16482 (indent-to vhdl-basic-offset)
16483 ;; insert block configuration (for architecture)
fda91268
RZ
16484 (vhdl-compose-configuration-architecture
16485 ent-name arch-name ent-alist conf-alist inst-alist t)
0a2e512a
RF
16486 (vhdl-insert-keyword "END ") (insert conf-name ";")
16487 (when conf-file-name
16488 ;; insert footer and save
16489 (insert "\n\n")
16490 (if (and vhdl-compose-include-header (not (equal vhdl-file-footer "")))
16491 (vhdl-template-footer)
16492 (vhdl-comment-display-line) (insert "\n"))
16493 (save-buffer))
29a4e67d 16494 (message "%s"
0a2e512a
RF
16495 (concat (format "Generating configuration \"%s\"...done" conf-name)
16496 (and conf-file-name
16497 (format "\n File created: \"%s\"" conf-file-name))))))
16498
3dcb36b7
JB
16499
16500;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16501;;; Compilation / Makefile generation
16502;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16503;; (using `compile.el')
16504
fda91268
RZ
16505(defvar vhdl-compile-post-command ""
16506 "String appended to compile command after file name.")
16507
3dcb36b7
JB
16508(defun vhdl-makefile-name ()
16509 "Return the Makefile name of the current project or the current compiler if
16510no project is defined."
16511 (let ((project-alist (aget vhdl-project-alist vhdl-project))
16512 (compiler-alist (aget vhdl-compiler-alist vhdl-compiler)))
16513 (vhdl-replace-string
16514 (cons "\\(.*\\)\n\\(.*\\)"
16515 (or (nth 8 project-alist) (nth 8 compiler-alist)))
16516 (concat (nth 9 compiler-alist) "\n" (nth 6 project-alist)))))
16517
16518(defun vhdl-compile-directory ()
16519 "Return the directory where compilation/make should be run."
16520 (let* ((project (aget vhdl-project-alist (vhdl-project-p t)))
16521 (compiler (aget vhdl-compiler-alist vhdl-compiler))
16522 (directory (vhdl-resolve-env-variable
16523 (if project
16524 (vhdl-replace-string
16525 (cons "\\(.*\\)" (nth 5 project)) (nth 9 compiler))
16526 (nth 6 compiler)))))
16527 (file-name-as-directory
16528 (if (file-name-absolute-p directory)
16529 directory
16530 (expand-file-name directory (vhdl-default-directory))))))
16531
16532(defun vhdl-uniquify (in-list)
16533 "Remove duplicate elements from IN-LIST."
16534 (let (out-list)
16535 (while in-list
16536 (add-to-list 'out-list (car in-list))
16537 (setq in-list (cdr in-list)))
16538 out-list))
16539
16540(defun vhdl-set-compiler (name)
16541 "Set current compiler to NAME."
16542 (interactive
16543 (list (let ((completion-ignore-case t))
16544 (completing-read "Compiler name: " vhdl-compiler-alist nil t))))
16545 (if (assoc name vhdl-compiler-alist)
16546 (progn (setq vhdl-compiler name)
16547 (message "Current compiler: \"%s\"" vhdl-compiler))
16548 (vhdl-warning (format "Unknown compiler: \"%s\"" name))))
16549
16550;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16551;; Compilation
16552
16553(defun vhdl-compile-init ()
16554 "Initialize for compilation."
16555 (when (or (null compilation-error-regexp-alist)
16556 (not (assoc (car (nth 11 (car vhdl-compiler-alist)))
16557 compilation-error-regexp-alist)))
16558 ;; `compilation-error-regexp-alist'
16559 (let ((commands-alist vhdl-compiler-alist)
16560 regexp-alist sublist)
16561 (while commands-alist
16562 (setq sublist (nth 11 (car commands-alist)))
16563 (unless (or (equal "" (car sublist))
16564 (assoc (car sublist) regexp-alist))
16565 (setq regexp-alist (cons (list (nth 0 sublist)
16566 (if (= 0 (nth 1 sublist))
f8246027 16567 (if (featurep 'xemacs) 9 nil)
3dcb36b7
JB
16568 (nth 1 sublist))
16569 (nth 2 sublist) (nth 3 sublist))
16570 regexp-alist)))
16571 (setq commands-alist (cdr commands-alist)))
16572 (setq compilation-error-regexp-alist
16573 (append compilation-error-regexp-alist (nreverse regexp-alist))))
16574 ;; `compilation-file-regexp-alist'
16575 (let ((commands-alist vhdl-compiler-alist)
16576 regexp-alist sublist)
16577 ;; matches vhdl-mode file name output
16578 (setq regexp-alist '(("^Compiling \"\\(.+\\)\"" 1)))
16579 (while commands-alist
16580 (setq sublist (nth 12 (car commands-alist)))
16581 (unless (or (equal "" (car sublist))
16582 (assoc (car sublist) regexp-alist))
16583 (setq regexp-alist (cons sublist regexp-alist)))
16584 (setq commands-alist (cdr commands-alist)))
16585 (setq compilation-file-regexp-alist
16586 (append compilation-file-regexp-alist (nreverse regexp-alist))))))
16587
16588(defvar vhdl-compile-file-name nil
16589 "Name of file to be compiled.")
16590
16591(defun vhdl-compile-print-file-name ()
16592 "Function called within `compile' to print out file name for compilers that
16593do not print any file names."
16594 (insert "Compiling \"" vhdl-compile-file-name "\"\n"))
16595
16596(defun vhdl-get-compile-options (project compiler file-name
16597 &optional file-options-only)
16598 "Get compiler options. Returning nil means do not compile this file."
16599 (let* ((compiler-options (nth 1 compiler))
16600 (project-entry (aget (nth 4 project) vhdl-compiler))
16601 (project-options (nth 0 project-entry))
16602 (exception-list (and file-name (nth 2 project-entry)))
16603 (work-library (vhdl-work-library))
16604 (case-fold-search nil)
16605 file-options)
16606 (while (and exception-list
16607 (not (string-match (caar exception-list) file-name)))
16608 (setq exception-list (cdr exception-list)))
16609 (if (and exception-list (not (cdar exception-list)))
16610 nil
16611 (if (and file-options-only (not exception-list))
16612 'default
16613 (setq file-options (cdar exception-list))
16614 ;; insert library name in compiler-specific options
16615 (setq compiler-options
16616 (vhdl-replace-string (cons "\\(.*\\)" compiler-options)
16617 work-library))
16618 ;; insert compiler-specific options in project-specific options
16619 (when project-options
16620 (setq project-options
16621 (vhdl-replace-string
16622 (cons "\\(.*\\)\n\\(.*\\)" project-options)
16623 (concat work-library "\n" compiler-options))))
16624 ;; insert project-specific options in file-specific options
16625 (when file-options
16626 (setq file-options
16627 (vhdl-replace-string
16628 (cons "\\(.*\\)\n\\(.*\\)\n\\(.*\\)" file-options)
16629 (concat work-library "\n" compiler-options "\n"
16630 project-options))))
16631 ;; return options
16632 (or file-options project-options compiler-options)))))
16633
16634(defun vhdl-get-make-options (project compiler)
16635 "Get make options."
16636 (let* ((compiler-options (nth 3 compiler))
16637 (project-entry (aget (nth 4 project) vhdl-compiler))
16638 (project-options (nth 1 project-entry))
16639 (makefile-name (vhdl-makefile-name)))
16640 ;; insert Makefile name in compiler-specific options
16641 (setq compiler-options
16642 (vhdl-replace-string (cons "\\(.*\\)" (nth 3 compiler))
16643 makefile-name))
16644 ;; insert compiler-specific options in project-specific options
16645 (when project-options
16646 (setq project-options
16647 (vhdl-replace-string
16648 (cons "\\(.*\\)\n\\(.*\\)" project-options)
16649 (concat makefile-name "\n" compiler-options))))
16650 ;; return options
16651 (or project-options compiler-options)))
16652
16653(defun vhdl-compile ()
16654 "Compile current buffer using the VHDL compiler specified in
16655`vhdl-compiler'."
16656 (interactive)
16657 (vhdl-compile-init)
16658 (let* ((project (aget vhdl-project-alist vhdl-project))
16659 (compiler (or (aget vhdl-compiler-alist vhdl-compiler nil)
16660 (error "ERROR: No such compiler: \"%s\"" vhdl-compiler)))
16661 (command (nth 0 compiler))
3dcb36b7 16662 (default-directory (vhdl-compile-directory))
fda91268
RZ
16663 (file-name (if vhdl-compile-absolute-path
16664 (buffer-file-name)
16665 (file-relative-name (buffer-file-name))))
16666 (options (vhdl-get-compile-options project compiler file-name))
3dcb36b7
JB
16667 compilation-process-setup-function)
16668 (unless (file-directory-p default-directory)
16669 (error "ERROR: Compile directory does not exist: \"%s\"" default-directory))
16670 ;; put file name into quotes if it contains spaces
16671 (when (string-match " " file-name)
16672 (setq file-name (concat "\"" file-name "\"")))
16673 ;; print out file name if compiler does not
fda91268
RZ
16674 (setq vhdl-compile-file-name (if vhdl-compile-absolute-path
16675 (buffer-file-name)
16676 (file-relative-name (buffer-file-name))))
3dcb36b7
JB
16677 (when (and (= 0 (nth 1 (nth 10 compiler)))
16678 (= 0 (nth 1 (nth 11 compiler))))
16679 (setq compilation-process-setup-function 'vhdl-compile-print-file-name))
16680 ;; run compilation
16681 (if options
16682 (when command
fda91268
RZ
16683 (compile (concat command " " options " " file-name
16684 (unless (equal vhdl-compile-post-command "")
16685 (concat " " vhdl-compile-post-command)))))
3dcb36b7
JB
16686 (vhdl-warning "Your project settings tell me not to compile this file"))))
16687
0a2e512a
RF
16688(defvar vhdl-make-target "all"
16689 "Default target for `vhdl-make' command.")
16690
3dcb36b7
JB
16691(defun vhdl-make (&optional target)
16692 "Call make command for compilation of all updated source files (requires
16693`Makefile'). Optional argument TARGET allows to compile the design
16694specified by a target."
16695 (interactive)
0a2e512a
RF
16696 (setq vhdl-make-target
16697 (or target (read-from-minibuffer "Target: " vhdl-make-target
16698 vhdl-minibuffer-local-map)))
3dcb36b7
JB
16699 (vhdl-compile-init)
16700 (let* ((project (aget vhdl-project-alist vhdl-project))
16701 (compiler (or (aget vhdl-compiler-alist vhdl-compiler)
16702 (error "ERROR: No such compiler: \"%s\"" vhdl-compiler)))
16703 (command (nth 2 compiler))
16704 (options (vhdl-get-make-options project compiler))
16705 (default-directory (vhdl-compile-directory)))
16706 (unless (file-directory-p default-directory)
16707 (error "ERROR: Compile directory does not exist: \"%s\"" default-directory))
16708 ;; run make
16709 (compile (concat (if (equal command "") "make" command)
0a2e512a 16710 " " options " " vhdl-make-target))))
3dcb36b7
JB
16711
16712;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16713;; Makefile generation
16714
16715(defun vhdl-generate-makefile ()
16716 "Generate `Makefile'."
16717 (interactive)
16718 (let* ((compiler (or (aget vhdl-compiler-alist vhdl-compiler)
16719 (error "ERROR: No such compiler: \"%s\"" vhdl-compiler)))
16720 (command (nth 4 compiler)))
16721 ;; generate makefile
16722 (if command
16723 (let ((default-directory (vhdl-compile-directory)))
16724 (compile (vhdl-replace-string
16725 (cons "\\(.*\\) \\(.*\\)" command)
16726 (concat (vhdl-makefile-name) " " (vhdl-work-library)))))
16727 (vhdl-generate-makefile-1))))
16728
16729(defun vhdl-get-packages (lib-alist work-library)
16730 "Get packages from LIB-ALIST that belong to WORK-LIBRARY."
16731 (let (pack-list)
16732 (while lib-alist
16733 (when (equal (downcase (caar lib-alist)) (downcase work-library))
16734 (setq pack-list (cons (cdar lib-alist) pack-list)))
16735 (setq lib-alist (cdr lib-alist)))
16736 pack-list))
16737
16738(defun vhdl-generate-makefile-1 ()
16739 "Generate Makefile for current project or directory."
16740 ;; scan hierarchy if required
16741 (if (vhdl-project-p)
16742 (unless (or (assoc vhdl-project vhdl-file-alist)
16743 (vhdl-load-cache vhdl-project))
16744 (vhdl-scan-project-contents vhdl-project))
16745 (let ((directory (abbreviate-file-name default-directory)))
16746 (unless (or (assoc directory vhdl-file-alist)
16747 (vhdl-load-cache directory))
16748 (vhdl-scan-directory-contents directory))))
16749 (let* ((directory (abbreviate-file-name (vhdl-default-directory)))
16750 (project (vhdl-project-p))
16751 (ent-alist (aget vhdl-entity-alist (or project directory) t))
16752 (conf-alist (aget vhdl-config-alist (or project directory) t))
16753 (pack-alist (aget vhdl-package-alist (or project directory) t))
16754 (regexp-list (nth 12 (aget vhdl-compiler-alist vhdl-compiler)))
16755 (ent-regexp (cons "\\(.*\\)" (nth 0 regexp-list)))
16756 (arch-regexp (cons "\\(.*\\) \\(.*\\)" (nth 1 regexp-list)))
16757 (conf-regexp (cons "\\(.*\\)" (nth 2 regexp-list)))
16758 (pack-regexp (cons "\\(.*\\)" (nth 3 regexp-list)))
16759 (pack-body-regexp (cons "\\(.*\\)" (nth 4 regexp-list)))
16760 (adjust-case (nth 5 regexp-list))
16761 (work-library (downcase (vhdl-work-library)))
16762 (compile-directory (expand-file-name (vhdl-compile-directory)
16763 default-directory))
16764 (makefile-name (vhdl-makefile-name))
16765 rule-alist arch-alist inst-alist
16766 target-list depend-list unit-list prim-list second-list subcomp-list
16767 lib-alist lib-body-alist pack-list all-pack-list
16768 ent-key ent-file-name arch-key arch-file-name ent-arch-key
16769 conf-key conf-file-name pack-key pack-file-name
16770 ent-entry arch-entry conf-entry pack-entry inst-entry
16771 pack-body-key pack-body-file-name inst-ent-key inst-conf-key
16772 tmp-key tmp-list rule)
16773 ;; check prerequisites
16774 (unless (file-exists-p compile-directory)
16775 (make-directory compile-directory t))
16776 (unless regexp-list
16777 (error "Please contact the VHDL Mode maintainer for support of \"%s\""
16778 vhdl-compiler))
16779 (message "Generating makefile \"%s\"..." makefile-name)
16780 ;; rules for all entities
16781 (setq tmp-list ent-alist)
16782 (while ent-alist
16783 (setq ent-entry (car ent-alist)
16784 ent-key (nth 0 ent-entry))
16785 (when (nth 2 ent-entry)
16786 (setq ent-file-name (file-relative-name
16787 (nth 2 ent-entry) compile-directory)
16788 arch-alist (nth 4 ent-entry)
0a2e512a 16789 lib-alist (nth 6 ent-entry)
3dcb36b7
JB
16790 rule (aget rule-alist ent-file-name)
16791 target-list (nth 0 rule)
16792 depend-list (nth 1 rule)
16793 second-list nil
16794 subcomp-list nil)
16795 (setq tmp-key (vhdl-replace-string
16796 ent-regexp (funcall adjust-case ent-key)))
16797 (setq unit-list (cons (cons ent-key tmp-key) unit-list))
16798 ;; rule target for this entity
16799 (setq target-list (cons ent-key target-list))
16800 ;; rule dependencies for all used packages
16801 (setq pack-list (vhdl-get-packages lib-alist work-library))
16802 (setq depend-list (append depend-list pack-list))
16803 (setq all-pack-list pack-list)
16804 ;; add rule
16805 (aput 'rule-alist ent-file-name (list target-list depend-list))
16806 ;; rules for all corresponding architectures
16807 (while arch-alist
16808 (setq arch-entry (car arch-alist)
16809 arch-key (nth 0 arch-entry)
16810 ent-arch-key (concat ent-key "-" arch-key)
16811 arch-file-name (file-relative-name (nth 2 arch-entry)
16812 compile-directory)
16813 inst-alist (nth 4 arch-entry)
16814 lib-alist (nth 5 arch-entry)
16815 rule (aget rule-alist arch-file-name)
16816 target-list (nth 0 rule)
16817 depend-list (nth 1 rule))
16818 (setq tmp-key (vhdl-replace-string
16819 arch-regexp
16820 (funcall adjust-case (concat arch-key " " ent-key))))
16821 (setq unit-list
16822 (cons (cons ent-arch-key tmp-key) unit-list))
16823 (setq second-list (cons ent-arch-key second-list))
16824 ;; rule target for this architecture
16825 (setq target-list (cons ent-arch-key target-list))
16826 ;; rule dependency for corresponding entity
16827 (setq depend-list (cons ent-key depend-list))
16828 ;; rule dependencies for contained component instantiations
16829 (while inst-alist
16830 (setq inst-entry (car inst-alist))
16831 (when (or (null (nth 8 inst-entry))
16832 (equal (downcase (nth 8 inst-entry)) work-library))
16833 (setq inst-ent-key (or (nth 7 inst-entry)
16834 (nth 5 inst-entry)))
16835 (setq depend-list (cons inst-ent-key depend-list)
16836 subcomp-list (cons inst-ent-key subcomp-list)))
16837 (setq inst-alist (cdr inst-alist)))
16838 ;; rule dependencies for all used packages
16839 (setq pack-list (vhdl-get-packages lib-alist work-library))
16840 (setq depend-list (append depend-list pack-list))
16841 (setq all-pack-list (append all-pack-list pack-list))
16842 ;; add rule
16843 (aput 'rule-alist arch-file-name (list target-list depend-list))
16844 (setq arch-alist (cdr arch-alist)))
16845 (setq prim-list (cons (list ent-key second-list
16846 (append subcomp-list all-pack-list))
16847 prim-list)))
16848 (setq ent-alist (cdr ent-alist)))
16849 (setq ent-alist tmp-list)
16850 ;; rules for all configurations
16851 (setq tmp-list conf-alist)
16852 (while conf-alist
16853 (setq conf-entry (car conf-alist)
16854 conf-key (nth 0 conf-entry)
16855 conf-file-name (file-relative-name
16856 (nth 2 conf-entry) compile-directory)
16857 ent-key (nth 4 conf-entry)
16858 arch-key (nth 5 conf-entry)
16859 inst-alist (nth 6 conf-entry)
16860 lib-alist (nth 7 conf-entry)
16861 rule (aget rule-alist conf-file-name)
16862 target-list (nth 0 rule)
16863 depend-list (nth 1 rule)
16864 subcomp-list (list ent-key))
16865 (setq tmp-key (vhdl-replace-string
16866 conf-regexp (funcall adjust-case conf-key)))
16867 (setq unit-list (cons (cons conf-key tmp-key) unit-list))
16868 ;; rule target for this configuration
16869 (setq target-list (cons conf-key target-list))
16870 ;; rule dependency for corresponding entity and architecture
16871 (setq depend-list
16872 (cons ent-key (cons (concat ent-key "-" arch-key) depend-list)))
16873 ;; rule dependencies for used packages
16874 (setq pack-list (vhdl-get-packages lib-alist work-library))
16875 (setq depend-list (append depend-list pack-list))
16876 ;; rule dependencies for contained component configurations
16877 (while inst-alist
16878 (setq inst-entry (car inst-alist))
16879 (setq inst-ent-key (nth 2 inst-entry)
16880; comp-arch-key (nth 2 inst-entry))
16881 inst-conf-key (nth 4 inst-entry))
16882 (when (equal (downcase (nth 5 inst-entry)) work-library)
16883 (when inst-ent-key
16884 (setq depend-list (cons inst-ent-key depend-list)
16885 subcomp-list (cons inst-ent-key subcomp-list)))
16886; (when comp-arch-key
16887; (setq depend-list (cons (concat comp-ent-key "-" comp-arch-key)
16888; depend-list)))
16889 (when inst-conf-key
16890 (setq depend-list (cons inst-conf-key depend-list)
16891 subcomp-list (cons inst-conf-key subcomp-list))))
16892 (setq inst-alist (cdr inst-alist)))
16893 ;; add rule
16894 (aput 'rule-alist conf-file-name (list target-list depend-list))
16895 (setq prim-list (cons (list conf-key nil (append subcomp-list pack-list))
16896 prim-list))
16897 (setq conf-alist (cdr conf-alist)))
16898 (setq conf-alist tmp-list)
16899 ;; rules for all packages
16900 (setq tmp-list pack-alist)
16901 (while pack-alist
16902 (setq pack-entry (car pack-alist)
16903 pack-key (nth 0 pack-entry)
16904 pack-body-key nil)
16905 (when (nth 2 pack-entry)
16906 (setq pack-file-name (file-relative-name (nth 2 pack-entry)
16907 compile-directory)
16908 lib-alist (nth 6 pack-entry) lib-body-alist (nth 10 pack-entry)
16909 rule (aget rule-alist pack-file-name)
16910 target-list (nth 0 rule) depend-list (nth 1 rule))
16911 (setq tmp-key (vhdl-replace-string
16912 pack-regexp (funcall adjust-case pack-key)))
16913 (setq unit-list (cons (cons pack-key tmp-key) unit-list))
16914 ;; rule target for this package
16915 (setq target-list (cons pack-key target-list))
16916 ;; rule dependencies for all used packages
16917 (setq pack-list (vhdl-get-packages lib-alist work-library))
16918 (setq depend-list (append depend-list pack-list))
16919 (setq all-pack-list pack-list)
16920 ;; add rule
16921 (aput 'rule-alist pack-file-name (list target-list depend-list))
16922 ;; rules for this package's body
16923 (when (nth 7 pack-entry)
16924 (setq pack-body-key (concat pack-key "-body")
16925 pack-body-file-name (file-relative-name (nth 7 pack-entry)
16926 compile-directory)
16927 rule (aget rule-alist pack-body-file-name)
16928 target-list (nth 0 rule)
16929 depend-list (nth 1 rule))
16930 (setq tmp-key (vhdl-replace-string
16931 pack-body-regexp (funcall adjust-case pack-key)))
16932 (setq unit-list
16933 (cons (cons pack-body-key tmp-key) unit-list))
16934 ;; rule target for this package's body
16935 (setq target-list (cons pack-body-key target-list))
16936 ;; rule dependency for corresponding package declaration
16937 (setq depend-list (cons pack-key depend-list))
16938 ;; rule dependencies for all used packages
16939 (setq pack-list (vhdl-get-packages lib-body-alist work-library))
16940 (setq depend-list (append depend-list pack-list))
16941 (setq all-pack-list (append all-pack-list pack-list))
16942 ;; add rule
16943 (aput 'rule-alist pack-body-file-name
16944 (list target-list depend-list)))
16945 (setq prim-list
16946 (cons (list pack-key (when pack-body-key (list pack-body-key))
16947 all-pack-list)
16948 prim-list)))
16949 (setq pack-alist (cdr pack-alist)))
16950 (setq pack-alist tmp-list)
16951 ;; generate Makefile
16952 (let* ((project (aget vhdl-project-alist project))
16953 (compiler (aget vhdl-compiler-alist vhdl-compiler))
16954 (compiler-id (nth 9 compiler))
16955 (library-directory
16956 (vhdl-resolve-env-variable
16957 (vhdl-replace-string
16958 (cons "\\(.*\\)" (or (nth 7 project) (nth 7 compiler)))
16959 compiler-id)))
16960 (makefile-path-name (expand-file-name
16961 makefile-name compile-directory))
16962 (orig-buffer (current-buffer))
16963 cell second-list subcomp-list options unit-key unit-name)
16964 ;; sort lists
16965 (setq unit-list (vhdl-sort-alist unit-list))
16966 (setq prim-list (vhdl-sort-alist prim-list))
16967 (setq tmp-list rule-alist)
16968 (while tmp-list ; pre-sort rule targets
16969 (setq cell (cdar tmp-list))
16970 (setcar cell (sort (car cell) 'string<))
16971 (setq tmp-list (cdr tmp-list)))
16972 (setq rule-alist ; sort by first rule target
16973 (sort rule-alist
16974 (function (lambda (a b)
16975 (string< (car (cadr a)) (car (cadr b)))))))
16976 ;; open and clear Makefile
16977 (set-buffer (find-file-noselect makefile-path-name t t))
16978 (erase-buffer)
16979 (insert "# -*- Makefile -*-\n"
16980 "### " (file-name-nondirectory makefile-name)
16981 " - VHDL Makefile generated by Emacs VHDL Mode " vhdl-version
16982 "\n")
16983 (if project
16984 (insert "\n# Project : " (nth 0 project))
16985 (insert "\n# Directory : \"" directory "\""))
16986 (insert "\n# Platform : " vhdl-compiler
16987 "\n# Generated : " (format-time-string "%Y-%m-%d %T ")
16988 (user-login-name) "\n")
16989 ;; insert compile and option variable settings
16990 (insert "\n\n# Define compilation command and options\n"
16991 "\nCOMPILE = " (nth 0 compiler)
16992 "\nOPTIONS = " (vhdl-get-compile-options project compiler nil)
fda91268
RZ
16993 (if (equal vhdl-compile-post-command "") ""
16994 (concat "\nPOST-COMPILE = " vhdl-compile-post-command))
3dcb36b7
JB
16995 "\n")
16996 ;; insert library paths
16997 (setq library-directory
16998 (directory-file-name
16999 (if (file-name-absolute-p library-directory)
17000 library-directory
17001 (file-relative-name
17002 (expand-file-name library-directory directory)
17003 compile-directory))))
17004 (insert "\n\n# Define library paths\n"
17005 "\nLIBRARY-" work-library " = " library-directory "\n")
17006 ;; insert variable definitions for all library unit files
17007 (insert "\n\n# Define library unit files\n")
17008 (setq tmp-list unit-list)
17009 (while unit-list
17010 (insert "\nUNIT-" work-library "-" (caar unit-list)
17011 " = \\\n\t$(LIBRARY-" work-library ")/" (cdar unit-list))
17012 (setq unit-list (cdr unit-list)))
17013 ;; insert variable definition for list of all library unit files
17014 (insert "\n\n\n# Define list of all library unit files\n"
17015 "\nALL_UNITS =")
17016 (setq unit-list tmp-list)
17017 (while unit-list
17018 (insert " \\\n\t" "$(UNIT-" work-library "-" (caar unit-list) ")")
17019 (setq unit-list (cdr unit-list)))
17020 (insert "\n")
17021 (setq unit-list tmp-list)
17022 ;; insert `make all' rule
17023 (insert "\n\n\n# Rule for compiling entire design\n"
fda91268
RZ
17024 "\n" (nth 0 vhdl-makefile-default-targets) " :"
17025 " \\\n\t\t" (nth 2 vhdl-makefile-default-targets)
3dcb36b7
JB
17026 " \\\n\t\t$(ALL_UNITS)\n")
17027 ;; insert `make clean' rule
17028 (insert "\n\n# Rule for cleaning entire design\n"
fda91268 17029 "\n" (nth 1 vhdl-makefile-default-targets) " : "
3dcb36b7
JB
17030 "\n\t-rm -f $(ALL_UNITS)\n")
17031 ;; insert `make library' rule
17032 (insert "\n\n# Rule for creating library directory\n"
fda91268 17033 "\n" (nth 2 vhdl-makefile-default-targets) " :"
3dcb36b7
JB
17034 " \\\n\t\t$(LIBRARY-" work-library ")\n"
17035 "\n$(LIBRARY-" work-library ") :"
17036 "\n\t"
17037 (vhdl-replace-string
17038 (cons "\\(.*\\)\n\\(.*\\)" (nth 5 compiler))
17039 (concat "$(LIBRARY-" work-library ")\n" (vhdl-work-library)))
17040 "\n")
fda91268
RZ
17041 ;; insert '.PHONY' declaration
17042 (insert "\n\n.PHONY : "
17043 (nth 0 vhdl-makefile-default-targets) " "
17044 (nth 1 vhdl-makefile-default-targets) " "
17045 (nth 2 vhdl-makefile-default-targets) "\n")
3dcb36b7
JB
17046 ;; insert rule for each library unit
17047 (insert "\n\n# Rules for compiling single library units and their subhierarchy\n")
17048 (while prim-list
17049 (setq second-list (sort (nth 1 (car prim-list)) 'string<))
17050 (setq subcomp-list
17051 (sort (vhdl-uniquify (nth 2 (car prim-list))) 'string<))
17052 (setq unit-key (caar prim-list)
17053 unit-name (or (nth 0 (aget ent-alist unit-key t))
17054 (nth 0 (aget conf-alist unit-key t))
17055 (nth 0 (aget pack-alist unit-key t))))
17056 (insert "\n" unit-key)
17057 (unless (equal unit-key unit-name)
17058 (insert " \\\n" unit-name))
17059 (insert " :"
fda91268 17060 " \\\n\t\t" (nth 2 vhdl-makefile-default-targets)
3dcb36b7
JB
17061 " \\\n\t\t$(UNIT-" work-library "-" unit-key ")")
17062 (while second-list
17063 (insert " \\\n\t\t$(UNIT-" work-library "-" (car second-list) ")")
17064 (setq second-list (cdr second-list)))
17065 (while subcomp-list
0a2e512a
RF
17066 (when (and (assoc (car subcomp-list) unit-list)
17067 (not (equal unit-key (car subcomp-list))))
3dcb36b7
JB
17068 (insert " \\\n\t\t" (car subcomp-list)))
17069 (setq subcomp-list (cdr subcomp-list)))
17070 (insert "\n")
17071 (setq prim-list (cdr prim-list)))
17072 ;; insert rule for each library unit file
17073 (insert "\n\n# Rules for compiling single library unit files\n")
17074 (while rule-alist
17075 (setq rule (car rule-alist))
17076 ;; get compiler options for this file
17077 (setq options
17078 (vhdl-get-compile-options project compiler (nth 0 rule) t))
17079 ;; insert rule if file is supposed to be compiled
17080 (setq target-list (nth 1 rule)
17081 depend-list (sort (vhdl-uniquify (nth 2 rule)) 'string<))
17082 ;; insert targets
17083 (setq tmp-list target-list)
17084 (while target-list
17085 (insert "\n$(UNIT-" work-library "-" (car target-list) ")"
17086 (if (cdr target-list) " \\" " :"))
17087 (setq target-list (cdr target-list)))
17088 (setq target-list tmp-list)
17089 ;; insert file name as first dependency
17090 (insert " \\\n\t\t" (nth 0 rule))
17091 ;; insert dependencies (except if also target or unit does not exist)
17092 (while depend-list
17093 (when (and (not (member (car depend-list) target-list))
17094 (assoc (car depend-list) unit-list))
17095 (insert " \\\n\t\t"
17096 "$(UNIT-" work-library "-" (car depend-list) ")"))
17097 (setq depend-list (cdr depend-list)))
17098 ;; insert compile command
17099 (if options
17100 (insert "\n\t$(COMPILE) "
17101 (if (eq options 'default) "$(OPTIONS)" options) " "
fda91268
RZ
17102 (nth 0 rule)
17103 (if (equal vhdl-compile-post-command "") ""
17104 " $(POST-COMPILE)") "\n")
3dcb36b7
JB
17105 (setq tmp-list target-list)
17106 (while target-list
17107 (insert "\n\t@touch $(UNIT-" work-library "-" (car target-list) ")"
17108 (if (cdr target-list) " \\" "\n"))
17109 (setq target-list (cdr target-list)))
17110 (setq target-list tmp-list))
17111 (setq rule-alist (cdr rule-alist)))
17112 (insert "\n\n### " makefile-name " ends here\n")
17113 ;; run Makefile generation hook
17114 (run-hooks 'vhdl-makefile-generation-hook)
17115 (message "Generating makefile \"%s\"...done" makefile-name)
17116 ;; save and close file
17117 (if (file-writable-p makefile-path-name)
17118 (progn (save-buffer)
17119 (kill-buffer (current-buffer))
17120 (set-buffer orig-buffer)
7cd80673 17121 (add-to-history 'file-name-history makefile-path-name))
3dcb36b7
JB
17122 (vhdl-warning-when-idle
17123 (format "File not writable: \"%s\""
17124 (abbreviate-file-name makefile-path-name)))
17125 (switch-to-buffer (current-buffer))))))
17126
5eabfe72
KH
17127
17128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17129;;; Bug reports
17130;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
17131;; (using `reporter.el')
17132
3dcb36b7
JB
17133(defconst vhdl-mode-help-address
17134 "Reto Zimmermann <reto@gnu.org>"
d2ddb974
KH
17135 "Address for VHDL Mode bug reports.")
17136
3dcb36b7
JB
17137(defun vhdl-submit-bug-report ()
17138 "Submit via mail a bug report on VHDL Mode."
17139 (interactive)
17140 ;; load in reporter
17141 (and
17142 (y-or-n-p "Do you want to submit a report on VHDL Mode? ")
17143 (let ((reporter-prompt-for-summary-p t))
17144 (reporter-submit-bug-report
17145 vhdl-mode-help-address
17146 (concat "VHDL Mode " vhdl-version)
17147 (list
17148 ;; report all important user options
17149 'vhdl-offsets-alist
17150 'vhdl-comment-only-line-offset
17151 'tab-width
17152 'vhdl-electric-mode
17153 'vhdl-stutter-mode
17154 'vhdl-indent-tabs-mode
17155 'vhdl-project-alist
17156 'vhdl-project
17157 'vhdl-project-file-name
17158 'vhdl-project-auto-load
17159 'vhdl-project-sort
17160 'vhdl-compiler-alist
17161 'vhdl-compiler
17162 'vhdl-compile-use-local-error-regexp
fda91268 17163 'vhdl-makefile-default-targets
3dcb36b7
JB
17164 'vhdl-makefile-generation-hook
17165 'vhdl-default-library
17166 'vhdl-standard
17167 'vhdl-basic-offset
17168 'vhdl-upper-case-keywords
17169 'vhdl-upper-case-types
17170 'vhdl-upper-case-attributes
17171 'vhdl-upper-case-enum-values
17172 'vhdl-upper-case-constants
17173 'vhdl-use-direct-instantiation
fda91268 17174 'vhdl-array-index-record-field-in-sensitivity-list
0a2e512a 17175 'vhdl-compose-configuration-name
3dcb36b7
JB
17176 'vhdl-entity-file-name
17177 'vhdl-architecture-file-name
0a2e512a 17178 'vhdl-configuration-file-name
3dcb36b7
JB
17179 'vhdl-package-file-name
17180 'vhdl-file-name-case
17181 'vhdl-electric-keywords
17182 'vhdl-optional-labels
17183 'vhdl-insert-empty-lines
17184 'vhdl-argument-list-indent
17185 'vhdl-association-list-with-formals
17186 'vhdl-conditions-in-parenthesis
17187 'vhdl-zero-string
17188 'vhdl-one-string
17189 'vhdl-file-header
17190 'vhdl-file-footer
17191 'vhdl-company-name
17192 'vhdl-copyright-string
17193 'vhdl-platform-spec
17194 'vhdl-date-format
17195 'vhdl-modify-date-prefix-string
17196 'vhdl-modify-date-on-saving
17197 'vhdl-reset-kind
17198 'vhdl-reset-active-high
17199 'vhdl-clock-rising-edge
17200 'vhdl-clock-edge-condition
17201 'vhdl-clock-name
17202 'vhdl-reset-name
17203 'vhdl-model-alist
17204 'vhdl-include-port-comments
17205 'vhdl-include-direction-comments
17206 'vhdl-include-type-comments
17207 'vhdl-include-group-comments
17208 'vhdl-actual-port-name
17209 'vhdl-instance-name
17210 'vhdl-testbench-entity-name
17211 'vhdl-testbench-architecture-name
17212 'vhdl-testbench-configuration-name
17213 'vhdl-testbench-dut-name
17214 'vhdl-testbench-include-header
17215 'vhdl-testbench-declarations
17216 'vhdl-testbench-statements
17217 'vhdl-testbench-initialize-signals
17218 'vhdl-testbench-include-library
17219 'vhdl-testbench-include-configuration
17220 'vhdl-testbench-create-files
0a2e512a
RF
17221 'vhdl-testbench-entity-file-name
17222 'vhdl-testbench-architecture-file-name
3dcb36b7 17223 'vhdl-compose-create-files
0a2e512a
RF
17224 'vhdl-compose-configuration-create-file
17225 'vhdl-compose-configuration-hierarchical
17226 'vhdl-compose-configuration-use-subconfiguration
3dcb36b7
JB
17227 'vhdl-compose-include-header
17228 'vhdl-compose-architecture-name
17229 'vhdl-components-package-name
17230 'vhdl-use-components-package
17231 'vhdl-self-insert-comments
17232 'vhdl-prompt-for-comments
17233 'vhdl-inline-comment-column
17234 'vhdl-end-comment-column
17235 'vhdl-auto-align
17236 'vhdl-align-groups
17237 'vhdl-align-group-separate
17238 'vhdl-align-same-indent
17239 'vhdl-highlight-keywords
17240 'vhdl-highlight-names
17241 'vhdl-highlight-special-words
17242 'vhdl-highlight-forbidden-words
17243 'vhdl-highlight-verilog-keywords
17244 'vhdl-highlight-translate-off
17245 'vhdl-highlight-case-sensitive
17246 'vhdl-special-syntax-alist
17247 'vhdl-forbidden-words
17248 'vhdl-forbidden-syntax
17249 'vhdl-directive-keywords
17250 'vhdl-speedbar-auto-open
17251 'vhdl-speedbar-display-mode
17252 'vhdl-speedbar-scan-limit
17253 'vhdl-speedbar-jump-to-unit
17254 'vhdl-speedbar-update-on-saving
17255 'vhdl-speedbar-save-cache
17256 'vhdl-speedbar-cache-file-name
17257 'vhdl-index-menu
17258 'vhdl-source-file-menu
17259 'vhdl-hideshow-menu
17260 'vhdl-hide-all-init
17261 'vhdl-print-two-column
17262 'vhdl-print-customize-faces
17263 'vhdl-intelligent-tab
17264 'vhdl-indent-syntax-based
fda91268 17265 'vhdl-indent-comment-like-next-code-line
3dcb36b7
JB
17266 'vhdl-word-completion-case-sensitive
17267 'vhdl-word-completion-in-minibuffer
17268 'vhdl-underscore-is-part-of-word
17269 'vhdl-mode-hook)
17270 (function
17271 (lambda ()
17272 (insert
17273 (if vhdl-special-indent-hook
17274 (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
17275 "vhdl-special-indent-hook is set to '"
17276 (format "%s" vhdl-special-indent-hook)
17277 ".\nPerhaps this is your problem?\n"
17278 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
17279 "\n"))))
17280 nil
17281 "Hi Reto,"))))
17282
17283
17284;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17285;;; Documentation
17286;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17287
17288(defconst vhdl-doc-release-notes nil
17289 "\
0a2e512a 17290Release Notes for VHDL Mode 3.33
3dcb36b7
JB
17291================================
17292
17293 - New Features
3dcb36b7 17294 - User Options
3dcb36b7
JB
17295
17296
17297New Features
17298------------
17299
0a2e512a
RF
17300CONFIGURATION DECLARATION GENERATION:
17301 - Automatic generation of a configuration declaration for a design.
17302 (See documentation (`C-c C-h') in section on STRUCTURAL COMPOSITION.)
3dcb36b7
JB
17303
17304
fda91268
RZ
17305Key Bindings
17306------------
17307
17308For Emacs compliance the following key bindings have been changed:
17309
17310- `C-c c' -> `C-c C-c' `vhdl-comment-uncomment-region'
17311- `C-c f' -> `C-c C-i C-f' `vhdl-fontify-buffer'
17312- `C-c s' -> `C-c C-i C-s' `vhdl-statistics-buffer'
17313- `C-c C-c ...' -> `C-c C-m ...' `vhdl-compose-...'
17314
17315
3dcb36b7
JB
17316User Options
17317------------
17318
0a2e512a
RF
17319`vhdl-configuration-file-name': (new)
17320 Specify how the configuration file name is obtained.
17321`vhdl-compose-configuration-name': (new)
e1dbe924 17322 Specify how the configuration name is obtained.
0a2e512a
RF
17323`vhdl-compose-configuration-create-file': (new)
17324 Specify whether a new file should be created for a configuration.
17325`vhdl-compose-configuration-hierarchical': (new)
17326 Specify whether hierarchical configurations should be created.
17327`vhdl-compose-configuration-use-subconfiguration': (new)
17328 Specify whether subconfigurations should be used inside configurations.
fda91268
RZ
17329`vhdl-makefile-default-targets': (new)
17330 Customize names of Makefile default targets.
17331`vhdl-indent-comment-like-next-code-line': (new)
17332 Specify whether comment lines are indented like following code line.
17333`vhdl-array-index-record-field-in-sensitivity-list': (new)
17334 Specify whether to include array indices / record fields in sensitivity list.
3dcb36b7
JB
17335")
17336
17337
17338(defconst vhdl-doc-keywords nil
17339 "\
17340Reserved words in VHDL
17341----------------------
17342
fda91268
RZ
17343VHDL'93/02 (IEEE Std 1076-1993/2002):
17344 `vhdl-02-keywords' : keywords
17345 `vhdl-02-types' : standardized types
17346 `vhdl-02-attributes' : standardized attributes
17347 `vhdl-02-enum-values' : standardized enumeration values
17348 `vhdl-02-functions' : standardized functions
17349 `vhdl-02-packages' : standardized packages and libraries
3dcb36b7 17350
fda91268 17351VHDL-AMS (IEEE Std 1076.1 / 1076.1.1):
3dcb36b7
JB
17352 `vhdl-ams-keywords' : keywords
17353 `vhdl-ams-types' : standardized types
17354 `vhdl-ams-attributes' : standardized attributes
17355 `vhdl-ams-enum-values' : standardized enumeration values
fda91268 17356 `vhdl-ams-constants' : standardized constants
3dcb36b7
JB
17357 `vhdl-ams-functions' : standardized functions
17358
17359Math Packages (IEEE Std 1076.2):
17360 `vhdl-math-types' : standardized types
17361 `vhdl-math-constants' : standardized constants
17362 `vhdl-math-functions' : standardized functions
17363 `vhdl-math-packages' : standardized packages
17364
17365Forbidden words:
17366 `vhdl-verilog-keywords' : Verilog reserved words
17367
17368NOTE: click `mouse-2' on variable names above (not in XEmacs).")
17369
17370
17371(defconst vhdl-doc-coding-style nil
17372 "\
17373For VHDL coding style and naming convention guidelines, see the following
17374references:
17375
17376\[1] Ben Cohen.
17377 \"VHDL Coding Styles and Methodologies\".
17378 Kluwer Academic Publishers, 1999.
17379 http://members.aol.com/vhdlcohen/vhdl/
17380
17381\[2] Michael Keating and Pierre Bricaud.
17382 \"Reuse Methodology Manual, Second Edition\".
17383 Kluwer Academic Publishers, 1999.
17384 http://www.openmore.com/openmore/rmm2.html
17385
17386\[3] European Space Agency.
17387 \"VHDL Modelling Guidelines\".
17388 ftp://ftp.estec.esa.nl/pub/vhdl/doc/ModelGuide.{pdf,ps}
17389
17390Use user options `vhdl-highlight-special-words' and `vhdl-special-syntax-alist'
17391to visually support naming conventions.")
17392
17393
d2ddb974
KH
17394(defun vhdl-version ()
17395 "Echo the current version of VHDL Mode in the minibuffer."
17396 (interactive)
3dcb36b7 17397 (message "VHDL Mode %s (%s)" vhdl-version vhdl-time-stamp)
d2ddb974
KH
17398 (vhdl-keep-region-active))
17399
3dcb36b7
JB
17400(defun vhdl-doc-variable (variable)
17401 "Display VARIABLE's documentation in *Help* buffer."
17402 (interactive)
f8246027 17403 (unless (featurep 'xemacs)
20367d28
RS
17404 (help-setup-xref (list #'vhdl-doc-variable variable)
17405 (called-interactively-p 'interactive)))
0a2e512a
RF
17406 (with-output-to-temp-buffer
17407 (if (fboundp 'help-buffer) (help-buffer) "*Help*")
3dcb36b7 17408 (princ (documentation-property variable 'variable-documentation))
4bcb9c95 17409 (with-current-buffer standard-output
3dcb36b7 17410 (help-mode))
d5d105e8 17411 (help-print-return-message)))
d2ddb974 17412
3dcb36b7
JB
17413(defun vhdl-doc-mode ()
17414 "Display VHDL Mode documentation in *Help* buffer."
d2ddb974 17415 (interactive)
f8246027 17416 (unless (featurep 'xemacs)
20367d28
RS
17417 (help-setup-xref (list #'vhdl-doc-mode)
17418 (called-interactively-p 'interactive)))
0a2e512a
RF
17419 (with-output-to-temp-buffer
17420 (if (fboundp 'help-buffer) (help-buffer) "*Help*")
3dcb36b7
JB
17421 (princ mode-name)
17422 (princ " mode:\n")
17423 (princ (documentation 'vhdl-mode))
4bcb9c95 17424 (with-current-buffer standard-output
3dcb36b7 17425 (help-mode))
d5d105e8 17426 (help-print-return-message)))
d2ddb974
KH
17427
17428
5eabfe72 17429;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
d2ddb974
KH
17430
17431(provide 'vhdl-mode)
17432
17433;;; vhdl-mode.el ends here