20665
|
1 ;;; vhdl-mode.el --- major mode for editing VHDL code
|
|
2
|
|
3 ;; Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
|
4
|
|
5 ;; Authors: Reto Zimmermann <mailto:Reto.Zimmermann@iaeth.ch>
|
|
6 ;; <http://www.iis.ee.ethz.ch/~zimmi/>
|
|
7 ;; Rodney J. Whitby <mailto:rwhitby@geocities.com>
|
|
8 ;; <http://www.geocities.com/SiliconValley/Park/8287/>
|
|
9 ;; Maintainer: vhdl-mode@geocities.com
|
|
10 ;; Maintainers' Version: 3.19
|
|
11 ;; Keywords: languages vhdl
|
|
12
|
|
13 ;; This file is part of GNU Emacs.
|
|
14
|
|
15 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
16 ;; it under the terms of the GNU General Public License as published by
|
|
17 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
18 ;; any later version.
|
|
19
|
|
20 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
23 ;; GNU General Public License for more details.
|
|
24
|
|
25 ;; You should have received a copy of the GNU General Public License
|
|
26 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
27 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
28 ;; Boston, MA 02111-1307, USA.
|
|
29
|
|
30 ;; ############################################################################
|
|
31 ;;; Commentary:
|
|
32 ;; ############################################################################
|
|
33
|
|
34 ;; This package provides an Emacs major mode for editing VHDL code.
|
|
35 ;; It includes the following features:
|
|
36
|
|
37 ;; - Highlighting of VHDL syntax
|
|
38 ;; - Indentation based on versatile syntax analysis
|
|
39 ;; - Template insertion (electrification) for most VHDL constructs
|
|
40 ;; - Insertion of customizable VHDL file headers
|
|
41 ;; - Word completion (dynamic abbreviations)
|
|
42 ;; - Menu containing all VHDL Mode commands
|
|
43 ;; - Index menu (jump index to main units and blocks in a file)
|
|
44 ;; - Source file menu (menu of all source files in current directory)
|
|
45 ;; - Source file compilation (syntax analysis)
|
|
46 ;; - Postscript printing with fontification
|
|
47 ;; - Lower and upper case keywords
|
|
48 ;; - Hiding blocks of code
|
|
49 ;; - Alignment functions
|
|
50 ;; - Easy customization
|
|
51 ;; - Works under GNU Emacs and XEmacs
|
|
52
|
|
53 ;; ############################################################################
|
|
54 ;; Usage
|
|
55 ;; ############################################################################
|
|
56
|
|
57 ;; see below (comment in vhdl-mode function) or type `C-c C-h' in Emacs.
|
|
58
|
|
59 ;; ############################################################################
|
|
60 ;; Emacs Versions
|
|
61 ;; ############################################################################
|
|
62
|
|
63 ;; - Emacs 20
|
|
64 ;; - XEmacs 19.15
|
|
65 ;; - This version does not support Emacs 19 (use VHDL Mode 3.10 instead)
|
|
66
|
|
67
|
|
68 ;; ############################################################################
|
|
69 ;; Acknowledgements
|
|
70 ;; ############################################################################
|
|
71
|
|
72 ;; Electrification ideas by Bob Pack <rlpst@cislabs.pitt.edu>
|
|
73 ;; and Steve Grout
|
|
74
|
|
75 ;; Fontification approach suggested by Ken Wood <ken@eda.com.au>
|
|
76 ;; Source file menu suggested by Michael Laajanen <mila@enea.se>
|
|
77 ;; Ideas about alignment from John Wiegley <johnw@borland.com>
|
|
78
|
|
79 ;; Many thanks to all the users who sent me bug reports and enhancement
|
|
80 ;; requests.
|
|
81 ;; Special thanks go to Dan Nicolaescu <done@ece.arizona.edu> for reviewing
|
|
82 ;; the code and for his valuable hints.
|
|
83
|
|
84 ;;; Code:
|
|
85
|
|
86 ;; ############################################################################
|
|
87 ;; User definable variables
|
|
88 ;; ############################################################################
|
|
89
|
|
90 ;; ############################################################################
|
|
91 ;; Variables for customization
|
|
92
|
|
93 (defgroup vhdl nil
|
|
94 "Customizations for VHDL Mode."
|
|
95 :prefix "vhdl-"
|
|
96 :group 'languages)
|
|
97
|
|
98
|
|
99 (defgroup vhdl-mode nil
|
|
100 "Customizations for modes."
|
|
101 :group 'vhdl)
|
|
102
|
|
103 (defcustom vhdl-electric-mode t
|
|
104 "*If non-nil, electrification (automatic template generation) is enabled.
|
|
105 If nil, template generators can still be invoked through key bindings
|
|
106 and menu. Can be toggled by `\\[vhdl-electric-mode]'."
|
|
107 :type 'boolean
|
|
108 :group 'vhdl-mode)
|
|
109
|
|
110 (defcustom vhdl-stutter-mode t
|
|
111 "*If non-nil, stuttering is enabled.
|
|
112 Can be toggled by `\\[vhdl-stutter-mode]'."
|
|
113 :type 'boolean
|
|
114 :group 'vhdl-mode)
|
|
115
|
|
116 (defcustom vhdl-indent-tabs-mode t
|
|
117 "*Indentation can insert tabs if this is non-nil.
|
|
118 Overrides local variable `indent-tabs-mode'."
|
|
119 :type 'boolean
|
|
120 :group 'vhdl-mode)
|
|
121
|
|
122
|
|
123 (defgroup vhdl-compile nil
|
|
124 "Customizations for compilation."
|
|
125 :group 'vhdl)
|
|
126
|
|
127 (defcustom vhdl-compiler 'v-system
|
|
128 "*VHDL compiler to be used for syntax analysis.
|
|
129 cadence Cadence Design Systems (`cv -file')
|
|
130 ikos Ikos Voyager (`analyze')
|
|
131 quickhdl QuickHDL, Mentor Graphics (`qvhcom')
|
|
132 synopsys Synopsys, VHDL Analyzer (`vhdlan')
|
|
133 vantage Vantage Analysis Systems (`analyze -libfile vsslib.ini -src')
|
|
134 viewlogic Viewlogic (`analyze -libfile vsslib.ini -src')
|
|
135 v-system V-System, Model Technology (`vcom')
|
|
136 For incorporation of additional compilers, please send me their command syntax
|
|
137 and some example error messages."
|
|
138 :type '(choice
|
|
139 (const cadence)
|
|
140 (const ikos)
|
|
141 (const quickhdl)
|
|
142 (const synopsys)
|
|
143 (const vantage)
|
|
144 (const viewlogic)
|
|
145 (const v-system)
|
|
146 )
|
|
147 :group 'vhdl-compile)
|
|
148
|
|
149 (defcustom vhdl-compiler-options ""
|
|
150 "*Options to be added to the compile command."
|
|
151 :type 'string
|
|
152 :group 'vhdl-compile)
|
|
153
|
|
154
|
|
155 (defgroup vhdl-style nil
|
|
156 "Customizations for code styles."
|
|
157 :group 'vhdl)
|
|
158
|
|
159 (defcustom vhdl-basic-offset 4
|
|
160 "*Amount of basic offset used for indentation.
|
|
161 This value is used by + and - symbols in `vhdl-offsets-alist'."
|
|
162 :type 'integer
|
|
163 :group 'vhdl-style)
|
|
164
|
|
165
|
|
166 (defgroup vhdl-word-case nil
|
|
167 "Customizations for case of VHDL words."
|
|
168 :group 'vhdl-style)
|
|
169
|
|
170 (defcustom vhdl-upper-case-keywords nil
|
|
171 "*If non-nil, keywords are converted to upper case
|
|
172 when typed or by the fix case functions."
|
|
173 :type 'boolean
|
|
174 :group 'vhdl-word-case)
|
|
175
|
|
176 (defcustom vhdl-upper-case-types nil
|
|
177 "*If non-nil, standardized types are converted to upper case
|
|
178 by the fix case functions."
|
|
179 :type 'boolean
|
|
180 :group 'vhdl-word-case)
|
|
181
|
|
182 (defcustom vhdl-upper-case-attributes nil
|
|
183 "*If non-nil, standardized attributes are converted to upper case
|
|
184 by the fix case functions."
|
|
185 :type 'boolean
|
|
186 :group 'vhdl-word-case)
|
|
187
|
|
188 (defcustom vhdl-upper-case-enum-values nil
|
|
189 "*If non-nil, standardized enumeration values are converted to upper case
|
|
190 by the fix case functions."
|
|
191 :type 'boolean
|
|
192 :group 'vhdl-word-case)
|
|
193
|
|
194
|
|
195 (defgroup vhdl-electric nil
|
|
196 "Customizations for comments."
|
|
197 :group 'vhdl)
|
|
198
|
|
199 (defcustom vhdl-auto-align nil
|
|
200 "*If non-nil, some templates are automatically aligned after generation."
|
|
201 :type 'boolean
|
|
202 :group 'vhdl-electric)
|
|
203
|
|
204 (defcustom vhdl-additional-empty-lines t
|
|
205 "*If non-nil, additional empty lines are inserted in some templates.
|
|
206 This improves readability of code."
|
|
207 :type 'boolean
|
|
208 :group 'vhdl-electric)
|
|
209
|
|
210 (defcustom vhdl-argument-list-indent t
|
|
211 "*If non-nil, argument lists are indented relative to the opening paren.
|
|
212 Normal indentation is applied otherwise."
|
|
213 :type 'boolean
|
|
214 :group 'vhdl-electric)
|
|
215
|
|
216 (defcustom vhdl-conditions-in-parenthesis nil
|
|
217 "*If non-nil, parenthesis are placed around condition expressions."
|
|
218 :type 'boolean
|
|
219 :group 'vhdl-electric)
|
|
220
|
|
221 (defcustom vhdl-date-format 'scientific
|
|
222 "*Specifies date format to be used in header.
|
|
223 Date formats are:
|
|
224 american (09/17/1997)
|
|
225 european (17.09.1997)
|
|
226 scientific (1997/09/17)"
|
|
227 :type '(choice (const american)
|
|
228 (const european)
|
|
229 (const scientific))
|
|
230 :group 'vhdl-electric)
|
|
231
|
|
232 (defcustom vhdl-header-file nil
|
|
233 "*Pathname/filename of the file to be inserted as header.
|
|
234 If the header contains RCS keywords, they may be written as <RCS>Keyword<RCS>
|
|
235 if the header needs to be version controlled.
|
|
236
|
|
237 The following keywords for template generation are supported:
|
|
238 <filename> : replaced by the name of the buffer
|
|
239 <author> : replaced by the user name and email address
|
|
240 <date> : replaced by the current date
|
|
241 <... string> : replaced by a prompted string (... is the prompt word)
|
|
242 <cursor> : final cursor position
|
|
243
|
|
244 Example:
|
|
245 -----------------------------------------
|
|
246 -- Title : <title string>
|
|
247 -- File : <filename>
|
|
248 -- Author : <author>
|
|
249 -- Created : <date>
|
|
250 -- Description : <cursor>
|
|
251 -----------------------------------------"
|
|
252 :type 'string
|
|
253 :group 'vhdl-electric)
|
|
254
|
|
255 (defcustom vhdl-modify-date-prefix-string "-- Last modified : "
|
|
256 "*Prefix string of modification date in VHDL file header.
|
|
257 If actualization of the modification date is called (menu, `\\[vhdl-modify]'),
|
|
258 this string is searched and the rest of the line replaced by the current date."
|
|
259 :type 'string
|
|
260 :group 'vhdl-electric)
|
|
261
|
|
262 (defcustom vhdl-zero-string "'0'"
|
|
263 "*String to use for a logic zero."
|
|
264 :type 'string
|
|
265 :group 'vhdl-electric)
|
|
266
|
|
267 (defcustom vhdl-one-string "'1'"
|
|
268 "*String to use for a logic one."
|
|
269 :type 'string
|
|
270 :group 'vhdl-electric)
|
|
271
|
|
272
|
|
273 (defgroup vhdl-comment nil
|
|
274 "Customizations for comments."
|
|
275 :group 'vhdl-electric)
|
|
276
|
|
277 (defcustom vhdl-self-insert-comments t
|
|
278 "*If non-nil, variables templates automatically insert help comments."
|
|
279 :type 'boolean
|
|
280 :group 'vhdl-comment)
|
|
281
|
|
282 (defcustom vhdl-prompt-for-comments t
|
|
283 "*If non-nil, various templates prompt for user definable comments."
|
|
284 :type 'boolean
|
|
285 :group 'vhdl-comment)
|
|
286
|
|
287 (defcustom vhdl-comment-column 40
|
|
288 "*Column to indent right-margin comments to.
|
|
289 Overrides local variable `comment-column'."
|
|
290 :type 'integer
|
|
291 :group 'vhdl-comment)
|
|
292
|
|
293 (defcustom vhdl-end-comment-column 79
|
|
294 "*End of comment column."
|
|
295 :type 'integer
|
|
296 :group 'vhdl-comment)
|
|
297
|
|
298 (defvar end-comment-column 79
|
|
299 "*End of comment column.")
|
|
300
|
|
301
|
|
302 (defgroup vhdl-highlight nil
|
|
303 "Customizations for highlighting."
|
|
304 :group 'vhdl)
|
|
305
|
|
306 (defcustom vhdl-highlight-names t
|
|
307 "*If non-nil, unit names, subprogram names, and labels are highlighted."
|
|
308 :type 'boolean
|
|
309 :group 'vhdl-highlight)
|
|
310
|
|
311 (defcustom vhdl-highlight-keywords t
|
|
312 "*If non-nil, VHDL keywords and other predefined words are highlighted.
|
|
313 That is, keywords, predefined types, predefined attributes, and predefined
|
|
314 enumeration values are highlighted."
|
|
315 :type 'boolean
|
|
316 :group 'vhdl-highlight)
|
|
317
|
|
318 (defcustom vhdl-highlight-signals nil
|
|
319 "*If non-nil, signals of different classes are highlighted using colors.
|
|
320 Signal classes are: clock, reset, status/control, data, and test."
|
|
321 :type 'boolean
|
|
322 :group 'vhdl-highlight)
|
|
323
|
|
324 (defcustom vhdl-highlight-case-sensitive nil
|
|
325 "*If non-nil, case is considered for highlighting.
|
|
326 Possible trade-off:
|
|
327 non-nil also upper-case VHDL words are highlighted, but case of signal names
|
|
328 is not considered (may lead to highlighting of unwanted words),
|
|
329 nil only lower-case VHDL words are highlighted, but case of signal names
|
|
330 is considered.
|
|
331 Overrides local variable `font-lock-keywords-case-fold-search'."
|
|
332 :type 'boolean
|
|
333 :group 'vhdl-highlight)
|
|
334
|
|
335 (defcustom vhdl-use-default-colors nil
|
|
336 "*If non-nil, the default colors are taken for syntax highlighting.
|
|
337 If nil, all colors are customized in VHDL Mode for better matching with the
|
|
338 additional signal colors."
|
|
339 :type 'boolean
|
|
340 :group 'vhdl-highlight)
|
|
341
|
|
342 (defcustom vhdl-use-default-faces nil
|
|
343 "*If non-nil, the default faces are taken for syntax highlighting.
|
|
344 If nil, all faces are customized for better matching with the additional faces
|
|
345 used in VHDL Mode. This variable comes only into effect if no colors are used
|
|
346 for highlighting or printing (i.e. variable `ps-print-color-p' is nil)."
|
|
347 :type 'boolean
|
|
348 :group 'vhdl-highlight)
|
|
349
|
|
350
|
|
351 (defgroup vhdl-signal-syntax nil
|
|
352 "Customizations of signal syntax for highlighting."
|
|
353 :group 'vhdl-highlight)
|
|
354
|
|
355 (defcustom vhdl-signal-syntax-doc-string "
|
|
356 Must be of the form \"\\ \<\\\(...\\\)\\\>\", where ... specifies the actual syntax.
|
|
357 (delete this space ^ , it's only a workaround to get this doc string.)
|
|
358 The basic regexp elements are:
|
|
359 [A-Z] any upper case letter
|
|
360 [A-Za-z] any letter
|
|
361 [0-9] any digit
|
|
362 \\w any letter or digit (corresponds to [A-Za-z0-9])
|
|
363 [XY] letter \"X\" or \"Y\"
|
|
364 [^XY] neither letter \"X\" nor \"Y\"
|
|
365 x letter \"x\"
|
|
366 * postfix operator for matching previous regexp element any times
|
|
367 + postfix operator for matching previous regexp element at least once
|
|
368 ? postfix operator for matching previous regexp element at most once"
|
|
369 "Common document string used for the custom variables below. Must be
|
|
370 defined as custom variable due to a bug in XEmacs.")
|
|
371
|
|
372 (defcustom vhdl-clock-signal-syntax "\\<\\([A-Z]\\w*xC\\w*\\)\\>"
|
|
373 (concat
|
|
374 "*Regular expression (regexp) for syntax of clock signals."
|
|
375 vhdl-signal-syntax-doc-string)
|
|
376 :type 'regexp
|
|
377 :group 'vhdl-signal-syntax)
|
|
378
|
|
379 (defcustom vhdl-reset-signal-syntax "\\<\\([A-Z]\\w*xR\\w*\\)\\>"
|
|
380 (concat
|
|
381 "*Regular expression (regexp) for syntax of (asynchronous) reset signals."
|
|
382 vhdl-signal-syntax-doc-string)
|
|
383 :type 'regexp
|
|
384 :group 'vhdl-signal-syntax)
|
|
385
|
|
386 (defcustom vhdl-control-signal-syntax "\\<\\([A-Z]\\w*x[IS]\\w*\\)\\>"
|
|
387 (concat
|
|
388 "*Regular expression (regexp) for syntax of status/control signals."
|
|
389 vhdl-signal-syntax-doc-string)
|
|
390 :type 'regexp
|
|
391 :group 'vhdl-signal-syntax)
|
|
392
|
|
393 (defcustom vhdl-data-signal-syntax "\\<\\([A-Z]\\w*xD\\w*\\)\\>"
|
|
394 (concat
|
|
395 "*Regular expression (regexp) for syntax of data signals."
|
|
396 vhdl-signal-syntax-doc-string)
|
|
397 :type 'regexp
|
|
398 :group 'vhdl-signal-syntax)
|
|
399
|
|
400 (defcustom vhdl-test-signal-syntax "\\<\\([A-Z]\\w*xT\\w*\\)\\>"
|
|
401 (concat
|
|
402 "*Regular expression (regexp) for syntax of test signals."
|
|
403 vhdl-signal-syntax-doc-string)
|
|
404 :type 'regexp
|
|
405 :group 'vhdl-signal-syntax)
|
|
406
|
|
407
|
|
408 (defgroup vhdl-menu nil
|
|
409 "Customizations for menues."
|
|
410 :group 'vhdl)
|
|
411
|
|
412 (defcustom vhdl-source-file-menu t
|
|
413 "*If non-nil, a menu of all source files in the current directory is created."
|
|
414 :type 'boolean
|
|
415 :group 'vhdl-menu)
|
|
416
|
|
417 (defcustom vhdl-index-menu t
|
|
418 "*If non-nil, an index menu for the current source file is created."
|
|
419 :type 'boolean
|
|
420 :group 'vhdl-menu)
|
|
421
|
|
422 (defcustom vhdl-hideshow-menu (not (string-match "XEmacs" emacs-version))
|
|
423 "*If non-nil, hideshow menu and functionality is added.
|
|
424 Hideshow allows hiding code of VHDL processes and blocks.
|
|
425 (Does not work under XEmacs.)"
|
|
426 :type 'boolean
|
|
427 :group 'vhdl-menu)
|
|
428
|
|
429
|
|
430 (defgroup vhdl-print nil
|
|
431 "Customizations for printing."
|
|
432 :group 'vhdl)
|
|
433
|
|
434 (defcustom vhdl-print-two-column t
|
|
435 "*If non-nil, code is printed in two columns and landscape format."
|
|
436 :type 'boolean
|
|
437 :group 'vhdl-print)
|
|
438
|
|
439
|
|
440 (defgroup vhdl-misc nil
|
|
441 "Miscellaneous customizations."
|
|
442 :group 'vhdl)
|
|
443
|
|
444 (defcustom vhdl-intelligent-tab t
|
|
445 "*If non-nil, `TAB' does indentation, word completion, and tab insertion.
|
|
446 That is, if preceeding character is part of a word then complete word,
|
|
447 else if not at beginning of line then insert tab,
|
|
448 else if last command was a `TAB' or `RET' then dedent one step,
|
|
449 else indent current line (i.e. `TAB' is bound to `vhdl-tab').
|
|
450 If nil, TAB always indents current line (i.e. `TAB' is bound to
|
|
451 `vhdl-indent-line')."
|
|
452 :type 'boolean
|
|
453 :group 'vhdl-misc)
|
|
454
|
|
455 (defcustom vhdl-template-key-binding-prefix "\C-t"
|
|
456 "*`C-c' plus this key gives the key binding prefix for all VHDL templates.
|
|
457 Default key binding prefix for templates is `C-c C-t' (example: architecture
|
|
458 `C-c C-t a'). If you have no own `C-c LETTER' bindings, you can shorten the
|
|
459 template key binding prefix to `C-c' (example: architecture `C-c a') by
|
|
460 assigning the empty character (\"\") to this variable. The syntax to enter
|
|
461 control keys is \"\\C-t\"."
|
|
462 :type 'sexp
|
|
463 :group 'vhdl-misc)
|
|
464
|
|
465 (defcustom vhdl-word-completion-in-minibuffer t
|
|
466 "*If non-nil, word completion works in minibuffer (for template prompts)."
|
|
467 :type 'boolean
|
|
468 :group 'vhdl-misc)
|
|
469
|
|
470 (defcustom vhdl-underscore-is-part-of-word nil
|
|
471 "*If non-nil, the underscore character `_' is considered as part of word.
|
|
472 An identifier containing underscores is then treated as a single word in
|
|
473 select and move operations. All parts of an identifier separated by underscore
|
|
474 are treated as single words otherwise."
|
|
475 :type 'boolean
|
|
476 :group 'vhdl-misc)
|
|
477
|
|
478 ;; ############################################################################
|
|
479 ;; Other variables
|
|
480
|
|
481 (defvar vhdl-inhibit-startup-warnings-p nil
|
|
482 "*If non-nil, inhibits start up compatibility warnings.")
|
|
483
|
|
484 (defvar vhdl-strict-syntax-p nil
|
|
485 "*If non-nil, all syntactic symbols must be found in `vhdl-offsets-alist'.
|
|
486 If the syntactic symbol for a particular line does not match a symbol
|
|
487 in the offsets alist, an error is generated, otherwise no error is
|
|
488 reported and the syntactic symbol is ignored.")
|
|
489
|
|
490 (defvar vhdl-echo-syntactic-information-p nil
|
|
491 "*If non-nil, syntactic info is echoed when the line is indented.")
|
|
492
|
|
493 (defconst vhdl-offsets-alist-default
|
|
494 '((string . -1000)
|
|
495 (block-open . 0)
|
|
496 (block-close . 0)
|
|
497 (statement . 0)
|
|
498 (statement-cont . vhdl-lineup-statement-cont)
|
|
499 (statement-block-intro . +)
|
|
500 (statement-case-intro . +)
|
|
501 (case-alternative . +)
|
|
502 (comment . vhdl-lineup-comment)
|
|
503 (arglist-intro . +)
|
|
504 (arglist-cont . 0)
|
|
505 (arglist-cont-nonempty . vhdl-lineup-arglist)
|
|
506 (arglist-close . vhdl-lineup-arglist)
|
|
507 (entity . 0)
|
|
508 (configuration . 0)
|
|
509 (package . 0)
|
|
510 (architecture . 0)
|
|
511 (package-body . 0)
|
|
512 )
|
|
513 "Default settings for offsets of syntactic elements.
|
|
514 Do not change this constant! See the variable `vhdl-offsets-alist' for
|
|
515 more information.")
|
|
516
|
|
517 (defvar vhdl-offsets-alist (copy-alist vhdl-offsets-alist-default)
|
|
518 "*Association list of syntactic element symbols and indentation offsets.
|
|
519 As described below, each cons cell in this list has the form:
|
|
520
|
|
521 (SYNTACTIC-SYMBOL . OFFSET)
|
|
522
|
|
523 When a line is indented, vhdl-mode first determines the syntactic
|
|
524 context of the line by generating a list of symbols called syntactic
|
|
525 elements. This list can contain more than one syntactic element and
|
|
526 the global variable `vhdl-syntactic-context' contains the context list
|
|
527 for the line being indented. Each element in this list is actually a
|
|
528 cons cell of the syntactic symbol and a buffer position. This buffer
|
|
529 position is call the relative indent point for the line. Some
|
|
530 syntactic symbols may not have a relative indent point associated with
|
|
531 them.
|
|
532
|
|
533 After the syntactic context list for a line is generated, vhdl-mode
|
|
534 calculates the absolute indentation for the line by looking at each
|
|
535 syntactic element in the list. First, it compares the syntactic
|
|
536 element against the SYNTACTIC-SYMBOL's in `vhdl-offsets-alist'. When it
|
|
537 finds a match, it adds the OFFSET to the column of the relative indent
|
|
538 point. The sum of this calculation for each element in the syntactic
|
|
539 list is the absolute offset for line being indented.
|
|
540
|
|
541 If the syntactic element does not match any in the `vhdl-offsets-alist',
|
|
542 an error is generated if `vhdl-strict-syntax-p' is non-nil, otherwise
|
|
543 the element is ignored.
|
|
544
|
|
545 Actually, OFFSET can be an integer, a function, a variable, or one of
|
|
546 the following symbols: `+', `-', `++', or `--'. These latter
|
|
547 designate positive or negative multiples of `vhdl-basic-offset',
|
|
548 respectively: *1, *-1, *2, and *-2. If OFFSET is a function, it is
|
|
549 called with a single argument containing the cons of the syntactic
|
|
550 element symbol and the relative indent point. The function should
|
|
551 return an integer offset.
|
|
552
|
|
553 Here is the current list of valid syntactic element symbols:
|
|
554
|
|
555 string -- inside multi-line string
|
|
556 block-open -- statement block open
|
|
557 block-close -- statement block close
|
|
558 statement -- a VHDL statement
|
|
559 statement-cont -- a continuation of a VHDL statement
|
|
560 statement-block-intro -- the first line in a new statement block
|
|
561 statement-case-intro -- the first line in a case alternative block
|
|
562 case-alternative -- a case statement alternative clause
|
|
563 comment -- a line containing only a comment
|
|
564 arglist-intro -- the first line in an argument list
|
|
565 arglist-cont -- subsequent argument list lines when no
|
|
566 arguments follow on the same line as the
|
|
567 the arglist opening paren
|
|
568 arglist-cont-nonempty -- subsequent argument list lines when at
|
|
569 least one argument follows on the same
|
|
570 line as the arglist opening paren
|
|
571 arglist-close -- the solo close paren of an argument list
|
|
572 entity -- inside an entity declaration
|
|
573 configuration -- inside a configuration declaration
|
|
574 package -- inside a package declaration
|
|
575 architecture -- inside an architecture body
|
|
576 package-body -- inside a package body
|
|
577 ")
|
|
578
|
|
579 (defvar vhdl-comment-only-line-offset 0
|
|
580 "*Extra offset for line which contains only the start of a comment.
|
|
581 Can contain an integer or a cons cell of the form:
|
|
582
|
|
583 (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
|
|
584
|
|
585 Where NON-ANCHORED-OFFSET is the amount of offset given to
|
|
586 non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
|
|
587 the amount of offset to give column-zero anchored comment-only lines.
|
|
588 Just an integer as value is equivalent to (<val> . 0)")
|
|
589
|
|
590 (defvar vhdl-special-indent-hook nil
|
|
591 "*Hook for user defined special indentation adjustments.
|
|
592 This hook gets called after a line is indented by the mode.")
|
|
593
|
|
594 (defvar vhdl-style-alist
|
|
595 '(("IEEE"
|
|
596 (vhdl-basic-offset . 4)
|
|
597 (vhdl-offsets-alist . ())
|
|
598 )
|
|
599 )
|
|
600 "Styles of Indentation.
|
|
601 Elements of this alist are of the form:
|
|
602
|
|
603 (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
|
|
604
|
|
605 where STYLE-STRING is a short descriptive string used to select a
|
|
606 style, VARIABLE is any vhdl-mode variable, and VALUE is the intended
|
|
607 value for that variable when using the selected style.
|
|
608
|
|
609 There is one special case when VARIABLE is `vhdl-offsets-alist'. In this
|
|
610 case, the VALUE is a list containing elements of the form:
|
|
611
|
|
612 (SYNTACTIC-SYMBOL . VALUE)
|
|
613
|
|
614 as described in `vhdl-offsets-alist'. These are passed directly to
|
|
615 `vhdl-set-offset' so there is no need to set every syntactic symbol in
|
|
616 your style, only those that are different from the default.")
|
|
617
|
|
618 ;; dynamically append the default value of most variables
|
|
619 (or (assoc "Default" vhdl-style-alist)
|
|
620 (let* ((varlist '(vhdl-inhibit-startup-warnings-p
|
|
621 vhdl-strict-syntax-p
|
|
622 vhdl-echo-syntactic-information-p
|
|
623 vhdl-basic-offset
|
|
624 vhdl-offsets-alist
|
|
625 vhdl-comment-only-line-offset))
|
|
626 (default (cons "Default"
|
|
627 (mapcar
|
|
628 (function
|
|
629 (lambda (var)
|
|
630 (cons var (symbol-value var))
|
|
631 ))
|
|
632 varlist))))
|
|
633 (setq vhdl-style-alist (cons default vhdl-style-alist))))
|
|
634
|
|
635 (defvar vhdl-mode-hook nil
|
|
636 "*Hook called by `vhdl-mode'.")
|
|
637
|
|
638
|
|
639 ;; ############################################################################
|
|
640 ;; Emacs variant handling
|
|
641 ;; ############################################################################
|
|
642
|
|
643 ;; active regions
|
|
644
|
|
645 (defun vhdl-keep-region-active ()
|
|
646 ;; do whatever is necessary to keep the region active in XEmacs
|
|
647 ;; (formerly Lucid). ignore byte-compiler warnings you might see
|
|
648 (and (boundp 'zmacs-region-stays)
|
|
649 (setq zmacs-region-stays t)))
|
|
650
|
|
651 (defconst vhdl-emacs-features
|
|
652 (let ((major (and (boundp 'emacs-major-version)
|
|
653 emacs-major-version))
|
|
654 (minor (and (boundp 'emacs-minor-version)
|
|
655 emacs-minor-version))
|
|
656 flavor)
|
|
657 ;; figure out version numbers if not already discovered
|
|
658 (and (or (not major) (not minor))
|
|
659 (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
|
|
660 (setq major (string-to-int (substring emacs-version
|
|
661 (match-beginning 1)
|
|
662 (match-end 1)))
|
|
663 minor (string-to-int (substring emacs-version
|
|
664 (match-beginning 2)
|
|
665 (match-end 2)))))
|
|
666 (if (not (and major minor))
|
|
667 (error "Cannot figure out the major and minor version numbers."))
|
|
668 ;; calculate the major version
|
|
669 (cond
|
|
670 ((= major 18) (setq major 'v18)) ;Emacs 18
|
|
671 ((= major 4) (setq major 'v18)) ;Epoch 4
|
|
672 ((= major 19) (setq major 'v19 ;Emacs 19
|
|
673 flavor (cond
|
|
674 ((string-match "Win-Emacs" emacs-version)
|
|
675 'Win-Emacs)
|
|
676 ((or (string-match "Lucid" emacs-version)
|
|
677 (string-match "XEmacs" emacs-version))
|
|
678 'XEmacs)
|
|
679 (t
|
|
680 t))))
|
|
681 ((= major 20) (setq major 'v20 ;Emacs 20
|
|
682 flavor (cond
|
|
683 ((string-match "Win-Emacs" emacs-version)
|
|
684 'Win-Emacs)
|
|
685 ((or (string-match "Lucid" emacs-version)
|
|
686 (string-match "XEmacs" emacs-version))
|
|
687 'XEmacs)
|
|
688 (t
|
|
689 t))))
|
|
690 ;; I don't know
|
|
691 (t (error "Cannot recognize major version number: %s" major)))
|
|
692 ;; lets do some minimal sanity checking.
|
|
693 (if (and (or
|
|
694 ;; Emacs 18 is brain dead
|
|
695 (eq major 'v18)
|
|
696 ;; Lemacs before 19.6 had bugs
|
|
697 (and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6))
|
|
698 ;; Emacs 19 before 19.21 had bugs
|
|
699 (and (eq major 'v19) (eq flavor t) (< minor 21)))
|
|
700 (not vhdl-inhibit-startup-warnings-p))
|
|
701 (with-output-to-temp-buffer "*vhdl-mode warnings*"
|
|
702 (print (format
|
|
703 "The version of Emacs that you are running, %s,
|
|
704 has known bugs in its syntax.c parsing routines which will affect the
|
|
705 performance of vhdl-mode. You should strongly consider upgrading to the
|
|
706 latest available version. vhdl-mode may continue to work, after a
|
|
707 fashion, but strange indentation errors could be encountered."
|
|
708 emacs-version))))
|
|
709 (list major flavor))
|
|
710 "A list of features extant in the Emacs you are using.
|
|
711 There are many flavors of Emacs out there, each with different
|
|
712 features supporting those needed by vhdl-mode. Here's the current
|
|
713 supported list, along with the values for this variable:
|
|
714
|
|
715 Emacs 18/Epoch 4: (v18)
|
|
716 XEmacs (formerly Lucid) 19: (v19 XEmacs)
|
|
717 Win-Emacs 1.35: (V19 Win-Emacs)
|
|
718 Emacs 19: (v19 t)
|
|
719 Emacs 20: (v20 t).")
|
|
720
|
|
721
|
|
722 ;; ############################################################################
|
|
723 ;; Bindings
|
|
724 ;; ############################################################################
|
|
725
|
|
726 ;; ############################################################################
|
|
727 ;; Key bindings
|
|
728
|
|
729 (defvar vhdl-template-map ()
|
|
730 "Keymap for VHDL templates.")
|
|
731
|
|
732 (if vhdl-template-map ()
|
|
733 (setq vhdl-template-map (make-sparse-keymap))
|
|
734 ;; key bindings for VHDL templates
|
|
735 (define-key vhdl-template-map "\M-A" 'vhdl-alias)
|
|
736 (define-key vhdl-template-map "a" 'vhdl-architecture)
|
|
737 (define-key vhdl-template-map "A" 'vhdl-array)
|
|
738 (define-key vhdl-template-map "\M-a" 'vhdl-assert)
|
|
739 (define-key vhdl-template-map "b" 'vhdl-block)
|
|
740 (define-key vhdl-template-map "c" 'vhdl-case)
|
|
741 (define-key vhdl-template-map "\M-c" 'vhdl-component)
|
|
742 (define-key vhdl-template-map "I" 'vhdl-component-instance)
|
|
743 (define-key vhdl-template-map "\M-s" 'vhdl-concurrent-signal-assignment)
|
|
744 (define-key vhdl-template-map "\M-Cb"'vhdl-block-configuration)
|
|
745 (define-key vhdl-template-map "\M-Cc"'vhdl-component-configuration)
|
|
746 (define-key vhdl-template-map "\M-Cd"'vhdl-configuration-decl)
|
|
747 (define-key vhdl-template-map "\M-Cs"'vhdl-configuration-spec)
|
|
748 (define-key vhdl-template-map "C" 'vhdl-constant)
|
|
749 (define-key vhdl-template-map "d" 'vhdl-disconnect)
|
|
750 (define-key vhdl-template-map "\M-e" 'vhdl-else)
|
|
751 (define-key vhdl-template-map "E" 'vhdl-elsif)
|
|
752 (define-key vhdl-template-map "e" 'vhdl-entity)
|
|
753 (define-key vhdl-template-map "x" 'vhdl-exit)
|
|
754 (define-key vhdl-template-map "f" 'vhdl-for)
|
|
755 (define-key vhdl-template-map "F" 'vhdl-function)
|
|
756 (define-key vhdl-template-map "g" 'vhdl-generate)
|
|
757 (define-key vhdl-template-map "G" 'vhdl-generic)
|
|
758 (define-key vhdl-template-map "h" 'vhdl-header)
|
|
759 (define-key vhdl-template-map "i" 'vhdl-if)
|
|
760 (define-key vhdl-template-map "L" 'vhdl-library)
|
|
761 (define-key vhdl-template-map "l" 'vhdl-loop)
|
|
762 (define-key vhdl-template-map "m" 'vhdl-modify)
|
|
763 (define-key vhdl-template-map "M" 'vhdl-map)
|
|
764 (define-key vhdl-template-map "n" 'vhdl-next)
|
|
765 (define-key vhdl-template-map "k" 'vhdl-package)
|
|
766 (define-key vhdl-template-map "(" 'vhdl-paired-parens)
|
|
767 (define-key vhdl-template-map "\M-p" 'vhdl-port)
|
|
768 (define-key vhdl-template-map "p" 'vhdl-procedure)
|
|
769 (define-key vhdl-template-map "P" 'vhdl-process)
|
|
770 (define-key vhdl-template-map "R" 'vhdl-record)
|
|
771 (define-key vhdl-template-map "r" 'vhdl-return-value)
|
|
772 (define-key vhdl-template-map "\M-S" 'vhdl-selected-signal-assignment)
|
|
773 (define-key vhdl-template-map "s" 'vhdl-signal)
|
|
774 (define-key vhdl-template-map "S" 'vhdl-subtype)
|
|
775 (define-key vhdl-template-map "t" 'vhdl-type)
|
|
776 (define-key vhdl-template-map "u" 'vhdl-use)
|
|
777 (define-key vhdl-template-map "v" 'vhdl-variable)
|
|
778 (define-key vhdl-template-map "W" 'vhdl-wait)
|
|
779 (define-key vhdl-template-map "w" 'vhdl-while-loop)
|
|
780 (define-key vhdl-template-map "\M-w" 'vhdl-with)
|
|
781 (define-key vhdl-template-map "\M-W" 'vhdl-clocked-wait)
|
|
782 (define-key vhdl-template-map "Kb" 'vhdl-package-numeric-bit)
|
|
783 (define-key vhdl-template-map "Kn" 'vhdl-package-numeric-std)
|
|
784 (define-key vhdl-template-map "Ks" 'vhdl-package-std-logic-1164)
|
|
785 (define-key vhdl-template-map "Kt" 'vhdl-package-textio)
|
|
786 )
|
|
787
|
|
788 (defvar vhdl-mode-map ()
|
|
789 "Keymap for VHDL Mode.")
|
|
790
|
|
791 (if vhdl-mode-map ()
|
|
792 (setq vhdl-mode-map (make-sparse-keymap))
|
|
793 ;; key bindings for templates
|
|
794 (define-key vhdl-mode-map
|
|
795 (concat "\C-c" vhdl-template-key-binding-prefix) vhdl-template-map)
|
|
796 ;; standard key bindings
|
|
797 (define-key vhdl-mode-map "\M-a" 'vhdl-beginning-of-statement)
|
|
798 (define-key vhdl-mode-map "\M-e" 'vhdl-end-of-statement)
|
|
799 (define-key vhdl-mode-map "\M-\C-f" 'vhdl-forward-sexp)
|
|
800 (define-key vhdl-mode-map "\M-\C-b" 'vhdl-backward-sexp)
|
|
801 (define-key vhdl-mode-map "\M-\C-u" 'vhdl-backward-up-list)
|
|
802 ;(define-key vhdl-mode-map "\M-\C-d" 'vhdl-down-list)
|
|
803 (define-key vhdl-mode-map "\M-\C-a" 'vhdl-beginning-of-defun)
|
|
804 (define-key vhdl-mode-map "\M-\C-e" 'vhdl-end-of-defun)
|
|
805 (define-key vhdl-mode-map "\M-\C-h" 'vhdl-mark-defun)
|
|
806 (define-key vhdl-mode-map "\M-\C-q" 'vhdl-indent-sexp)
|
|
807 (define-key vhdl-mode-map "\177" 'backward-delete-char-untabify)
|
|
808 (define-key vhdl-mode-map "\r" 'vhdl-return)
|
|
809 (if vhdl-intelligent-tab
|
|
810 (define-key vhdl-mode-map "\t" 'vhdl-tab)
|
|
811 (define-key vhdl-mode-map "\t" 'vhdl-indent-line))
|
|
812 (define-key vhdl-mode-map " " 'vhdl-outer-space)
|
|
813 ;; new key bindings for VHDL Mode, with no counterpart to BOCM
|
|
814 (define-key vhdl-mode-map "\C-c\C-e" 'vhdl-electric-mode)
|
|
815 (define-key vhdl-mode-map "\C-c\C-s" 'vhdl-stutter-mode)
|
|
816 (define-key vhdl-mode-map "\C-c\C-u" 'vhdl-fix-case-buffer)
|
|
817 (define-key vhdl-mode-map "\C-c\C-f" 'font-lock-fontify-buffer)
|
|
818 (define-key vhdl-mode-map "\C-c\C-x" 'vhdl-show-syntactic-information)
|
|
819 (define-key vhdl-mode-map "\C-c\C-r" 'vhdl-regress-line)
|
|
820 (define-key vhdl-mode-map "\C-c\C-i" 'vhdl-indent-line)
|
|
821 (define-key vhdl-mode-map "\C-c\C-a" 'vhdl-align-noindent-region)
|
|
822 (define-key vhdl-mode-map "\C-c\M-\C-a" 'vhdl-align-comment-region)
|
|
823 (define-key vhdl-mode-map "\C-c\C-c" 'vhdl-comment-uncomment-region)
|
|
824 (define-key vhdl-mode-map "\C-c-" 'vhdl-inline-comment)
|
|
825 (define-key vhdl-mode-map "\C-c\M--" 'vhdl-display-comment-line)
|
|
826 (define-key vhdl-mode-map "\C-c\C-o" 'vhdl-open-line)
|
|
827 (define-key vhdl-mode-map "\C-c\C-g" 'goto-line)
|
|
828 (define-key vhdl-mode-map "\C-c\C-d" 'vhdl-kill-line)
|
|
829 (define-key vhdl-mode-map "\C-c\C-h" 'vhdl-help)
|
|
830 (define-key vhdl-mode-map "\C-c\C-v" 'vhdl-version)
|
|
831 (define-key vhdl-mode-map "\C-c\C-b" 'vhdl-submit-bug-report)
|
|
832 (define-key vhdl-mode-map "\C-c\C-k" 'vhdl-compile)
|
|
833 (define-key vhdl-mode-map "\C-c\M-\C-k" 'vhdl-make)
|
|
834 (define-key vhdl-mode-map "\M-\t" 'tab-to-tab-stop)
|
|
835 ;; key bindings for stuttering
|
|
836 (define-key vhdl-mode-map "-" 'vhdl-stutter-mode-dash)
|
|
837 (define-key vhdl-mode-map "'" 'vhdl-stutter-mode-quote)
|
|
838 (define-key vhdl-mode-map ";" 'vhdl-stutter-mode-semicolon)
|
|
839 (define-key vhdl-mode-map "[" 'vhdl-stutter-mode-open-bracket)
|
|
840 (define-key vhdl-mode-map "]" 'vhdl-stutter-mode-close-bracket)
|
|
841 (define-key vhdl-mode-map "." 'vhdl-stutter-mode-period)
|
|
842 (define-key vhdl-mode-map "," 'vhdl-stutter-mode-comma)
|
|
843 (let ((c 97))
|
|
844 (while (< c 123) ; for little a-z
|
|
845 (define-key vhdl-mode-map (char-to-string c) 'vhdl-stutter-mode-caps)
|
|
846 (setq c (1+ c))
|
|
847 ))
|
|
848 )
|
|
849
|
|
850 ;; define special minibuffer keymap for enabling word completion in minibuffer
|
|
851 ;; (useful in template generator prompts)
|
|
852 (defvar vhdl-minibuffer-local-map (copy-keymap minibuffer-local-map)
|
|
853 "Keymap for minibuffer used in VHDL Mode.")
|
|
854
|
|
855 (define-key vhdl-minibuffer-local-map "\t" 'vhdl-minibuffer-tab)
|
|
856
|
|
857 (defvar vhdl-mode-syntax-table nil
|
|
858 "Syntax table used in vhdl-mode buffers.")
|
|
859
|
|
860 (if vhdl-mode-syntax-table ()
|
|
861 (setq vhdl-mode-syntax-table (make-syntax-table))
|
|
862 ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
|
|
863 ;; why not? (is left to the user here)
|
|
864 (if vhdl-underscore-is-part-of-word
|
|
865 (modify-syntax-entry ?_ "w" vhdl-mode-syntax-table))
|
|
866 (modify-syntax-entry ?\" "\"" vhdl-mode-syntax-table)
|
|
867 (modify-syntax-entry ?\$ "." vhdl-mode-syntax-table)
|
|
868 (modify-syntax-entry ?\% "." vhdl-mode-syntax-table)
|
|
869 (modify-syntax-entry ?\& "." vhdl-mode-syntax-table)
|
|
870 (modify-syntax-entry ?\' "." vhdl-mode-syntax-table)
|
|
871 (modify-syntax-entry ?\( "()" vhdl-mode-syntax-table)
|
|
872 (modify-syntax-entry ?\) ")(" vhdl-mode-syntax-table)
|
|
873 (modify-syntax-entry ?\* "." vhdl-mode-syntax-table)
|
|
874 (modify-syntax-entry ?\+ "." vhdl-mode-syntax-table)
|
|
875 (modify-syntax-entry ?\. "." vhdl-mode-syntax-table)
|
|
876 (modify-syntax-entry ?\/ "." vhdl-mode-syntax-table)
|
|
877 (modify-syntax-entry ?\: "." vhdl-mode-syntax-table)
|
|
878 (modify-syntax-entry ?\; "." vhdl-mode-syntax-table)
|
|
879 (modify-syntax-entry ?\< "." vhdl-mode-syntax-table)
|
|
880 (modify-syntax-entry ?\= "." vhdl-mode-syntax-table)
|
|
881 (modify-syntax-entry ?\> "." vhdl-mode-syntax-table)
|
|
882 (modify-syntax-entry ?\[ "(]" vhdl-mode-syntax-table)
|
|
883 (modify-syntax-entry ?\\ "\\" vhdl-mode-syntax-table)
|
|
884 (modify-syntax-entry ?\] ")[" vhdl-mode-syntax-table)
|
|
885 (modify-syntax-entry ?\{ "(}" vhdl-mode-syntax-table)
|
|
886 (modify-syntax-entry ?\| "." vhdl-mode-syntax-table)
|
|
887 (modify-syntax-entry ?\} "){" vhdl-mode-syntax-table)
|
|
888 ;; add comment syntax
|
|
889 (modify-syntax-entry ?\- ". 12" vhdl-mode-syntax-table)
|
|
890 (modify-syntax-entry ?\n ">" vhdl-mode-syntax-table)
|
|
891 (modify-syntax-entry ?\^M ">" vhdl-mode-syntax-table))
|
|
892
|
|
893 (defvar vhdl-syntactic-context nil
|
|
894 "Buffer local variable containing syntactic analysis list.")
|
|
895 (make-variable-buffer-local 'vhdl-syntactic-context)
|
|
896
|
|
897 ;; ############################################################################
|
|
898 ;; Abbrev hook bindings
|
|
899
|
|
900 (defvar vhdl-mode-abbrev-table nil
|
|
901 "Abbrev table in use in vhdl-mode buffers.")
|
|
902
|
|
903 (define-abbrev-table 'vhdl-mode-abbrev-table
|
|
904 '(
|
|
905 ("--" "" vhdl-display-comment-hook 0)
|
|
906 ("abs" "" vhdl-default-hook 0)
|
|
907 ("access" "" vhdl-default-hook 0)
|
|
908 ("after" "" vhdl-default-hook 0)
|
|
909 ("alias" "" vhdl-alias-hook 0)
|
|
910 ("all" "" vhdl-default-hook 0)
|
|
911 ("and" "" vhdl-default-hook 0)
|
|
912 ("arch" "" vhdl-architecture-hook 0)
|
|
913 ("architecture" "" vhdl-architecture-hook 0)
|
|
914 ("array" "" vhdl-array-hook 0)
|
|
915 ("assert" "" vhdl-assert-hook 0)
|
|
916 ("attr" "" vhdl-attribute-hook 0)
|
|
917 ("attribute" "" vhdl-attribute-hook 0)
|
|
918 ("begin" "" vhdl-default-indent-hook 0)
|
|
919 ("block" "" vhdl-block-hook 0)
|
|
920 ("body" "" vhdl-default-hook 0)
|
|
921 ("buffer" "" vhdl-default-hook 0)
|
|
922 ("bus" "" vhdl-default-hook 0)
|
|
923 ("case" "" vhdl-case-hook 0)
|
|
924 ("comp" "" vhdl-component-hook 0)
|
|
925 ("component" "" vhdl-component-hook 0)
|
|
926 ("conc" "" vhdl-concurrent-signal-assignment-hook 0)
|
|
927 ("concurrent" "" vhdl-concurrent-signal-assignment-hook 0)
|
|
928 ("conf" "" vhdl-configuration-hook 0)
|
|
929 ("configuration" "" vhdl-configuration-hook 0)
|
|
930 ("cons" "" vhdl-constant-hook 0)
|
|
931 ("constant" "" vhdl-constant-hook 0)
|
|
932 ("disconnect" "" vhdl-disconnect-hook 0)
|
|
933 ("downto" "" vhdl-default-hook 0)
|
|
934 ("else" "" vhdl-else-hook 0)
|
|
935 ("elseif" "" vhdl-elsif-hook 0)
|
|
936 ("elsif" "" vhdl-elsif-hook 0)
|
|
937 ("end" "" vhdl-default-indent-hook 0)
|
|
938 ("entity" "" vhdl-entity-hook 0)
|
|
939 ("exit" "" vhdl-exit-hook 0)
|
|
940 ("file" "" vhdl-default-hook 0)
|
|
941 ("for" "" vhdl-for-hook 0)
|
|
942 ("func" "" vhdl-function-hook 0)
|
|
943 ("function" "" vhdl-function-hook 0)
|
|
944 ("gen" "" vhdl-generate-hook 0)
|
|
945 ("generate" "" vhdl-generate-hook 0)
|
|
946 ("generic" "" vhdl-generic-hook 0)
|
|
947 ("group" "" vhdl-default-hook 0)
|
|
948 ("guarded" "" vhdl-default-hook 0)
|
|
949 ("header" "" vhdl-header-hook 0)
|
|
950 ("if" "" vhdl-if-hook 0)
|
|
951 ("impure" "" vhdl-default-hook 0)
|
|
952 ("in" "" vhdl-default-hook 0)
|
|
953 ("inertial" "" vhdl-default-hook 0)
|
|
954 ("inout" "" vhdl-default-hook 0)
|
|
955 ("inst" "" vhdl-component-instance-hook 0)
|
|
956 ("instance" "" vhdl-component-instance-hook 0)
|
|
957 ("is" "" vhdl-default-hook 0)
|
|
958 ("label" "" vhdl-default-hook 0)
|
|
959 ("library" "" vhdl-library-hook 0)
|
|
960 ("linkage" "" vhdl-default-hook 0)
|
|
961 ("literal" "" vhdl-default-hook 0)
|
|
962 ("loop" "" vhdl-loop-hook 0)
|
|
963 ("map" "" vhdl-map-hook 0)
|
|
964 ("mod" "" vhdl-default-hook 0)
|
|
965 ("modify" "" vhdl-modify-hook 0)
|
|
966 ("nand" "" vhdl-default-hook 0)
|
|
967 ("new" "" vhdl-default-hook 0)
|
|
968 ("next" "" vhdl-next-hook 0)
|
|
969 ("nor" "" vhdl-default-hook 0)
|
|
970 ("not" "" vhdl-default-hook 0)
|
|
971 ("null" "" vhdl-default-hook 0)
|
|
972 ("of" "" vhdl-default-hook 0)
|
|
973 ("on" "" vhdl-default-hook 0)
|
|
974 ("open" "" vhdl-default-hook 0)
|
|
975 ("or" "" vhdl-default-hook 0)
|
|
976 ("others" "" vhdl-default-hook 0)
|
|
977 ("out" "" vhdl-default-hook 0)
|
|
978 ("pack" "" vhdl-package-hook 0)
|
|
979 ("package" "" vhdl-package-hook 0)
|
|
980 ("port" "" vhdl-port-hook 0)
|
|
981 ("postponed" "" vhdl-default-hook 0)
|
|
982 ("procedure" "" vhdl-procedure-hook 0)
|
|
983 ("process" "" vhdl-process-hook 0)
|
|
984 ("pure" "" vhdl-default-hook 0)
|
|
985 ("range" "" vhdl-default-hook 0)
|
|
986 ("record" "" vhdl-record-hook 0)
|
|
987 ("register" "" vhdl-default-hook 0)
|
|
988 ("reject" "" vhdl-default-hook 0)
|
|
989 ("rem" "" vhdl-default-hook 0)
|
|
990 ("report" "" vhdl-default-hook 0)
|
|
991 ("ret" "" vhdl-return-hook 0)
|
|
992 ("return" "" vhdl-return-hook 0)
|
|
993 ("rol" "" vhdl-default-hook 0)
|
|
994 ("ror" "" vhdl-default-hook 0)
|
|
995 ("select" "" vhdl-selected-signal-assignment-hook 0)
|
|
996 ("severity" "" vhdl-default-hook 0)
|
|
997 ("shared" "" vhdl-default-hook 0)
|
|
998 ("sig" "" vhdl-signal-hook 0)
|
|
999 ("signal" "" vhdl-signal-hook 0)
|
|
1000 ("sla" "" vhdl-default-hook 0)
|
|
1001 ("sll" "" vhdl-default-hook 0)
|
|
1002 ("sra" "" vhdl-default-hook 0)
|
|
1003 ("srl" "" vhdl-default-hook 0)
|
|
1004 ("sub" "" vhdl-subtype-hook 0)
|
|
1005 ("subtype" "" vhdl-subtype-hook 0)
|
|
1006 ("then" "" vhdl-default-hook 0)
|
|
1007 ("to" "" vhdl-default-hook 0)
|
|
1008 ("transport" "" vhdl-default-hook 0)
|
|
1009 ("type" "" vhdl-type-hook 0)
|
|
1010 ("unaffected" "" vhdl-default-hook 0)
|
|
1011 ("units" "" vhdl-default-hook 0)
|
|
1012 ("until" "" vhdl-default-hook 0)
|
|
1013 ("use" "" vhdl-use-hook 0)
|
|
1014 ("var" "" vhdl-variable-hook 0)
|
|
1015 ("variable" "" vhdl-variable-hook 0)
|
|
1016 ("wait" "" vhdl-wait-hook 0)
|
|
1017 ("warning" "" vhdl-default-hook 0)
|
|
1018 ("when" "" vhdl-when-hook 0)
|
|
1019 ("while" "" vhdl-while-loop-hook 0)
|
|
1020 ("with" "" vhdl-selected-signal-assignment-hook 0)
|
|
1021 ("xnor" "" vhdl-default-hook 0)
|
|
1022 ("xor" "" vhdl-default-hook 0)
|
|
1023 ))
|
|
1024
|
|
1025
|
|
1026 ;; ############################################################################
|
|
1027 ;; Menues
|
|
1028 ;; ############################################################################
|
|
1029
|
|
1030 ;; ############################################################################
|
|
1031 ;; VHDL menu (using `easy-menu.el')
|
|
1032
|
|
1033 ;; `customize-menu-create' is included in `cus-edit.el' version 1.9954,
|
|
1034 ;; which is not yet distributed with XEmacs 19.15
|
|
1035 (defun vhdl-customize-menu-create (symbol &optional name)
|
|
1036 "Return a customize menu for customization group SYMBOL.
|
|
1037 If optional NAME is given, use that as the name of the menu.
|
|
1038 Otherwise the menu will be named `Customize'.
|
|
1039 The format is suitable for use with `easy-menu-define'."
|
|
1040 (unless name
|
|
1041 (setq name "Customize"))
|
|
1042 (if (memq 'XEmacs vhdl-emacs-features)
|
|
1043 ;; We can delay it under XEmacs.
|
|
1044 `(,name
|
|
1045 :filter (lambda (&rest junk)
|
|
1046 (cdr (custom-menu-create ',symbol))))
|
|
1047 ;; But we must create it now under Emacs.
|
|
1048 (cons name (cdr (custom-menu-create symbol)))))
|
|
1049
|
|
1050 (defvar vhdl-mode-menu
|
|
1051 (append
|
|
1052 '("VHDL"
|
|
1053 ("Mode"
|
|
1054 ["Electric" vhdl-electric-mode :style toggle :selected vhdl-electric-mode]
|
|
1055 ["Stutter" vhdl-stutter-mode :style toggle :selected vhdl-stutter-mode]
|
|
1056 )
|
|
1057 "--"
|
|
1058 ("Compile"
|
|
1059 ["Compile Buffer" vhdl-compile t]
|
|
1060 ["Stop Compilation" kill-compilation t]
|
|
1061 "--"
|
|
1062 ["Make" vhdl-make t]
|
|
1063 ["Generate Makefile" vhdl-generate-makefile t]
|
|
1064 "--"
|
|
1065 ["Next Error" next-error t]
|
|
1066 ["Previous Error" previous-error t]
|
|
1067 ["First Error" first-error t]
|
|
1068 )
|
|
1069 "--"
|
|
1070 ("Template"
|
|
1071 ("VHDL Construct 1"
|
|
1072 ["Alias" vhdl-alias t]
|
|
1073 ["Architecture" vhdl-architecture t]
|
|
1074 ["Array" vhdl-array t]
|
|
1075 ["Assert" vhdl-assert t]
|
|
1076 ["Attribute" vhdl-attribute t]
|
|
1077 ["Block" vhdl-block t]
|
|
1078 ["Case" vhdl-case t]
|
|
1079 ["Component" vhdl-component t]
|
|
1080 ["Concurrent (Signal Asst)" vhdl-concurrent-signal-assignment t]
|
|
1081 ["Configuration (Block)" vhdl-block-configuration t]
|
|
1082 ["Configuration (Comp)" vhdl-component-configuration t]
|
|
1083 ["Configuration (Decl)" vhdl-configuration-decl t]
|
|
1084 ["Configuration (Spec)" vhdl-configuration-spec t]
|
|
1085 ["Constant" vhdl-constant t]
|
|
1086 ["Disconnect" vhdl-disconnect t]
|
|
1087 ["Else" vhdl-else t]
|
|
1088 ["Elsif" vhdl-elsif t]
|
|
1089 ["Entity" vhdl-entity t]
|
|
1090 ["Exit" vhdl-exit t]
|
|
1091 ["For (Loop)" vhdl-for t]
|
|
1092 ["Function" vhdl-function t]
|
|
1093 ["(For/If) Generate" vhdl-generate t]
|
|
1094 ["Generic" vhdl-generic t]
|
|
1095 )
|
|
1096 ("VHDL Construct 2"
|
|
1097 ["If" vhdl-if t]
|
|
1098 ["Instance" vhdl-component-instance t]
|
|
1099 ["Library" vhdl-library t]
|
|
1100 ["Loop" vhdl-loop t]
|
|
1101 ["Map" vhdl-map t]
|
|
1102 ["Next" vhdl-next t]
|
|
1103 ["Package" vhdl-package t]
|
|
1104 ["Port" vhdl-port t]
|
|
1105 ["Procedure" vhdl-procedure t]
|
|
1106 ["Process" vhdl-process t]
|
|
1107 ["Record" vhdl-record t]
|
|
1108 ["Return" vhdl-return-value t]
|
|
1109 ["Select" vhdl-selected-signal-assignment t]
|
|
1110 ["Signal" vhdl-signal t]
|
|
1111 ["Subtype" vhdl-subtype t]
|
|
1112 ["Type" vhdl-type t]
|
|
1113 ["Use" vhdl-use t]
|
|
1114 ["Variable" vhdl-variable t]
|
|
1115 ["Wait" vhdl-wait t]
|
|
1116 ["(Clocked Wait)" vhdl-clocked-wait t]
|
|
1117 ["When" vhdl-when t]
|
|
1118 ["While (Loop)" vhdl-while-loop t]
|
|
1119 ["With" vhdl-with t]
|
|
1120 )
|
|
1121 ("Standard Package"
|
|
1122 ["numeric_bit" vhdl-package-numeric-bit t]
|
|
1123 ["numeric_std" vhdl-package-numeric-std t]
|
|
1124 ["std_logic_1164" vhdl-package-std-logic-1164 t]
|
|
1125 ["textio" vhdl-package-textio t]
|
|
1126 )
|
|
1127 ["Header" vhdl-header t]
|
|
1128 ["Modify (Date)" vhdl-modify t]
|
|
1129 )
|
|
1130 ("Comment"
|
|
1131 ["(Un)Comment Out Region" vhdl-comment-uncomment-region (mark)]
|
|
1132 ["Insert Inline Comment" vhdl-inline-comment t]
|
|
1133 ["Insert Horizontal Line" vhdl-display-comment-line t]
|
|
1134 ["Insert Display Comment" vhdl-display-comment t]
|
|
1135 ["Fill Comment" fill-paragraph t]
|
|
1136 ["Fill Comment Region" fill-region (mark)]
|
|
1137 )
|
|
1138 ("Indent"
|
|
1139 ["Line" vhdl-indent-line t]
|
|
1140 ["Region" indent-region (mark)]
|
|
1141 ["Buffer" vhdl-indent-buffer t]
|
|
1142 )
|
|
1143 ("Align"
|
|
1144 ["Region" vhdl-align-noindent-region (mark)]
|
|
1145 ["Comment Region" vhdl-align-comment-region (mark)]
|
|
1146 )
|
|
1147 ("Line"
|
|
1148 ["Open" vhdl-open-line t]
|
|
1149 ["Delete" vhdl-kill-line t]
|
|
1150 ["Join" delete-indentation t]
|
|
1151 ["Goto" goto-line t]
|
|
1152 )
|
|
1153 ("Move"
|
|
1154 ["Forward Statement" vhdl-end-of-statement t]
|
|
1155 ["Backward Statement" vhdl-beginning-of-statement t]
|
|
1156 ["Forward Expression" vhdl-forward-sexp t]
|
|
1157 ["Backward Expression" vhdl-backward-sexp t]
|
|
1158 ["Forward Function" vhdl-end-of-defun t]
|
|
1159 ["Backward Function" vhdl-beginning-of-defun t]
|
|
1160 )
|
|
1161 "--"
|
|
1162 ("Fix Case"
|
|
1163 ["Buffer" vhdl-fix-case-buffer t]
|
|
1164 ["Region" vhdl-fix-case-region (mark)]
|
|
1165 )
|
|
1166 ["Fontify Buffer" font-lock-fontify-buffer t]
|
|
1167 ["Syntactic Info" vhdl-show-syntactic-information t]
|
|
1168 "--"
|
|
1169 ["Help" vhdl-help t]
|
|
1170 ["Version" vhdl-version t]
|
|
1171 ["Bug Report" vhdl-submit-bug-report t]
|
|
1172 "--"
|
|
1173 )
|
|
1174 (list (vhdl-customize-menu-create 'vhdl))
|
|
1175 ))
|
|
1176
|
|
1177 (require 'easymenu)
|
|
1178
|
|
1179 ;; ############################################################################
|
|
1180 ;; Index menu (using `imenu.el')
|
|
1181
|
|
1182 (defvar vhdl-imenu-generic-expression
|
|
1183 '(
|
|
1184 ("Entity"
|
|
1185 "^\\s-*\\(entity\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
|
|
1186 2)
|
|
1187 ("Architecture"
|
|
1188 "^\\s-*\\(architecture\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)"
|
|
1189 2)
|
|
1190 ("Configuration"
|
|
1191 "^\\s-*\\(configuration\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\s-+of\\s-+\\(\\w\\|\\s_\\)+\\)"
|
|
1192 2)
|
|
1193 ("Package Body"
|
|
1194 "^\\s-*\\(package body\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
|
|
1195 2)
|
|
1196 ("Package"
|
|
1197 "^\\s-*\\(package\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
|
|
1198 2)
|
|
1199 ("Type"
|
|
1200 "^\\s-*\\(sub\\)?type\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
|
|
1201 2)
|
|
1202 ("Component"
|
|
1203 "^\\s-*\\(component\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
|
|
1204 2)
|
|
1205 ("Function / Procedure"
|
|
1206 "^\\s-*\\(procedure\\|function\\)\\s-+\\(\\(\\w\\|\\s_\\)+\\)"
|
|
1207 2)
|
|
1208 ("Process / Block"
|
|
1209 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\)\\s-*:\\(\\s-\\|\n\\)*\\(process\\|block\\)"
|
|
1210 1)
|
|
1211 ("Instance"
|
|
1212 "^\\s-*\\(\\(\\w\\|\\s_\\)+\\s-*:\\(\\s-\\|\n\\)*\\(\\w\\|\\s_\\)+\\)\\(\\s-\\|\n\\)+\\(generic\\|port\\)\\s-+map\\>"
|
|
1213 1)
|
|
1214 )
|
|
1215 "Imenu generic expression for VHDL Mode. See `imenu-generic-expression'.")
|
|
1216
|
|
1217 (defun vhdl-add-index-menu ()
|
|
1218 (make-local-variable 'imenu-generic-expression)
|
|
1219 (setq imenu-generic-expression vhdl-imenu-generic-expression)
|
|
1220 (imenu-add-to-menubar "Index"))
|
|
1221
|
|
1222 ;; ############################################################################
|
|
1223 ;; Source file menu (using `easy-menu.el')
|
|
1224
|
|
1225 (defvar vhdl-extlist '("[A-Za-z0-9_.]*.vhdl?$"))
|
|
1226 (defvar vhdl-filelist-menu nil)
|
|
1227
|
|
1228 (defun vhdl-add-source-files-menu ()
|
|
1229 "Scan directory of current source file for all VHDL source files, and
|
|
1230 generate menu."
|
|
1231 (interactive)
|
|
1232 (message "Scanning directory for source files ...")
|
|
1233 (let (filelist menulist tmpextlist found
|
|
1234 (newmap (current-local-map)))
|
|
1235 (cd (file-name-directory (buffer-file-name)))
|
|
1236 ;; find files
|
|
1237 (setq menulist '())
|
|
1238 (setq tmpextlist vhdl-extlist)
|
|
1239 (while tmpextlist
|
|
1240 (setq filelist (nreverse (directory-files
|
|
1241 (file-name-directory (buffer-file-name))
|
|
1242 nil (car tmpextlist) nil)))
|
|
1243 ;; Create list for menu
|
|
1244 (setq found nil)
|
|
1245 (while filelist
|
|
1246 (setq found t)
|
|
1247 (setq menulist (cons (vector (car filelist)
|
|
1248 (list 'find-file (car filelist)) t)
|
|
1249 menulist))
|
|
1250 (setq filelist (cdr filelist)))
|
|
1251 (setq menulist (vhdl-menu-split menulist 25))
|
|
1252 (if found
|
|
1253 (setq menulist (cons "--" menulist)))
|
|
1254 (setq tmpextlist (cdr tmpextlist)))
|
|
1255 (setq menulist (cons ["*Rescan*" vhdl-add-source-files-menu t] menulist))
|
|
1256 (setq menulist (cons "Sources" menulist))
|
|
1257 ;; Create menu
|
|
1258 (easy-menu-add menulist)
|
|
1259 (easy-menu-define vhdl-filelist-menu newmap
|
|
1260 "VHDL source files menu" menulist)
|
|
1261 ; (use-local-map (append (current-local-map) newmap))
|
|
1262 ; (use-local-map newmap)
|
|
1263 )
|
|
1264 (message ""))
|
|
1265
|
|
1266 (defun vhdl-menu-split (list n)
|
|
1267 "Split menu into several submenues, if number of elements > n."
|
|
1268 (if (> (length list) n)
|
|
1269 (let ((remain list)
|
|
1270 (result '())
|
|
1271 (sublist '())
|
|
1272 (menuno 1)
|
|
1273 (i 0))
|
|
1274 (while remain
|
|
1275 (setq sublist (cons (car remain) sublist))
|
|
1276 (setq remain (cdr remain))
|
|
1277 (setq i (+ i 1))
|
|
1278 (if (= i n)
|
|
1279 (progn
|
|
1280 (setq result (cons (cons (format "Sources %s" menuno)
|
|
1281 (nreverse sublist)) result))
|
|
1282 (setq i 0)
|
|
1283 (setq menuno (+ menuno 1))
|
|
1284 (setq sublist '()))))
|
|
1285 (and sublist
|
|
1286 (setq result (cons (cons (format "Sources %s" menuno)
|
|
1287 (nreverse sublist)) result)))
|
|
1288 (nreverse result))
|
|
1289 list))
|
|
1290
|
|
1291
|
|
1292 ;; ############################################################################
|
|
1293 ;; VHDL Mode definition
|
|
1294 ;; ############################################################################
|
|
1295
|
|
1296 (defun vhdl-mode ()
|
|
1297 "Major mode for editing VHDL code.
|
|
1298
|
|
1299 Usage:
|
|
1300 ------
|
|
1301
|
|
1302 - TEMPLATE INSERTION (electrification) (`\\[vhdl-outer-space]'): After typing
|
|
1303 a VHDL keyword and entering `\\[vhdl-outer-space]', you are prompted for
|
|
1304 arguments while a template is generated for that VHDL construct. Typing
|
|
1305 `\\[vhdl-return]' (or `\\[keyboard-quit]' in yes-no queries) at the first
|
|
1306 prompt aborts the current template generation. Typing `\\[just-one-space]'
|
|
1307 after a keyword inserts a space without calling the template generator.
|
|
1308 Automatic calling of the template generators (i.e. electrification) can be
|
|
1309 disabled (enabled) by setting the variable `vhdl-electric-mode' to nil
|
|
1310 (non-nil) or by typing `\\[vhdl-electric-mode]' (toggles electrification
|
|
1311 mode).
|
|
1312 Template generators can be called using the VHDL menu, the key bindings, or
|
|
1313 by typing the keyword (first word of menu entry not in parenthesis) and
|
|
1314 `\\[vhdl-outer-space]'. The following abbreviations can also be used:
|
|
1315 arch, attr, conc, conf, comp, cons, func, inst, pack, ret, sig, sub, var.
|
|
1316
|
|
1317 - HEADER INSERTION (`\\[vhdl-header]'): A customized header can be inserted
|
|
1318 including the actual file name, user name, and current date as well as
|
|
1319 prompted title strings. A custom header can be defined in a separate file
|
|
1320 (see custom variable `vhdl-header-file').
|
|
1321
|
|
1322 - STUTTERING (double strike): Double striking of some keys inserts cumbersome
|
|
1323 VHDL syntax elements. Stuttering can be disabled by variable
|
|
1324 `vhdl-stutter-mode' and be toggled by typing `\\[vhdl-stutter-mode]'.
|
|
1325 '' --> \" [ --> ( -- --> comment
|
|
1326 ;; --> \" : \" [[ --> [ --CR --> comment-out code
|
|
1327 ;;; --> \" := \" ] --> ) --- --> horizontal line
|
|
1328 .. --> \" => \" ]] --> ] ---- --> display comment
|
|
1329 ,, --> \" <= \" aa --> A - zz --> Z
|
|
1330
|
|
1331 - WORD COMPLETION (`\\[vhdl-tab]'): Typing `\\[vhdl-tab]' after a (not
|
|
1332 completed) word looks for a word in the buffer that starts alike and
|
|
1333 inserts it. Re-typing `\\[vhdl-tab]' toggles through alternative word
|
|
1334 completions. This also works in the minibuffer (i.e. in template generator
|
|
1335 prompts).
|
|
1336
|
|
1337 Typing `\\[vhdl-tab]' after a non-word character indents the line if at the
|
|
1338 beginning of a line (i.e. no preceding non-blank characters), and inserts a
|
|
1339 tabulator stop otherwise. `\\[tab-to-tab-stop]' always inserts a tabulator
|
|
1340 stop.
|
|
1341
|
|
1342 - COMMENTS (`--', `---', `----', `--CR'):
|
|
1343 `--' puts a single comment.
|
|
1344 `---' draws a horizontal line for separating code segments.
|
|
1345 `----' inserts a display comment, i.e. two horizontal lines with a
|
|
1346 comment in between.
|
|
1347 `--CR' comments out code on that line. Re-hitting CR comments out
|
|
1348 following lines.
|
|
1349 `\\[vhdl-comment-uncomment-region]' comments out a region if not
|
|
1350 commented out, uncomments out a region if already
|
|
1351 commented out.
|
|
1352
|
|
1353 You are prompted for comments after object definitions (i.e. signals,
|
|
1354 variables, constants, ports) and after subprogram and process specifications
|
|
1355 if variable `vhdl-prompt-for-comments' is non-nil. Comments are
|
|
1356 automatically inserted as additional labels (e.g. after begin statements)
|
|
1357 and help comments if `vhdl-self-insert-comments' is non-nil.
|
|
1358 Inline comments (i.e. comments after a piece of code on the same line) are
|
|
1359 indented at least to `vhdl-comment-column'. Comments go at maximum to
|
|
1360 `vhdl-end-comment-column'. `\\[vhdl-return]' after a space in a comment will
|
|
1361 open a new comment line. Typing beyond `vhdl-end-comment-column' in a
|
|
1362 comment automatically opens a new comment line. `\\[fill-paragraph]'
|
|
1363 re-fills multi-line comments.
|
|
1364
|
|
1365 - INDENTATION: `\\[vhdl-tab]' indents a line if at the beginning of the line.
|
|
1366 The amount of indentation is specified by variable `vhdl-basic-offset'.
|
|
1367 `\\[vhdl-indent-line]' always indents the current line (is bound to `TAB'
|
|
1368 if variable `vhdl-intelligent-tab' is nil). Indentation can be done for
|
|
1369 an entire region (`\\[indent-region]') or buffer (menu). Argument and
|
|
1370 port lists are indented normally (nil) or relative to the opening
|
|
1371 parenthesis (non-nil) according to variable `vhdl-argument-list-indent'.
|
|
1372 If variable `vhdl-indent-tabs-mode' is nil, spaces are used instead of tabs.
|
|
1373 `\\[tabify]' and `\\[untabify]' allow to convert spaces to tabs and vice
|
|
1374 versa.
|
|
1375
|
|
1376 - ALIGNMENT: `\\[vhdl-align-noindent-region]' aligns port maps, signal and
|
|
1377 variable assignments, inline comments, some keywords, etc., on consecutive
|
|
1378 lines relative to each other within a defined region.
|
|
1379 `\\[vhdl-align-comment-region]' only aligns inline comments (i.e. comments
|
|
1380 that are at the end of a line of code). Some templates are automatically
|
|
1381 aligned after generation if custom variable `vhdl-auto-align' is non-nil.
|
|
1382
|
|
1383 - KEY BINDINGS: Key bindings (`C-c ...') exist for most commands (see in menu).
|
|
1384
|
|
1385 - VHDL MENU: All commands can be called from the VHDL menu.
|
|
1386
|
|
1387 - INDEX MENU: For each VHDL source file, an index of the contained entities,
|
|
1388 architectures, packages, procedures, processes, etc., is created as a menu.
|
|
1389 Selecting a meny entry causes the cursor to jump to the corresponding
|
|
1390 position in the file. Controlled by variable `vhdl-index-menu'.
|
|
1391
|
|
1392 - SOURCE FILE MENU: A menu containing all VHDL source files in the directory
|
|
1393 of the current file is generated. Selecting a menu entry loads the file.
|
|
1394 Controlled by variable `vhdl-source-file-menu'.
|
|
1395
|
|
1396 - SOURCE FILE COMPILATION: The syntax of the current buffer can be analyzed
|
|
1397 by calling a VHDL compiler (menu, `\\[vhdl-compile]'). The compiler to be
|
|
1398 used is defined by variable `vhdl-compiler'. Currently supported are
|
|
1399 `cadence', `ikos', `quickhdl', `synopsys', `vantage', `viewlogic', and
|
|
1400 `v-system'. Not all compilers are tested. Please contact me for
|
|
1401 incorporating additional VHDL compilers. An entire hierarchy of source
|
|
1402 files can be compiled by the `make' command (menu, `\\[vhdl-make]').
|
|
1403 This only works if an appropriate `Makefile' exists. Compiler options can
|
|
1404 be defined by variable `vhdl-compiler-options'.
|
|
1405
|
|
1406 - KEYWORD CASE: Lower and upper case for keywords, predefined types, predefined
|
|
1407 attributes, and predefined enumeration values is supported. If the variable
|
|
1408 `vhdl-upper-case-keywords' is set to non-nil, keywords can be typed in
|
|
1409 lower case and are converted into upper case automatically (not for types,
|
|
1410 attributes, and enumeration values). The case of keywords, types,
|
|
1411 attributes, and enumeration values can be fixed for an entire region (menu)
|
|
1412 or buffer (`\\[vhdl-fix-case-buffer]') according to the variables
|
|
1413 `vhdl-upper-case-{keywords,types,attributes,enum-values}'.
|
|
1414
|
|
1415 - HIGHLIGHTING (fontification): Keywords, predefined types, predefined
|
|
1416 attributes, and predefined enumeration values (controlled by variable
|
|
1417 `vhdl-highlight-keywords'), as well as comments, strings, and template
|
|
1418 prompts are highlighted using different colors. Unit and subprogram names
|
|
1419 as well as labels are highlighted if variable `vhdl-highlight-names' is
|
|
1420 non-nil. The default colors from `font-lock.el' are used if variable
|
|
1421 `vhdl-use-default-colors' is non-nil. Otherwise, an optimized set of colors
|
|
1422 is taken, which uses bright colors for signals and muted colors for
|
|
1423 everything else. Variable `vhdl-use-default-faces' does the same on
|
|
1424 monochrome monitors.
|
|
1425
|
|
1426 Signal highlighting allows distinction between clock, reset,
|
|
1427 status/control, data, and test signals according to some signal
|
|
1428 naming convention. Their syntax is defined by variables
|
|
1429 `vhdl-{clock,reset,control,data,test}-signal-syntax'. Signal coloring
|
|
1430 is controlled by the variable `vhdl-highlight-signals'. The default
|
|
1431 signal naming convention is as follows:
|
|
1432
|
|
1433 Signal attributes:
|
|
1434 C clock S control and status
|
|
1435 R asynchronous reset D data and address
|
|
1436 I synchronous reset T test
|
|
1437
|
|
1438 Syntax:
|
|
1439 signal name ::= \"[A-Z][a-zA-Z0-9]*x[CRISDT][a-zA-Z0-9]*\"
|
|
1440 signal identifier -^^^^^^^^^^^^^^^^^
|
|
1441 delimiter --------------------------^
|
|
1442 above signal attributes -------------^^^^^^^^
|
|
1443 additional attributes -----------------------^^^^^^^^^^^^
|
|
1444
|
|
1445 (`x' is used as delimiter because `_' is reserved by the VITAL standard.)
|
|
1446 Examples: ClkxCfast, ResetxRB, ClearxI, SelectDataxS, DataxD, ScanEnablexT.
|
|
1447
|
|
1448 If all VHDL words are written in lower case (i.e. variables
|
|
1449 `vhdl-upper-case-{keywords,types,attributes,enum-values}' are set to nil),
|
|
1450 make highlighting case sensitive by setting variable
|
|
1451 `vhdl-highlight-case-sensitive' to non-nil. This way, only names fulfilling
|
|
1452 the above signal syntax including case are highlighted.
|
|
1453
|
|
1454 - HIDE/SHOW: The code of entire VHDL processes or blocks can be hidden using
|
|
1455 the `Hide/Show' menu or by pressing `S-mouse-2' within the code
|
|
1456 (not in XEmacs).
|
|
1457
|
|
1458 - PRINTING: Postscript printing with different fonts (`ps-print-color-p' is
|
|
1459 nil, default faces from `font-lock.el' used if `vhdl-use-default-faces' is
|
|
1460 non-nil) or colors (`ps-print-color-p' is non-nil) is possible using the
|
|
1461 standard Emacs postscript printing commands. Variable `vhdl-print-two-column'
|
|
1462 defines appropriate default settings for nice landscape two-column printing.
|
|
1463 The paper format can be set by variable `ps-paper-type'.
|
|
1464
|
|
1465 - CUSTOMIZATION: All variables can easily be customized using the `Customize'
|
|
1466 menu entry. For some variables, customization only takes effect after
|
|
1467 re-starting Emacs. Customization can also be done globally (i.e. site-wide,
|
|
1468 read INSTALL file). Variables of VHDL Mode must NOT be set using the
|
|
1469 `vhdl-mode-hook' in the .emacs file anymore (delete them if they still are).
|
|
1470
|
|
1471
|
|
1472 Maintenance:
|
|
1473 ------------
|
|
1474
|
|
1475 To submit a bug report, enter `\\[vhdl-submit-bug-report]' within VHDL Mode.
|
|
1476 Add a description of the problem and include a reproducible test case.
|
|
1477
|
|
1478 Questions and enhancement requests can be sent to <vhdl-mode@geocities.com>.
|
|
1479
|
|
1480 The `vhdl-mode-announce' mailing list informs about new VHDL Mode releases.
|
|
1481 The `vhdl-mode-victims' mailing list informs about new VHDL Mode beta releases.
|
|
1482 You are kindly invited to participate in beta testing. Subscribe to above
|
|
1483 mailing lists by sending an email to <vhdl-mode@geocities.com>.
|
|
1484
|
|
1485 The archive with the latest version is located at
|
|
1486 <http://www.geocities.com/SiliconValley/Peaks/8287>.
|
|
1487
|
|
1488
|
|
1489 Bugs and Limitations:
|
|
1490 ---------------------
|
|
1491
|
|
1492 - Index menu does not work under XEmacs (limitation of XEmacs ?!).
|
|
1493
|
|
1494 - Re-indenting large regions or expressions can be slow.
|
|
1495
|
|
1496 - Hideshow does not work under XEmacs.
|
|
1497
|
|
1498 - Parsing compilation error messages for Ikos and Vantage VHDL compilers
|
|
1499 does not work under XEmacs.
|
|
1500
|
|
1501
|
|
1502 Key bindings:
|
|
1503 -------------
|
|
1504
|
|
1505 \\{vhdl-mode-map}"
|
|
1506 (interactive)
|
|
1507 (kill-all-local-variables)
|
|
1508 (set-syntax-table vhdl-mode-syntax-table)
|
|
1509 (setq major-mode 'vhdl-mode)
|
|
1510 (setq mode-name "VHDL")
|
|
1511 (setq local-abbrev-table vhdl-mode-abbrev-table)
|
|
1512 (use-local-map vhdl-mode-map)
|
|
1513 ;; set local variable values
|
|
1514 (set (make-local-variable 'paragraph-start) "\\s-*\\(---\\|[a-zA-Z]\\|$\\)")
|
|
1515 (set (make-local-variable 'paragraph-separate) paragraph-start)
|
|
1516 (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
|
|
1517 (set (make-local-variable 'require-final-newline) t)
|
|
1518 (set (make-local-variable 'parse-sexp-ignore-comments) t)
|
|
1519 (set (make-local-variable 'indent-line-function) 'vhdl-indent-line)
|
|
1520 (set (make-local-variable 'comment-start) "--")
|
|
1521 (set (make-local-variable 'comment-end) "")
|
|
1522 (set (make-local-variable 'comment-column) vhdl-comment-column)
|
|
1523 (set (make-local-variable 'end-comment-column) vhdl-end-comment-column)
|
|
1524 (set (make-local-variable 'comment-start-skip) "--+\\s-*")
|
|
1525 (set (make-local-variable 'dabbrev-case-fold-search) nil)
|
|
1526 (set (make-local-variable 'indent-tabs-mode) vhdl-indent-tabs-mode)
|
|
1527
|
|
1528 ;; setup the comment indent variable in a Emacs version portable way
|
|
1529 ;; ignore any byte compiler warnings you might get here
|
|
1530 (if (boundp 'comment-indent-function)
|
|
1531 (progn (make-local-variable 'comment-indent-function)
|
|
1532 (setq comment-indent-function 'vhdl-comment-indent)))
|
|
1533
|
|
1534 ;; initialize font locking
|
|
1535 (require 'font-lock)
|
|
1536 (vhdl-font-lock-init)
|
|
1537 (make-local-variable 'font-lock-defaults)
|
|
1538 (setq font-lock-defaults (list 'vhdl-font-lock-keywords nil
|
|
1539 (not vhdl-highlight-case-sensitive)
|
|
1540 '((?\_ . "w"))))
|
|
1541 (turn-on-font-lock)
|
|
1542
|
|
1543 ;; variables for source file compilation
|
|
1544 (make-local-variable 'compile-command)
|
|
1545 (set (make-local-variable 'compilation-error-regexp-alist)
|
|
1546 vhdl-compilation-error-regexp-alist)
|
|
1547
|
|
1548 ;; add menus
|
|
1549 (if vhdl-index-menu
|
|
1550 (if (or (not (consp font-lock-maximum-size))
|
|
1551 (> font-lock-maximum-size (buffer-size)))
|
|
1552 (vhdl-add-index-menu)
|
|
1553 (message "Scanning buffer for index...buffer too big")))
|
|
1554 (if vhdl-source-file-menu (vhdl-add-source-files-menu))
|
|
1555 (easy-menu-add vhdl-mode-menu)
|
|
1556 (easy-menu-define vhdl-mode-easy-menu vhdl-mode-map
|
|
1557 "Menu keymap for VHDL Mode." vhdl-mode-menu)
|
|
1558 (run-hooks 'menu-bar-update-hook)
|
|
1559
|
|
1560 ;; initialize hideshow and add menu
|
|
1561 (if vhdl-hideshow-menu (hs-minor-mode))
|
|
1562
|
|
1563 ;; initialize postscript printing
|
|
1564 (vhdl-ps-init)
|
|
1565
|
|
1566 (setq mode-name (if vhdl-electric-mode "Electric VHDL" "VHDL"))
|
|
1567 (message "Type C-c C-h for VHDL Mode documentation.")
|
|
1568
|
|
1569 (run-hooks 'vhdl-mode-hook)
|
|
1570 )
|
|
1571
|
|
1572
|
|
1573 ;; ############################################################################
|
|
1574 ;; Keywords and predefined words in VHDL'93
|
|
1575 ;; ############################################################################
|
|
1576
|
|
1577 ;; `regexp-opt' was not used at this place because it is not yet implemented
|
|
1578 ;; in XEmacs and because it resulted in SLOWER regexps!!
|
|
1579
|
|
1580 (defconst vhdl-93-keywords-regexp
|
|
1581 (eval-when-compile
|
|
1582 (concat
|
|
1583 "\\<\\("
|
|
1584 (mapconcat
|
|
1585 'identity
|
|
1586 '(
|
|
1587 "abs" "access" "after" "alias" "all" "and" "architecture" "array"
|
|
1588 "assert" "attribute"
|
|
1589 "begin" "block" "body" "buffer" "bus"
|
|
1590 "case" "component" "configuration" "constant"
|
|
1591 "disconnect" "downto"
|
|
1592 "else" "elsif" "end" "entity" "exit"
|
|
1593 "file" "for" "function"
|
|
1594 "generate" "generic" "group" "guarded"
|
|
1595 "if" "impure" "in" "inertial" "inout" "is"
|
|
1596 "label" "library" "linkage" "literal" "loop"
|
|
1597 "map" "mod"
|
|
1598 "nand" "new" "next" "nor" "not" "null"
|
|
1599 "of" "on" "open" "or" "others" "out"
|
|
1600 "package" "port" "postponed" "procedure" "process" "pure"
|
|
1601 "range" "record" "register" "reject" "rem" "report" "return"
|
|
1602 "rol" "ror"
|
|
1603 "select" "severity" "shared" "signal" "sla" "sll" "sra" "srl" "subtype"
|
|
1604 "then" "to" "transport" "type"
|
|
1605 "unaffected" "units" "until" "use"
|
|
1606 "variable"
|
|
1607 "wait" "warning" "when" "while" "with"
|
|
1608 "xnor" "xor"
|
|
1609 )
|
|
1610 "\\|")
|
|
1611 "\\)\\>"))
|
|
1612 "Regexp for VHDL'93 keywords.")
|
|
1613
|
|
1614 (defconst vhdl-93-types-regexp
|
|
1615 (eval-when-compile
|
|
1616 (concat
|
|
1617 "\\<\\("
|
|
1618 (mapconcat
|
|
1619 'identity
|
|
1620 '(
|
|
1621 "boolean" "bit" "bit_vector" "character" "severity_level" "integer"
|
|
1622 "real" "time" "natural" "positive" "string" "text" "line"
|
|
1623 "unsigned" "signed"
|
|
1624 "std_logic" "std_logic_vector"
|
|
1625 "std_ulogic" "std_ulogic_vector"
|
|
1626 )
|
|
1627 "\\|")
|
|
1628 "\\)\\>"))
|
|
1629 "Regexp for VHDL'93 standardized types.")
|
|
1630
|
|
1631 (defconst vhdl-93-attributes-regexp
|
|
1632 (eval-when-compile
|
|
1633 (concat
|
|
1634 "\\<\\("
|
|
1635 (mapconcat
|
|
1636 'identity
|
|
1637 '(
|
|
1638 "base" "left" "right" "high" "low" "pos" "val" "succ"
|
|
1639 "pred" "leftof" "rightof" "range" "reverse_range"
|
|
1640 "length" "delayed" "stable" "quiet" "transaction"
|
|
1641 "event" "active" "last_event" "last_active" "last_value"
|
|
1642 "driving" "driving_value" "ascending" "value" "image"
|
|
1643 "simple_name" "instance_name" "path_name"
|
|
1644 "foreign"
|
|
1645 )
|
|
1646 "\\|")
|
|
1647 "\\)\\>"))
|
|
1648 "Regexp for VHDL'93 standardized attributes.")
|
|
1649
|
|
1650 (defconst vhdl-93-enum-values-regexp
|
|
1651 (eval-when-compile
|
|
1652 (concat
|
|
1653 "\\<\\("
|
|
1654 (mapconcat
|
|
1655 'identity
|
|
1656 '(
|
|
1657 "true" "false"
|
|
1658 "note" "warning" "error" "failure"
|
|
1659 "fs" "ps" "ns" "us" "ms" "sec" "min" "hr"
|
|
1660 )
|
|
1661 "\\|")
|
|
1662 "\\)\\>"))
|
|
1663 "Regexp for VHDL'93 standardized enumeration values.")
|
|
1664
|
|
1665
|
|
1666 ;; ############################################################################
|
|
1667 ;; Syntax analysis and indentation
|
|
1668 ;; ############################################################################
|
|
1669
|
|
1670 ;; ############################################################################
|
|
1671 ;; Syntax analysis
|
|
1672
|
|
1673 ;; constant regular expressions for looking at various constructs
|
|
1674
|
|
1675 (defconst vhdl-symbol-key "\\(\\w\\|\\s_\\)+"
|
|
1676 "Regexp describing a VHDL symbol.
|
|
1677 We cannot use just `word' syntax class since `_' cannot be in word
|
|
1678 class. Putting underscore in word class breaks forward word movement
|
|
1679 behavior that users are familiar with.")
|
|
1680
|
|
1681 (defconst vhdl-case-header-key "case[( \t\n][^;=>]+[) \t\n]is"
|
|
1682 "Regexp describing a case statement header key.")
|
|
1683
|
|
1684 (defconst vhdl-label-key
|
|
1685 (concat "\\(" vhdl-symbol-key "\\s-*:\\)[^=]")
|
|
1686 "Regexp describing a VHDL label.")
|
|
1687
|
|
1688 ;; Macro definitions:
|
|
1689
|
|
1690 (defmacro vhdl-point (position)
|
|
1691 ;; Returns the value of point at certain commonly referenced POSITIONs.
|
|
1692 ;; POSITION can be one of the following symbols:
|
|
1693 ;;
|
|
1694 ;; bol -- beginning of line
|
|
1695 ;; eol -- end of line
|
|
1696 ;; bod -- beginning of defun
|
|
1697 ;; boi -- back to indentation
|
|
1698 ;; eoi -- last whitespace on line
|
|
1699 ;; ionl -- indentation of next line
|
|
1700 ;; iopl -- indentation of previous line
|
|
1701 ;; bonl -- beginning of next line
|
|
1702 ;; bopl -- beginning of previous line
|
|
1703 ;;
|
|
1704 ;; This function does not modify point or mark.
|
|
1705 (or (and (eq 'quote (car-safe position))
|
|
1706 (null (cdr (cdr position))))
|
|
1707 (error "bad buffer position requested: %s" position))
|
|
1708 (setq position (nth 1 position))
|
|
1709 (` (let ((here (point)))
|
|
1710 (,@ (cond
|
|
1711 ((eq position 'bol) '((beginning-of-line)))
|
|
1712 ((eq position 'eol) '((end-of-line)))
|
|
1713 ((eq position 'bod) '((save-match-data
|
|
1714 (vhdl-beginning-of-defun))))
|
|
1715 ((eq position 'boi) '((back-to-indentation)))
|
|
1716 ((eq position 'eoi) '((end-of-line)(skip-chars-backward " \t")))
|
|
1717 ((eq position 'bonl) '((forward-line 1)))
|
|
1718 ((eq position 'bopl) '((forward-line -1)))
|
|
1719 ((eq position 'iopl)
|
|
1720 '((forward-line -1)
|
|
1721 (back-to-indentation)))
|
|
1722 ((eq position 'ionl)
|
|
1723 '((forward-line 1)
|
|
1724 (back-to-indentation)))
|
|
1725 (t (error "unknown buffer position requested: %s" position))
|
|
1726 ))
|
|
1727 (prog1
|
|
1728 (point)
|
|
1729 (goto-char here))
|
|
1730 ;; workaround for an Emacs18 bug -- blech! Well, at least it
|
|
1731 ;; doesn't hurt for v19
|
|
1732 (,@ nil)
|
|
1733 )))
|
|
1734
|
|
1735 (defmacro vhdl-safe (&rest body)
|
|
1736 ;; safely execute BODY, return nil if an error occurred
|
|
1737 (` (condition-case nil
|
|
1738 (progn (,@ body))
|
|
1739 (error nil))))
|
|
1740
|
|
1741 (defmacro vhdl-add-syntax (symbol &optional relpos)
|
|
1742 ;; a simple macro to append the syntax in symbol to the syntax list.
|
|
1743 ;; try to increase performance by using this macro
|
|
1744 (` (setq vhdl-syntactic-context
|
|
1745 (cons (cons (, symbol) (, relpos)) vhdl-syntactic-context))))
|
|
1746
|
|
1747 (defmacro vhdl-has-syntax (symbol)
|
|
1748 ;; a simple macro to return check the syntax list.
|
|
1749 ;; try to increase performance by using this macro
|
|
1750 (` (assoc (, symbol) vhdl-syntactic-context)))
|
|
1751
|
|
1752 ;; Syntactic element offset manipulation:
|
|
1753
|
|
1754 (defun vhdl-read-offset (langelem)
|
|
1755 ;; read new offset value for LANGELEM from minibuffer. return a
|
|
1756 ;; legal value only
|
|
1757 (let ((oldoff (format "%s" (cdr-safe (assq langelem vhdl-offsets-alist))))
|
|
1758 (errmsg "Offset must be int, func, var, or one of +, -, ++, --: ")
|
|
1759 (prompt "Offset: ")
|
|
1760 offset input interned)
|
|
1761 (while (not offset)
|
|
1762 (setq input (read-string prompt oldoff)
|
|
1763 offset (cond ((string-equal "+" input) '+)
|
|
1764 ((string-equal "-" input) '-)
|
|
1765 ((string-equal "++" input) '++)
|
|
1766 ((string-equal "--" input) '--)
|
|
1767 ((string-match "^-?[0-9]+$" input)
|
|
1768 (string-to-int input))
|
|
1769 ((fboundp (setq interned (intern input)))
|
|
1770 interned)
|
|
1771 ((boundp interned) interned)
|
|
1772 ;; error, but don't signal one, keep trying
|
|
1773 ;; to read an input value
|
|
1774 (t (ding)
|
|
1775 (setq prompt errmsg)
|
|
1776 nil))))
|
|
1777 offset))
|
|
1778
|
|
1779 (defun vhdl-set-offset (symbol offset &optional add-p)
|
|
1780 "Change the value of a syntactic element symbol in `vhdl-offsets-alist'.
|
|
1781 SYMBOL is the syntactic element symbol to change and OFFSET is the new
|
|
1782 offset for that syntactic element. Optional ADD says to add SYMBOL to
|
|
1783 `vhdl-offsets-alist' if it doesn't already appear there."
|
|
1784 (interactive
|
|
1785 (let* ((langelem
|
|
1786 (intern (completing-read
|
|
1787 (concat "Syntactic symbol to change"
|
|
1788 (if current-prefix-arg " or add" "")
|
|
1789 ": ")
|
|
1790 (mapcar
|
|
1791 (function
|
|
1792 (lambda (langelem)
|
|
1793 (cons (format "%s" (car langelem)) nil)))
|
|
1794 vhdl-offsets-alist)
|
|
1795 nil (not current-prefix-arg)
|
|
1796 ;; initial contents tries to be the last element
|
|
1797 ;; on the syntactic analysis list for the current
|
|
1798 ;; line
|
|
1799 (let* ((syntax (vhdl-get-syntactic-context))
|
|
1800 (len (length syntax))
|
|
1801 (ic (format "%s" (car (nth (1- len) syntax)))))
|
|
1802 (if (memq 'v19 vhdl-emacs-features)
|
|
1803 (cons ic 0)
|
|
1804 ic))
|
|
1805 )))
|
|
1806 (offset (vhdl-read-offset langelem)))
|
|
1807 (list langelem offset current-prefix-arg)))
|
|
1808 ;; sanity check offset
|
|
1809 (or (eq offset '+)
|
|
1810 (eq offset '-)
|
|
1811 (eq offset '++)
|
|
1812 (eq offset '--)
|
|
1813 (integerp offset)
|
|
1814 (fboundp offset)
|
|
1815 (boundp offset)
|
|
1816 (error "Offset must be int, func, var, or one of +, -, ++, --: %s"
|
|
1817 offset))
|
|
1818 (let ((entry (assq symbol vhdl-offsets-alist)))
|
|
1819 (if entry
|
|
1820 (setcdr entry offset)
|
|
1821 (if add-p
|
|
1822 (setq vhdl-offsets-alist (cons (cons symbol offset) vhdl-offsets-alist))
|
|
1823 (error "%s is not a valid syntactic symbol." symbol))))
|
|
1824 (vhdl-keep-region-active))
|
|
1825
|
|
1826 (defun vhdl-set-style (style &optional local)
|
|
1827 "Set vhdl-mode variables to use one of several different indentation styles.
|
|
1828 STYLE is a string representing the desired style and optional LOCAL is
|
|
1829 a flag which, if non-nil, means to make the style variables being
|
|
1830 changed buffer local, instead of the default, which is to set the
|
|
1831 global variables. Interactively, the flag comes from the prefix
|
|
1832 argument. The styles are chosen from the `vhdl-style-alist' variable."
|
|
1833 (interactive (list (completing-read "Use which VHDL indentation style? "
|
|
1834 vhdl-style-alist nil t)
|
|
1835 current-prefix-arg))
|
|
1836 (let ((vars (cdr (assoc style vhdl-style-alist))))
|
|
1837 (or vars
|
|
1838 (error "Invalid VHDL indentation style `%s'" style))
|
|
1839 ;; set all the variables
|
|
1840 (mapcar
|
|
1841 (function
|
|
1842 (lambda (varentry)
|
|
1843 (let ((var (car varentry))
|
|
1844 (val (cdr varentry)))
|
|
1845 (and local
|
|
1846 (make-local-variable var))
|
|
1847 ;; special case for vhdl-offsets-alist
|
|
1848 (if (not (eq var 'vhdl-offsets-alist))
|
|
1849 (set var val)
|
|
1850 ;; reset vhdl-offsets-alist to the default value first
|
|
1851 (setq vhdl-offsets-alist (copy-alist vhdl-offsets-alist-default))
|
|
1852 ;; now set the langelems that are different
|
|
1853 (mapcar
|
|
1854 (function
|
|
1855 (lambda (langentry)
|
|
1856 (let ((langelem (car langentry))
|
|
1857 (offset (cdr langentry)))
|
|
1858 (vhdl-set-offset langelem offset)
|
|
1859 )))
|
|
1860 val))
|
|
1861 )))
|
|
1862 vars))
|
|
1863 (vhdl-keep-region-active))
|
|
1864
|
|
1865 (defun vhdl-get-offset (langelem)
|
|
1866 ;; Get offset from LANGELEM which is a cons cell of the form:
|
|
1867 ;; (SYMBOL . RELPOS). The symbol is matched against
|
|
1868 ;; vhdl-offsets-alist and the offset found there is either returned,
|
|
1869 ;; or added to the indentation at RELPOS. If RELPOS is nil, then
|
|
1870 ;; the offset is simply returned.
|
|
1871 (let* ((symbol (car langelem))
|
|
1872 (relpos (cdr langelem))
|
|
1873 (match (assq symbol vhdl-offsets-alist))
|
|
1874 (offset (cdr-safe match)))
|
|
1875 ;; offset can be a number, a function, a variable, or one of the
|
|
1876 ;; symbols + or -
|
|
1877 (cond
|
|
1878 ((not match)
|
|
1879 (if vhdl-strict-syntax-p
|
|
1880 (error "don't know how to indent a %s" symbol)
|
|
1881 (setq offset 0
|
|
1882 relpos 0)))
|
|
1883 ((eq offset '+) (setq offset vhdl-basic-offset))
|
|
1884 ((eq offset '-) (setq offset (- vhdl-basic-offset)))
|
|
1885 ((eq offset '++) (setq offset (* 2 vhdl-basic-offset)))
|
|
1886 ((eq offset '--) (setq offset (* 2 (- vhdl-basic-offset))))
|
|
1887 ((and (not (numberp offset))
|
|
1888 (fboundp offset))
|
|
1889 (setq offset (funcall offset langelem)))
|
|
1890 ((not (numberp offset))
|
|
1891 (setq offset (eval offset)))
|
|
1892 )
|
|
1893 (+ (if (and relpos
|
|
1894 (< relpos (vhdl-point 'bol)))
|
|
1895 (save-excursion
|
|
1896 (goto-char relpos)
|
|
1897 (current-column))
|
|
1898 0)
|
|
1899 offset)))
|
|
1900
|
|
1901 ;; Syntactic support functions:
|
|
1902
|
|
1903 ;; Returns `comment' if in a comment, `string' if in a string literal,
|
|
1904 ;; or nil if not in a literal at all. Optional LIM is used as the
|
|
1905 ;; backward limit of the search. If omitted, or nil, (point-min) is
|
|
1906 ;; used.
|
|
1907
|
|
1908 (defun vhdl-in-literal (&optional lim)
|
|
1909 ;; Determine if point is in a VHDL literal.
|
|
1910 (save-excursion
|
|
1911 (let* ((lim (or lim (point-min)))
|
|
1912 (state (parse-partial-sexp lim (point))))
|
|
1913 (cond
|
|
1914 ((nth 3 state) 'string)
|
|
1915 ((nth 4 state) 'comment)
|
|
1916 (t nil)))
|
|
1917 ))
|
|
1918
|
|
1919 ;; This is the best we can do in Win-Emacs.
|
|
1920 (defun vhdl-win-il (&optional lim)
|
|
1921 ;; Determine if point is in a VHDL literal
|
|
1922 (save-excursion
|
|
1923 (let* ((here (point))
|
|
1924 (state nil)
|
|
1925 (match nil)
|
|
1926 (lim (or lim (vhdl-point 'bod))))
|
|
1927 (goto-char lim )
|
|
1928 (while (< (point) here)
|
|
1929 (setq match
|
|
1930 (and (re-search-forward "--\\|[\"']"
|
|
1931 here 'move)
|
|
1932 (buffer-substring (match-beginning 0) (match-end 0))))
|
|
1933 (setq state
|
|
1934 (cond
|
|
1935 ;; no match
|
|
1936 ((null match) nil)
|
|
1937 ;; looking at the opening of a VHDL style comment
|
|
1938 ((string= "--" match)
|
|
1939 (if (<= here (progn (end-of-line) (point))) 'comment))
|
|
1940 ;; looking at the opening of a double quote string
|
|
1941 ((string= "\"" match)
|
|
1942 (if (not (save-restriction
|
|
1943 ;; this seems to be necessary since the
|
|
1944 ;; re-search-forward will not work without it
|
|
1945 (narrow-to-region (point) here)
|
|
1946 (re-search-forward
|
|
1947 ;; this regexp matches a double quote
|
|
1948 ;; which is preceded by an even number
|
|
1949 ;; of backslashes, including zero
|
|
1950 "\\([^\\]\\|^\\)\\(\\\\\\\\\\)*\"" here 'move)))
|
|
1951 'string))
|
|
1952 ;; looking at the opening of a single quote string
|
|
1953 ((string= "'" match)
|
|
1954 (if (not (save-restriction
|
|
1955 ;; see comments from above
|
|
1956 (narrow-to-region (point) here)
|
|
1957 (re-search-forward
|
|
1958 ;; this matches a single quote which is
|
|
1959 ;; preceded by zero or two backslashes.
|
|
1960 "\\([^\\]\\|^\\)\\(\\\\\\\\\\)?'"
|
|
1961 here 'move)))
|
|
1962 'string))
|
|
1963 (t nil)))
|
|
1964 ) ; end-while
|
|
1965 state)))
|
|
1966
|
|
1967 (and (memq 'Win-Emacs vhdl-emacs-features)
|
|
1968 (fset 'vhdl-in-literal 'vhdl-win-il))
|
|
1969
|
|
1970 ;; Skipping of "syntactic whitespace". Syntactic whitespace is
|
|
1971 ;; defined as lexical whitespace or comments. Search no farther back
|
|
1972 ;; or forward than optional LIM. If LIM is omitted, (point-min) is
|
|
1973 ;; used for backward skipping, (point-max) is used for forward
|
|
1974 ;; skipping.
|
|
1975
|
|
1976 (defun vhdl-forward-syntactic-ws (&optional lim)
|
|
1977 ;; Forward skip of syntactic whitespace.
|
|
1978 (save-restriction
|
|
1979 (let* ((lim (or lim (point-max)))
|
|
1980 (here lim)
|
|
1981 (hugenum (point-max)))
|
|
1982 (narrow-to-region lim (point))
|
|
1983 (while (/= here (point))
|
|
1984 (setq here (point))
|
|
1985 (forward-comment hugenum))
|
|
1986 )))
|
|
1987
|
|
1988 ;; This is the best we can do in Win-Emacs.
|
|
1989 (defun vhdl-win-fsws (&optional lim)
|
|
1990 ;; Forward skip syntactic whitespace for Win-Emacs.
|
|
1991 (let ((lim (or lim (point-max)))
|
|
1992 stop)
|
|
1993 (while (not stop)
|
|
1994 (skip-chars-forward " \t\n\r\f" lim)
|
|
1995 (cond
|
|
1996 ;; vhdl comment
|
|
1997 ((looking-at "--") (end-of-line))
|
|
1998 ;; none of the above
|
|
1999 (t (setq stop t))
|
|
2000 ))))
|
|
2001
|
|
2002 (and (memq 'Win-Emacs vhdl-emacs-features)
|
|
2003 (fset 'vhdl-forward-syntactic-ws 'vhdl-win-fsws))
|
|
2004
|
|
2005 (defun vhdl-backward-syntactic-ws (&optional lim)
|
|
2006 ;; Backward skip over syntactic whitespace.
|
|
2007 (save-restriction
|
|
2008 (let* ((lim (or lim (point-min)))
|
|
2009 (here lim)
|
|
2010 (hugenum (- (point-max))))
|
|
2011 (if (< lim (point))
|
|
2012 (progn
|
|
2013 (narrow-to-region lim (point))
|
|
2014 (while (/= here (point))
|
|
2015 (setq here (point))
|
|
2016 (forward-comment hugenum)
|
|
2017 )))
|
|
2018 )))
|
|
2019
|
|
2020 ;; This is the best we can do in Win-Emacs.
|
|
2021 (defun vhdl-win-bsws (&optional lim)
|
|
2022 ;; Backward skip syntactic whitespace for Win-Emacs.
|
|
2023 (let ((lim (or lim (vhdl-point 'bod)))
|
|
2024 stop)
|
|
2025 (while (not stop)
|
|
2026 (skip-chars-backward " \t\n\r\f" lim)
|
|
2027 (cond
|
|
2028 ;; vhdl comment
|
|
2029 ((eq (vhdl-in-literal lim) 'comment)
|
|
2030 (skip-chars-backward "^-" lim)
|
|
2031 (skip-chars-backward "-" lim)
|
|
2032 (while (not (or (and (= (following-char) ?-)
|
|
2033 (= (char-after (1+ (point))) ?-))
|
|
2034 (<= (point) lim)))
|
|
2035 (skip-chars-backward "^-" lim)
|
|
2036 (skip-chars-backward "-" lim)))
|
|
2037 ;; none of the above
|
|
2038 (t (setq stop t))
|
|
2039 ))))
|
|
2040
|
|
2041 (and (memq 'Win-Emacs vhdl-emacs-features)
|
|
2042 (fset 'vhdl-backward-syntactic-ws 'vhdl-win-bsws))
|
|
2043
|
|
2044 ;; Functions to help finding the correct indentation column:
|
|
2045
|
|
2046 (defun vhdl-first-word (point)
|
|
2047 "If the keyword at POINT is at boi, then return (current-column) at
|
|
2048 that point, else nil."
|
|
2049 (save-excursion
|
|
2050 (and (goto-char point)
|
|
2051 (eq (point) (vhdl-point 'boi))
|
|
2052 (current-column))))
|
|
2053
|
|
2054 (defun vhdl-last-word (point)
|
|
2055 "If the keyword at POINT is at eoi, then return (current-column) at
|
|
2056 that point, else nil."
|
|
2057 (save-excursion
|
|
2058 (and (goto-char point)
|
|
2059 (save-excursion (or (eq (progn (forward-sexp) (point))
|
|
2060 (vhdl-point 'eoi))
|
|
2061 (looking-at "\\s-*\\(--\\)?")))
|
|
2062 (current-column))))
|
|
2063
|
|
2064 ;; Core syntactic evaluation functions:
|
|
2065
|
|
2066 (defconst vhdl-libunit-re
|
|
2067 "\\b\\(architecture\\|configuration\\|entity\\|package\\)\\b[^_]")
|
|
2068
|
|
2069 (defun vhdl-libunit-p ()
|
|
2070 (and
|
|
2071 (save-excursion
|
|
2072 (forward-sexp)
|
|
2073 (skip-chars-forward " \t\n")
|
|
2074 (not (looking-at "is\\b[^_]")))
|
|
2075 (save-excursion
|
|
2076 (backward-sexp)
|
|
2077 (and (not (looking-at "use\\b[^_]"))
|
|
2078 (progn
|
|
2079 (forward-sexp)
|
|
2080 (vhdl-forward-syntactic-ws)
|
|
2081 (/= (following-char) ?:))))
|
|
2082 ))
|
|
2083
|
|
2084 (defconst vhdl-defun-re
|
|
2085 "\\b\\(architecture\\|block\\|configuration\\|entity\\|package\\|process\\|procedure\\|function\\)\\b[^_]")
|
|
2086
|
|
2087 (defun vhdl-defun-p ()
|
|
2088 (save-excursion
|
|
2089 (if (looking-at "block\\|process")
|
|
2090 ;; "block", "process":
|
|
2091 (save-excursion
|
|
2092 (backward-sexp)
|
|
2093 (not (looking-at "end\\s-+\\w")))
|
|
2094 ;; "architecture", "configuration", "entity",
|
|
2095 ;; "package", "procedure", "function":
|
|
2096 t)))
|
|
2097
|
|
2098 (defun vhdl-corresponding-defun ()
|
|
2099 "If the word at the current position corresponds to a \"defun\"
|
|
2100 keyword, then return a string that can be used to find the
|
|
2101 corresponding \"begin\" keyword, else return nil."
|
|
2102 (save-excursion
|
|
2103 (and (looking-at vhdl-defun-re)
|
|
2104 (vhdl-defun-p)
|
|
2105 (if (looking-at "block\\|process")
|
|
2106 ;; "block", "process":
|
|
2107 (buffer-substring (match-beginning 0) (match-end 0))
|
|
2108 ;; "architecture", "configuration", "entity", "package",
|
|
2109 ;; "procedure", "function":
|
|
2110 "is"))))
|
|
2111
|
|
2112 (defconst vhdl-begin-fwd-re
|
|
2113 "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|units\\|record\\|for\\)\\b\\([^_]\\|\\'\\)"
|
|
2114 "A regular expression for searching forward that matches all known
|
|
2115 \"begin\" keywords.")
|
|
2116
|
|
2117 (defconst vhdl-begin-bwd-re
|
|
2118 "\\b\\(is\\|begin\\|block\\|component\\|generate\\|then\\|else\\|loop\\|process\\|units\\|record\\|for\\)\\b[^_]"
|
|
2119 "A regular expression for searching backward that matches all known
|
|
2120 \"begin\" keywords.")
|
|
2121
|
|
2122 (defun vhdl-begin-p (&optional lim)
|
|
2123 "Return t if we are looking at a real \"begin\" keyword.
|
|
2124 Assumes that the caller will make sure that we are looking at
|
|
2125 vhdl-begin-fwd-re, and are not inside a literal, and that we are not in
|
|
2126 the middle of an identifier that just happens to contain a \"begin\"
|
|
2127 keyword."
|
|
2128 (cond
|
|
2129 ;; "[architecture|case|configuration|entity|package|
|
|
2130 ;; procedure|function] ... is":
|
|
2131 ((and (looking-at "i")
|
|
2132 (save-excursion
|
|
2133 ;; Skip backward over first sexp (needed to skip over a
|
|
2134 ;; procedure interface list, and is harmless in other
|
|
2135 ;; situations). Note that we need "return" in the
|
|
2136 ;; following search list so that we don't run into
|
|
2137 ;; semicolons in the function interface list.
|
|
2138 (backward-sexp)
|
|
2139 (let (foundp)
|
|
2140 (while (and (not foundp)
|
|
2141 (re-search-backward
|
|
2142 ";\\|\\b\\(architecture\\|case\\|configuration\\|entity\\|package\\|procedure\\|return\\|is\\|begin\\|process\\|block\\)\\b[^_]"
|
|
2143 lim 'move))
|
|
2144 (if (or (= (preceding-char) ?_)
|
|
2145 (vhdl-in-literal lim))
|
|
2146 (backward-char)
|
|
2147 (setq foundp t))))
|
|
2148 (and (/= (following-char) ?\;)
|
|
2149 (not (looking-at "is\\|begin\\|process\\|block")))))
|
|
2150 t)
|
|
2151 ;; "begin", "then":
|
|
2152 ((looking-at "be\\|t")
|
|
2153 t)
|
|
2154 ;; "else":
|
|
2155 ((and (looking-at "e")
|
|
2156 ;; make sure that the "else" isn't inside a
|
|
2157 ;; conditional signal assignment.
|
|
2158 (save-excursion
|
|
2159 (re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move)
|
|
2160 (or (eq (following-char) ?\;)
|
|
2161 (eq (point) lim))))
|
|
2162 t)
|
|
2163 ;; "block", "generate", "loop", "process",
|
|
2164 ;; "units", "record":
|
|
2165 ((and (looking-at "bl\\|[glpur]")
|
|
2166 (save-excursion
|
|
2167 (backward-sexp)
|
|
2168 (not (looking-at "end\\s-+\\w"))))
|
|
2169 t)
|
|
2170 ;; "component":
|
|
2171 ((and (looking-at "c")
|
|
2172 (save-excursion
|
|
2173 (backward-sexp)
|
|
2174 (not (looking-at "end\\s-+\\w")))
|
|
2175 ;; look out for the dreaded entity class in an attribute
|
|
2176 (save-excursion
|
|
2177 (vhdl-backward-syntactic-ws lim)
|
|
2178 (/= (preceding-char) ?:)))
|
|
2179 t)
|
|
2180 ;; "for" (inside configuration declaration):
|
|
2181 ((and (looking-at "f")
|
|
2182 (save-excursion
|
|
2183 (backward-sexp)
|
|
2184 (not (looking-at "end\\s-+\\w")))
|
|
2185 (vhdl-has-syntax 'configuration))
|
|
2186 t)
|
|
2187 ))
|
|
2188
|
|
2189 (defun vhdl-corresponding-mid (&optional lim)
|
|
2190 (cond
|
|
2191 ((looking-at "is\\|block\\|process")
|
|
2192 "begin")
|
|
2193 ((looking-at "then")
|
|
2194 "<else>")
|
|
2195 (t
|
|
2196 "end")))
|
|
2197
|
|
2198 (defun vhdl-corresponding-end (&optional lim)
|
|
2199 "If the word at the current position corresponds to a \"begin\"
|
|
2200 keyword, then return a vector containing enough information to find
|
|
2201 the corresponding \"end\" keyword, else return nil. The keyword to
|
|
2202 search forward for is aref 0. The column in which the keyword must
|
|
2203 appear is aref 1 or nil if any column is suitable.
|
|
2204 Assumes that the caller will make sure that we are not in the middle
|
|
2205 of an identifier that just happens to contain a \"begin\" keyword."
|
|
2206 (save-excursion
|
|
2207 (and (looking-at vhdl-begin-fwd-re)
|
|
2208 (/= (preceding-char) ?_)
|
|
2209 (not (vhdl-in-literal lim))
|
|
2210 (vhdl-begin-p lim)
|
|
2211 (cond
|
|
2212 ;; "is", "generate", "loop":
|
|
2213 ((looking-at "[igl]")
|
|
2214 (vector "end"
|
|
2215 (and (vhdl-last-word (point))
|
|
2216 (or (vhdl-first-word (point))
|
|
2217 (save-excursion
|
|
2218 (vhdl-beginning-of-statement-1 lim)
|
|
2219 (vhdl-backward-skip-label lim)
|
|
2220 (vhdl-first-word (point)))))))
|
|
2221 ;; "begin", "else", "for":
|
|
2222 ((looking-at "be\\|[ef]")
|
|
2223 (vector "end"
|
|
2224 (and (vhdl-last-word (point))
|
|
2225 (or (vhdl-first-word (point))
|
|
2226 (save-excursion
|
|
2227 (vhdl-beginning-of-statement-1 lim)
|
|
2228 (vhdl-backward-skip-label lim)
|
|
2229 (vhdl-first-word (point)))))))
|
|
2230 ;; "component", "units", "record":
|
|
2231 ((looking-at "[cur]")
|
|
2232 ;; The first end found will close the block
|
|
2233 (vector "end" nil))
|
|
2234 ;; "block", "process":
|
|
2235 ((looking-at "bl\\|p")
|
|
2236 (vector "end"
|
|
2237 (or (vhdl-first-word (point))
|
|
2238 (save-excursion
|
|
2239 (vhdl-beginning-of-statement-1 lim)
|
|
2240 (vhdl-backward-skip-label lim)
|
|
2241 (vhdl-first-word (point))))))
|
|
2242 ;; "then":
|
|
2243 ((looking-at "t")
|
|
2244 (vector "elsif\\|else\\|end\\s-+if"
|
|
2245 (and (vhdl-last-word (point))
|
|
2246 (or (vhdl-first-word (point))
|
|
2247 (save-excursion
|
|
2248 (vhdl-beginning-of-statement-1 lim)
|
|
2249 (vhdl-backward-skip-label lim)
|
|
2250 (vhdl-first-word (point)))))))
|
|
2251 ))))
|
|
2252
|
|
2253 (defconst vhdl-end-fwd-re "\\b\\(end\\|else\\|elsif\\)\\b\\([^_]\\|\\'\\)")
|
|
2254
|
|
2255 (defconst vhdl-end-bwd-re "\\b\\(end\\|else\\|elsif\\)\\b[^_]")
|
|
2256
|
|
2257 (defun vhdl-end-p (&optional lim)
|
|
2258 "Return t if we are looking at a real \"end\" keyword.
|
|
2259 Assumes that the caller will make sure that we are looking at
|
|
2260 vhdl-end-fwd-re, and are not inside a literal, and that we are not in
|
|
2261 the middle of an identifier that just happens to contain an \"end\"
|
|
2262 keyword."
|
|
2263 (or (not (looking-at "else"))
|
|
2264 ;; make sure that the "else" isn't inside a conditional signal
|
|
2265 ;; assignment.
|
|
2266 (save-excursion
|
|
2267 (re-search-backward ";\\|\\bwhen\\b[^_]" lim 'move)
|
|
2268 (or (eq (following-char) ?\;)
|
|
2269 (eq (point) lim)))))
|
|
2270
|
|
2271 (defun vhdl-corresponding-begin (&optional lim)
|
|
2272 "If the word at the current position corresponds to an \"end\"
|
|
2273 keyword, then return a vector containing enough information to find
|
|
2274 the corresponding \"begin\" keyword, else return nil. The keyword to
|
|
2275 search backward for is aref 0. The column in which the keyword must
|
|
2276 appear is aref 1 or nil if any column is suitable. The supplementary
|
|
2277 keyword to search forward for is aref 2 or nil if this is not
|
|
2278 required. If aref 3 is t, then the \"begin\" keyword may be found in
|
|
2279 the middle of a statement.
|
|
2280 Assumes that the caller will make sure that we are not in the middle
|
|
2281 of an identifier that just happens to contain an \"end\" keyword."
|
|
2282 (save-excursion
|
|
2283 (let (pos)
|
|
2284 (if (and (looking-at vhdl-end-fwd-re)
|
|
2285 (not (vhdl-in-literal lim))
|
|
2286 (vhdl-end-p lim))
|
|
2287 (if (looking-at "el")
|
|
2288 ;; "else", "elsif":
|
|
2289 (vector "if\\|elsif" (vhdl-first-word (point)) "then" nil)
|
|
2290 ;; "end ...":
|
|
2291 (setq pos (point))
|
|
2292 (forward-sexp)
|
|
2293 (skip-chars-forward " \t\n")
|
|
2294 (cond
|
|
2295 ;; "end if":
|
|
2296 ((looking-at "if\\b[^_]")
|
|
2297 (vector "else\\|elsif\\|if"
|
|
2298 (vhdl-first-word pos)
|
|
2299 "else\\|then" nil))
|
|
2300 ;; "end component":
|
|
2301 ((looking-at "component\\b[^_]")
|
|
2302 (vector (buffer-substring (match-beginning 1)
|
|
2303 (match-end 1))
|
|
2304 (vhdl-first-word pos)
|
|
2305 nil nil))
|
|
2306 ;; "end units", "end record":
|
|
2307 ((looking-at "\\(units\\|record\\)\\b[^_]")
|
|
2308 (vector (buffer-substring (match-beginning 1)
|
|
2309 (match-end 1))
|
|
2310 (vhdl-first-word pos)
|
|
2311 nil t))
|
|
2312 ;; "end block", "end process":
|
|
2313 ((looking-at "\\(block\\|process\\)\\b[^_]")
|
|
2314 (vector "begin" (vhdl-first-word pos) nil nil))
|
|
2315 ;; "end case":
|
|
2316 ((looking-at "case\\b[^_]")
|
|
2317 (vector "case" (vhdl-first-word pos) "is" nil))
|
|
2318 ;; "end generate":
|
|
2319 ((looking-at "generate\\b[^_]")
|
|
2320 (vector "generate\\|for\\|if"
|
|
2321 (vhdl-first-word pos)
|
|
2322 "generate" nil))
|
|
2323 ;; "end loop":
|
|
2324 ((looking-at "loop\\b[^_]")
|
|
2325 (vector "loop\\|while\\|for"
|
|
2326 (vhdl-first-word pos)
|
|
2327 "loop" nil))
|
|
2328 ;; "end for" (inside configuration declaration):
|
|
2329 ((looking-at "for\\b[^_]")
|
|
2330 (vector "for" (vhdl-first-word pos) nil nil))
|
|
2331 ;; "end [id]":
|
|
2332 (t
|
|
2333 (vector "begin\\|architecture\\|configuration\\|entity\\|package\\|procedure\\|function"
|
|
2334 (vhdl-first-word pos)
|
|
2335 ;; return an alist of (statement . keyword) mappings
|
|
2336 '(
|
|
2337 ;; "begin ... end [id]":
|
|
2338 ("begin" . nil)
|
|
2339 ;; "architecture ... is ... begin ... end [id]":
|
|
2340 ("architecture" . "is")
|
|
2341 ;; "configuration ... is ... end [id]":
|
|
2342 ("configuration" . "is")
|
|
2343 ;; "entity ... is ... end [id]":
|
|
2344 ("entity" . "is")
|
|
2345 ;; "package ... is ... end [id]":
|
|
2346 ("package" . "is")
|
|
2347 ;; "procedure ... is ... begin ... end [id]":
|
|
2348 ("procedure" . "is")
|
|
2349 ;; "function ... is ... begin ... end [id]":
|
|
2350 ("function" . "is")
|
|
2351 )
|
|
2352 nil))
|
|
2353 ))) ; "end ..."
|
|
2354 )))
|
|
2355
|
|
2356 (defconst vhdl-leader-re
|
|
2357 "\\b\\(block\\|component\\|process\\|for\\)\\b[^_]")
|
|
2358
|
|
2359 (defun vhdl-end-of-leader ()
|
|
2360 (save-excursion
|
|
2361 (cond ((looking-at "block\\|process")
|
|
2362 (if (save-excursion
|
|
2363 (forward-sexp)
|
|
2364 (skip-chars-forward " \t\n")
|
|
2365 (= (following-char) ?\())
|
|
2366 (forward-sexp 2)
|
|
2367 (forward-sexp))
|
|
2368 (point))
|
|
2369 ((looking-at "component")
|
|
2370 (forward-sexp 2)
|
|
2371 (point))
|
|
2372 ((looking-at "for")
|
|
2373 (forward-sexp 2)
|
|
2374 (skip-chars-forward " \t\n")
|
|
2375 (while (looking-at "[,:(]")
|
|
2376 (forward-sexp)
|
|
2377 (skip-chars-forward " \t\n"))
|
|
2378 (point))
|
|
2379 (t nil)
|
|
2380 )))
|
|
2381
|
|
2382 (defconst vhdl-trailer-re
|
|
2383 "\\b\\(is\\|then\\|generate\\|loop\\)\\b[^_]")
|
|
2384
|
|
2385 (defconst vhdl-statement-fwd-re
|
|
2386 "\\b\\(if\\|for\\|while\\)\\b\\([^_]\\|\\'\\)"
|
|
2387 "A regular expression for searching forward that matches all known
|
|
2388 \"statement\" keywords.")
|
|
2389
|
|
2390 (defconst vhdl-statement-bwd-re
|
|
2391 "\\b\\(if\\|for\\|while\\)\\b[^_]"
|
|
2392 "A regular expression for searching backward that matches all known
|
|
2393 \"statement\" keywords.")
|
|
2394
|
|
2395 (defun vhdl-statement-p (&optional lim)
|
|
2396 "Return t if we are looking at a real \"statement\" keyword.
|
|
2397 Assumes that the caller will make sure that we are looking at
|
|
2398 vhdl-statement-fwd-re, and are not inside a literal, and that we are not in
|
|
2399 the middle of an identifier that just happens to contain a \"statement\"
|
|
2400 keyword."
|
|
2401 (cond
|
|
2402 ;; "for" ... "generate":
|
|
2403 ((and (looking-at "f")
|
|
2404 ;; Make sure it's the start of a parameter specification.
|
|
2405 (save-excursion
|
|
2406 (forward-sexp 2)
|
|
2407 (skip-chars-forward " \t\n")
|
|
2408 (looking-at "in\\b[^_]"))
|
|
2409 ;; Make sure it's not an "end for".
|
|
2410 (save-excursion
|
|
2411 (backward-sexp)
|
|
2412 (not (looking-at "end\\s-+\\w"))))
|
|
2413 t)
|
|
2414 ;; "if" ... "then", "if" ... "generate", "if" ... "loop":
|
|
2415 ((and (looking-at "i")
|
|
2416 ;; Make sure it's not an "end if".
|
|
2417 (save-excursion
|
|
2418 (backward-sexp)
|
|
2419 (not (looking-at "end\\s-+\\w"))))
|
|
2420 t)
|
|
2421 ;; "while" ... "loop":
|
|
2422 ((looking-at "w")
|
|
2423 t)
|
|
2424 ))
|
|
2425
|
|
2426 (defconst vhdl-case-alternative-re "when[( \t\n][^;=>]+=>"
|
|
2427 "Regexp describing a case statement alternative key.")
|
|
2428
|
|
2429 (defun vhdl-case-alternative-p (&optional lim)
|
|
2430 "Return t if we are looking at a real case alternative.
|
|
2431 Assumes that the caller will make sure that we are looking at
|
|
2432 vhdl-case-alternative-re, and are not inside a literal, and that
|
|
2433 we are not in the middle of an identifier that just happens to
|
|
2434 contain a \"when\" keyword."
|
|
2435 (save-excursion
|
|
2436 (let (foundp)
|
|
2437 (while (and (not foundp)
|
|
2438 (re-search-backward ";\\|<=" lim 'move))
|
|
2439 (if (or (= (preceding-char) ?_)
|
|
2440 (vhdl-in-literal lim))
|
|
2441 (backward-char)
|
|
2442 (setq foundp t)))
|
|
2443 (or (eq (following-char) ?\;)
|
|
2444 (eq (point) lim)))
|
|
2445 ))
|
|
2446
|
|
2447 ;; Core syntactic movement functions:
|
|
2448
|
|
2449 (defconst vhdl-b-t-b-re
|
|
2450 (concat vhdl-begin-bwd-re "\\|" vhdl-end-bwd-re))
|
|
2451
|
|
2452 (defun vhdl-backward-to-block (&optional lim)
|
|
2453 "Move backward to the previous \"begin\" or \"end\" keyword."
|
|
2454 (let (foundp)
|
|
2455 (while (and (not foundp)
|
|
2456 (re-search-backward vhdl-b-t-b-re lim 'move))
|
|
2457 (if (or (= (preceding-char) ?_)
|
|
2458 (vhdl-in-literal lim))
|
|
2459 (backward-char)
|
|
2460 (cond
|
|
2461 ;; "begin" keyword:
|
|
2462 ((and (looking-at vhdl-begin-fwd-re)
|
|
2463 (/= (preceding-char) ?_)
|
|
2464 (vhdl-begin-p lim))
|
|
2465 (setq foundp 'begin))
|
|
2466 ;; "end" keyword:
|
|
2467 ((and (looking-at vhdl-end-fwd-re)
|
|
2468 (/= (preceding-char) ?_)
|
|
2469 (vhdl-end-p lim))
|
|
2470 (setq foundp 'end))
|
|
2471 ))
|
|
2472 )
|
|
2473 foundp
|
|
2474 ))
|
|
2475
|
|
2476 (defun vhdl-forward-sexp (&optional count lim)
|
|
2477 "Move forward across one balanced expression (sexp).
|
|
2478 With COUNT, do it that many times."
|
|
2479 (interactive "p")
|
|
2480 (let ((count (or count 1))
|
|
2481 (case-fold-search t)
|
|
2482 end-vec target)
|
|
2483 (save-excursion
|
|
2484 (while (> count 0)
|
|
2485 ;; skip whitespace
|
|
2486 (skip-chars-forward " \t\n")
|
|
2487 ;; Check for an unbalanced "end" keyword
|
|
2488 (if (and (looking-at vhdl-end-fwd-re)
|
|
2489 (/= (preceding-char) ?_)
|
|
2490 (not (vhdl-in-literal lim))
|
|
2491 (vhdl-end-p lim)
|
|
2492 (not (looking-at "else")))
|
|
2493 (error
|
|
2494 "Containing expression ends prematurely in vhdl-forward-sexp"))
|
|
2495 ;; If the current keyword is a "begin" keyword, then find the
|
|
2496 ;; corresponding "end" keyword.
|
|
2497 (if (setq end-vec (vhdl-corresponding-end lim))
|
|
2498 (let (
|
|
2499 ;; end-re is the statement keyword to search for
|
|
2500 (end-re
|
|
2501 (concat "\\b\\(" (aref end-vec 0) "\\)\\b\\([^_]\\|\\'\\)"))
|
|
2502 ;; column is either the statement keyword target column
|
|
2503 ;; or nil
|
|
2504 (column (aref end-vec 1))
|
|
2505 (eol (vhdl-point 'eol))
|
|
2506 foundp literal placeholder)
|
|
2507 ;; Look for the statement keyword.
|
|
2508 (while (and (not foundp)
|
|
2509 (re-search-forward end-re nil t)
|
|
2510 (setq placeholder (match-end 1))
|
|
2511 (goto-char (match-beginning 0)))
|
|
2512 ;; If we are in a literal, or not in the right target
|
|
2513 ;; column and not on the same line as the begin, then
|
|
2514 ;; try again.
|
|
2515 (if (or (and column
|
|
2516 (/= (current-indentation) column)
|
|
2517 (> (point) eol))
|
|
2518 (= (preceding-char) ?_)
|
|
2519 (setq literal (vhdl-in-literal lim)))
|
|
2520 (if (eq literal 'comment)
|
|
2521 (end-of-line)
|
|
2522 (forward-char))
|
|
2523 ;; An "else" keyword corresponds to both the opening brace
|
|
2524 ;; of the following sexp and the closing brace of the
|
|
2525 ;; previous sexp.
|
|
2526 (if (not (looking-at "else"))
|
|
2527 (goto-char placeholder))
|
|
2528 (setq foundp t))
|
|
2529 )
|
|
2530 (if (not foundp)
|
|
2531 (error "Unbalanced keywords in vhdl-forward-sexp"))
|
|
2532 )
|
|
2533 ;; If the current keyword is not a "begin" keyword, then just
|
|
2534 ;; perform the normal forward-sexp.
|
|
2535 (forward-sexp)
|
|
2536 )
|
|
2537 (setq count (1- count))
|
|
2538 )
|
|
2539 (setq target (point)))
|
|
2540 (goto-char target)
|
|
2541 nil))
|
|
2542
|
|
2543 (defun vhdl-backward-sexp (&optional count lim)
|
|
2544 "Move backward across one balanced expression (sexp).
|
|
2545 With COUNT, do it that many times. LIM bounds any required backward
|
|
2546 searches."
|
|
2547 (interactive "p")
|
|
2548 (let ((count (or count 1))
|
|
2549 (case-fold-search t)
|
|
2550 begin-vec target)
|
|
2551 (save-excursion
|
|
2552 (while (> count 0)
|
|
2553 ;; Perform the normal backward-sexp, unless we are looking at
|
|
2554 ;; "else" - an "else" keyword corresponds to both the opening brace
|
|
2555 ;; of the following sexp and the closing brace of the previous sexp.
|
|
2556 (if (and (looking-at "else\\b\\([^_]\\|\\'\\)")
|
|
2557 (/= (preceding-char) ?_)
|
|
2558 (not (vhdl-in-literal lim)))
|
|
2559 nil
|
|
2560 (backward-sexp)
|
|
2561 (if (and (looking-at vhdl-begin-fwd-re)
|
|
2562 (/= (preceding-char) ?_)
|
|
2563 (not (vhdl-in-literal lim))
|
|
2564 (vhdl-begin-p lim))
|
|
2565 (error "Containing expression ends prematurely in vhdl-backward-sexp")))
|
|
2566 ;; If the current keyword is an "end" keyword, then find the
|
|
2567 ;; corresponding "begin" keyword.
|
|
2568 (if (and (setq begin-vec (vhdl-corresponding-begin lim))
|
|
2569 (/= (preceding-char) ?_))
|
|
2570 (let (
|
|
2571 ;; begin-re is the statement keyword to search for
|
|
2572 (begin-re
|
|
2573 (concat "\\b\\(" (aref begin-vec 0) "\\)\\b[^_]"))
|
|
2574 ;; column is either the statement keyword target column
|
|
2575 ;; or nil
|
|
2576 (column (aref begin-vec 1))
|
|
2577 ;; internal-p controls where the statement keyword can
|
|
2578 ;; be found.
|
|
2579 (internal-p (aref begin-vec 3))
|
|
2580 (last-backward (point)) last-forward
|
|
2581 foundp literal keyword)
|
|
2582 ;; Look for the statement keyword.
|
|
2583 (while (and (not foundp)
|
|
2584 (re-search-backward begin-re lim t)
|
|
2585 (setq keyword
|
|
2586 (buffer-substring (match-beginning 1)
|
|
2587 (match-end 1))))
|
|
2588 ;; If we are in a literal or in the wrong column,
|
|
2589 ;; then try again.
|
|
2590 (if (or (and column
|
|
2591 (and (/= (current-indentation) column)
|
|
2592 ;; possibly accept current-column as
|
|
2593 ;; well as current-indentation.
|
|
2594 (or (not internal-p)
|
|
2595 (/= (current-column) column))))
|
|
2596 (= (preceding-char) ?_)
|
|
2597 (vhdl-in-literal lim))
|
|
2598 (backward-char)
|
|
2599 ;; If there is a supplementary keyword, then
|
|
2600 ;; search forward for it.
|
|
2601 (if (and (setq begin-re (aref begin-vec 2))
|
|
2602 (or (not (listp begin-re))
|
|
2603 ;; If begin-re is an alist, then find the
|
|
2604 ;; element corresponding to the actual
|
|
2605 ;; keyword that we found.
|
|
2606 (progn
|
|
2607 (setq begin-re
|
|
2608 (assoc keyword begin-re))
|
|
2609 (and begin-re
|
|
2610 (setq begin-re (cdr begin-re))))))
|
|
2611 (and
|
|
2612 (setq begin-re
|
|
2613 (concat "\\b\\(" begin-re "\\)\\b[^_]"))
|
|
2614 (save-excursion
|
|
2615 (setq last-forward (point))
|
|
2616 ;; Look for the supplementary keyword
|
|
2617 ;; (bounded by the backward search start
|
|
2618 ;; point).
|
|
2619 (while (and (not foundp)
|
|
2620 (re-search-forward begin-re
|
|
2621 last-backward t)
|
|
2622 (goto-char (match-beginning 1)))
|
|
2623 ;; If we are in a literal, then try again.
|
|
2624 (if (or (= (preceding-char) ?_)
|
|
2625 (setq literal
|
|
2626 (vhdl-in-literal last-forward)))
|
|
2627 (if (eq literal 'comment)
|
|
2628 (goto-char
|
|
2629 (min (vhdl-point 'eol) last-backward))
|
|
2630 (forward-char))
|
|
2631 ;; We have found the supplementary keyword.
|
|
2632 ;; Save the position of the keyword in foundp.
|
|
2633 (setq foundp (point)))
|
|
2634 )
|
|
2635 foundp)
|
|
2636 ;; If the supplementary keyword was found, then
|
|
2637 ;; move point to the supplementary keyword.
|
|
2638 (goto-char foundp))
|
|
2639 ;; If there was no supplementary keyword, then
|
|
2640 ;; point is already at the statement keyword.
|
|
2641 (setq foundp t)))
|
|
2642 ) ; end of the search for the statement keyword
|
|
2643 (if (not foundp)
|
|
2644 (error "Unbalanced keywords in vhdl-backward-sexp"))
|
|
2645 ))
|
|
2646 (setq count (1- count))
|
|
2647 )
|
|
2648 (setq target (point)))
|
|
2649 (goto-char target)
|
|
2650 nil))
|
|
2651
|
|
2652 (defun vhdl-backward-up-list (&optional count limit)
|
|
2653 "Move backward out of one level of blocks.
|
|
2654 With argument, do this that many times."
|
|
2655 (interactive "p")
|
|
2656 (let ((count (or count 1))
|
|
2657 target)
|
|
2658 (save-excursion
|
|
2659 (while (> count 0)
|
|
2660 (if (looking-at vhdl-defun-re)
|
|
2661 (error "Unbalanced blocks"))
|
|
2662 (vhdl-backward-to-block limit)
|
|
2663 (setq count (1- count)))
|
|
2664 (setq target (point)))
|
|
2665 (goto-char target)))
|
|
2666
|
|
2667 (defun vhdl-end-of-defun (&optional count)
|
|
2668 "Move forward to the end of a VHDL defun."
|
|
2669 (interactive)
|
|
2670 (let ((case-fold-search t))
|
|
2671 (vhdl-beginning-of-defun)
|
|
2672 (if (not (looking-at "block\\|process"))
|
|
2673 (re-search-forward "\\bis\\b"))
|
|
2674 (vhdl-forward-sexp)))
|
|
2675
|
|
2676 (defun vhdl-mark-defun ()
|
|
2677 "Put mark at end of this \"defun\", point at beginning."
|
|
2678 (interactive)
|
|
2679 (let ((case-fold-search t))
|
|
2680 (push-mark)
|
|
2681 (vhdl-beginning-of-defun)
|
|
2682 (push-mark)
|
|
2683 (if (not (looking-at "block\\|process"))
|
|
2684 (re-search-forward "\\bis\\b"))
|
|
2685 (vhdl-forward-sexp)
|
|
2686 (exchange-point-and-mark)))
|
|
2687
|
|
2688 (defun vhdl-beginning-of-libunit ()
|
|
2689 "Move backward to the beginning of a VHDL library unit.
|
|
2690 Returns the location of the corresponding begin keyword, unless search
|
|
2691 stops due to beginning or end of buffer."
|
|
2692 ;; Note that if point is between the "libunit" keyword and the
|
|
2693 ;; corresponding "begin" keyword, then that libunit will not be
|
|
2694 ;; recognised, and the search will continue backwards. If point is
|
|
2695 ;; at the "begin" keyword, then the defun will be recognised. The
|
|
2696 ;; returned point is at the first character of the "libunit" keyword.
|
|
2697 (let ((last-forward (point))
|
|
2698 (last-backward
|
|
2699 ;; Just in case we are actually sitting on the "begin"
|
|
2700 ;; keyword, allow for the keyword and an extra character,
|
|
2701 ;; as this will be used when looking forward for the
|
|
2702 ;; "begin" keyword.
|
|
2703 (save-excursion (forward-word 1) (1+ (point))))
|
|
2704 foundp literal placeholder)
|
|
2705 ;; Find the "libunit" keyword.
|
|
2706 (while (and (not foundp)
|
|
2707 (re-search-backward vhdl-libunit-re nil 'move))
|
|
2708 ;; If we are in a literal, or not at a real libunit, then try again.
|
|
2709 (if (or (= (preceding-char) ?_)
|
|
2710 (vhdl-in-literal (point-min))
|
|
2711 (not (vhdl-libunit-p)))
|
|
2712 (backward-char)
|
|
2713 ;; Find the corresponding "begin" keyword.
|
|
2714 (setq last-forward (point))
|
|
2715 (while (and (not foundp)
|
|
2716 (re-search-forward "\\bis\\b[^_]" last-backward t)
|
|
2717 (setq placeholder (match-beginning 0)))
|
|
2718 (if (or (= (preceding-char) ?_)
|
|
2719 (setq literal (vhdl-in-literal last-forward)))
|
|
2720 ;; It wasn't a real keyword, so keep searching.
|
|
2721 (if (eq literal 'comment)
|
|
2722 (goto-char
|
|
2723 (min (vhdl-point 'eol) last-backward))
|
|
2724 (forward-char))
|
|
2725 ;; We have found the begin keyword, loop will exit.
|
|
2726 (setq foundp placeholder)))
|
|
2727 ;; Go back to the libunit keyword
|
|
2728 (goto-char last-forward)))
|
|
2729 foundp))
|
|
2730
|
|
2731 (defun vhdl-beginning-of-defun (&optional count)
|
|
2732 "Move backward to the beginning of a VHDL defun.
|
|
2733 With argument, do it that many times.
|
|
2734 Returns the location of the corresponding begin keyword, unless search
|
|
2735 stops due to beginning or end of buffer."
|
|
2736 ;; Note that if point is between the "defun" keyword and the
|
|
2737 ;; corresponding "begin" keyword, then that defun will not be
|
|
2738 ;; recognised, and the search will continue backwards. If point is
|
|
2739 ;; at the "begin" keyword, then the defun will be recognised. The
|
|
2740 ;; returned point is at the first character of the "defun" keyword.
|
|
2741 (interactive "p")
|
|
2742 (let ((count (or count 1))
|
|
2743 (case-fold-search t)
|
|
2744 (last-forward (point))
|
|
2745 foundp)
|
|
2746 (while (> count 0)
|
|
2747 (setq foundp nil)
|
|
2748 (goto-char last-forward)
|
|
2749 (let ((last-backward
|
|
2750 ;; Just in case we are actually sitting on the "begin"
|
|
2751 ;; keyword, allow for the keyword and an extra character,
|
|
2752 ;; as this will be used when looking forward for the
|
|
2753 ;; "begin" keyword.
|
|
2754 (save-excursion (forward-word 1) (1+ (point))))
|
|
2755 begin-string literal)
|
|
2756 (while (and (not foundp)
|
|
2757 (re-search-backward vhdl-defun-re nil 'move))
|
|
2758 ;; If we are in a literal, then try again.
|
|
2759 (if (or (= (preceding-char) ?_)
|
|
2760 (vhdl-in-literal (point-min)))
|
|
2761 (backward-char)
|
|
2762 (if (setq begin-string (vhdl-corresponding-defun))
|
|
2763 ;; This is a real defun keyword.
|
|
2764 ;; Find the corresponding "begin" keyword.
|
|
2765 ;; Look for the begin keyword.
|
|
2766 (progn
|
|
2767 ;; Save the search start point.
|
|
2768 (setq last-forward (point))
|
|
2769 (while (and (not foundp)
|
|
2770 (search-forward begin-string last-backward t))
|
|
2771 (if (or (= (preceding-char) ?_)
|
|
2772 (save-match-data
|
|
2773 (setq literal (vhdl-in-literal last-forward))))
|
|
2774 ;; It wasn't a real keyword, so keep searching.
|
|
2775 (if (eq literal 'comment)
|
|
2776 (goto-char
|
|
2777 (min (vhdl-point 'eol) last-backward))
|
|
2778 (forward-char))
|
|
2779 ;; We have found the begin keyword, loop will exit.
|
|
2780 (setq foundp (match-beginning 0)))
|
|
2781 )
|
|
2782 ;; Go back to the defun keyword
|
|
2783 (goto-char last-forward)) ; end search for begin keyword
|
|
2784 ))
|
|
2785 ) ; end of the search for the defun keyword
|
|
2786 )
|
|
2787 (setq count (1- count))
|
|
2788 )
|
|
2789 (vhdl-keep-region-active)
|
|
2790 foundp))
|
|
2791
|
|
2792 (defun vhdl-beginning-of-statement (&optional count lim)
|
|
2793 "Go to the beginning of the innermost VHDL statement.
|
|
2794 With prefix arg, go back N - 1 statements. If already at the
|
|
2795 beginning of a statement then go to the beginning of the preceding
|
|
2796 one. If within a string or comment, or next to a comment (only
|
|
2797 whitespace between), move by sentences instead of statements.
|
|
2798
|
|
2799 When called from a program, this function takes 2 optional args: the
|
|
2800 prefix arg, and a buffer position limit which is the farthest back to
|
|
2801 search."
|
|
2802 (interactive "p")
|
|
2803 (let ((count (or count 1))
|
|
2804 (case-fold-search t)
|
|
2805 (lim (or lim (point-min)))
|
|
2806 (here (point))
|
|
2807 state)
|
|
2808 (save-excursion
|
|
2809 (goto-char lim)
|
|
2810 (setq state (parse-partial-sexp (point) here nil nil)))
|
|
2811 (if (and (interactive-p)
|
|
2812 (or (nth 3 state)
|
|
2813 (nth 4 state)
|
|
2814 (looking-at (concat "[ \t]*" comment-start-skip))))
|
|
2815 (forward-sentence (- count))
|
|
2816 (while (> count 0)
|
|
2817 (vhdl-beginning-of-statement-1 lim)
|
|
2818 (setq count (1- count))))
|
|
2819 ;; its possible we've been left up-buf of lim
|
|
2820 (goto-char (max (point) lim))
|
|
2821 )
|
|
2822 (vhdl-keep-region-active))
|
|
2823
|
|
2824 (defconst vhdl-e-o-s-re
|
|
2825 (concat ";\\|" vhdl-begin-fwd-re "\\|" vhdl-statement-fwd-re))
|
|
2826
|
|
2827 (defun vhdl-end-of-statement ()
|
|
2828 "Very simple implementation."
|
|
2829 (interactive)
|
|
2830 (re-search-forward vhdl-e-o-s-re))
|
|
2831
|
|
2832 (defconst vhdl-b-o-s-re
|
|
2833 (concat ";\\|\(\\|\)\\|\\bwhen\\b[^_]\\|"
|
|
2834 vhdl-begin-bwd-re "\\|" vhdl-statement-bwd-re))
|
|
2835
|
|
2836 (defun vhdl-beginning-of-statement-1 (&optional lim)
|
|
2837 ;; move to the start of the current statement, or the previous
|
|
2838 ;; statement if already at the beginning of one.
|
|
2839 (let ((lim (or lim (point-min)))
|
|
2840 (here (point))
|
|
2841 (pos (point))
|
|
2842 donep)
|
|
2843 ;; go backwards one balanced expression, but be careful of
|
|
2844 ;; unbalanced paren being reached
|
|
2845 (if (not (vhdl-safe (progn (backward-sexp) t)))
|
|
2846 (progn
|
|
2847 (backward-up-list 1)
|
|
2848 (forward-char)
|
|
2849 (vhdl-forward-syntactic-ws here)
|
|
2850 (setq donep t)))
|
|
2851 (while (and (not donep)
|
|
2852 (not (bobp))
|
|
2853 ;; look backwards for a statement boundary
|
|
2854 (re-search-backward vhdl-b-o-s-re lim 'move))
|
|
2855 (if (or (= (preceding-char) ?_)
|
|
2856 (vhdl-in-literal lim))
|
|
2857 (backward-char)
|
|
2858 (cond
|
|
2859 ;; If we are looking at an open paren, then stop after it
|
|
2860 ((eq (following-char) ?\()
|
|
2861 (forward-char)
|
|
2862 (vhdl-forward-syntactic-ws here)
|
|
2863 (setq donep t))
|
|
2864 ;; If we are looking at a close paren, then skip it
|
|
2865 ((eq (following-char) ?\))
|
|
2866 (forward-char)
|
|
2867 (setq pos (point))
|
|
2868 (backward-sexp)
|
|
2869 (if (< (point) lim)
|
|
2870 (progn (goto-char pos)
|
|
2871 (vhdl-forward-syntactic-ws here)
|
|
2872 (setq donep t))))
|
|
2873 ;; If we are looking at a semicolon, then stop
|
|
2874 ((eq (following-char) ?\;)
|
|
2875 (progn
|
|
2876 (forward-char)
|
|
2877 (vhdl-forward-syntactic-ws here)
|
|
2878 (setq donep t)))
|
|
2879 ;; If we are looking at a "begin", then stop
|
|
2880 ((and (looking-at vhdl-begin-fwd-re)
|
|
2881 (/= (preceding-char) ?_)
|
|
2882 (vhdl-begin-p nil))
|
|
2883 ;; If it's a leader "begin", then find the
|
|
2884 ;; right place
|
|
2885 (if (looking-at vhdl-leader-re)
|
|
2886 (save-excursion
|
|
2887 ;; set a default stop point at the begin
|
|
2888 (setq pos (point))
|
|
2889 ;; is the start point inside the leader area ?
|
|
2890 (goto-char (vhdl-end-of-leader))
|
|
2891 (vhdl-forward-syntactic-ws here)
|
|
2892 (if (< (point) here)
|
|
2893 ;; start point was not inside leader area
|
|
2894 ;; set stop point at word after leader
|
|
2895 (setq pos (point))))
|
|
2896 (forward-word 1)
|
|
2897 (vhdl-forward-syntactic-ws here)
|
|
2898 (setq pos (point)))
|
|
2899 (goto-char pos)
|
|
2900 (setq donep t))
|
|
2901 ;; If we are looking at a "statement", then stop
|
|
2902 ((and (looking-at vhdl-statement-fwd-re)
|
|
2903 (/= (preceding-char) ?_)
|
|
2904 (vhdl-statement-p nil))
|
|
2905 (setq donep t))
|
|
2906 ;; If we are looking at a case alternative key, then stop
|
|
2907 ((and (looking-at vhdl-case-alternative-re)
|
|
2908 (vhdl-case-alternative-p lim))
|
|
2909 (save-excursion
|
|
2910 ;; set a default stop point at the when
|
|
2911 (setq pos (point))
|
|
2912 ;; is the start point inside the case alternative key ?
|
|
2913 (looking-at vhdl-case-alternative-re)
|
|
2914 (goto-char (match-end 0))
|
|
2915 (vhdl-forward-syntactic-ws here)
|
|
2916 (if (< (point) here)
|
|
2917 ;; start point was not inside the case alternative key
|
|
2918 ;; set stop point at word after case alternative keyleader
|
|
2919 (setq pos (point))))
|
|
2920 (goto-char pos)
|
|
2921 (setq donep t))
|
|
2922 ;; Bogus find, continue
|
|
2923 (t
|
|
2924 (backward-char)))))
|
|
2925 ))
|
|
2926
|
|
2927 ;; Defuns for calculating the current syntactic state:
|
|
2928
|
|
2929 (defun vhdl-get-library-unit (bod placeholder)
|
|
2930 ;; If there is an enclosing library unit at bod, with it's \"begin\"
|
|
2931 ;; keyword at placeholder, then return the library unit type.
|
|
2932 (let ((here (vhdl-point 'bol)))
|
|
2933 (if (save-excursion
|
|
2934 (goto-char placeholder)
|
|
2935 (vhdl-safe (vhdl-forward-sexp 1 bod))
|
|
2936 (<= here (point)))
|
|
2937 (save-excursion
|
|
2938 (goto-char bod)
|
|
2939 (cond
|
|
2940 ((looking-at "e") 'entity)
|
|
2941 ((looking-at "a") 'architecture)
|
|
2942 ((looking-at "c") 'configuration)
|
|
2943 ((looking-at "p")
|
|
2944 (save-excursion
|
|
2945 (goto-char bod)
|
|
2946 (forward-sexp)
|
|
2947 (vhdl-forward-syntactic-ws here)
|
|
2948 (if (looking-at "body\\b[^_]")
|
|
2949 'package-body 'package))))))
|
|
2950 ))
|
|
2951
|
|
2952 (defun vhdl-get-block-state (&optional lim)
|
|
2953 ;; Finds and records all the closest opens.
|
|
2954 ;; lim is the furthest back we need to search (it should be the
|
|
2955 ;; previous libunit keyword).
|
|
2956 (let ((here (point))
|
|
2957 (lim (or lim (point-min)))
|
|
2958 keyword sexp-start sexp-mid sexp-end
|
|
2959 preceding-sexp containing-sexp
|
|
2960 containing-begin containing-mid containing-paren)
|
|
2961 (save-excursion
|
|
2962 ;; Find the containing-paren, and use that as the limit
|
|
2963 (if (setq containing-paren
|
|
2964 (save-restriction
|
|
2965 (narrow-to-region lim (point))
|
|
2966 (vhdl-safe (scan-lists (point) -1 1))))
|
|
2967 (setq lim containing-paren))
|
|
2968 ;; Look backwards for "begin" and "end" keywords.
|
|
2969 (while (and (> (point) lim)
|
|
2970 (not containing-sexp))
|
|
2971 (setq keyword (vhdl-backward-to-block lim))
|
|
2972 (cond
|
|
2973 ((eq keyword 'begin)
|
|
2974 ;; Found a "begin" keyword
|
|
2975 (setq sexp-start (point))
|
|
2976 (setq sexp-mid (vhdl-corresponding-mid lim))
|
|
2977 (setq sexp-end (vhdl-safe
|
|
2978 (save-excursion
|
|
2979 (vhdl-forward-sexp 1 lim) (point))))
|
|
2980 (if (and sexp-end (<= sexp-end here))
|
|
2981 ;; we want to record this sexp, but we only want to
|
|
2982 ;; record the last-most of any of them before here
|
|
2983 (or preceding-sexp
|
|
2984 (setq preceding-sexp sexp-start))
|
|
2985 ;; we're contained in this sexp so put sexp-start on
|
|
2986 ;; front of list
|
|
2987 (setq containing-sexp sexp-start)
|
|
2988 (setq containing-mid sexp-mid)
|
|
2989 (setq containing-begin t)))
|
|
2990 ((eq keyword 'end)
|
|
2991 ;; Found an "end" keyword
|
|
2992 (forward-sexp)
|
|
2993 (setq sexp-end (point))
|
|
2994 (setq sexp-mid nil)
|
|
2995 (setq sexp-start
|
|
2996 (or (vhdl-safe (vhdl-backward-sexp 1 lim) (point))
|
|
2997 (progn (backward-sexp) (point))))
|
|
2998 ;; we want to record this sexp, but we only want to
|
|
2999 ;; record the last-most of any of them before here
|
|
3000 (or preceding-sexp
|
|
3001 (setq preceding-sexp sexp-start)))
|
|
3002 )))
|
|
3003 ;; Check if the containing-paren should be the containing-sexp
|
|
3004 (if (and containing-paren
|
|
3005 (or (null containing-sexp)
|
|
3006 (< containing-sexp containing-paren)))
|
|
3007 (setq containing-sexp containing-paren
|
|
3008 preceding-sexp nil
|
|
3009 containing-begin nil
|
|
3010 containing-mid nil))
|
|
3011 (vector containing-sexp preceding-sexp containing-begin containing-mid)
|
|
3012 ))
|
|
3013
|
|
3014
|
|
3015 (defconst vhdl-s-c-a-re
|
|
3016 (concat vhdl-case-alternative-re "\\|" vhdl-case-header-key))
|
|
3017
|
|
3018 (defun vhdl-skip-case-alternative (&optional lim)
|
|
3019 ;; skip forward over case/when bodies, with optional maximal
|
|
3020 ;; limit. if no next case alternative is found, nil is returned and point
|
|
3021 ;; is not moved
|
|
3022 (let ((lim (or lim (point-max)))
|
|
3023 (here (point))
|
|
3024 donep foundp)
|
|
3025 (while (and (< (point) lim)
|
|
3026 (not donep))
|
|
3027 (if (and (re-search-forward vhdl-s-c-a-re lim 'move)
|
|
3028 (save-match-data
|
|
3029 (not (vhdl-in-literal)))
|
|
3030 (/= (match-beginning 0) here))
|
|
3031 (progn
|
|
3032 (goto-char (match-beginning 0))
|
|
3033 (cond
|
|
3034 ((and (looking-at "case")
|
|
3035 (re-search-forward "\\bis[^_]" lim t))
|
|
3036 (backward-sexp)
|
|
3037 (vhdl-forward-sexp))
|
|
3038 (t
|
|
3039 (setq donep t
|
|
3040 foundp t))))))
|
|
3041 (if (not foundp)
|
|
3042 (goto-char here))
|
|
3043 foundp))
|
|
3044
|
|
3045 (defun vhdl-backward-skip-label (&optional lim)
|
|
3046 ;; skip backward over a label, with optional maximal
|
|
3047 ;; limit. if label is not found, nil is returned and point
|
|
3048 ;; is not moved
|
|
3049 (let ((lim (or lim (point-min)))
|
|
3050 placeholder)
|
|
3051 (if (save-excursion
|
|
3052 (vhdl-backward-syntactic-ws lim)
|
|
3053 (and (eq (preceding-char) ?:)
|
|
3054 (progn
|
|
3055 (backward-sexp)
|
|
3056 (setq placeholder (point))
|
|
3057 (looking-at vhdl-label-key))))
|
|
3058 (goto-char placeholder))
|
|
3059 ))
|
|
3060
|
|
3061 (defun vhdl-forward-skip-label (&optional lim)
|
|
3062 ;; skip forward over a label, with optional maximal
|
|
3063 ;; limit. if label is not found, nil is returned and point
|
|
3064 ;; is not moved
|
|
3065 (let ((lim (or lim (point-max))))
|
|
3066 (if (looking-at vhdl-label-key)
|
|
3067 (progn
|
|
3068 (goto-char (match-end 0))
|
|
3069 (vhdl-forward-syntactic-ws lim)))
|
|
3070 ))
|
|
3071
|
|
3072 (defun vhdl-get-syntactic-context ()
|
|
3073 ;; guess the syntactic description of the current line of VHDL code.
|
|
3074 (save-excursion
|
|
3075 (save-restriction
|
|
3076 (beginning-of-line)
|
|
3077 (let* ((indent-point (point))
|
|
3078 (case-fold-search t)
|
|
3079 vec literal containing-sexp preceding-sexp
|
|
3080 containing-begin containing-mid containing-leader
|
|
3081 char-before-ip char-after-ip begin-after-ip end-after-ip
|
|
3082 placeholder lim library-unit
|
|
3083 )
|
|
3084
|
|
3085 ;; Reset the syntactic context
|
|
3086 (setq vhdl-syntactic-context nil)
|
|
3087
|
|
3088 (save-excursion
|
|
3089 ;; Move to the start of the previous library unit, and
|
|
3090 ;; record the position of the "begin" keyword.
|
|
3091 (setq placeholder (vhdl-beginning-of-libunit))
|
|
3092 ;; The position of the "libunit" keyword gives us a gross
|
|
3093 ;; limit point.
|
|
3094 (setq lim (point))
|
|
3095 )
|
|
3096
|
|
3097 ;; If there is a previous library unit, and we are enclosed by
|
|
3098 ;; it, then set the syntax accordingly.
|
|
3099 (and placeholder
|
|
3100 (setq library-unit (vhdl-get-library-unit lim placeholder))
|
|
3101 (vhdl-add-syntax library-unit lim))
|
|
3102
|
|
3103 ;; Find the surrounding state.
|
|
3104 (if (setq vec (vhdl-get-block-state lim))
|
|
3105 (progn
|
|
3106 (setq containing-sexp (aref vec 0))
|
|
3107 (setq preceding-sexp (aref vec 1))
|
|
3108 (setq containing-begin (aref vec 2))
|
|
3109 (setq containing-mid (aref vec 3))
|
|
3110 ))
|
|
3111
|
|
3112 ;; set the limit on the farthest back we need to search
|
|
3113 (setq lim (if containing-sexp
|
|
3114 (save-excursion
|
|
3115 (goto-char containing-sexp)
|
|
3116 ;; set containing-leader if required
|
|
3117 (if (looking-at vhdl-leader-re)
|
|
3118 (setq containing-leader (vhdl-end-of-leader)))
|
|
3119 (vhdl-point 'bol))
|
|
3120 (point-min)))
|
|
3121
|
|
3122 ;; cache char before and after indent point, and move point to
|
|
3123 ;; the most likely position to perform the majority of tests
|
|
3124 (goto-char indent-point)
|
|
3125 (skip-chars-forward " \t")
|
|
3126 (setq literal (vhdl-in-literal lim))
|
|
3127 (setq char-after-ip (following-char))
|
|
3128 (setq begin-after-ip (and
|
|
3129 (not literal)
|
|
3130 (looking-at vhdl-begin-fwd-re)
|
|
3131 (vhdl-begin-p)))
|
|
3132 (setq end-after-ip (and
|
|
3133 (not literal)
|
|
3134 (looking-at vhdl-end-fwd-re)
|
|
3135 (vhdl-end-p)))
|
|
3136 (vhdl-backward-syntactic-ws lim)
|
|
3137 (setq char-before-ip (preceding-char))
|
|
3138 (goto-char indent-point)
|
|
3139 (skip-chars-forward " \t")
|
|
3140
|
|
3141 ;; now figure out syntactic qualities of the current line
|
|
3142 (cond
|
|
3143 ;; CASE 1: in a string or comment.
|
|
3144 ((memq literal '(string comment))
|
|
3145 (vhdl-add-syntax literal (vhdl-point 'bopl)))
|
|
3146 ;; CASE 2: Line is at top level.
|
|
3147 ((null containing-sexp)
|
|
3148 ;; Find the point to which indentation will be relative
|
|
3149 (save-excursion
|
|
3150 (if (null preceding-sexp)
|
|
3151 ;; CASE 2X.1
|
|
3152 ;; no preceding-sexp -> use the preceding statement
|
|
3153 (vhdl-beginning-of-statement-1 lim)
|
|
3154 ;; CASE 2X.2
|
|
3155 ;; if there is a preceding-sexp then indent relative to it
|
|
3156 (goto-char preceding-sexp)
|
|
3157 ;; if not at boi, then the block-opening keyword is
|
|
3158 ;; probably following a label, so we need a different
|
|
3159 ;; relpos
|
|
3160 (if (/= (point) (vhdl-point 'boi))
|
|
3161 ;; CASE 2X.3
|
|
3162 (vhdl-beginning-of-statement-1 lim)))
|
|
3163 ;; v-b-o-s could have left us at point-min
|
|
3164 (and (bobp)
|
|
3165 ;; CASE 2X.4
|
|
3166 (vhdl-forward-syntactic-ws indent-point))
|
|
3167 (setq placeholder (point)))
|
|
3168 (cond
|
|
3169 ;; CASE 2A : we are looking at a block-open
|
|
3170 (begin-after-ip
|
|
3171 (vhdl-add-syntax 'block-open placeholder))
|
|
3172 ;; CASE 2B: we are looking at a block-close
|
|
3173 (end-after-ip
|
|
3174 (vhdl-add-syntax 'block-close placeholder))
|
|
3175 ;; CASE 2C: we are looking at a top-level statement
|
|
3176 ((progn
|
|
3177 (vhdl-backward-syntactic-ws lim)
|
|
3178 (or (bobp)
|
|
3179 (= (preceding-char) ?\;)))
|
|
3180 (vhdl-add-syntax 'statement placeholder))
|
|
3181 ;; CASE 2D: we are looking at a top-level statement-cont
|
|
3182 (t
|
|
3183 (vhdl-beginning-of-statement-1 lim)
|
|
3184 ;; v-b-o-s could have left us at point-min
|
|
3185 (and (bobp)
|
|
3186 ;; CASE 2D.1
|
|
3187 (vhdl-forward-syntactic-ws indent-point))
|
|
3188 (vhdl-add-syntax 'statement-cont (point)))
|
|
3189 )) ; end CASE 2
|
|
3190 ;; CASE 3: line is inside parentheses. Most likely we are
|
|
3191 ;; either in a subprogram argument (interface) list, or a
|
|
3192 ;; continued expression containing parentheses.
|
|
3193 ((null containing-begin)
|
|
3194 (vhdl-backward-syntactic-ws containing-sexp)
|
|
3195 (cond
|
|
3196 ;; CASE 3A: we are looking at the arglist closing paren
|
|
3197 ((eq char-after-ip ?\))
|
|
3198 (goto-char containing-sexp)
|
|
3199 (vhdl-add-syntax 'arglist-close (vhdl-point 'boi)))
|
|
3200 ;; CASE 3B: we are looking at the first argument in an empty
|
|
3201 ;; argument list.
|
|
3202 ((eq char-before-ip ?\()
|
|
3203 (goto-char containing-sexp)
|
|
3204 (vhdl-add-syntax 'arglist-intro (vhdl-point 'boi)))
|
|
3205 ;; CASE 3C: we are looking at an arglist continuation line,
|
|
3206 ;; but the preceding argument is on the same line as the
|
|
3207 ;; opening paren. This case includes multi-line
|
|
3208 ;; expression paren groupings.
|
|
3209 ((and (save-excursion
|
|
3210 (goto-char (1+ containing-sexp))
|
|
3211 (skip-chars-forward " \t")
|
|
3212 (not (eolp))
|
|
3213 (not (looking-at "--")))
|
|
3214 (save-excursion
|
|
3215 (vhdl-beginning-of-statement-1 containing-sexp)
|
|
3216 (skip-chars-backward " \t(")
|
|
3217 (<= (point) containing-sexp)))
|
|
3218 (goto-char containing-sexp)
|
|
3219 (vhdl-add-syntax 'arglist-cont-nonempty (vhdl-point 'boi)))
|
|
3220 ;; CASE 3D: we are looking at just a normal arglist
|
|
3221 ;; continuation line
|
|
3222 (t (vhdl-beginning-of-statement-1 containing-sexp)
|
|
3223 (vhdl-forward-syntactic-ws indent-point)
|
|
3224 (vhdl-add-syntax 'arglist-cont (vhdl-point 'boi)))
|
|
3225 ))
|
|
3226 ;; CASE 4: A block mid open
|
|
3227 ((and begin-after-ip
|
|
3228 (looking-at containing-mid))
|
|
3229 (goto-char containing-sexp)
|
|
3230 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
|
|
3231 (if (looking-at vhdl-trailer-re)
|
|
3232 ;; CASE 4.1
|
|
3233 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
|
|
3234 (vhdl-backward-skip-label (vhdl-point 'boi))
|
|
3235 (vhdl-add-syntax 'block-open (point)))
|
|
3236 ;; CASE 5: block close brace
|
|
3237 (end-after-ip
|
|
3238 (goto-char containing-sexp)
|
|
3239 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
|
|
3240 (if (looking-at vhdl-trailer-re)
|
|
3241 ;; CASE 5.1
|
|
3242 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
|
|
3243 (vhdl-backward-skip-label (vhdl-point 'boi))
|
|
3244 (vhdl-add-syntax 'block-close (point)))
|
|
3245 ;; CASE 6: A continued statement
|
|
3246 ((and (/= char-before-ip ?\;)
|
|
3247 ;; check it's not a trailer begin keyword, or a begin
|
|
3248 ;; keyword immediately following a label.
|
|
3249 (not (and begin-after-ip
|
|
3250 (or (looking-at vhdl-trailer-re)
|
|
3251 (save-excursion
|
|
3252 (vhdl-backward-skip-label containing-sexp)))))
|
|
3253 ;; check it's not a statement keyword
|
|
3254 (not (and (looking-at vhdl-statement-fwd-re)
|
|
3255 (vhdl-statement-p)))
|
|
3256 ;; see if the b-o-s is before the indent point
|
|
3257 (> indent-point
|
|
3258 (save-excursion
|
|
3259 (vhdl-beginning-of-statement-1 containing-sexp)
|
|
3260 ;; If we ended up after a leader, then this will
|
|
3261 ;; move us forward to the start of the first
|
|
3262 ;; statement. Note that a containing sexp here is
|
|
3263 ;; always a keyword, not a paren, so this will
|
|
3264 ;; have no effect if we hit the containing-sexp.
|
|
3265 (vhdl-forward-syntactic-ws indent-point)
|
|
3266 (setq placeholder (point))))
|
|
3267 ;; check it's not a block-intro
|
|
3268 (/= placeholder containing-sexp)
|
|
3269 ;; check it's not a case block-intro
|
|
3270 (save-excursion
|
|
3271 (goto-char placeholder)
|
|
3272 (or (not (looking-at vhdl-case-alternative-re))
|
|
3273 (> (match-end 0) indent-point))))
|
|
3274 ;; Make placeholder skip a label, but only if it puts us
|
|
3275 ;; before the indent point at the start of a line.
|
|
3276 (let ((new placeholder))
|
|
3277 (if (and (> indent-point
|
|
3278 (save-excursion
|
|
3279 (goto-char placeholder)
|
|
3280 (vhdl-forward-skip-label indent-point)
|
|
3281 (setq new (point))))
|
|
3282 (save-excursion
|
|
3283 (goto-char new)
|
|
3284 (eq new (progn (back-to-indentation) (point)))))
|
|
3285 (setq placeholder new)))
|
|
3286 (vhdl-add-syntax 'statement-cont placeholder)
|
|
3287 (if begin-after-ip
|
|
3288 (vhdl-add-syntax 'block-open)))
|
|
3289 ;; Statement. But what kind?
|
|
3290 ;; CASE 7: A case alternative key
|
|
3291 ((and (looking-at vhdl-case-alternative-re)
|
|
3292 (vhdl-case-alternative-p containing-sexp))
|
|
3293 ;; for a case alternative key, we set relpos to the first
|
|
3294 ;; non-whitespace char on the line containing the "case"
|
|
3295 ;; keyword.
|
|
3296 (goto-char containing-sexp)
|
|
3297 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
|
|
3298 (if (looking-at vhdl-trailer-re)
|
|
3299 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
|
|
3300 (vhdl-add-syntax 'case-alternative (vhdl-point 'boi)))
|
|
3301 ;; CASE 8: statement catchall
|
|
3302 (t
|
|
3303 ;; we know its a statement, but we need to find out if it is
|
|
3304 ;; the first statement in a block
|
|
3305 (if containing-leader
|
|
3306 (goto-char containing-leader)
|
|
3307 (goto-char containing-sexp)
|
|
3308 ;; Note that a containing sexp here is always a keyword,
|
|
3309 ;; not a paren, so skip over the keyword.
|
|
3310 (forward-sexp))
|
|
3311 ;; move to the start of the first statement
|
|
3312 (vhdl-forward-syntactic-ws indent-point)
|
|
3313 (setq placeholder (point))
|
|
3314 ;; we want to ignore case alternatives keys when skipping forward
|
|
3315 (let (incase-p)
|
|
3316 (while (looking-at vhdl-case-alternative-re)
|
|
3317 (setq incase-p (point))
|
|
3318 ;; we also want to skip over the body of the
|
|
3319 ;; case/when statement if that doesn't put us at
|
|
3320 ;; after the indent-point
|
|
3321 (while (vhdl-skip-case-alternative indent-point))
|
|
3322 ;; set up the match end
|
|
3323 (looking-at vhdl-case-alternative-re)
|
|
3324 (goto-char (match-end 0))
|
|
3325 ;; move to the start of the first case alternative statement
|
|
3326 (vhdl-forward-syntactic-ws indent-point)
|
|
3327 (setq placeholder (point)))
|
|
3328 (cond
|
|
3329 ;; CASE 8A: we saw a case/when statement so we must be
|
|
3330 ;; in a switch statement. find out if we are at the
|
|
3331 ;; statement just after a case alternative key
|
|
3332 ((and incase-p
|
|
3333 (= (point) indent-point))
|
|
3334 ;; relpos is the "when" keyword
|
|
3335 (vhdl-add-syntax 'statement-case-intro incase-p))
|
|
3336 ;; CASE 8B: any old statement
|
|
3337 ((< (point) indent-point)
|
|
3338 ;; relpos is the first statement of the block
|
|
3339 (vhdl-add-syntax 'statement placeholder)
|
|
3340 (if begin-after-ip
|
|
3341 (vhdl-add-syntax 'block-open)))
|
|
3342 ;; CASE 8C: first statement in a block
|
|
3343 (t
|
|
3344 (goto-char containing-sexp)
|
|
3345 ;; If the \"begin\" keyword is a trailer, then find v-b-o-s
|
|
3346 (if (looking-at vhdl-trailer-re)
|
|
3347 (progn (forward-sexp) (vhdl-beginning-of-statement-1 nil)))
|
|
3348 (vhdl-backward-skip-label (vhdl-point 'boi))
|
|
3349 (vhdl-add-syntax 'statement-block-intro (point))
|
|
3350 (if begin-after-ip
|
|
3351 (vhdl-add-syntax 'block-open)))
|
|
3352 )))
|
|
3353 )
|
|
3354
|
|
3355 ;; now we need to look at any modifiers
|
|
3356 (goto-char indent-point)
|
|
3357 (skip-chars-forward " \t")
|
|
3358 (if (looking-at "--")
|
|
3359 (vhdl-add-syntax 'comment))
|
|
3360 ;; return the syntax
|
|
3361 vhdl-syntactic-context))))
|
|
3362
|
|
3363 ;; Standard indentation line-ups:
|
|
3364
|
|
3365 (defun vhdl-lineup-arglist (langelem)
|
|
3366 ;; lineup the current arglist line with the arglist appearing just
|
|
3367 ;; after the containing paren which starts the arglist.
|
|
3368 (save-excursion
|
|
3369 (let* ((containing-sexp
|
|
3370 (save-excursion
|
|
3371 ;; arglist-cont-nonempty gives relpos ==
|
|
3372 ;; to boi of containing-sexp paren. This
|
|
3373 ;; is good when offset is +, but bad
|
|
3374 ;; when it is vhdl-lineup-arglist, so we
|
|
3375 ;; have to special case a kludge here.
|
|
3376 (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
|
|
3377 (progn
|
|
3378 (beginning-of-line)
|
|
3379 (backward-up-list 1)
|
|
3380 (skip-chars-forward " \t" (vhdl-point 'eol)))
|
|
3381 (goto-char (cdr langelem)))
|
|
3382 (point)))
|
|
3383 (cs-curcol (save-excursion
|
|
3384 (goto-char (cdr langelem))
|
|
3385 (current-column))))
|
|
3386 (if (save-excursion
|
|
3387 (beginning-of-line)
|
|
3388 (looking-at "[ \t]*)"))
|
|
3389 (progn (goto-char (match-end 0))
|
|
3390 (backward-sexp)
|
|
3391 (forward-char)
|
|
3392 (vhdl-forward-syntactic-ws)
|
|
3393 (- (current-column) cs-curcol))
|
|
3394 (goto-char containing-sexp)
|
|
3395 (or (eolp)
|
|
3396 (let ((eol (vhdl-point 'eol))
|
|
3397 (here (progn
|
|
3398 (forward-char)
|
|
3399 (skip-chars-forward " \t")
|
|
3400 (point))))
|
|
3401 (vhdl-forward-syntactic-ws)
|
|
3402 (if (< (point) eol)
|
|
3403 (goto-char here))))
|
|
3404 (- (current-column) cs-curcol)
|
|
3405 ))))
|
|
3406
|
|
3407 (defun vhdl-lineup-arglist-intro (langelem)
|
|
3408 ;; lineup an arglist-intro line to just after the open paren
|
|
3409 (save-excursion
|
|
3410 (let ((cs-curcol (save-excursion
|
|
3411 (goto-char (cdr langelem))
|
|
3412 (current-column)))
|
|
3413 (ce-curcol (save-excursion
|
|
3414 (beginning-of-line)
|
|
3415 (backward-up-list 1)
|
|
3416 (skip-chars-forward " \t" (vhdl-point 'eol))
|
|
3417 (current-column))))
|
|
3418 (- ce-curcol cs-curcol -1))))
|
|
3419
|
|
3420 (defun vhdl-lineup-comment (langelem)
|
|
3421 ;; support old behavior for comment indentation. we look at
|
|
3422 ;; vhdl-comment-only-line-offset to decide how to indent comment
|
|
3423 ;; only-lines
|
|
3424 (save-excursion
|
|
3425 (back-to-indentation)
|
|
3426 ;; at or to the right of comment-column
|
|
3427 (if (>= (current-column) comment-column)
|
|
3428 (vhdl-comment-indent)
|
|
3429 ;; otherwise, indent as specified by vhdl-comment-only-line-offset
|
|
3430 (if (not (bolp))
|
|
3431 (or (car-safe vhdl-comment-only-line-offset)
|
|
3432 vhdl-comment-only-line-offset)
|
|
3433 (or (cdr-safe vhdl-comment-only-line-offset)
|
|
3434 (car-safe vhdl-comment-only-line-offset)
|
|
3435 -1000 ;jam it against the left side
|
|
3436 )))))
|
|
3437
|
|
3438 (defun vhdl-lineup-statement-cont (langelem)
|
|
3439 ;; line up statement-cont after the assignment operator
|
|
3440 (save-excursion
|
|
3441 (let* ((relpos (cdr langelem))
|
|
3442 (assignp (save-excursion
|
|
3443 (goto-char (vhdl-point 'boi))
|
|
3444 (and (re-search-forward "\\(<\\|:\\)="
|
|
3445 (vhdl-point 'eol) t)
|
|
3446 (- (point) (vhdl-point 'boi)))))
|
|
3447 (curcol (progn
|
|
3448 (goto-char relpos)
|
|
3449 (current-column)))
|
|
3450 foundp)
|
|
3451 (while (and (not foundp)
|
|
3452 (< (point) (vhdl-point 'eol)))
|
|
3453 (re-search-forward "\\(<\\|:\\)=\\|(" (vhdl-point 'eol) 'move)
|
|
3454 (if (vhdl-in-literal (cdr langelem))
|
|
3455 (forward-char)
|
|
3456 (if (= (preceding-char) ?\()
|
|
3457 ;; skip over any parenthesized expressions
|
|
3458 (goto-char (min (vhdl-point 'eol)
|
|
3459 (scan-lists (point) 1 1)))
|
|
3460 ;; found an assignment operator (not at eol)
|
|
3461 (setq foundp (not (looking-at "\\s-*$"))))))
|
|
3462 (if (not foundp)
|
|
3463 ;; there's no assignment operator on the line
|
|
3464 vhdl-basic-offset
|
|
3465 ;; calculate indentation column after assign and ws, unless
|
|
3466 ;; our line contains an assignment operator
|
|
3467 (if (not assignp)
|
|
3468 (progn
|
|
3469 (forward-char)
|
|
3470 (skip-chars-forward " \t")
|
|
3471 (setq assignp 0)))
|
|
3472 (- (current-column) assignp curcol))
|
|
3473 )))
|
|
3474
|
|
3475 ;; ############################################################################
|
|
3476 ;; Indentation commands
|
|
3477
|
|
3478 (defun vhdl-tab (&optional pre-arg)
|
|
3479 "If preceeding character is part of a word then dabbrev-expand,
|
|
3480 else if right of non whitespace on line then tab-to-tab-stop,
|
|
3481 else if last command was a tab or return then dedent one step,
|
|
3482 else indent `correctly'."
|
|
3483 (interactive "*P")
|
|
3484 (cond ((= (char-syntax (preceding-char)) ?w)
|
|
3485 (let ((case-fold-search nil)) (dabbrev-expand pre-arg)))
|
|
3486 ((> (current-column) (current-indentation))
|
|
3487 (tab-to-tab-stop))
|
|
3488 ((and (or (eq last-command 'vhdl-tab)
|
|
3489 (eq last-command 'vhdl-return))
|
|
3490 (/= 0 (current-indentation)))
|
|
3491 (backward-delete-char-untabify vhdl-basic-offset nil))
|
|
3492 ((vhdl-indent-line))
|
|
3493 )
|
|
3494 (setq this-command 'vhdl-tab)
|
|
3495 )
|
|
3496
|
|
3497 (defun vhdl-untab ()
|
|
3498 "Delete backwards to previous tab stop."
|
|
3499 (interactive)
|
|
3500 (backward-delete-char-untabify vhdl-basic-offset nil)
|
|
3501 )
|
|
3502
|
|
3503 (defun vhdl-return ()
|
|
3504 "newline-and-indent or indent-new-comment-line if in comment and preceding
|
|
3505 character is a space."
|
|
3506 (interactive)
|
|
3507 (if (and (= (preceding-char) ? ) (vhdl-in-comment-p))
|
|
3508 (indent-new-comment-line)
|
|
3509 (newline-and-indent)
|
|
3510 )
|
|
3511 )
|
|
3512
|
|
3513 (defun vhdl-indent-line ()
|
|
3514 "Indent the current line as VHDL code. Returns the amount of
|
|
3515 indentation change."
|
|
3516 (interactive)
|
|
3517 (let* ((syntax (vhdl-get-syntactic-context))
|
|
3518 (pos (- (point-max) (point)))
|
|
3519 (indent (apply '+ (mapcar 'vhdl-get-offset syntax)))
|
|
3520 (shift-amt (- (current-indentation) indent)))
|
|
3521 (and vhdl-echo-syntactic-information-p
|
|
3522 (message "syntax: %s, indent= %d" syntax indent))
|
|
3523 (if (zerop shift-amt)
|
|
3524 nil
|
|
3525 (delete-region (vhdl-point 'bol) (vhdl-point 'boi))
|
|
3526 (beginning-of-line)
|
|
3527 (indent-to indent))
|
|
3528 (if (< (point) (vhdl-point 'boi))
|
|
3529 (back-to-indentation)
|
|
3530 ;; If initial point was within line's indentation, position after
|
|
3531 ;; the indentation. Else stay at same point in text.
|
|
3532 (if (> (- (point-max) pos) (point))
|
|
3533 (goto-char (- (point-max) pos)))
|
|
3534 )
|
|
3535 (run-hooks 'vhdl-special-indent-hook)
|
|
3536 shift-amt))
|
|
3537
|
|
3538 (defun vhdl-indent-buffer ()
|
|
3539 "Indent whole buffer as VHDL code."
|
|
3540 (interactive)
|
|
3541 (indent-region (point-min) (point-max) nil)
|
|
3542 )
|
|
3543
|
|
3544 (defun vhdl-indent-sexp (&optional endpos)
|
|
3545 "Indent each line of the list starting just after point.
|
|
3546 If optional arg ENDPOS is given, indent each line, stopping when
|
|
3547 ENDPOS is encountered."
|
|
3548 (interactive)
|
|
3549 (save-excursion
|
|
3550 (let ((beg (point))
|
|
3551 (end (progn
|
|
3552 (vhdl-forward-sexp nil endpos)
|
|
3553 (point))))
|
|
3554 (indent-region beg end nil))))
|
|
3555
|
|
3556 ;; ############################################################################
|
|
3557 ;; Miscellaneous commands
|
|
3558
|
|
3559 (defun vhdl-show-syntactic-information ()
|
|
3560 "Show syntactic information for current line."
|
|
3561 (interactive)
|
|
3562 (message "syntactic analysis: %s" (vhdl-get-syntactic-context))
|
|
3563 (vhdl-keep-region-active))
|
|
3564
|
|
3565 ;; Verification and regression functions:
|
|
3566
|
|
3567 (defun vhdl-regress-line (&optional arg)
|
|
3568 "Check syntactic information for current line."
|
|
3569 (interactive "P")
|
|
3570 (let ((expected (save-excursion
|
|
3571 (end-of-line)
|
|
3572 (if (search-backward " -- ((" (vhdl-point 'bol) t)
|
|
3573 (progn
|
|
3574 (forward-char 4)
|
|
3575 (read (current-buffer))))))
|
|
3576 (actual (vhdl-get-syntactic-context))
|
|
3577 (expurgated))
|
|
3578 ;; remove the library unit symbols
|
|
3579 (mapcar
|
|
3580 (function
|
|
3581 (lambda (elt)
|
|
3582 (if (memq (car elt) '(entity configuration package
|
|
3583 package-body architecture))
|
|
3584 nil
|
|
3585 (setq expurgated (append expurgated (list elt))))))
|
|
3586 actual)
|
|
3587 (if (and (not arg) expected (listp expected))
|
|
3588 (if (not (equal expected expurgated))
|
|
3589 (error "Should be: %s, is: %s" expected expurgated))
|
|
3590 (save-excursion
|
|
3591 (beginning-of-line)
|
|
3592 (if (not (looking-at "^\\s-*\\(--.*\\)?$"))
|
|
3593 (progn
|
|
3594 (end-of-line)
|
|
3595 (if (search-backward " -- ((" (vhdl-point 'bol) t)
|
|
3596 (kill-line))
|
|
3597 (insert " -- ")
|
|
3598 (insert (format "%s" expurgated)))))))
|
|
3599 (vhdl-keep-region-active))
|
|
3600
|
|
3601
|
|
3602 ;; ############################################################################
|
|
3603 ;; Alignment
|
|
3604 ;; ############################################################################
|
|
3605
|
|
3606 (defvar vhdl-align-alist
|
|
3607 '(
|
|
3608 ;; after some keywords
|
|
3609 (vhdl-mode "\\<\\(alias\\|constant\\|signal\\|subtype\\|type\\|variable\\)[ \t]"
|
|
3610 "\\<\\(alias\\|constant\\|signal\\|subtype\\|type\\|variable\\)\\([ \t]+\\)" 2)
|
|
3611 ;; before ':'
|
|
3612 (vhdl-mode ":[^=]" "[^ \t]\\([ \t]*\\):[^=]")
|
|
3613 ;; after ':'
|
|
3614 (vhdl-mode ":[^=]" ":\\([ \t]*\\)[^=]" 1)
|
|
3615 ;; after direction specifications
|
|
3616 (vhdl-mode ":[ \t]*\\(in\\|out\\|inout\\|buffer\\)\\>"
|
|
3617 ":[ \t]*\\(in\\|out\\|inout\\|buffer\\)\\([ \t]+\\)" 2)
|
|
3618 ;; before "<=", "=>", and ":="
|
|
3619 (vhdl-mode "<=" "[^ \t]\\([ \t]*\\)<=" 1)
|
|
3620 (vhdl-mode "=>" "[^ \t]\\([ \t]*\\)=>" 1)
|
|
3621 (vhdl-mode ":=" "[^ \t]\\([ \t]*\\):=" 1)
|
|
3622 ;; after "<=", "=>", and ":="
|
|
3623 (vhdl-mode "<=" "<=\\([ \t]*\\)" 1)
|
|
3624 (vhdl-mode "=>" "=>\\([ \t]*\\)" 1)
|
|
3625 (vhdl-mode ":=" ":=\\([ \t]*\\)" 1)
|
|
3626 ;; before some keywords
|
|
3627 (vhdl-mode "[ \t]after\\>" "[^ \t]\\([ \t]+\\)after\\>" 1)
|
|
3628 (vhdl-mode "[ \t]\\(fs\\|ps\\|ns\\|us\\|ms\\|sec\\|min\\|hr\\)\\>"
|
|
3629 "[^ \t]\\([ \t]+\\)\\(fs\\|ps\\|ns\\|us\\|ms\\|sec\\|min\\|hr\\)\\>" 1)
|
|
3630 (vhdl-mode "[ \t]when\\>" "[^ \t]\\([ \t]+\\)when\\>" 1)
|
|
3631 (vhdl-mode "[ \t]else\\>" "[^ \t]\\([ \t]+\\)else\\>" 1)
|
|
3632 (vhdl-mode "[ \t]is\\>" "[^ \t]\\([ \t]+\\)is\\>" 1)
|
|
3633 (vhdl-mode "[ \t]of\\>" "[^ \t]\\([ \t]+\\)of\\>" 1)
|
|
3634 (vhdl-mode "[ \t]use\\>" "[^ \t]\\([ \t]+\\)use\\>" 1)
|
|
3635 ;; before comments (two steps required for correct insertion of two spaces)
|
|
3636 (vhdl-mode "--" "[^ \t]\\([ \t]*\\)--" 1)
|
|
3637 (vhdl-mode "--" "[^ \t][ \t]\\([ \t]*\\)--" 1)
|
|
3638 )
|
|
3639 "The format of this alist is
|
|
3640 (MODES [or MODE] REGEXP ALIGN-PATTERN SUBEXP).
|
|
3641 It is searched in order. If REGEXP is found anywhere in the first
|
|
3642 line of a region to be aligned, ALIGN-PATTERN will be used for that
|
|
3643 region. ALIGN-PATTERN must include the whitespace to be expanded or
|
|
3644 contracted. It may also provide regexps for the text surrounding the
|
|
3645 whitespace. SUBEXP specifies which sub-expression of
|
|
3646 ALIGN-PATTERN matches the white space to be expanded/contracted.")
|
|
3647
|
|
3648 (defvar vhdl-align-try-all-clauses t
|
|
3649 "If REGEXP is not found on the first line of the region that clause
|
|
3650 is ignored. If this variable is non-nil, then the clause is tried anyway.")
|
|
3651
|
|
3652 (defun vhdl-align (begin end spacing &optional alignment-list quick)
|
|
3653 "Attempt to align a range of lines based on the content of the
|
|
3654 lines. The definition of 'alignment-list' determines the matching
|
|
3655 order and the manner in which the lines are aligned. If ALIGNMENT-LIST
|
|
3656 is not specified 'vhdl-align-alist' is used. If QUICK is non-nil, no
|
|
3657 indentation is done before aligning."
|
|
3658 (interactive "r\np")
|
|
3659 (if (not alignment-list)
|
|
3660 (setq alignment-list vhdl-align-alist))
|
|
3661 (if (not spacing)
|
|
3662 (setq spacing 1))
|
|
3663 (save-excursion
|
|
3664 (let (bol indent)
|
|
3665 (goto-char end)
|
|
3666 (setq end (point-marker))
|
|
3667 (goto-char begin)
|
|
3668 (setq bol
|
|
3669 (setq begin (progn (beginning-of-line) (point))))
|
|
3670 (untabify bol end)
|
|
3671 (if quick
|
|
3672 nil
|
|
3673 (indent-region bol end nil))))
|
|
3674 (let ((copy (copy-alist alignment-list)))
|
|
3675 (while copy
|
|
3676 (save-excursion
|
|
3677 (goto-char begin)
|
|
3678 (let (element
|
|
3679 (eol (save-excursion (progn (end-of-line) (point)))))
|
|
3680 (setq element (nth 0 copy))
|
|
3681 (if (and (or (and (listp (car element))
|
|
3682 (memq major-mode (car element)))
|
|
3683 (eq major-mode (car element)))
|
|
3684 (or vhdl-align-try-all-clauses
|
|
3685 (re-search-forward (car (cdr element)) eol t)))
|
|
3686 (progn
|
|
3687 (vhdl-align-region begin end (car (cdr (cdr element)))
|
|
3688 (car (cdr (cdr (cdr element)))) spacing)))
|
|
3689 (setq copy (cdr copy)))))))
|
|
3690
|
|
3691 (defun vhdl-align-region (begin end match &optional substr spacing)
|
|
3692 "Align a range of lines from BEGIN to END. The regular expression
|
|
3693 MATCH must match exactly one fields: the whitespace to be
|
|
3694 contracted/expanded. The alignment column will equal the
|
|
3695 rightmost column of the widest whitespace block. SPACING is
|
|
3696 the amount of extra spaces to add to the calculated maximum required.
|
|
3697 SPACING defaults to 1 so that at least one space is inserted after
|
|
3698 the token in MATCH."
|
|
3699 (if (not spacing)
|
|
3700 (setq spacing 1))
|
|
3701 (if (not substr)
|
|
3702 (setq substr 1))
|
|
3703 (save-excursion
|
|
3704 (let (distance (max 0) (lines 0) bol eol width)
|
|
3705 ;; Determine the greatest whitespace distance to the alignment
|
|
3706 ;; character
|
|
3707 (goto-char begin)
|
|
3708 (setq eol (progn (end-of-line) (point))
|
|
3709 bol (setq begin (progn (beginning-of-line) (point))))
|
|
3710 (while (< bol end)
|
|
3711 (save-excursion
|
|
3712 (if (re-search-forward match eol t)
|
|
3713 (progn
|
|
3714 (setq distance (- (match-beginning substr) bol))
|
|
3715 (if (> distance max)
|
|
3716 (setq max distance)))))
|
|
3717 (forward-line)
|
|
3718 (setq bol (point)
|
|
3719 eol (save-excursion
|
|
3720 (end-of-line)
|
|
3721 (point)))
|
|
3722 (setq lines (1+ lines)))
|
|
3723 ;; Now insert enough maxs to push each assignment operator to
|
|
3724 ;; the same column. We need to use 'lines' as a counter, since
|
|
3725 ;; the location of the mark may change
|
|
3726 (goto-char (setq bol begin))
|
|
3727 (setq eol (save-excursion
|
|
3728 (end-of-line)
|
|
3729 (point)))
|
|
3730 (while (> lines 0)
|
|
3731 (if (re-search-forward match eol t)
|
|
3732 (progn
|
|
3733 (setq width (- (match-end substr) (match-beginning substr)))
|
|
3734 (setq distance (- (match-beginning substr) bol))
|
|
3735 (goto-char (match-beginning substr))
|
|
3736 (delete-char width)
|
|
3737 (insert-char ? (+ (- max distance) spacing))))
|
|
3738 (beginning-of-line)
|
|
3739 (forward-line)
|
|
3740 (setq bol (point)
|
|
3741 eol (save-excursion
|
|
3742 (end-of-line)
|
|
3743 (point)))
|
|
3744 (setq lines (1- lines))
|
|
3745 ))))
|
|
3746
|
|
3747 (defun vhdl-align-comment-region (begin end spacing)
|
|
3748 "Aligns inline comments within a region relative to first comment."
|
|
3749 (interactive "r\nP")
|
|
3750 (vhdl-align begin end (or spacing 2)
|
|
3751 `((vhdl-mode "--" "[^ \t]\\([ \t]*\\)--" 1)) t))
|
|
3752
|
|
3753 (defun vhdl-align-noindent-region (begin end spacing)
|
|
3754 "Align without indentation."
|
|
3755 (interactive "r\nP")
|
|
3756 (vhdl-align begin end spacing nil t)
|
|
3757 )
|
|
3758
|
|
3759
|
|
3760 ;; ############################################################################
|
|
3761 ;; VHDL electrification
|
|
3762 ;; ############################################################################
|
|
3763
|
|
3764 ;; ############################################################################
|
|
3765 ;; Stuttering
|
|
3766
|
|
3767 (defun vhdl-stutter-mode-caps (count)
|
|
3768 "Double first letters of a word replaced by a single capital of the letter."
|
|
3769 (interactive "p")
|
|
3770 (if vhdl-stutter-mode
|
|
3771 (if (and
|
|
3772 (= (preceding-char) last-input-char) ; doubled
|
|
3773 (or (= (point) 2) ; beginning of buffer
|
|
3774 (/= (char-syntax (char-after (- (point) 2))) ?w) ;not mid-word
|
|
3775 (< (char-after (- (point) 2)) ?A))) ;alfa-numeric
|
|
3776 (progn (delete-char -1) (insert-char (- last-input-char 32) count))
|
|
3777 (self-insert-command count))
|
|
3778 (self-insert-command count)
|
|
3779 ))
|
|
3780
|
|
3781 (defun vhdl-stutter-mode-close-bracket (count) " ']' --> ')', ')]' --> ']'"
|
|
3782 (interactive "p")
|
|
3783 (if (and vhdl-stutter-mode (= count 1))
|
|
3784 (progn
|
|
3785 (if (= (preceding-char) 41) ; close-paren
|
|
3786 (progn (delete-char -1) (insert-char 93 1)) ; close-bracket
|
|
3787 (insert-char 41 1) ; close-paren
|
|
3788 )
|
|
3789 (blink-matching-open))
|
|
3790 (self-insert-command count)
|
|
3791 ))
|
|
3792
|
|
3793 (defun vhdl-stutter-mode-semicolon (count) " ';;' --> ' : ', ': ;' --> ' := '"
|
|
3794 (interactive "p")
|
|
3795 (if (and vhdl-stutter-mode (= count 1))
|
|
3796 (progn
|
|
3797 (cond ((= (preceding-char) last-input-char)
|
|
3798 (progn (delete-char -1)
|
|
3799 (if (not (eq (preceding-char) ? )) (insert " "))
|
|
3800 (insert ": ")))
|
|
3801 ((and
|
|
3802 (eq last-command 'vhdl-stutter-mode-colon) (= (preceding-char) ? ))
|
|
3803 (progn (delete-char -1) (insert "= ")))
|
|
3804 (t
|
|
3805 (insert-char 59 1)) ; semi-colon
|
|
3806 )
|
|
3807 (setq this-command 'vhdl-stutter-mode-colon))
|
|
3808 (self-insert-command count)
|
|
3809 ))
|
|
3810
|
|
3811 (defun vhdl-stutter-mode-open-bracket (count) " '[' --> '(', '([' --> '['"
|
|
3812 (interactive "p")
|
|
3813 (if (and vhdl-stutter-mode (= count 1))
|
|
3814 (if (= (preceding-char) 40) ; open-paren
|
|
3815 (progn (delete-char -1) (insert-char 91 1)) ; open-bracket
|
|
3816 (insert-char 40 1)) ; open-paren
|
|
3817 (self-insert-command count)
|
|
3818 ))
|
|
3819
|
|
3820 (defun vhdl-stutter-mode-quote (count) " '' --> \""
|
|
3821 (interactive "p")
|
|
3822 (if (and vhdl-stutter-mode (= count 1))
|
|
3823 (if (= (preceding-char) last-input-char)
|
|
3824 (progn (delete-backward-char 1) (insert-char 34 1)) ; double-quote
|
|
3825 (insert-char 39 1)) ; single-quote
|
|
3826 (self-insert-command count)
|
|
3827 ))
|
|
3828
|
|
3829 (defun vhdl-stutter-mode-comma (count) " ',,' --> ' <= '"
|
|
3830 (interactive "p")
|
|
3831 (if (and vhdl-stutter-mode (= count 1))
|
|
3832 (cond ((= (preceding-char) last-input-char)
|
|
3833 (progn (delete-char -1)
|
|
3834 (if (not (eq (preceding-char) ? )) (insert " "))
|
|
3835 (insert "<= ")))
|
|
3836 (t
|
|
3837 (insert-char 44 1))) ; comma
|
|
3838 (self-insert-command count)
|
|
3839 ))
|
|
3840
|
|
3841 (defun vhdl-stutter-mode-period (count) " '..' --> ' => '"
|
|
3842 (interactive "p")
|
|
3843 (if (and vhdl-stutter-mode (= count 1))
|
|
3844 (cond ((= (preceding-char) last-input-char)
|
|
3845 (progn (delete-char -1)
|
|
3846 (if (not (eq (preceding-char) ? )) (insert " "))
|
|
3847 (insert "=> ")))
|
|
3848 (t
|
|
3849 (insert-char 46 1))) ; period
|
|
3850 (self-insert-command count)
|
|
3851 ))
|
|
3852
|
|
3853 (defun vhdl-paired-parens ()
|
|
3854 "Insert a pair of round parentheses, placing point between them."
|
|
3855 (interactive)
|
|
3856 (insert "()")
|
|
3857 (backward-char)
|
|
3858 )
|
|
3859
|
|
3860 (defun vhdl-stutter-mode-dash (count)
|
|
3861 "-- starts a comment, --- draws a horizontal line,
|
|
3862 ---- starts a display comment"
|
|
3863 (interactive "p")
|
|
3864 (if vhdl-stutter-mode
|
|
3865 (cond ((and abbrev-start-location (= abbrev-start-location (point)))
|
|
3866 (setq abbrev-start-location nil)
|
|
3867 (goto-char last-abbrev-location)
|
|
3868 (beginning-of-line nil)
|
|
3869 (vhdl-display-comment))
|
|
3870 ((/= (preceding-char) ?-) ; standard dash (minus)
|
|
3871 (self-insert-command count))
|
|
3872 (t
|
|
3873 (self-insert-command count)
|
|
3874 (message "Enter - for horiz. line, CR for commenting-out code, else 1st char of comment")
|
|
3875 (let ((next-input (read-char)))
|
|
3876 (if (= next-input ?-) ; triple dash
|
|
3877 (progn
|
|
3878 (vhdl-display-comment-line)
|
|
3879 (message
|
|
3880 "Enter - for display comment, else continue with coding")
|
|
3881 (let ((next-input (read-char)))
|
|
3882 (if (= next-input ?-) ; four dashes
|
|
3883 (vhdl-display-comment t)
|
|
3884 (setq unread-command-events ;pushback the char
|
|
3885 (list
|
|
3886 (vhdl-character-to-event-hack next-input)))
|
|
3887 )))
|
|
3888 (setq unread-command-events ;pushback the char
|
|
3889 (list (vhdl-character-to-event-hack next-input)))
|
|
3890 (vhdl-inline-comment)
|
|
3891 ))))
|
|
3892 (self-insert-command count)
|
|
3893 ))
|
|
3894
|
|
3895 ;; ############################################################################
|
|
3896 ;; VHDL templates
|
|
3897
|
|
3898 (defun vhdl-alias ()
|
|
3899 "Insert alias declaration."
|
|
3900 (interactive)
|
|
3901 (vhdl-insert-keyword "ALIAS ")
|
|
3902 (if (equal (vhdl-field "name") "")
|
|
3903 nil
|
|
3904 (insert " : ")
|
|
3905 (vhdl-field "type")
|
|
3906 (vhdl-insert-keyword " IS ")
|
|
3907 (vhdl-field "name" ";")
|
|
3908 (vhdl-declaration-comment)
|
|
3909 ))
|
|
3910
|
|
3911 (defun vhdl-architecture ()
|
|
3912 "Insert architecture template."
|
|
3913 (interactive)
|
|
3914 (let ((margin (current-column))
|
|
3915 (vhdl-architecture-name)
|
|
3916 (position)
|
|
3917 (entity-exists)
|
|
3918 (string)
|
|
3919 (case-fold-search t))
|
|
3920 (vhdl-insert-keyword "ARCHITECTURE ")
|
|
3921 (if (equal (setq vhdl-architecture-name (vhdl-field "name")) "")
|
|
3922 nil
|
|
3923 (vhdl-insert-keyword " OF ")
|
|
3924 (setq position (point))
|
|
3925 (setq entity-exists
|
|
3926 (re-search-backward "entity \\(\\(\\w\\|\\s_\\)+\\) is" nil t))
|
|
3927 (setq string (match-string 1))
|
|
3928 (goto-char position)
|
|
3929 (if (and entity-exists (not (equal string "")))
|
|
3930 (insert string)
|
|
3931 (vhdl-field "entity name"))
|
|
3932 (vhdl-insert-keyword " IS")
|
|
3933 (vhdl-begin-end (cons vhdl-architecture-name margin))
|
|
3934 (vhdl-block-comment)
|
|
3935 )))
|
|
3936
|
|
3937
|
|
3938 (defun vhdl-array ()
|
|
3939 "Insert array type definition."
|
|
3940 (interactive)
|
|
3941 (vhdl-insert-keyword "ARRAY (")
|
|
3942 (if (equal (vhdl-field "range") "")
|
|
3943 (delete-char -1)
|
|
3944 (vhdl-insert-keyword ") OF ")
|
|
3945 (vhdl-field "type")
|
|
3946 (vhdl-insert-keyword ";")
|
|
3947 ))
|
|
3948
|
|
3949 (defun vhdl-assert ()
|
|
3950 "Inserts a assertion statement."
|
|
3951 (interactive)
|
|
3952 (vhdl-insert-keyword "ASSERT ")
|
|
3953 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
3954 (if (equal (vhdl-field "condition (negated)") "")
|
|
3955 (progn (undo 0) (insert " "))
|
|
3956 (if vhdl-conditions-in-parenthesis (insert ")"))
|
|
3957 (vhdl-insert-keyword " REPORT \"")
|
|
3958 (vhdl-field "string-expression" "\" ")
|
|
3959 (vhdl-insert-keyword "SEVERITY ")
|
|
3960 (if (equal (vhdl-field "[note | warning | error | failure]") "")
|
|
3961 (delete-char -10))
|
|
3962 (insert ";")
|
|
3963 ))
|
|
3964
|
|
3965 (defun vhdl-attribute ()
|
|
3966 "Inserts an attribute declaration or specification."
|
|
3967 (interactive)
|
|
3968 (vhdl-insert-keyword "ATTRIBUTE ")
|
|
3969 (if (y-or-n-p "declaration (or specification)? ")
|
|
3970 (progn
|
|
3971 (vhdl-field "name" " : ")
|
|
3972 (vhdl-field "type" ";")
|
|
3973 (vhdl-declaration-comment))
|
|
3974 (vhdl-field "name")
|
|
3975 (vhdl-insert-keyword " OF ")
|
|
3976 (vhdl-field "entity name" " : ")
|
|
3977 (vhdl-field "entity class")
|
|
3978 (vhdl-insert-keyword " IS ")
|
|
3979 (vhdl-field "expression" ";")
|
|
3980 ))
|
|
3981
|
|
3982 (defun vhdl-block ()
|
|
3983 "Insert a block template."
|
|
3984 (interactive)
|
|
3985 (let ((position (point)))
|
|
3986 (vhdl-insert-keyword " : BLOCK ")
|
|
3987 (goto-char position))
|
|
3988 (let* ((margin (current-column))
|
|
3989 (name (vhdl-field "label")))
|
|
3990 (if (equal name "")
|
|
3991 (progn (undo 0) (insert " "))
|
|
3992 (end-of-line)
|
|
3993 (insert "(")
|
|
3994 (if (equal (vhdl-field "[guard expression]") "")
|
|
3995 (delete-char -2)
|
|
3996 (insert ")"))
|
|
3997 (vhdl-begin-end (cons (concat (vhdl-case-keyword "BLOCK ") name) margin))
|
|
3998 (vhdl-block-comment)
|
|
3999 )))
|
|
4000
|
|
4001 (defun vhdl-block-configuration ()
|
|
4002 "Insert a block configuration statement."
|
|
4003 (interactive)
|
|
4004 (let ((margin (current-column)))
|
|
4005 (vhdl-insert-keyword "FOR ")
|
|
4006 (if (equal (setq name (vhdl-field "block specification")) "")
|
|
4007 nil
|
|
4008 (vhdl-insert-keyword "\n\n")
|
|
4009 (indent-to margin)
|
|
4010 (vhdl-insert-keyword "END FOR;")
|
|
4011 (end-of-line 0)
|
|
4012 (indent-to (+ margin vhdl-basic-offset))
|
|
4013 )))
|
|
4014
|
|
4015 (defun vhdl-case ()
|
|
4016 "Inserts a case statement."
|
|
4017 (interactive)
|
|
4018 (let ((margin (current-column))
|
|
4019 (name))
|
|
4020 (vhdl-insert-keyword "CASE ")
|
|
4021 (if (equal (setq name (vhdl-field "expression")) "")
|
|
4022 nil
|
|
4023 (vhdl-insert-keyword " IS\n\n")
|
|
4024 (indent-to margin)
|
|
4025 (vhdl-insert-keyword "END CASE;")
|
|
4026 ; (if vhdl-self-insert-comments (insert " -- " name))
|
|
4027 (forward-line -1)
|
|
4028 (indent-to (+ margin vhdl-basic-offset))
|
|
4029 (vhdl-insert-keyword "WHEN => ")
|
|
4030 (backward-char 4)
|
|
4031 )))
|
|
4032
|
|
4033 (defun vhdl-component ()
|
|
4034 "Inserts a component declaration."
|
|
4035 (interactive)
|
|
4036 (let ((margin (current-column)))
|
|
4037 (vhdl-insert-keyword "COMPONENT ")
|
|
4038 (if (equal (vhdl-field "name") "")
|
|
4039 nil
|
|
4040 (insert "\n\n")
|
|
4041 (indent-to margin)
|
|
4042 (vhdl-insert-keyword "END COMPONENT;")
|
|
4043 (end-of-line -0)
|
|
4044 (indent-to (+ margin vhdl-basic-offset))
|
|
4045 (vhdl-insert-keyword "GENERIC (")
|
|
4046 (vhdl-get-generic t t)
|
|
4047 (insert "\n")
|
|
4048 (indent-to (+ margin vhdl-basic-offset))
|
|
4049 (vhdl-insert-keyword "PORT (")
|
|
4050 (vhdl-get-port t t)
|
|
4051 (forward-line 1))
|
|
4052 ))
|
|
4053
|
|
4054 (defun vhdl-component-configuration ()
|
|
4055 "Inserts a component configuration (uses `vhdl-configuration-spec' since
|
|
4056 these are almost equivalent)."
|
|
4057 (interactive)
|
|
4058 (let ((margin (current-column)))
|
|
4059 (vhdl-configuration-spec)
|
|
4060 (insert "\n")
|
|
4061 (indent-to margin)
|
|
4062 (vhdl-insert-keyword "END FOR;")
|
|
4063 ))
|
|
4064
|
|
4065 (defun vhdl-component-instance ()
|
|
4066 "Inserts a component instantiation statement."
|
|
4067 (interactive)
|
|
4068 (let ((margin (current-column)))
|
|
4069 (if (equal (vhdl-field "instance label") "")
|
|
4070 nil
|
|
4071 (insert " : ")
|
|
4072 (vhdl-field "component name" "\n")
|
|
4073 (indent-to (+ margin vhdl-basic-offset))
|
|
4074 (let ((position (point)))
|
|
4075 (vhdl-insert-keyword "GENERIC MAP (")
|
|
4076 (if (equal (vhdl-field "[association list]") "")
|
|
4077 (progn (goto-char position)
|
|
4078 (kill-line))
|
|
4079 (insert ")\n")
|
|
4080 (indent-to (+ margin vhdl-basic-offset))))
|
|
4081 (vhdl-insert-keyword "PORT MAP (")
|
|
4082 (vhdl-field "association list" ");")
|
|
4083 )))
|
|
4084
|
|
4085 (defun vhdl-concurrent-signal-assignment ()
|
|
4086 "Inserts a concurrent signal assignment."
|
|
4087 (interactive)
|
|
4088 (if (equal (vhdl-field "target signal") "")
|
|
4089 nil
|
|
4090 (insert " <= ")
|
|
4091 ; (if (not (equal (vhdl-field "[GUARDED] [TRANSPORT]") ""))
|
|
4092 ; (insert " "))
|
|
4093 (let ((margin (current-column))
|
|
4094 (start (point)))
|
|
4095 (vhdl-field "waveform")
|
|
4096 (vhdl-insert-keyword " WHEN ")
|
|
4097 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
4098 (while (not (equal (vhdl-field "[condition]") ""))
|
|
4099 (if vhdl-conditions-in-parenthesis (insert ")"))
|
|
4100 (vhdl-insert-keyword " ELSE")
|
|
4101 (insert "\n")
|
|
4102 (indent-to margin)
|
|
4103 (vhdl-field "waveform")
|
|
4104 (vhdl-insert-keyword " WHEN ")
|
|
4105 (if vhdl-conditions-in-parenthesis (insert "(")))
|
|
4106 (delete-char -6)
|
|
4107 (if vhdl-conditions-in-parenthesis (delete-char -1))
|
|
4108 (insert ";")
|
|
4109 (if vhdl-auto-align (vhdl-align start (point) 1))
|
|
4110 )))
|
|
4111
|
|
4112 (defun vhdl-configuration ()
|
|
4113 "Inserts a configuration specification if within an architecture,
|
|
4114 a block or component configuration if within a configuration declaration,
|
|
4115 a configuration declaration if not within a design unit."
|
|
4116 (interactive)
|
|
4117 (cond ((equal (car (car (cdr (vhdl-get-syntactic-context)))) 'architecture)
|
|
4118 (vhdl-configuration-spec))
|
|
4119 ((equal (car (car (cdr (vhdl-get-syntactic-context)))) 'configuration)
|
|
4120 (if (y-or-n-p "block configuration (or component configuration)? ")
|
|
4121 (vhdl-block-configuration)
|
|
4122 (vhdl-component-configuration)))
|
|
4123 (t (vhdl-configuration-decl)))
|
|
4124 )
|
|
4125
|
|
4126 (defun vhdl-configuration-spec ()
|
|
4127 "Inserts a configuration specification."
|
|
4128 (interactive)
|
|
4129 (let ((margin (current-column)))
|
|
4130 (vhdl-insert-keyword "FOR ")
|
|
4131 (if (equal (vhdl-field "(component names | ALL)" " : ") "")
|
|
4132 (progn (undo 0) (insert " "))
|
|
4133 (vhdl-field "component type" "\n")
|
|
4134 (indent-to (+ margin vhdl-basic-offset))
|
|
4135 (vhdl-insert-keyword "USE ENTITY ")
|
|
4136 (vhdl-field "library name" ".")
|
|
4137 (vhdl-field "entity name" "(")
|
|
4138 (if (equal (vhdl-field "[architecture name]") "")
|
|
4139 (delete-char -1)
|
|
4140 (insert ")"))
|
|
4141 (insert "\n")
|
|
4142 (indent-to (+ margin vhdl-basic-offset))
|
|
4143 (vhdl-insert-keyword "GENERIC MAP (")
|
|
4144 (if (equal (vhdl-field "[association list]") "")
|
|
4145 (progn (kill-line -0)
|
|
4146 (indent-to (+ margin vhdl-basic-offset)))
|
|
4147 (insert ")\n")
|
|
4148 (indent-to (+ margin vhdl-basic-offset)))
|
|
4149 (vhdl-insert-keyword "PORT MAP (")
|
|
4150 (if (equal (vhdl-field "[association list]") "")
|
|
4151 (progn (kill-line -0)
|
|
4152 (delete-char -1))
|
|
4153 (insert ")"))
|
|
4154 (insert ";")
|
|
4155 )))
|
|
4156
|
|
4157 (defun vhdl-configuration-decl ()
|
|
4158 "Inserts a configuration declaration."
|
|
4159 (interactive)
|
|
4160 (let ((margin (current-column))
|
|
4161 (position)
|
|
4162 (entity-exists)
|
|
4163 (string)
|
|
4164 (name))
|
|
4165 (vhdl-insert-keyword "CONFIGURATION ")
|
|
4166 (if (equal (setq name (vhdl-field "name")) "")
|
|
4167 nil
|
|
4168 (vhdl-insert-keyword " OF ")
|
|
4169 (setq position (point))
|
|
4170 (setq entity-exists
|
|
4171 (re-search-backward "entity \\(\\(\\w\\|\\s_\\)*\\) is" nil t))
|
|
4172 (setq string (match-string 1))
|
|
4173 (goto-char position)
|
|
4174 (if (and entity-exists (not (equal string "")))
|
|
4175 (insert string)
|
|
4176 (vhdl-field "entity name"))
|
|
4177 (vhdl-insert-keyword " IS\n\n")
|
|
4178 (indent-to margin)
|
|
4179 (vhdl-insert-keyword "END ")
|
|
4180 (insert name ";")
|
|
4181 (end-of-line 0)
|
|
4182 (indent-to (+ margin vhdl-basic-offset))
|
|
4183 )))
|
|
4184
|
|
4185 (defun vhdl-constant ()
|
|
4186 "Inserts a constant declaration."
|
|
4187 (interactive)
|
|
4188 (vhdl-insert-keyword "CONSTANT ")
|
|
4189 (let ((in-arglist (string-match "arglist"
|
|
4190 (format "%s" (car (car (vhdl-get-syntactic-context)))))))
|
|
4191 (if (not in-arglist)
|
|
4192 (let ((opoint (point)))
|
|
4193 (beginning-of-line)
|
|
4194 (setq in-arglist (looking-at ".*("))
|
|
4195 (goto-char opoint)))
|
|
4196 (if (equal (vhdl-field "name") "")
|
|
4197 nil
|
|
4198 (insert " : ")
|
|
4199 (if in-arglist (vhdl-insert-keyword "IN "))
|
|
4200 (vhdl-field "type")
|
|
4201 (if in-arglist
|
|
4202 (insert ";")
|
|
4203 (let ((position (point)))
|
|
4204 (insert " := ")
|
|
4205 (if (equal (vhdl-field "[initialization]" ";") "")
|
|
4206 (progn (goto-char position) (kill-line) (insert ";")))
|
|
4207 (vhdl-declaration-comment))
|
|
4208 ))))
|
|
4209
|
|
4210 (defun vhdl-default ()
|
|
4211 "Insert nothing."
|
|
4212 (interactive)
|
|
4213 (insert " ")
|
|
4214 (unexpand-abbrev)
|
|
4215 (backward-word 1)
|
|
4216 (vhdl-case-word 1)
|
|
4217 (forward-char 1)
|
|
4218 )
|
|
4219
|
|
4220 (defun vhdl-default-indent ()
|
|
4221 "Insert nothing and indent."
|
|
4222 (interactive)
|
|
4223 (insert " ")
|
|
4224 (unexpand-abbrev)
|
|
4225 (backward-word 1)
|
|
4226 (vhdl-case-word 1)
|
|
4227 (forward-char 1)
|
|
4228 (vhdl-indent-line)
|
|
4229 )
|
|
4230
|
|
4231 (defun vhdl-disconnect ()
|
|
4232 "Insert a disconnect statement."
|
|
4233 (interactive)
|
|
4234 (vhdl-insert-keyword "DISCONNECT ")
|
|
4235 (if (equal (vhdl-field "guarded signal specification") "")
|
|
4236 nil
|
|
4237 (vhdl-insert-keyword " AFTER ")
|
|
4238 (vhdl-field "time expression" ";")
|
|
4239 ))
|
|
4240
|
|
4241 (defun vhdl-else ()
|
|
4242 "Insert an else statement."
|
|
4243 (interactive)
|
|
4244 (let ((margin))
|
|
4245 (vhdl-insert-keyword "ELSE")
|
|
4246 (if (not (equal 'block-close (car (car (vhdl-get-syntactic-context)))))
|
|
4247 (insert " ")
|
|
4248 (vhdl-indent-line)
|
|
4249 (setq margin (current-indentation))
|
|
4250 (insert "\n")
|
|
4251 (indent-to (+ margin vhdl-basic-offset))
|
|
4252 )))
|
|
4253
|
|
4254 (defun vhdl-elsif ()
|
|
4255 "Insert an elsif statement."
|
|
4256 (interactive)
|
|
4257 (let ((margin))
|
|
4258 (vhdl-insert-keyword "ELSIF ")
|
|
4259 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
4260 (if (equal (vhdl-field "condition") "")
|
|
4261 (progn (undo 0) (insert " "))
|
|
4262 (if vhdl-conditions-in-parenthesis (insert ")"))
|
|
4263 (vhdl-indent-line)
|
|
4264 (setq margin (current-indentation))
|
|
4265 (vhdl-insert-keyword " THEN\n")
|
|
4266 (indent-to (+ margin vhdl-basic-offset))
|
|
4267 )))
|
|
4268
|
|
4269 (defun vhdl-entity ()
|
|
4270 "Insert an entity template."
|
|
4271 (interactive)
|
|
4272 (let ((margin (current-column))
|
|
4273 (vhdl-entity-name))
|
|
4274 (vhdl-insert-keyword "ENTITY ")
|
|
4275 (if (equal (setq vhdl-entity-name (vhdl-field "entity name")) "")
|
|
4276 nil
|
|
4277 (vhdl-insert-keyword " IS\n\n")
|
|
4278 (indent-to margin)
|
|
4279 (vhdl-insert-keyword "END ")
|
|
4280 (insert vhdl-entity-name ";")
|
|
4281 (end-of-line -0)
|
|
4282 (indent-to (+ margin vhdl-basic-offset))
|
|
4283 (vhdl-entity-body)
|
|
4284 )))
|
|
4285
|
|
4286 (defun vhdl-entity-body ()
|
|
4287 "Insert an entity body."
|
|
4288 (interactive)
|
|
4289 (let ((margin (current-column)))
|
|
4290 (if vhdl-additional-empty-lines (insert "\n"))
|
|
4291 (indent-to margin)
|
|
4292 (vhdl-insert-keyword "GENERIC (")
|
|
4293 (if (vhdl-get-generic t)
|
|
4294 (if vhdl-additional-empty-lines (insert "\n")))
|
|
4295 (insert "\n")
|
|
4296 (indent-to margin)
|
|
4297 (vhdl-insert-keyword "PORT (")
|
|
4298 (if (vhdl-get-port t)
|
|
4299 (if vhdl-additional-empty-lines (insert "\n")))
|
|
4300 (end-of-line 2)
|
|
4301 ))
|
|
4302
|
|
4303 (defun vhdl-exit ()
|
|
4304 "Insert an exit statement."
|
|
4305 (interactive)
|
|
4306 (vhdl-insert-keyword "EXIT ")
|
|
4307 (if (string-equal (vhdl-field "[loop label]") "")
|
|
4308 (delete-char -1))
|
|
4309 (let ((opoint (point)))
|
|
4310 (vhdl-insert-keyword " WHEN ")
|
|
4311 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
4312 (if (equal (vhdl-field "[condition]") "")
|
|
4313 (progn (goto-char opoint)
|
|
4314 (kill-line))
|
|
4315 (if vhdl-conditions-in-parenthesis (insert ")"))))
|
|
4316 (insert ";")
|
|
4317 )
|
|
4318
|
|
4319 (defun vhdl-for ()
|
|
4320 "Inserts a block or component configuration if within a configuration
|
|
4321 declaration, a for loop otherwise."
|
|
4322 (interactive)
|
|
4323 (if (equal (car (car (cdr (vhdl-get-syntactic-context)))) 'configuration)
|
|
4324 (if (y-or-n-p "block configuration (or component configuration)? ")
|
|
4325 (vhdl-block-configuration)
|
|
4326 (vhdl-component-configuration))
|
|
4327 (vhdl-for-loop)))
|
|
4328
|
|
4329 (defun vhdl-for-loop ()
|
|
4330 "Insert a for loop template."
|
|
4331 (interactive)
|
|
4332 (let ((position (point)))
|
|
4333 (vhdl-insert-keyword " : FOR ")
|
|
4334 (goto-char position))
|
|
4335 (let* ((margin (current-column))
|
|
4336 (name (vhdl-field "[label]"))
|
|
4337 (named (not (string-equal name "")))
|
|
4338 (index))
|
|
4339 (if (not named) (delete-char 3))
|
|
4340 (end-of-line)
|
|
4341 (if (equal (setq index (vhdl-field "loop variable")) "")
|
|
4342 nil
|
|
4343 (vhdl-insert-keyword " IN ")
|
|
4344 (vhdl-field "range")
|
|
4345 (vhdl-insert-keyword " LOOP\n\n")
|
|
4346 (indent-to margin)
|
|
4347 (vhdl-insert-keyword "END LOOP")
|
|
4348 (if named (insert " " name ";")
|
|
4349 (insert ";")
|
|
4350 (if vhdl-self-insert-comments (insert " -- " index)))
|
|
4351 (forward-line -1)
|
|
4352 (indent-to (+ margin vhdl-basic-offset))
|
|
4353 )))
|
|
4354
|
|
4355 (defun vhdl-function ()
|
|
4356 "Insert function specification or body template."
|
|
4357 (interactive)
|
|
4358 (let ((margin (current-column))
|
|
4359 (name))
|
|
4360 (vhdl-insert-keyword "FUNCTION ")
|
|
4361 (if (equal (setq name (vhdl-field "name")) "")
|
|
4362 nil
|
|
4363 (vhdl-get-arg-list)
|
|
4364 (vhdl-insert-keyword " RETURN ")
|
|
4365 (vhdl-field "type" " ")
|
|
4366 (if (y-or-n-p "insert body? ")
|
|
4367 (progn (vhdl-insert-keyword "IS")
|
|
4368 (vhdl-begin-end (cons name margin))
|
|
4369 (vhdl-block-comment))
|
|
4370 (delete-char -1)
|
|
4371 (insert ";\n")
|
|
4372 (indent-to margin)))
|
|
4373 ))
|
|
4374
|
|
4375 (defun vhdl-generate ()
|
|
4376 "Insert a generate template."
|
|
4377 (interactive)
|
|
4378 (let ((position (point)))
|
|
4379 (vhdl-insert-keyword " GENERATE")
|
|
4380 (goto-char position))
|
|
4381 (let ((margin (current-column))
|
|
4382 (label (vhdl-field "label"))
|
|
4383 (string))
|
|
4384 (if (equal label "")
|
|
4385 (progn (undo 0) (insert " "))
|
|
4386 (insert " : ")
|
|
4387 (setq string (vhdl-field "(FOR | IF)"))
|
|
4388 (insert " ")
|
|
4389 (if (equal (upcase string) "IF")
|
|
4390 (progn
|
|
4391 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
4392 (vhdl-field "condition")
|
|
4393 (if vhdl-conditions-in-parenthesis (insert ")")))
|
|
4394 (vhdl-field "loop variable")
|
|
4395 (vhdl-insert-keyword " IN ")
|
|
4396 (vhdl-field "range"))
|
|
4397 (end-of-line)
|
|
4398 (insert "\n\n")
|
|
4399 (indent-to margin)
|
|
4400 (vhdl-insert-keyword "END GENERATE ")
|
|
4401 (insert label ";")
|
|
4402 (end-of-line 0)
|
|
4403 (indent-to (+ margin vhdl-basic-offset))
|
|
4404 )))
|
|
4405
|
|
4406 (defun vhdl-generic ()
|
|
4407 "Insert generic declaration, or generic map in instantiation statements."
|
|
4408 (interactive)
|
|
4409 (vhdl-insert-keyword "GENERIC (")
|
|
4410 (cond ((equal (car (car (cdr (vhdl-get-syntactic-context)))) 'entity)
|
|
4411 (vhdl-get-generic nil))
|
|
4412 ((or (equal 'statement-cont (car (car (vhdl-get-syntactic-context))))
|
|
4413 (save-excursion
|
|
4414 (and (backward-word 2) (skip-chars-backward " ")
|
|
4415 (eq (preceding-char) ?:))))
|
|
4416 (delete-char -1) (vhdl-map))
|
|
4417 (t (vhdl-get-generic nil t))))
|
|
4418
|
|
4419 (defun vhdl-header ()
|
|
4420 "Insert a VHDL file header."
|
|
4421 (interactive)
|
|
4422 (let (eot)
|
|
4423 (save-excursion
|
|
4424 (save-restriction
|
|
4425 (widen)
|
|
4426 (goto-char (point-min))
|
|
4427 (if vhdl-header-file
|
|
4428 (setq eot (car (cdr (insert-file-contents vhdl-header-file))))
|
|
4429 ; insert default header
|
|
4430 (insert "\
|
|
4431 -------------------------------------------------------------------------------
|
|
4432 -- Title : <title string>
|
|
4433 -- Project : <project string>
|
|
4434 -------------------------------------------------------------------------------
|
|
4435 -- File : <filename>
|
|
4436 -- Author : <author>
|
|
4437 -- Created : <date>
|
|
4438 -- Last modified : <date>
|
|
4439 -------------------------------------------------------------------------------
|
|
4440 -- Description :
|
|
4441 -- <cursor>
|
|
4442 -------------------------------------------------------------------------------
|
|
4443 -- Modification history :
|
|
4444 -- <date> : created
|
|
4445 -------------------------------------------------------------------------------
|
|
4446
|
|
4447 ")
|
|
4448 (setq eot (point)))
|
|
4449 (narrow-to-region (point-min) eot)
|
|
4450 (goto-char (point-min))
|
|
4451 (while (search-forward "<filename>" nil t)
|
|
4452 (replace-match (buffer-name) t t))
|
|
4453 (goto-char (point-min))
|
|
4454 (while (search-forward "<author>" nil t)
|
|
4455 (replace-match "" t t)
|
|
4456 (insert (user-full-name) " <" user-mail-address ">"))
|
|
4457 (goto-char (point-min))
|
|
4458 ;; Replace <RCS> with $, so that RCS for the source is
|
|
4459 ;; not over-enthusiastic with replacements
|
|
4460 (while (search-forward "<RCS>" nil t)
|
|
4461 (replace-match "$" nil t))
|
|
4462 (goto-char (point-min))
|
|
4463 (while (search-forward "<date>" nil t)
|
|
4464 (replace-match "" t t)
|
|
4465 (vhdl-insert-date))
|
|
4466 (goto-char (point-min))
|
|
4467 (let (string)
|
|
4468 (while (re-search-forward "<\\(\\w*\\) string>" nil t)
|
|
4469 (setq string (read-string (concat (match-string 1) ": ")))
|
|
4470 (replace-match string t t)))))
|
|
4471 (goto-char (point-min))
|
|
4472 (if (search-forward "<cursor>" nil t)
|
|
4473 (replace-match "" t t))))
|
|
4474
|
|
4475 (defun vhdl-if ()
|
|
4476 "Insert an if statement template."
|
|
4477 (interactive)
|
|
4478 (let ((margin (current-column)))
|
|
4479 (vhdl-insert-keyword "IF ")
|
|
4480 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
4481 (if (equal (vhdl-field "condition") "")
|
|
4482 (progn (undo 0) (insert " "))
|
|
4483 (if vhdl-conditions-in-parenthesis (insert ")"))
|
|
4484 (vhdl-insert-keyword " THEN\n\n")
|
|
4485 (indent-to margin)
|
|
4486 (vhdl-insert-keyword "END IF;")
|
|
4487 (forward-line -1)
|
|
4488 (indent-to (+ margin vhdl-basic-offset))
|
|
4489 )))
|
|
4490
|
|
4491 (defun vhdl-library ()
|
|
4492 "Insert a library specification."
|
|
4493 (interactive)
|
|
4494 (let ((margin (current-column))
|
|
4495 (lib-name))
|
|
4496 (vhdl-insert-keyword "LIBRARY ")
|
|
4497 (if (equal (setq lib-name (vhdl-field "library name")) "")
|
|
4498 nil
|
|
4499 (insert ";\n")
|
|
4500 (indent-to margin)
|
|
4501 (vhdl-insert-keyword "USE ")
|
|
4502 (insert lib-name)
|
|
4503 (vhdl-insert-keyword "..ALL;")
|
|
4504 (backward-char 5)
|
|
4505 (if (equal (vhdl-field "package name") "")
|
|
4506 (progn (vhdl-kill-entire-line)
|
|
4507 (end-of-line -0))
|
|
4508 (end-of-line)
|
|
4509 ))))
|
|
4510
|
|
4511 (defun vhdl-loop ()
|
|
4512 "Insert a loop template."
|
|
4513 (interactive)
|
|
4514 (let ((position (point)))
|
|
4515 (vhdl-insert-keyword " : LOOP")
|
|
4516 (goto-char position))
|
|
4517 (let* ((margin (current-column))
|
|
4518 (name (vhdl-field "[label]"))
|
|
4519 (named (not (string-equal name ""))))
|
|
4520 (if (not named) (delete-char 3))
|
|
4521 (end-of-line)
|
|
4522 (insert "\n\n")
|
|
4523 (indent-to margin)
|
|
4524 (vhdl-insert-keyword "END LOOP")
|
|
4525 (insert (if named (concat " " name ";") ?;))
|
|
4526 (forward-line -1)
|
|
4527 (indent-to (+ margin vhdl-basic-offset))
|
|
4528 ))
|
|
4529
|
|
4530 (defun vhdl-map ()
|
|
4531 "Insert a map specification."
|
|
4532 (interactive)
|
|
4533 (vhdl-insert-keyword "MAP (")
|
|
4534 (if (equal (vhdl-field "[association list]") "")
|
|
4535 (progn (undo 0) (insert " "))
|
|
4536 (insert ")")
|
|
4537 ))
|
|
4538
|
|
4539 (defun vhdl-modify ()
|
|
4540 "Actualize modification date."
|
|
4541 (interactive)
|
|
4542 (goto-char (point-min))
|
|
4543 (if (search-forward vhdl-modify-date-prefix-string nil t)
|
|
4544 (progn (kill-line)
|
|
4545 (vhdl-insert-date))
|
|
4546 (message (concat "Modification date prefix string \""
|
|
4547 vhdl-modify-date-prefix-string
|
|
4548 "\" not found!"))
|
|
4549 (beep)))
|
|
4550
|
|
4551 (defun vhdl-next ()
|
|
4552 "Inserts a next statement."
|
|
4553 (interactive)
|
|
4554 (vhdl-insert-keyword "NEXT ")
|
|
4555 (if (string-equal (vhdl-field "[loop label]") "")
|
|
4556 (delete-char -1))
|
|
4557 (let ((opoint (point)))
|
|
4558 (vhdl-insert-keyword " WHEN ")
|
|
4559 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
4560 (if (equal (vhdl-field "[condition]") "")
|
|
4561 (progn (goto-char opoint)
|
|
4562 (kill-line))
|
|
4563 (if vhdl-conditions-in-parenthesis (insert ")"))))
|
|
4564 (insert ";")
|
|
4565 )
|
|
4566
|
|
4567 (defun vhdl-package ()
|
|
4568 "Insert a package specification or body."
|
|
4569 (interactive)
|
|
4570 (let ((margin (current-column))
|
|
4571 (name))
|
|
4572 (vhdl-insert-keyword "PACKAGE ")
|
|
4573 (if (y-or-n-p "body? ")
|
|
4574 (vhdl-insert-keyword "BODY "))
|
|
4575 (setq name (vhdl-field "name" " is\n\n"))
|
|
4576 (indent-to margin)
|
|
4577 (vhdl-insert-keyword "END ")
|
|
4578 (insert name ";")
|
|
4579 (forward-line -1)
|
|
4580 (indent-to (+ margin vhdl-basic-offset))
|
|
4581 ))
|
|
4582
|
|
4583 (defun vhdl-port ()
|
|
4584 "Insert a port declaration, or port map in instantiation statements."
|
|
4585 (interactive)
|
|
4586 (vhdl-insert-keyword "PORT (")
|
|
4587 (cond ((equal (car (car (cdr (vhdl-get-syntactic-context)))) 'entity)
|
|
4588 (vhdl-get-port nil))
|
|
4589 ((or (equal 'statement-cont (car (car (vhdl-get-syntactic-context))))
|
|
4590 (save-excursion
|
|
4591 (and (backward-word 2) (skip-chars-backward " ")
|
|
4592 (eq (preceding-char) ?:))))
|
|
4593 (delete-char -1) (vhdl-map))
|
|
4594 (t (vhdl-get-port nil t))))
|
|
4595
|
|
4596 (defun vhdl-procedure ()
|
|
4597 "Insert a procedure specification or body template."
|
|
4598 (interactive)
|
|
4599 (let ((margin (current-column))
|
|
4600 (name))
|
|
4601 (vhdl-insert-keyword "PROCEDURE ")
|
|
4602 (if (equal (setq name (vhdl-field "name")) "")
|
|
4603 nil
|
|
4604 (vhdl-get-arg-list)
|
|
4605 (insert " ")
|
|
4606 (if (y-or-n-p "insert body? ")
|
|
4607 (progn (vhdl-insert-keyword "IS")
|
|
4608 (vhdl-begin-end (cons name margin))
|
|
4609 (vhdl-block-comment))
|
|
4610 (delete-char -1)
|
|
4611 (insert ";\n")
|
|
4612 (indent-to margin)
|
|
4613 ))))
|
|
4614
|
|
4615 (defun vhdl-process ()
|
|
4616 "Insert a process template."
|
|
4617 (interactive)
|
|
4618 (let ((clocked))
|
|
4619 (let ((position (point)))
|
|
4620 (vhdl-insert-keyword "PROCESS")
|
|
4621 (setq clocked (y-or-n-p "clocked process? "))
|
|
4622 (goto-char position)
|
|
4623 (insert " : ")
|
|
4624 (goto-char position))
|
|
4625 (let* ((margin (current-column))
|
|
4626 (finalline)
|
|
4627 (name (vhdl-field "[label]"))
|
|
4628 (named (not (string-equal name "")))
|
|
4629 (clock) (reset)
|
|
4630 (case-fold-search t))
|
|
4631 (if (not named) (delete-char 3))
|
|
4632 (end-of-line)
|
|
4633 (insert " (")
|
|
4634 (if (not clocked)
|
|
4635 (if (equal (vhdl-field "[sensitivity list]" ")") "")
|
|
4636 (delete-char -3))
|
|
4637 (setq clock (vhdl-field "clock name" ", "))
|
|
4638 (setq reset (vhdl-field "reset name" ")")))
|
|
4639 (vhdl-begin-end (cons (concat (vhdl-case-keyword "PROCESS")
|
|
4640 (if named (concat " " name))) margin))
|
|
4641 (if clocked (vhdl-clock-async-reset clock reset))
|
|
4642 (if vhdl-prompt-for-comments
|
|
4643 (progn
|
|
4644 (setq finalline (vhdl-current-line))
|
|
4645 (if (and (re-search-backward "\\<begin\\>" nil t)
|
|
4646 (re-search-backward "\\<process\\>" nil t))
|
|
4647 (progn
|
|
4648 (end-of-line -0)
|
|
4649 (insert "\n")
|
|
4650 (indent-to margin)
|
|
4651 (insert "-- purpose: ")
|
|
4652 (if (equal (vhdl-field "description") "")
|
|
4653 (vhdl-kill-entire-line)
|
|
4654 (newline)
|
|
4655 (indent-to margin)
|
|
4656 (insert "-- type: ")
|
|
4657 (insert (if clocked "memorizing" "memoryless") "\n")
|
|
4658 (indent-to margin)
|
|
4659 (insert "-- inputs: ")
|
|
4660 (if clocked
|
|
4661 (insert clock ", " reset ", "))
|
|
4662 (if (and (equal (vhdl-field "signal names") "")
|
|
4663 clocked)
|
|
4664 (delete-char -2))
|
|
4665 (insert "\n")
|
|
4666 (indent-to margin)
|
|
4667 (insert "-- outputs: ")
|
|
4668 (vhdl-field "signal names")
|
|
4669 (setq finalline (+ finalline 4)))))
|
|
4670 (goto-line finalline)
|
|
4671 (end-of-line)
|
|
4672 )))))
|
|
4673
|
|
4674 (defun vhdl-record ()
|
|
4675 "Insert a record type declaration."
|
|
4676 (interactive)
|
|
4677 (let ((margin (current-column))
|
|
4678 (start (point))
|
|
4679 (first t))
|
|
4680 (vhdl-insert-keyword "RECORD\n")
|
|
4681 (indent-to (+ margin vhdl-basic-offset))
|
|
4682 (if (equal (vhdl-field "identifiers") "")
|
|
4683 (progn (kill-line -0)
|
|
4684 (delete-char -1)
|
|
4685 (insert " "))
|
|
4686 (while (or first (not (equal (vhdl-field "[identifiers]") "")))
|
|
4687 (insert " : ")
|
|
4688 (vhdl-field "type" ";")
|
|
4689 (vhdl-declaration-comment)
|
|
4690 (newline)
|
|
4691 (indent-to (+ margin vhdl-basic-offset))
|
|
4692 (setq first nil))
|
|
4693 (kill-line -0)
|
|
4694 (indent-to margin)
|
|
4695 (vhdl-insert-keyword "END RECORD;")
|
|
4696 (if vhdl-auto-align (vhdl-align start (point) 1))
|
|
4697 )))
|
|
4698
|
|
4699 (defun vhdl-return-value ()
|
|
4700 "Insert a return statement."
|
|
4701 (interactive)
|
|
4702 (vhdl-insert-keyword "RETURN ")
|
|
4703 (if (equal (vhdl-field "[expression]") "")
|
|
4704 (delete-char -1))
|
|
4705 (insert ";")
|
|
4706 )
|
|
4707
|
|
4708 (defun vhdl-selected-signal-assignment ()
|
|
4709 "Insert a selected signal assignment."
|
|
4710 (interactive)
|
|
4711 (let ((margin (current-column))
|
|
4712 (start (point)))
|
|
4713 (let ((position (point)))
|
|
4714 (vhdl-insert-keyword " SELECT")
|
|
4715 (goto-char position))
|
|
4716 (vhdl-insert-keyword "WITH ")
|
|
4717 (if (equal (vhdl-field "selector expression") "")
|
|
4718 (progn (undo 0) (insert " "))
|
|
4719 (end-of-line)
|
|
4720 (insert "\n")
|
|
4721 (indent-to (+ margin vhdl-basic-offset))
|
|
4722 (vhdl-field "target signal" " <= ")
|
|
4723 ; (vhdl-field "[GUARDED] [TRANSPORT]")
|
|
4724 (insert "\n")
|
|
4725 (indent-to (+ margin vhdl-basic-offset))
|
|
4726 (while (not (equal (vhdl-field "[waveform]") ""))
|
|
4727 (vhdl-insert-keyword " WHEN ")
|
|
4728 (vhdl-field "choices" ",")
|
|
4729 (newline)
|
|
4730 (indent-to (+ margin vhdl-basic-offset)))
|
|
4731 (if (not (equal (vhdl-field "[alternative waveform]") ""))
|
|
4732 (vhdl-insert-keyword " WHEN OTHERS")
|
|
4733 (fixup-whitespace)
|
|
4734 (delete-char -2))
|
|
4735 (insert ";")
|
|
4736 (if vhdl-auto-align (vhdl-align start (point) 1))
|
|
4737 )))
|
|
4738
|
|
4739 (defun vhdl-signal ()
|
|
4740 "Insert a signal declaration."
|
|
4741 (interactive)
|
|
4742 (vhdl-insert-keyword "SIGNAL ")
|
|
4743 (let ((in-arglist (string-match "arglist"
|
|
4744 (format "%s" (car (car (vhdl-get-syntactic-context)))))))
|
|
4745 (if (not in-arglist)
|
|
4746 (let ((opoint (point)))
|
|
4747 (beginning-of-line)
|
|
4748 (setq in-arglist (looking-at ".*("))
|
|
4749 (goto-char opoint)))
|
|
4750 (if (equal (vhdl-field "names") "")
|
|
4751 nil
|
|
4752 (insert " : ")
|
|
4753 (if in-arglist
|
|
4754 (progn (vhdl-field "direction")
|
|
4755 (insert " ")))
|
|
4756 (vhdl-field "type")
|
|
4757 (if in-arglist
|
|
4758 (insert ";")
|
|
4759 (let ((position (point)))
|
|
4760 (insert " := ")
|
|
4761 (if (equal (vhdl-field "[initialization]" ";") "")
|
|
4762 (progn (goto-char position) (kill-line) (insert ";")))
|
|
4763 (vhdl-declaration-comment))
|
|
4764 ))))
|
|
4765
|
|
4766 (defun vhdl-subtype ()
|
|
4767 "Insert a subtype declaration."
|
|
4768 (interactive)
|
|
4769 (vhdl-insert-keyword "SUBTYPE ")
|
|
4770 (if (equal (vhdl-field "name") "")
|
|
4771 nil
|
|
4772 (vhdl-insert-keyword " IS ")
|
|
4773 (vhdl-field "type" " ")
|
|
4774 (if (equal (vhdl-field "[RANGE value range | ( index range )]") "")
|
|
4775 (delete-char -1))
|
|
4776 (insert ";")
|
|
4777 (vhdl-declaration-comment)
|
|
4778 ))
|
|
4779
|
|
4780 (defun vhdl-type ()
|
|
4781 "Insert a type declaration."
|
|
4782 (interactive)
|
|
4783 (vhdl-insert-keyword "TYPE ")
|
|
4784 (if (equal (vhdl-field "name") "")
|
|
4785 nil
|
|
4786 (vhdl-insert-keyword " IS ")
|
|
4787 (let ((definition (upcase (vhdl-field "(scalar type | ARRAY | RECORD | ACCESS | FILE)"))))
|
|
4788 (cond ((equal definition "ARRAY")
|
|
4789 (kill-word -1) (vhdl-array))
|
|
4790 ((equal definition "RECORD")
|
|
4791 (kill-word -1) (vhdl-record))
|
|
4792 ((equal definition "ACCESS")
|
|
4793 (insert " ") (vhdl-field "type" ";"))
|
|
4794 ((equal definition "FILE")
|
|
4795 (vhdl-insert-keyword " OF ") (vhdl-field "type" ";"))
|
|
4796 (t (insert ";")))
|
|
4797 (vhdl-declaration-comment)
|
|
4798 )))
|
|
4799
|
|
4800 (defun vhdl-use ()
|
|
4801 "Insert a use clause."
|
|
4802 (interactive)
|
|
4803 (vhdl-insert-keyword "USE ..ALL;")
|
|
4804 (backward-char 6)
|
|
4805 (if (equal (vhdl-field "library name") "")
|
|
4806 (progn (undo 0) (insert " "))
|
|
4807 (forward-char 1)
|
|
4808 (vhdl-field "package name")
|
|
4809 (end-of-line)
|
|
4810 ))
|
|
4811
|
|
4812 (defun vhdl-variable ()
|
|
4813 "Insert a variable declaration."
|
|
4814 (interactive)
|
|
4815 (vhdl-insert-keyword "VARIABLE ")
|
|
4816 (let ((in-arglist (string-match "arglist"
|
|
4817 (format "%s" (car (car (vhdl-get-syntactic-context)))))))
|
|
4818 (if (not in-arglist)
|
|
4819 (let ((opoint (point)))
|
|
4820 (beginning-of-line)
|
|
4821 (setq in-arglist (looking-at ".*("))
|
|
4822 (goto-char opoint)))
|
|
4823 (if (equal (vhdl-field "names") "")
|
|
4824 nil
|
|
4825 (insert " : ")
|
|
4826 (if in-arglist
|
|
4827 (progn (vhdl-field "direction")
|
|
4828 (insert " ")))
|
|
4829 (vhdl-field "type")
|
|
4830 (if in-arglist
|
|
4831 (insert ";")
|
|
4832 (let ((position (point)))
|
|
4833 (insert " := ")
|
|
4834 (if (equal (vhdl-field "[initialization]" ";") "")
|
|
4835 (progn (goto-char position) (kill-line) (insert ";")))
|
|
4836 (vhdl-declaration-comment))
|
|
4837 ))))
|
|
4838
|
|
4839 (defun vhdl-wait ()
|
|
4840 "Insert a wait statement."
|
|
4841 (interactive)
|
|
4842 (vhdl-insert-keyword "WAIT ")
|
|
4843 (if (equal (vhdl-field
|
|
4844 "[ON sensitivity list] [UNTIL condition] [FOR time expression]")
|
|
4845 "")
|
|
4846 (delete-char -1))
|
|
4847 (insert ";")
|
|
4848 )
|
|
4849
|
|
4850 (defun vhdl-when ()
|
|
4851 "Indent correctly if within a case statement."
|
|
4852 (interactive)
|
|
4853 (let ((position (point))
|
|
4854 (margin))
|
|
4855 (if (and (re-search-forward "\\<end\\>" nil t)
|
|
4856 (looking-at "\\s-*\\<case\\>"))
|
|
4857 (progn
|
|
4858 (setq margin (current-indentation))
|
|
4859 (goto-char position)
|
|
4860 (delete-horizontal-space)
|
|
4861 (indent-to (+ margin vhdl-basic-offset)))
|
|
4862 (goto-char position)
|
|
4863 )
|
|
4864 (vhdl-insert-keyword "WHEN ")
|
|
4865 ))
|
|
4866
|
|
4867 (defun vhdl-while-loop ()
|
|
4868 "Insert a while loop template."
|
|
4869 (interactive)
|
|
4870 (let ((position (point)))
|
|
4871 (vhdl-insert-keyword " : WHILE ")
|
|
4872 (goto-char position))
|
|
4873 (let* ((margin (current-column))
|
|
4874 (name (vhdl-field "[label]"))
|
|
4875 (named (not (string-equal name ""))))
|
|
4876 (if (not named) (delete-char 3))
|
|
4877 (end-of-line)
|
|
4878 (if vhdl-conditions-in-parenthesis (insert "("))
|
|
4879 (if (equal (vhdl-field "condition") "")
|
|
4880 (progn (undo 0) (insert " "))
|
|
4881 (if vhdl-conditions-in-parenthesis (insert ")"))
|
|
4882 (vhdl-insert-keyword " LOOP\n\n")
|
|
4883 (indent-to margin)
|
|
4884 (vhdl-insert-keyword "END LOOP")
|
|
4885 (insert (if named (concat " " name ";") ?;))
|
|
4886 (forward-line -1)
|
|
4887 (indent-to (+ margin vhdl-basic-offset))
|
|
4888 )))
|
|
4889
|
|
4890 (defun vhdl-with ()
|
|
4891 "Insert a with statement (i.e. selected signal assignment)."
|
|
4892 (interactive)
|
|
4893 (vhdl-selected-signal-assignment)
|
|
4894 )
|
|
4895
|
|
4896 ;; ############################################################################
|
|
4897 ;; Custom functions
|
|
4898
|
|
4899 (defun vhdl-clocked-wait ()
|
|
4900 "Insert a wait statement for rising clock edge."
|
|
4901 (interactive)
|
|
4902 (vhdl-insert-keyword "WAIT UNTIL ")
|
|
4903 (let* ((clock (vhdl-field "clock name")))
|
|
4904 (insert "'event")
|
|
4905 (vhdl-insert-keyword " AND ")
|
|
4906 (insert clock)
|
|
4907 (insert " = " vhdl-one-string ";")
|
|
4908 ))
|
|
4909
|
|
4910 (defun vhdl-clock-async-reset (clock reset)
|
|
4911 "Insert a template reacting on asynchronous reset and rising clock edge
|
|
4912 for inside a memorizing processes."
|
|
4913 (interactive)
|
|
4914 (let* ( (margin (current-column))
|
|
4915 (opoint))
|
|
4916 (if vhdl-self-insert-comments
|
|
4917 (insert "-- activities triggered by asynchronous reset (active low)\n"))
|
|
4918 (indent-to margin)
|
|
4919 (vhdl-insert-keyword "IF ")
|
|
4920 (insert reset " = " vhdl-zero-string)
|
|
4921 (vhdl-insert-keyword " THEN\n")
|
|
4922 (indent-to (+ margin vhdl-basic-offset))
|
|
4923 (setq opoint (point))
|
|
4924 (newline)
|
|
4925 (indent-to margin)
|
|
4926 (if vhdl-self-insert-comments
|
|
4927 (insert "-- activities triggered by rising edge of clock\n"))
|
|
4928 (indent-to margin)
|
|
4929 (vhdl-insert-keyword "ELSIF ")
|
|
4930 (insert clock "'event")
|
|
4931 (vhdl-insert-keyword " AND ")
|
|
4932 (insert clock " = " vhdl-one-string)
|
|
4933 (vhdl-insert-keyword " THEN\n")
|
|
4934 (indent-to (+ margin vhdl-basic-offset))
|
|
4935 (newline)
|
|
4936 (indent-to margin)
|
|
4937 (vhdl-insert-keyword "END IF;")
|
|
4938 ; (if vhdl-self-insert-comments (insert " -- " clock))
|
|
4939 (goto-char opoint)
|
|
4940 ))
|
|
4941
|
|
4942 (defun vhdl-standard-package (library package)
|
|
4943 "Insert specification of a standard package."
|
|
4944 (interactive)
|
|
4945 (let ((margin (current-column)))
|
|
4946 (vhdl-insert-keyword "LIBRARY ")
|
|
4947 (insert library ";\n")
|
|
4948 (indent-to margin)
|
|
4949 (vhdl-insert-keyword "USE ")
|
|
4950 (insert library "." package)
|
|
4951 (vhdl-insert-keyword ".ALL;")
|
|
4952 ))
|
|
4953
|
|
4954 (defun vhdl-package-numeric-bit ()
|
|
4955 "Insert specification of 'numeric_bit' package."
|
|
4956 (interactive)
|
|
4957 (vhdl-standard-package "ieee" "numeric_bit"))
|
|
4958
|
|
4959 (defun vhdl-package-numeric-std ()
|
|
4960 "Insert specification of 'numeric_std' package."
|
|
4961 (interactive)
|
|
4962 (vhdl-standard-package "ieee" "numeric_std"))
|
|
4963
|
|
4964 (defun vhdl-package-std-logic-1164 ()
|
|
4965 "Insert specification of 'std_logic_1164' package."
|
|
4966 (interactive)
|
|
4967 (vhdl-standard-package "ieee" "std_logic_1164"))
|
|
4968
|
|
4969 (defun vhdl-package-textio ()
|
|
4970 "Insert specification of 'textio' package."
|
|
4971 (interactive)
|
|
4972 (vhdl-standard-package "std" "textio"))
|
|
4973
|
|
4974 ;; ############################################################################
|
|
4975 ;; Comment functions
|
|
4976
|
|
4977 (defun vhdl-comment-indent ()
|
|
4978 (let* ((opoint (point))
|
|
4979 (col (progn
|
|
4980 (forward-line -1)
|
|
4981 (if (re-search-forward "--" opoint t)
|
|
4982 (- (current-column) 2) ;Existing comment at bol stays there.
|
|
4983 (goto-char opoint)
|
|
4984 (skip-chars-backward " \t")
|
|
4985 (max comment-column ;else indent to comment column
|
|
4986 (1+ (current-column))) ;except leave at least one space.
|
|
4987 ))))
|
|
4988 (goto-char opoint)
|
|
4989 col
|
|
4990 ))
|
|
4991
|
|
4992 (defun vhdl-inline-comment ()
|
|
4993 "Start a comment at the end of the line.
|
|
4994 if on line with code, indent at least comment-column.
|
|
4995 if starting after end-comment-column, start a new line."
|
|
4996 (interactive)
|
|
4997 (if (> (current-column) end-comment-column) (newline-and-indent))
|
|
4998 (if (or (looking-at "\\s-*$") ;end of line
|
|
4999 (and (not unread-command-events) ; called with key binding or menu
|
|
5000 (not (end-of-line))))
|
|
5001 (let ((margin))
|
|
5002 (while (= (preceding-char) ?-) (delete-char -1))
|
|
5003 (setq margin (current-column))
|
|
5004 (delete-horizontal-space)
|
|
5005 (if (bolp)
|
|
5006 (progn (indent-to margin) (insert "--"))
|
|
5007 (insert " ")
|
|
5008 (indent-to comment-column)
|
|
5009 (insert "--"))
|
|
5010 (if (not unread-command-events) (insert " ")))
|
|
5011 ; else code following current point implies commenting out code
|
|
5012 (let (next-input code)
|
|
5013 (while (= (preceding-char) ?-) (delete-char -2))
|
|
5014 (while (= (setq next-input (read-char)) 13) ; CR
|
|
5015 (insert "--"); or have a space after it?
|
|
5016 (forward-char -2)
|
|
5017 (forward-line 1)
|
|
5018 (message "Enter CR if commenting out a line of code.")
|
|
5019 (setq code t)
|
|
5020 )
|
|
5021 (if (not code) (progn
|
|
5022 ; (indent-to comment-column)
|
|
5023 (insert "--") ;hardwire to 1 space or use vhdl-basic-offset?
|
|
5024 ))
|
|
5025 (setq unread-command-events
|
|
5026 (list (vhdl-character-to-event-hack next-input))) ;pushback the char
|
|
5027 )))
|
|
5028
|
|
5029 (defun vhdl-display-comment (&optional line-exists)
|
|
5030 "Add 2 comment lines at the current indent, making a display comment."
|
|
5031 (interactive)
|
|
5032 (if (not line-exists)
|
|
5033 (vhdl-display-comment-line))
|
|
5034 (let* ((col (current-column))
|
|
5035 (len (- end-comment-column col)))
|
|
5036 (insert "\n")
|
|
5037 (insert-char ? col)
|
|
5038 (insert-char ?- len)
|
|
5039 (insert "\n")
|
|
5040 (insert-char ? col)
|
|
5041 (end-of-line -1)
|
|
5042 )
|
|
5043 (insert "-- ")
|
|
5044 )
|
|
5045
|
|
5046 (defun vhdl-display-comment-line ()
|
|
5047 "Displays one line of dashes."
|
|
5048 (interactive)
|
|
5049 (while (= (preceding-char) ?-) (delete-char -2))
|
|
5050 (let* ((col (current-column))
|
|
5051 (len (- end-comment-column col)))
|
|
5052 (insert-char ?- len)
|
|
5053 (insert-char ?\n 1)
|
|
5054 (insert-char ? col)
|
|
5055 ))
|
|
5056
|
|
5057 (defun vhdl-declaration-comment ()
|
|
5058 (if vhdl-prompt-for-comments
|
|
5059 (let ((position (point)))
|
|
5060 (insert " ")
|
|
5061 (indent-to comment-column)
|
|
5062 (insert "-- ")
|
|
5063 (if (equal (vhdl-field "comment") "")
|
|
5064 (progn (goto-char position) (kill-line))
|
|
5065 ))))
|
|
5066
|
|
5067 (defun vhdl-block-comment ()
|
|
5068 (if vhdl-prompt-for-comments
|
|
5069 (let ((finalline (vhdl-current-line))
|
|
5070 (case-fold-search t))
|
|
5071 (beginning-of-line -0)
|
|
5072 (if (re-search-backward "\\<\\(architecture\\|block\\|function\\|procedure\\|process\\)\\>" nil t)
|
|
5073 (let ((margin))
|
|
5074 (back-to-indentation)
|
|
5075 (setq margin (current-column))
|
|
5076 (end-of-line -0)
|
|
5077 (insert "\n")
|
|
5078 (indent-to margin)
|
|
5079 (insert "-- purpose: ")
|
|
5080 (if (equal (vhdl-field "description") "")
|
|
5081 (vhdl-kill-entire-line)
|
|
5082 (setq finalline (+ finalline 1)))))
|
|
5083 (goto-line finalline)
|
|
5084 (end-of-line)
|
|
5085 )))
|
|
5086
|
|
5087 (defun vhdl-comment-uncomment-region (beg end &optional arg)
|
|
5088 "Comment out region if not commented out, uncomment out region if already
|
|
5089 commented out."
|
|
5090 (interactive "r\nP")
|
|
5091 (goto-char beg)
|
|
5092 (if (looking-at comment-start)
|
|
5093 (comment-region beg end -1)
|
|
5094 (comment-region beg end)
|
|
5095 ))
|
|
5096
|
|
5097 ;; ############################################################################
|
|
5098 ;; Help functions
|
|
5099
|
|
5100 (defun vhdl-outer-space (count)
|
|
5101 "Expand abbreviations and self-insert space(s), do indent-new-comment-line
|
|
5102 if in comment and past end-comment-column."
|
|
5103 (interactive "p")
|
|
5104 (if (or (and (>= (preceding-char) ?a) (<= (preceding-char) ?z))
|
|
5105 (and (>= (preceding-char) ?A) (<= (preceding-char) ?Z)))
|
|
5106 (expand-abbrev))
|
|
5107 (if (not (vhdl-in-comment-p))
|
|
5108 (self-insert-command count)
|
|
5109 (if (< (current-column) end-comment-column)
|
|
5110 (self-insert-command count)
|
|
5111 (while (> (current-column) end-comment-column) (forward-word -1))
|
|
5112 (while (> (preceding-char) ? ) (forward-word -1))
|
|
5113 (delete-horizontal-space)
|
|
5114 (indent-new-comment-line)
|
|
5115 (end-of-line nil)
|
|
5116 (insert-char ? count)
|
|
5117 )))
|
|
5118
|
|
5119 (defun vhdl-field (prompt &optional following-string)
|
|
5120 "Prompt for string and insert it in buffer with optional following-string."
|
|
5121 (let ((opoint (point)))
|
|
5122 (insert "<" prompt ">")
|
|
5123 (let ((string (read-from-minibuffer (concat prompt ": ") ""
|
|
5124 vhdl-minibuffer-local-map)))
|
|
5125 (delete-region opoint (point))
|
|
5126 (insert string (or following-string ""))
|
|
5127 (if vhdl-upper-case-keywords
|
|
5128 (vhdl-fix-case-region-1
|
|
5129 opoint (point) t vhdl-93-keywords-regexp))
|
|
5130 string
|
|
5131 )))
|
|
5132
|
|
5133 (defun vhdl-in-comment-p ()
|
|
5134 "Check if point is to right of beginning comment delimiter."
|
|
5135 (interactive)
|
|
5136 (let ((opoint (point)))
|
|
5137 (save-excursion ; finds an unquoted comment
|
|
5138 (beginning-of-line)
|
|
5139 (re-search-forward "^\\([^\"]*\"[^\"]*\"\\)*[^\"]*--" opoint t)
|
|
5140 )))
|
|
5141
|
|
5142 (defun vhdl-in-string-p ()
|
|
5143 "Check if point is in a string."
|
|
5144 (interactive)
|
|
5145 (let ((opoint (point)))
|
|
5146 (save-excursion ; preceeded by odd number of string delimiters?
|
|
5147 (beginning-of-line)
|
|
5148 (equal
|
|
5149 opoint
|
|
5150 (re-search-forward "^\\([^\"]*\"[^\"]*\"\\)*[^\"]*\"[^\"]*" opoint t))
|
|
5151 )))
|
|
5152
|
|
5153 (defun vhdl-begin-end (list)
|
|
5154 "Insert a begin ... end pair with optional name after the end.
|
|
5155 Point is left between them."
|
|
5156 (let ((return)
|
|
5157 (name (car list))
|
|
5158 (margin (cdr list)))
|
|
5159 (if vhdl-additional-empty-lines
|
|
5160 (progn
|
|
5161 (insert "\n")
|
|
5162 (indent-to (+ margin vhdl-basic-offset))))
|
|
5163 (insert "\n")
|
|
5164 (indent-to margin)
|
|
5165 (vhdl-insert-keyword "BEGIN")
|
|
5166 (if vhdl-self-insert-comments
|
|
5167 (insert (and name (concat " -- " name))))
|
|
5168 (insert "\n")
|
|
5169 (indent-to (+ margin vhdl-basic-offset))
|
|
5170 (setq return (point))
|
|
5171 (newline)
|
|
5172 (indent-to margin)
|
|
5173 (vhdl-insert-keyword "END")
|
|
5174 (insert (and name (concat " " name)) ";")
|
|
5175 (goto-char return)
|
|
5176 ))
|
|
5177
|
|
5178 (defun vhdl-get-arg-list ()
|
|
5179 "Read from user a procedure or function argument list."
|
|
5180 (insert " (")
|
|
5181 (let ((margin (current-column)))
|
|
5182 (if (not vhdl-argument-list-indent)
|
|
5183 (let ((opoint (point)))
|
|
5184 (back-to-indentation)
|
|
5185 (setq margin (+ (current-column) vhdl-basic-offset))
|
|
5186 (goto-char opoint)
|
|
5187 (newline)
|
|
5188 (indent-to margin)))
|
|
5189 (let (not-empty interface)
|
|
5190 (setq interface (vhdl-field "[CONSTANT] [SIGNAL] [VARIABLE]"))
|
|
5191 (if (not (equal interface ""))
|
|
5192 (insert " "))
|
|
5193 (while (not (string-equal (vhdl-field "[names]") ""))
|
|
5194 (setq not-empty t)
|
|
5195 (insert " : ")
|
|
5196 (if (not (equal (vhdl-field "[direction]") ""))
|
|
5197 (insert " "))
|
|
5198 (vhdl-field "type" ";\n")
|
|
5199 (indent-to margin)
|
|
5200 (setq interface (vhdl-field "[CONSTANT] [SIGNAL] [VARIABLE]"))
|
|
5201 (if (not (equal interface ""))
|
|
5202 (insert " ")))
|
|
5203 (if not-empty
|
|
5204 (progn (kill-line -0)
|
|
5205 (delete-char -2)
|
|
5206 (if (not vhdl-argument-list-indent)
|
|
5207 (progn (insert "\n") (indent-to margin)))
|
|
5208 (insert ")"))
|
|
5209 (if vhdl-argument-list-indent
|
|
5210 (backward-delete-char 2)
|
|
5211 (kill-line -0)
|
|
5212 (backward-delete-char 3)))
|
|
5213 ; (while (string-match "[,;]$" args)
|
|
5214 ; (newline)
|
|
5215 ; (indent-to margin) (setq args (vhdl-field "next argument")))
|
|
5216 ; (insert 41) ;close-paren
|
|
5217 )))
|
|
5218
|
|
5219 (defun vhdl-get-port (optional &optional no-comment)
|
|
5220 "Read from user a port spec argument list."
|
|
5221 (let ((margin (current-column))
|
|
5222 (start (point)))
|
|
5223 (if (not vhdl-argument-list-indent)
|
|
5224 (let ((opoint (point)))
|
|
5225 (back-to-indentation)
|
|
5226 (setq margin (+ (current-column) vhdl-basic-offset))
|
|
5227 (goto-char opoint)
|
|
5228 (newline)
|
|
5229 (indent-to margin)))
|
|
5230 (let ((vhdl-ports (vhdl-field "[names]")))
|
|
5231 (if (string-equal vhdl-ports "")
|
|
5232 (if optional
|
|
5233 (progn (vhdl-kill-entire-line) (forward-line -1)
|
|
5234 (if (not vhdl-argument-list-indent)
|
|
5235 (progn (vhdl-kill-entire-line) (forward-line -1))))
|
|
5236 (progn (undo 0) (insert " "))
|
|
5237 nil )
|
|
5238 (insert " : ")
|
|
5239 (progn
|
|
5240 (let ((semicolon-pos))
|
|
5241 (while (not (string-equal "" vhdl-ports))
|
|
5242 (vhdl-field "direction")
|
|
5243 (insert " ")
|
|
5244 (vhdl-field "type")
|
|
5245 (setq semicolon-pos (point))
|
|
5246 (insert ";")
|
|
5247 (if (not no-comment)
|
|
5248 (vhdl-declaration-comment))
|
|
5249 (newline)
|
|
5250 (indent-to margin)
|
|
5251 (setq vhdl-ports (vhdl-field "[names]" " : ")))
|
|
5252 (goto-char semicolon-pos)
|
|
5253 (if (not vhdl-argument-list-indent)
|
|
5254 (progn (insert "\n") (indent-to margin)))
|
|
5255 (insert ")")
|
|
5256 (forward-char 1)
|
|
5257 (if (= (following-char) ? )
|
|
5258 (delete-char 1))
|
|
5259 (forward-line 1)
|
|
5260 (vhdl-kill-entire-line)
|
|
5261 (end-of-line -0)
|
|
5262 (if vhdl-auto-align (vhdl-align start (point) 1))
|
|
5263 t))))))
|
|
5264
|
|
5265 (defun vhdl-get-generic (optional &optional no-value )
|
|
5266 "Read from user a generic spec argument list."
|
|
5267 (let ((margin (current-column))
|
|
5268 (start (point)))
|
|
5269 (if (not vhdl-argument-list-indent)
|
|
5270 (let ((opoint (point)))
|
|
5271 (back-to-indentation)
|
|
5272 (setq margin (+ (current-column) vhdl-basic-offset))
|
|
5273 (goto-char opoint)
|
|
5274 (newline)
|
|
5275 (indent-to margin)))
|
|
5276 (let ((vhdl-generic))
|
|
5277 (if no-value
|
|
5278 (setq vhdl-generic (vhdl-field "[names]"))
|
|
5279 (setq vhdl-generic (vhdl-field "[name]")))
|
|
5280 (if (string-equal vhdl-generic "")
|
|
5281 (if optional
|
|
5282 (progn (vhdl-kill-entire-line) (end-of-line -0)
|
|
5283 (if (not vhdl-argument-list-indent)
|
|
5284 (progn (vhdl-kill-entire-line) (end-of-line -0))))
|
|
5285 (progn (undo 0) (insert " "))
|
|
5286 nil )
|
|
5287 (insert " : ")
|
|
5288 (progn
|
|
5289 (let ((semicolon-pos))
|
|
5290 (while (not(string-equal "" vhdl-generic))
|
|
5291 (vhdl-field "type")
|
|
5292 (if no-value
|
|
5293 (progn (setq semicolon-pos (point))
|
|
5294 (insert ";"))
|
|
5295 (insert " := ")
|
|
5296 (if (equal (vhdl-field "[value]") "")
|
|
5297 (delete-char -4))
|
|
5298 (setq semicolon-pos (point))
|
|
5299 (insert ";")
|
|
5300 (vhdl-declaration-comment))
|
|
5301 (newline)
|
|
5302 (indent-to margin)
|
|
5303 (if no-value
|
|
5304 (setq vhdl-generic (vhdl-field "[names]" " : "))
|
|
5305 (setq vhdl-generic (vhdl-field "[name]" " : "))))
|
|
5306 (goto-char semicolon-pos)
|
|
5307 (if (not vhdl-argument-list-indent)
|
|
5308 (progn (insert "\n") (indent-to margin)))
|
|
5309 (insert ")")
|
|
5310 (forward-char 1)
|
|
5311 (if (= (following-char) ? )
|
|
5312 (delete-char 1))
|
|
5313 (forward-line 1)
|
|
5314 (vhdl-kill-entire-line)
|
|
5315 (end-of-line -0)
|
|
5316 (if vhdl-auto-align (vhdl-align start (point) 1))
|
|
5317 t))))))
|
|
5318
|
|
5319 (defun vhdl-insert-date ()
|
|
5320 "Insert date in appropriate format."
|
|
5321 (interactive)
|
|
5322 (insert
|
|
5323 (cond
|
|
5324 ((eq vhdl-date-format 'american) (format-time-string "%m/%d/%Y" nil))
|
|
5325 ((eq vhdl-date-format 'european) (format-time-string "%d.%m.%Y" nil))
|
|
5326 ((eq vhdl-date-format 'scientific) (format-time-string "%Y/%m/%d" nil))
|
|
5327 )))
|
|
5328
|
|
5329 (defun vhdl-insert-keyword (keyword)
|
|
5330 (insert (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword)))
|
|
5331 )
|
|
5332
|
|
5333 (defun vhdl-case-keyword (keyword)
|
|
5334 (if vhdl-upper-case-keywords (upcase keyword) (downcase keyword))
|
|
5335 )
|
|
5336
|
|
5337 (defun vhdl-case-word (num)
|
|
5338 (if vhdl-upper-case-keywords (upcase-word num) (downcase-word num))
|
|
5339 )
|
|
5340
|
|
5341 (defun vhdl-fix-case-region-1 (beg end upper-case word-regexp &optional count)
|
|
5342 "Convert all words matching word-regexp in region to lower or upper case,
|
|
5343 depending on parameter upper-case."
|
|
5344 (let ((case-fold-search t)
|
|
5345 (case-replace nil)
|
|
5346 (busy-counter 0))
|
|
5347 (modify-syntax-entry ?_ "w" vhdl-mode-syntax-table)
|
|
5348 (save-excursion
|
|
5349 (goto-char beg)
|
|
5350 (while (re-search-forward word-regexp end t)
|
|
5351 (or (vhdl-in-comment-p)
|
|
5352 (vhdl-in-string-p)
|
|
5353 (if upper-case
|
|
5354 (upcase-word -1)
|
|
5355 (downcase-word -1)))
|
|
5356 (if (and count
|
|
5357 (/= busy-counter (setq busy-counter
|
|
5358 (+ (* count 25) (/ (* 25 (- (point) beg)) (- end beg))))))
|
|
5359 (message (format "Fixing case ... (%2d%s)" busy-counter "%%"))))
|
|
5360 (goto-char end))
|
|
5361 (if (not vhdl-underscore-is-part-of-word)
|
|
5362 (modify-syntax-entry ?_ "_" vhdl-mode-syntax-table))
|
|
5363 (message "")
|
|
5364 ))
|
|
5365
|
|
5366 (defun vhdl-fix-case-region (beg end &optional arg)
|
|
5367 "Convert all VHDL words in region to lower or upper case, depending on
|
|
5368 variables vhdl-upper-case-{keywords,types,attributes,enum-values}."
|
|
5369 (interactive "r\nP")
|
|
5370 (vhdl-fix-case-region-1
|
|
5371 beg end vhdl-upper-case-keywords vhdl-93-keywords-regexp 0)
|
|
5372 (vhdl-fix-case-region-1
|
|
5373 beg end vhdl-upper-case-types vhdl-93-types-regexp 1)
|
|
5374 (vhdl-fix-case-region-1
|
|
5375 beg end vhdl-upper-case-attributes vhdl-93-attributes-regexp 2)
|
|
5376 (vhdl-fix-case-region-1
|
|
5377 beg end vhdl-upper-case-enum-values vhdl-93-enum-values-regexp 3)
|
|
5378 )
|
|
5379
|
|
5380 (defun vhdl-fix-case-buffer ()
|
|
5381 "Convert all VHDL words in buffer to lower or upper case, depending on
|
|
5382 variables vhdl-upper-case-{keywords,types,attributes,enum-values}."
|
|
5383 (interactive)
|
|
5384 (vhdl-fix-case-region (point-min) (point-max))
|
|
5385 )
|
|
5386
|
|
5387 (defun vhdl-minibuffer-tab (&optional prefix-arg)
|
|
5388 "If preceeding character is part of a word then dabbrev-expand,
|
|
5389 else if right of non whitespace on line then tab-to-tab-stop,
|
|
5390 else indent line in proper way for current major mode
|
|
5391 (used for word completion in VHDL minibuffer)."
|
|
5392 (interactive "P")
|
|
5393 (cond ((= (char-syntax (preceding-char)) ?w)
|
|
5394 (let ((case-fold-search nil)) (dabbrev-expand prefix-arg)))
|
|
5395 ((> (current-column) (current-indentation))
|
|
5396 (tab-to-tab-stop))
|
|
5397 (t
|
|
5398 (if (eq indent-line-function 'indent-to-left-margin)
|
|
5399 (insert-tab prefix-arg)
|
|
5400 (if prefix-arg
|
|
5401 (funcall indent-line-function prefix-arg)
|
|
5402 (funcall indent-line-function))))))
|
|
5403
|
|
5404 (defun vhdl-help ()
|
|
5405 "Display help information in '*Help*' buffer ."
|
|
5406 (interactive)
|
|
5407 (with-output-to-temp-buffer "*Help*"
|
|
5408 (princ mode-name)
|
|
5409 (princ " mode:\n")
|
|
5410 (princ (documentation major-mode))
|
|
5411 (save-excursion
|
|
5412 (set-buffer standard-output)
|
|
5413 (help-mode))
|
|
5414 (print-help-return-message)))
|
|
5415
|
|
5416 (defun vhdl-current-line ()
|
|
5417 "Return the line number of the line containing point."
|
|
5418 (save-restriction
|
|
5419 (widen)
|
|
5420 (save-excursion
|
|
5421 (beginning-of-line)
|
|
5422 (1+ (count-lines 1 (point)))))
|
|
5423 )
|
|
5424
|
|
5425 (defun vhdl-kill-entire-line ()
|
|
5426 "Delete entire line."
|
|
5427 (interactive)
|
|
5428 (end-of-line)
|
|
5429 (kill-line -0)
|
|
5430 (delete-char 1)
|
|
5431 )
|
|
5432
|
|
5433 (defun vhdl-open-line ()
|
|
5434 "Open a new line and indent."
|
|
5435 (interactive)
|
|
5436 (end-of-line)
|
|
5437 (newline-and-indent)
|
|
5438 )
|
|
5439
|
|
5440 (defun vhdl-kill-line ()
|
|
5441 "Kill current line."
|
|
5442 (interactive)
|
|
5443 (vhdl-kill-entire-line)
|
|
5444 )
|
|
5445
|
|
5446 (defun vhdl-character-to-event-hack (char)
|
|
5447 (if (memq 'XEmacs vhdl-emacs-features)
|
|
5448 (character-to-event char)
|
|
5449 char))
|
|
5450
|
|
5451 ;; ############################################################################
|
|
5452 ;; Abbrev hooks
|
|
5453
|
|
5454 (defun vhdl-electric-mode ()
|
|
5455 "Toggle VHDL Electric mode."
|
|
5456 (interactive)
|
|
5457 (setq vhdl-electric-mode (not vhdl-electric-mode))
|
|
5458 (setq mode-name (if vhdl-electric-mode "Electric VHDL" "VHDL"))
|
|
5459 (force-mode-line-update)
|
|
5460 )
|
|
5461
|
|
5462 (defun vhdl-stutter-mode ()
|
|
5463 "Toggle VHDL Stuttering mode."
|
|
5464 (interactive)
|
|
5465 (setq vhdl-stutter-mode (not vhdl-stutter-mode))
|
|
5466 )
|
|
5467
|
|
5468 (defun vhdl-hooked-abbrev (fun)
|
|
5469 "Do function, if syntax says abbrev is a keyword, invoked by hooked abbrev,
|
|
5470 but not if inside a comment or quote)"
|
|
5471 (if (or (vhdl-in-comment-p)
|
|
5472 (vhdl-in-string-p)
|
|
5473 (save-excursion (forward-word -1) (looking-at "end")))
|
|
5474 (progn
|
|
5475 (insert " ")
|
|
5476 (unexpand-abbrev)
|
|
5477 (delete-char -1))
|
|
5478 (if (not vhdl-electric-mode)
|
|
5479 (progn
|
|
5480 (insert " ")
|
|
5481 (unexpand-abbrev)
|
|
5482 (backward-word 1)
|
|
5483 (vhdl-case-word 1)
|
|
5484 (delete-char 1)
|
|
5485 )
|
|
5486 (let ((invoke-char last-command-char) (abbrev-mode -1))
|
|
5487 (funcall fun)
|
|
5488 (if (= invoke-char ?-) (setq abbrev-start-location (point)))
|
|
5489 ;; delete CR which is still in event queue
|
|
5490 (if (memq 'XEmacs vhdl-emacs-features)
|
|
5491 (enqueue-eval-event 'delete-char -1)
|
|
5492 (setq unread-command-events ; push back a delete char
|
|
5493 (list (vhdl-character-to-event-hack ?\177))))
|
|
5494 ))))
|
|
5495
|
|
5496 (defun vhdl-alias-hook () "hooked version of vhdl-alias."
|
|
5497 (vhdl-hooked-abbrev 'vhdl-alias))
|
|
5498 (defun vhdl-architecture-hook () "hooked version of vhdl-architecture."
|
|
5499 (vhdl-hooked-abbrev 'vhdl-architecture))
|
|
5500 (defun vhdl-array-hook () "hooked version of vhdl-array."
|
|
5501 (vhdl-hooked-abbrev 'vhdl-array))
|
|
5502 (defun vhdl-assert-hook () "hooked version of vhdl-assert."
|
|
5503 (vhdl-hooked-abbrev 'vhdl-assert))
|
|
5504 (defun vhdl-attribute-hook () "hooked version of vhdl-attribute."
|
|
5505 (vhdl-hooked-abbrev 'vhdl-attribute))
|
|
5506 (defun vhdl-block-hook () "hooked version of vhdl-block."
|
|
5507 (vhdl-hooked-abbrev 'vhdl-block))
|
|
5508 (defun vhdl-case-hook () "hooked version of vhdl-case."
|
|
5509 (vhdl-hooked-abbrev 'vhdl-case))
|
|
5510 (defun vhdl-component-hook () "hooked version of vhdl-component."
|
|
5511 (vhdl-hooked-abbrev 'vhdl-component))
|
|
5512 (defun vhdl-component-instance-hook ()
|
|
5513 "hooked version of vhdl-component-instance."
|
|
5514 (vhdl-hooked-abbrev 'vhdl-component-instance))
|
|
5515 (defun vhdl-concurrent-signal-assignment-hook ()
|
|
5516 "hooked version of vhdl-concurrent-signal-assignment."
|
|
5517 (vhdl-hooked-abbrev 'vhdl-concurrent-signal-assignment))
|
|
5518 (defun vhdl-configuration-hook ()
|
|
5519 "hooked version of vhdl-configuration."
|
|
5520 (vhdl-hooked-abbrev 'vhdl-configuration))
|
|
5521 (defun vhdl-constant-hook () "hooked version of vhdl-constant."
|
|
5522 (vhdl-hooked-abbrev 'vhdl-constant))
|
|
5523 (defun vhdl-disconnect-hook () "hooked version of vhdl-disconnect."
|
|
5524 (vhdl-hooked-abbrev 'vhdl-disconnect))
|
|
5525 (defun vhdl-display-comment-hook () "hooked version of vhdl-display-comment."
|
|
5526 (vhdl-hooked-abbrev 'vhdl-display-comment))
|
|
5527 (defun vhdl-else-hook () "hooked version of vhdl-else."
|
|
5528 (vhdl-hooked-abbrev 'vhdl-else))
|
|
5529 (defun vhdl-elsif-hook () "hooked version of vhdl-elsif."
|
|
5530 (vhdl-hooked-abbrev 'vhdl-elsif))
|
|
5531 (defun vhdl-entity-hook () "hooked version of vhdl-entity."
|
|
5532 (vhdl-hooked-abbrev 'vhdl-entity))
|
|
5533 (defun vhdl-exit-hook () "hooked version of vhdl-exit."
|
|
5534 (vhdl-hooked-abbrev 'vhdl-exit))
|
|
5535 (defun vhdl-for-hook () "hooked version of vhdl-for."
|
|
5536 (vhdl-hooked-abbrev 'vhdl-for))
|
|
5537 (defun vhdl-function-hook () "hooked version of vhdl-function."
|
|
5538 (vhdl-hooked-abbrev 'vhdl-function))
|
|
5539 (defun vhdl-generate-hook () "hooked version of vhdl-generate."
|
|
5540 (vhdl-hooked-abbrev 'vhdl-generate))
|
|
5541 (defun vhdl-generic-hook () "hooked version of vhdl-generic."
|
|
5542 (vhdl-hooked-abbrev 'vhdl-generic))
|
|
5543 (defun vhdl-library-hook () "hooked version of vhdl-library."
|
|
5544 (vhdl-hooked-abbrev 'vhdl-library))
|
|
5545 (defun vhdl-header-hook () "hooked version of vhdl-header."
|
|
5546 (vhdl-hooked-abbrev 'vhdl-header))
|
|
5547 (defun vhdl-if-hook () "hooked version of vhdl-if."
|
|
5548 (vhdl-hooked-abbrev 'vhdl-if))
|
|
5549 (defun vhdl-loop-hook () "hooked version of vhdl-loop."
|
|
5550 (vhdl-hooked-abbrev 'vhdl-loop))
|
|
5551 (defun vhdl-map-hook () "hooked version of vhdl-map."
|
|
5552 (vhdl-hooked-abbrev 'vhdl-map))
|
|
5553 (defun vhdl-modify-hook () "hooked version of vhdl-modify."
|
|
5554 (vhdl-hooked-abbrev 'vhdl-modify))
|
|
5555 (defun vhdl-next-hook () "hooked version of vhdl-next."
|
|
5556 (vhdl-hooked-abbrev 'vhdl-next))
|
|
5557 (defun vhdl-package-hook () "hooked version of vhdl-package."
|
|
5558 (vhdl-hooked-abbrev 'vhdl-package))
|
|
5559 (defun vhdl-port-hook () "hooked version of vhdl-port."
|
|
5560 (vhdl-hooked-abbrev 'vhdl-port))
|
|
5561 (defun vhdl-procedure-hook () "hooked version of vhdl-procedure."
|
|
5562 (vhdl-hooked-abbrev 'vhdl-procedure))
|
|
5563 (defun vhdl-process-hook () "hooked version of vhdl-process."
|
|
5564 (vhdl-hooked-abbrev 'vhdl-process))
|
|
5565 (defun vhdl-record-hook () "hooked version of vhdl-record."
|
|
5566 (vhdl-hooked-abbrev 'vhdl-record))
|
|
5567 (defun vhdl-return-hook () "hooked version of vhdl-return-value."
|
|
5568 (vhdl-hooked-abbrev 'vhdl-return-value))
|
|
5569 (defun vhdl-selected-signal-assignment-hook ()
|
|
5570 "hooked version of vhdl-selected-signal-assignment."
|
|
5571 (vhdl-hooked-abbrev 'vhdl-selected-signal-assignment))
|
|
5572 (defun vhdl-signal-hook () "hooked version of vhdl-signal."
|
|
5573 (vhdl-hooked-abbrev 'vhdl-signal))
|
|
5574 (defun vhdl-subtype-hook () "hooked version of vhdl-subtype."
|
|
5575 (vhdl-hooked-abbrev 'vhdl-subtype))
|
|
5576 (defun vhdl-type-hook () "hooked version of vhdl-type."
|
|
5577 (vhdl-hooked-abbrev 'vhdl-type))
|
|
5578 (defun vhdl-use-hook () "hooked version of vhdl-use."
|
|
5579 (vhdl-hooked-abbrev 'vhdl-use))
|
|
5580 (defun vhdl-variable-hook () "hooked version of vhdl-variable."
|
|
5581 (vhdl-hooked-abbrev 'vhdl-variable))
|
|
5582 (defun vhdl-wait-hook () "hooked version of vhdl-wait."
|
|
5583 (vhdl-hooked-abbrev 'vhdl-wait))
|
|
5584 (defun vhdl-when-hook () "hooked version of vhdl-when."
|
|
5585 (vhdl-hooked-abbrev 'vhdl-when))
|
|
5586 (defun vhdl-while-loop-hook () "hooked version of vhdl-while-loop."
|
|
5587 (vhdl-hooked-abbrev 'vhdl-while-loop))
|
|
5588 (defun vhdl-and-hook () "hooked version of vhdl-and."
|
|
5589 (vhdl-hooked-abbrev 'vhdl-and))
|
|
5590 (defun vhdl-or-hook () "hooked version of vhdl-or."
|
|
5591 (vhdl-hooked-abbrev 'vhdl-or))
|
|
5592 (defun vhdl-nand-hook () "hooked version of vhdl-nand."
|
|
5593 (vhdl-hooked-abbrev 'vhdl-nand))
|
|
5594 (defun vhdl-nor-hook () "hooked version of vhdl-nor."
|
|
5595 (vhdl-hooked-abbrev 'vhdl-nor))
|
|
5596 (defun vhdl-xor-hook () "hooked version of vhdl-xor."
|
|
5597 (vhdl-hooked-abbrev 'vhdl-xor))
|
|
5598 (defun vhdl-xnor-hook () "hooked version of vhdl-xnor."
|
|
5599 (vhdl-hooked-abbrev 'vhdl-xnor))
|
|
5600 (defun vhdl-not-hook () "hooked version of vhdl-not."
|
|
5601 (vhdl-hooked-abbrev 'vhdl-not))
|
|
5602
|
|
5603 (defun vhdl-default-hook () "hooked version of vhdl-default."
|
|
5604 (vhdl-hooked-abbrev 'vhdl-default))
|
|
5605 (defun vhdl-default-indent-hook () "hooked version of vhdl-default-indent."
|
|
5606 (vhdl-hooked-abbrev 'vhdl-default-indent))
|
|
5607
|
|
5608
|
|
5609 ;; ############################################################################
|
|
5610 ;; Font locking
|
|
5611 ;; ############################################################################
|
|
5612 ;; (using `font-lock.el')
|
|
5613
|
|
5614 ;; ############################################################################
|
|
5615 ;; Syntax definitions
|
|
5616
|
|
5617 (defvar vhdl-font-lock-keywords nil
|
|
5618 "Regular expressions to highlight in VHDL Mode.")
|
|
5619
|
|
5620 (defconst vhdl-font-lock-keywords-0
|
|
5621 (list
|
|
5622 ;; highlight template prompts
|
|
5623 '("\\(^\\|[ (.\t]\\)\\(<[^ =].*[^ =]>\\)\\([ .]\\|$\\)"
|
|
5624 2 vhdl-font-lock-prompt-face)
|
|
5625
|
|
5626 ;; highlight character literals
|
|
5627 '("'\\(.\\)'" 1 'font-lock-string-face)
|
|
5628 )
|
|
5629 "For consideration as a value of `vhdl-font-lock-keywords'.
|
|
5630 This does highlighting of template prompts and character literals.")
|
|
5631
|
|
5632 (defconst vhdl-font-lock-keywords-1
|
|
5633 (list
|
|
5634 ;; highlight names of units, subprograms, and components when declared
|
|
5635 (list
|
|
5636 (concat
|
|
5637 "^\\s-*\\("
|
|
5638 "architecture\\|configuration\\|entity\\|package\\(\\s-+body\\|\\)\\|"
|
|
5639 "function\\|procedure\\|component"
|
|
5640 "\\)\\s-+\\(\\w+\\)")
|
|
5641 3 'font-lock-function-name-face)
|
|
5642
|
|
5643 ;; highlight labels of common constructs
|
|
5644 (list
|
|
5645 (concat
|
|
5646 "^\\s-*\\(\\w+\\)\\s-*:\\(\\s-\\|\n\\)*\\("
|
|
5647 "assert\\|block\\|case\\|exit\\|for\\|if\\|loop\\|"
|
|
5648 "next\\|null\\|process\\| with\\|while\\|"
|
|
5649 "\\w+\\(\\s-\\|\n\\)+\\(generic\\|port\\)\\s-+map"
|
|
5650 "\\)\\>")
|
|
5651 1 'font-lock-function-name-face)
|
|
5652
|
|
5653 ;; highlight entity names of architectures and configurations
|
|
5654 (list
|
|
5655 "^\\s-*\\(architecture\\|configuration\\)\\s-+\\w+\\s-+of\\s-+\\(\\w+\\)"
|
|
5656 2 'font-lock-function-name-face)
|
|
5657
|
|
5658 ;; highlight names and labels at end of constructs
|
|
5659 (list
|
|
5660 (concat
|
|
5661 "^\\s-*end\\s-+\\("
|
|
5662 "\\(block\\|case\\|component\\|for\\|generate\\|if\\|loop\\|"
|
|
5663 "process\\|record\\|units\\)\\>\\|"
|
|
5664 "\\)\\s-*\\(\\w*\\)")
|
|
5665 3 'font-lock-function-name-face)
|
|
5666 )
|
|
5667 "For consideration as a value of `vhdl-font-lock-keywords'.
|
|
5668 This does highlighting of names and labels.")
|
|
5669
|
|
5670 (defconst vhdl-font-lock-keywords-2
|
|
5671 (list
|
|
5672 ;; highlight keywords, and types, standardized attributes, enumeration values
|
|
5673 (list (concat "'" vhdl-93-attributes-regexp)
|
|
5674 1 'vhdl-font-lock-attribute-face)
|
|
5675 (list vhdl-93-types-regexp 1 'font-lock-type-face)
|
|
5676 (list vhdl-93-enum-values-regexp 1 'vhdl-font-lock-value-face)
|
|
5677 (list vhdl-93-keywords-regexp 1 'font-lock-keyword-face)
|
|
5678 )
|
|
5679 "For consideration as a value of `vhdl-font-lock-keywords'.
|
|
5680 This does highlighting of comments, keywords, and standard types.")
|
|
5681
|
|
5682 (defconst vhdl-font-lock-keywords-3
|
|
5683 (list
|
|
5684 ;; highlight clock signals.
|
|
5685 (cons vhdl-clock-signal-syntax 'vhdl-font-lock-clock-signal-face)
|
|
5686 (cons vhdl-reset-signal-syntax 'vhdl-font-lock-reset-signal-face)
|
|
5687 (cons vhdl-control-signal-syntax 'vhdl-font-lock-control-signal-face)
|
|
5688 (cons vhdl-data-signal-syntax 'vhdl-font-lock-data-signal-face)
|
|
5689 (cons vhdl-test-signal-syntax 'vhdl-font-lock-test-signal-face)
|
|
5690 )
|
|
5691 "For consideration as a value of `vhdl-font-lock-keywords'.
|
|
5692 This does highlighting of signal names with specific syntax.")
|
|
5693
|
|
5694 ;; ############################################################################
|
|
5695 ;; Font and color definitions
|
|
5696
|
|
5697 (defvar vhdl-font-lock-prompt-face 'vhdl-font-lock-prompt-face
|
|
5698 "Face name to use for prompts.")
|
|
5699
|
|
5700 (defvar vhdl-font-lock-attribute-face 'vhdl-font-lock-attribute-face
|
|
5701 "Face name to use for attributes.")
|
|
5702
|
|
5703 (defvar vhdl-font-lock-value-face 'vhdl-font-lock-value-face
|
|
5704 "Face name to use for enumeration values.")
|
|
5705
|
|
5706 (defvar vhdl-font-lock-clock-signal-face 'vhdl-font-lock-clock-signal-face
|
|
5707 "Face name to use for clock signals.")
|
|
5708
|
|
5709 (defvar vhdl-font-lock-reset-signal-face 'vhdl-font-lock-reset-signal-face
|
|
5710 "Face name to use for reset signals.")
|
|
5711
|
|
5712 (defvar vhdl-font-lock-control-signal-face 'vhdl-font-lock-control-signal-face
|
|
5713 "Face name to use for control signals.")
|
|
5714
|
|
5715 (defvar vhdl-font-lock-data-signal-face 'vhdl-font-lock-data-signal-face
|
|
5716 "Face name to use for data signals.")
|
|
5717
|
|
5718 (defvar vhdl-font-lock-test-signal-face 'vhdl-font-lock-test-signal-face
|
|
5719 "Face name to use for test signals.")
|
|
5720
|
|
5721 (defface vhdl-font-lock-prompt-face
|
|
5722 '((((class color) (background light)) (:foreground "Red"))
|
|
5723 (((class color) (background dark)) (:foreground "Red"))
|
|
5724 (t (:inverse-video t)))
|
|
5725 "Font Lock mode face used to highlight prompts."
|
|
5726 :group 'font-lock-highlighting-faces)
|
|
5727
|
|
5728 (defface vhdl-font-lock-attribute-face
|
|
5729 '((((class color) (background light)) (:foreground "CadetBlue"))
|
|
5730 (((class color) (background dark)) (:foreground "CadetBlue"))
|
|
5731 (t (:italic t :bold t)))
|
|
5732 "Font Lock mode face used to highlight attributes."
|
|
5733 :group 'font-lock-highlighting-faces)
|
|
5734
|
|
5735 (defface vhdl-font-lock-value-face
|
|
5736 '((((class color) (background light)) (:foreground "DarkGoldenrod"))
|
|
5737 (((class color) (background dark)) (:foreground "DarkGoldenrod"))
|
|
5738 (t (:italic t :bold t)))
|
|
5739 "Font Lock mode face used to highlight enumeration values."
|
|
5740 :group 'font-lock-highlighting-faces)
|
|
5741
|
|
5742 (defface vhdl-font-lock-clock-signal-face
|
|
5743 '((((class color) (background light)) (:foreground "LimeGreen"))
|
|
5744 (((class color) (background dark)) (:foreground "LimeGreen"))
|
|
5745 (t ()))
|
|
5746 "Font Lock mode face used to highlight clock signals."
|
|
5747 :group 'font-lock-highlighting-faces)
|
|
5748
|
|
5749 (defface vhdl-font-lock-reset-signal-face
|
|
5750 '((((class color) (background light)) (:foreground "Red"))
|
|
5751 (((class color) (background dark)) (:foreground "Red"))
|
|
5752 (t ()))
|
|
5753 "Font Lock mode face used to highlight reset signals."
|
|
5754 :group 'font-lock-highlighting-faces)
|
|
5755
|
|
5756 (defface vhdl-font-lock-control-signal-face
|
|
5757 '((((class color) (background light)) (:foreground "Blue"))
|
|
5758 (((class color) (background dark)) (:foreground "Blue"))
|
|
5759 (t ()))
|
|
5760 "Font Lock mode face used to highlight control signals."
|
|
5761 :group 'font-lock-highlighting-faces)
|
|
5762
|
|
5763 (defface vhdl-font-lock-data-signal-face
|
|
5764 '((((class color) (background light)) (:foreground "Black"))
|
|
5765 (((class color) (background dark)) (:foreground "Black"))
|
|
5766 (t ()))
|
|
5767 "Font Lock mode face used to highlight data signals."
|
|
5768 :group 'font-lock-highlighting-faces)
|
|
5769
|
|
5770 (defface vhdl-font-lock-test-signal-face
|
|
5771 '((((class color) (background light)) (:foreground "Gold"))
|
|
5772 (((class color) (background dark)) (:foreground "Gold"))
|
|
5773 (t ()))
|
|
5774 "Font Lock mode face used to highlight test signals."
|
|
5775 :group 'font-lock-highlighting-faces)
|
|
5776
|
|
5777 ;; Custom color definitions for existing faces
|
|
5778 (defun vhdl-set-face-foreground ()
|
|
5779 (set-face-foreground 'font-lock-comment-face "IndianRed")
|
|
5780 (set-face-foreground 'font-lock-function-name-face "MediumOrchid")
|
|
5781 (set-face-foreground 'font-lock-keyword-face "SlateBlue")
|
|
5782 (set-face-foreground 'font-lock-string-face "RosyBrown")
|
|
5783 (set-face-foreground 'font-lock-type-face "ForestGreen")
|
|
5784 )
|
|
5785
|
|
5786 (defun vhdl-set-face-grayscale ()
|
|
5787 (interactive)
|
|
5788 (set-face-bold-p 'font-lock-comment-face nil)
|
|
5789 (set-face-inverse-video-p 'font-lock-comment-face nil)
|
|
5790 (set-face-italic-p 'font-lock-comment-face t)
|
|
5791 (set-face-underline-p 'font-lock-comment-face nil)
|
|
5792
|
|
5793 (set-face-bold-p 'font-lock-function-name-face nil)
|
|
5794 (set-face-inverse-video-p 'font-lock-function-name-face nil)
|
|
5795 (set-face-italic-p 'font-lock-function-name-face t)
|
|
5796 (set-face-underline-p 'font-lock-function-name-face nil)
|
|
5797
|
|
5798 (set-face-bold-p 'font-lock-keyword-face t)
|
|
5799 (set-face-inverse-video-p 'font-lock-keyword-face nil)
|
|
5800 (set-face-italic-p 'font-lock-keyword-face nil)
|
|
5801 (set-face-underline-p 'font-lock-keyword-face nil)
|
|
5802
|
|
5803 (set-face-bold-p 'font-lock-string-face nil)
|
|
5804 (set-face-inverse-video-p 'font-lock-string-face nil)
|
|
5805 (set-face-italic-p 'font-lock-string-face nil)
|
|
5806 (set-face-underline-p 'font-lock-string-face t)
|
|
5807
|
|
5808 (set-face-bold-p 'font-lock-type-face t)
|
|
5809 (set-face-inverse-video-p 'font-lock-type-face nil)
|
|
5810 (set-face-italic-p 'font-lock-type-face t)
|
|
5811 (set-face-underline-p 'font-lock-type-face nil)
|
|
5812 )
|
|
5813
|
|
5814 ;; ############################################################################
|
|
5815 ;; Font lock initialization
|
|
5816
|
|
5817 (defun vhdl-font-lock-init ()
|
|
5818 "Initializes fontification."
|
|
5819 (setq vhdl-font-lock-keywords
|
|
5820 (append vhdl-font-lock-keywords-0
|
|
5821 (if vhdl-highlight-names vhdl-font-lock-keywords-1)
|
|
5822 (if vhdl-highlight-keywords vhdl-font-lock-keywords-2)
|
|
5823 (if (and vhdl-highlight-signals (x-display-color-p))
|
|
5824 vhdl-font-lock-keywords-3)))
|
|
5825 (if (x-display-color-p)
|
|
5826 (if (not vhdl-use-default-colors) (vhdl-set-face-foreground))
|
|
5827 (if (not vhdl-use-default-faces) (vhdl-set-face-grayscale))
|
|
5828 ))
|
|
5829
|
|
5830 ;; ############################################################################
|
|
5831 ;; Fontification for postscript printing
|
|
5832
|
|
5833 (defun vhdl-ps-init ()
|
|
5834 "Initializes face and page settings for postscript printing."
|
|
5835 (require 'ps-print)
|
|
5836 (unless (or vhdl-use-default-faces
|
|
5837 ps-print-color-p)
|
|
5838 (set (make-local-variable 'ps-bold-faces)
|
|
5839 '(font-lock-keyword-face
|
|
5840 font-lock-type-face
|
|
5841 vhdl-font-lock-attribute-face
|
|
5842 vhdl-font-lock-value-face))
|
|
5843 (set (make-local-variable 'ps-italic-faces)
|
|
5844 '(font-lock-comment-face
|
|
5845 font-lock-function-name-face
|
|
5846 font-lock-type-face
|
|
5847 vhdl-font-lock-prompt-face
|
|
5848 vhdl-font-lock-attribute-face
|
|
5849 vhdl-font-lock-value-face))
|
|
5850 (set (make-local-variable 'ps-underlined-faces)
|
|
5851 '(font-lock-string-face))
|
|
5852 )
|
|
5853 ;; define page settings, so that a line containing 79 characters (default)
|
|
5854 ;; fits into one column
|
|
5855 (if vhdl-print-two-column
|
|
5856 (progn
|
|
5857 (set (make-local-variable 'ps-landscape-mode) t)
|
|
5858 (set (make-local-variable 'ps-number-of-columns) 2)
|
|
5859 (set (make-local-variable 'ps-font-size) 7.0)
|
|
5860 (set (make-local-variable 'ps-header-title-font-size) 10.0)
|
|
5861 (set (make-local-variable 'ps-header-font-size) 9.0)
|
|
5862 (set (make-local-variable 'ps-header-offset) 12.0)
|
|
5863 (if (eq ps-paper-type 'letter)
|
|
5864 (progn
|
|
5865 (set (make-local-variable 'ps-inter-column) 40.0)
|
|
5866 (set (make-local-variable 'ps-left-margin) 40.0)
|
|
5867 (set (make-local-variable 'ps-right-margin) 40.0)
|
|
5868 )))))
|
|
5869
|
|
5870
|
|
5871 ;; ############################################################################
|
|
5872 ;; Hideshow
|
|
5873 ;; ############################################################################
|
|
5874 ;; (using `hideshow.el')
|
|
5875
|
|
5876 (defun vhdl-forward-sexp-function (&optional count)
|
|
5877 "Find begin and end of VHDL process or block (for hideshow)."
|
|
5878 (interactive "p")
|
|
5879 (let (name
|
|
5880 (case-fold-search t))
|
|
5881 (end-of-line)
|
|
5882 (if (< count 0)
|
|
5883 (re-search-backward "\\s-*\\(\\w\\|\\s_\\)+\\s-*:\\s-*\\(process\\|block\\)\\>" nil t)
|
|
5884 (re-search-forward "\\s-*\\<end\\s-+\\(process\\|block\\)\\>" nil t)
|
|
5885 )))
|
|
5886
|
|
5887 (require 'hideshow)
|
|
5888
|
|
5889 (unless (assq 'vhdl-mode hs-special-modes-alist)
|
|
5890 (setq hs-special-modes-alist
|
|
5891 (cons
|
|
5892 '(vhdl-mode
|
|
5893 "\\s-*\\(\\w\\|\\s_\\)+\\s-*:\\s-*\\(process\\|PROCESS\\|block\\|BLOCK\\)\\>"
|
|
5894 "\\s-*\\<\\(end\\|END\\)\\s-+\\(process\\|PROCESS\\|block\\|BLOCK\\)\\>"
|
|
5895 "-- "
|
|
5896 vhdl-forward-sexp-function)
|
|
5897 hs-special-modes-alist)))
|
|
5898
|
|
5899
|
|
5900 ;; ############################################################################
|
|
5901 ;; Compilation
|
|
5902 ;; ############################################################################
|
|
5903 ;; (using `compile.el')
|
|
5904
|
|
5905 (defvar vhdl-compile-commands
|
|
5906 '(
|
|
5907 (cadence "cv -file" nil)
|
|
5908 (ikos "analyze" nil)
|
|
5909 (quickhdl "qvhcom" nil)
|
|
5910 (synopsys "vhdlan" nil)
|
|
5911 (vantage "analyze -libfile vsslib.ini -src" nil)
|
|
5912 (viewlogic "analyze -libfile vsslib.ini -src" nil)
|
|
5913 (v-system "vcom" "vmake > Makefile")
|
|
5914 )
|
|
5915 "Commands to be called in the shell for compilation (syntax analysis) of a
|
|
5916 single buffer and `Makefile' generation for different tools. First item is tool
|
|
5917 identifier, second item is shell command for compilation, and third item is
|
|
5918 shell command for `Makefile' generation. A tool is specified by assigning a
|
|
5919 tool identifier to variable `vhdl-compiler'.")
|
|
5920
|
|
5921 (defvar vhdl-compilation-error-regexp-alist
|
|
5922 (list
|
|
5923 ;; Cadence Design Systems: cv -file test.vhd
|
|
5924 ;; duluth: *E,430 (test.vhd,13): identifier (POSITIV) is not declared
|
|
5925 '("duluth: \\*E,[0-9]+ (\\(.+\\),\\([0-9]+\\)):" 1 2)
|
|
5926
|
|
5927 ;; Ikos Voyager: analyze test.vhd
|
|
5928 ;; E L4/C5: this library unit is inaccessible
|
|
5929 ; Xemacs does not support error messages without included file name
|
|
5930 (if (not (memq 'XEmacs vhdl-emacs-features))
|
|
5931 '("E L\\([0-9]+\\)/C[0-9]+:" nil 1)
|
|
5932 '("E L\\([0-9]+\\)/C[0-9]+:" 2 1)
|
|
5933 )
|
|
5934
|
|
5935 ;; QuickHDL, Mentor Graphics: qvhcom test.vhd
|
|
5936 ;; ERROR: test.vhd(24): near "dnd": expecting: END
|
|
5937 '("ERROR: \\(.+\\)(\\([0-9]+\\)):" 1 2)
|
|
5938
|
|
5939 ;; Synopsys, VHDL Analyzer: vhdlan test.vhd
|
|
5940 ;; **Error: vhdlan,703 test.vhd(22): OTHERS is not legal in this context.
|
|
5941 '("\\*\\*Error: vhdlan,[0-9]+ \\(.+\\)(\\([0-9]+\\)):" 1 2)
|
|
5942
|
|
5943 ;; Vantage Analysis Systems: analyze -libfile vsslib.ini -src test.vhd
|
|
5944 ;; **Error: LINE 499 *** No aggregate value is valid in this context.
|
|
5945 ; Xemacs does not support error messages without included file name
|
|
5946 (if (not (memq 'XEmacs vhdl-emacs-features))
|
|
5947 '("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" nil 1)
|
|
5948 '("\\*\\*Error: LINE \\([0-9]+\\) \\*\\*\\*" 2 1)
|
|
5949 )
|
|
5950
|
|
5951 ;; Viewlogic: analyze -libfile vsslib.ini -src test.vhd
|
|
5952 ;; **Error: LINE 499 *** No aggregate value is valid in this context.
|
|
5953 ;; same regexp as for Vantage
|
|
5954
|
|
5955 ;; V-System, Model Technology: vcom test.vhd
|
|
5956 ;; ERROR: test.vhd(14): Unknown identifier: positiv
|
|
5957 ;; same regexp as for QuickHDL
|
|
5958
|
|
5959 ) "Alist that specifies how to match errors in VHDL compiler output.")
|
|
5960
|
|
5961 (defvar compilation-file-regexp-alist
|
|
5962 '(
|
|
5963 ;; Ikos Voyager: analyze -libfile vsslib.ini -src test.vhd
|
|
5964 ;; analyze sdrctl.vhd
|
|
5965 ("^analyze +\\(.+ +\\)*\\(.+\\)$" 2)
|
|
5966
|
|
5967 ;; Vantage Analysis Systems: analyze -libfile vsslib.ini -src test.vhd
|
|
5968 ;; Compiling "pcu.vhd" line 1...
|
|
5969 (" *Compiling \"\\(.+\\)\" " 1)
|
|
5970
|
|
5971 ;; Viewlogic: analyze -libfile vsslib.ini -src test.vhd
|
|
5972 ;; Compiling "pcu.vhd" line 1...
|
|
5973 ;; same regexp as for Vantage
|
|
5974
|
|
5975 ) "Alist specifying how to match lines that indicate a new current file.
|
|
5976 Used for compilers with no file name in the error messages.")
|
|
5977
|
|
5978 (defun vhdl-compile ()
|
|
5979 "Compile current buffer using the VHDL compiler specified in
|
|
5980 `vhdl-compiler'."
|
|
5981 (interactive)
|
|
5982 (let ((command-list vhdl-compile-commands)
|
|
5983 command)
|
|
5984 (while command-list
|
|
5985 (if (eq vhdl-compiler (car (car command-list)))
|
|
5986 (setq command (car (cdr (car command-list)))))
|
|
5987 (setq command-list (cdr command-list)))
|
|
5988 (if command
|
|
5989 (compile (concat command " " vhdl-compiler-options
|
|
5990 (if (not (string-equal vhdl-compiler-options "")) " ")
|
|
5991 (file-name-nondirectory (buffer-file-name)))))))
|
|
5992
|
|
5993 (defun vhdl-make ()
|
|
5994 "Call make command for compilation of all updated source files
|
|
5995 (requires `Makefile')."
|
|
5996 (interactive)
|
|
5997 (compile "make"))
|
|
5998
|
|
5999 (defun vhdl-generate-makefile ()
|
|
6000 "Generate new `Makefile'."
|
|
6001 (interactive)
|
|
6002 (let ((command-list vhdl-compile-commands)
|
|
6003 command)
|
|
6004 (while command-list
|
|
6005 (if (eq vhdl-compiler (car (car command-list)))
|
|
6006 (setq command (car (cdr (cdr (car command-list))))))
|
|
6007 (setq command-list (cdr command-list)))
|
|
6008 (if command
|
|
6009 (compile command )
|
|
6010 (message (format "Not implemented for `%s'!" vhdl-compiler))
|
|
6011 (beep))))
|
|
6012
|
|
6013
|
|
6014 ;; ############################################################################
|
|
6015 ;; Bug reports
|
|
6016 ;; ############################################################################
|
|
6017 ;; (using `reporter.el')
|
|
6018
|
|
6019 (defconst vhdl-version "3.19"
|
|
6020 "VHDL Mode version number.")
|
|
6021
|
|
6022 (defconst vhdl-mode-help-address "vhdl-mode@geocities.com"
|
|
6023 "Address for VHDL Mode bug reports.")
|
|
6024
|
|
6025 (defun vhdl-version ()
|
|
6026 "Echo the current version of VHDL Mode in the minibuffer."
|
|
6027 (interactive)
|
|
6028 (message "Using VHDL Mode version %s" vhdl-version)
|
|
6029 (vhdl-keep-region-active))
|
|
6030
|
|
6031 ;; get reporter-submit-bug-report when byte-compiling
|
|
6032 (and (fboundp 'eval-when-compile)
|
|
6033 (eval-when-compile
|
|
6034 (require 'reporter)))
|
|
6035
|
|
6036 (defun vhdl-submit-bug-report ()
|
|
6037 "Submit via mail a bug report on VHDL Mode."
|
|
6038 (interactive)
|
|
6039 ;; load in reporter
|
|
6040 (and
|
|
6041 (y-or-n-p "Do you want to submit a report on VHDL Mode? ")
|
|
6042 (require 'reporter)
|
|
6043 (reporter-submit-bug-report
|
|
6044 vhdl-mode-help-address
|
|
6045 (concat "VHDL Mode " vhdl-version)
|
|
6046 (list
|
|
6047 ;; report all important variables
|
|
6048 'vhdl-basic-offset
|
|
6049 'vhdl-offsets-alist
|
|
6050 'vhdl-comment-only-line-offset
|
|
6051 'tab-width
|
|
6052 'vhdl-electric-mode
|
|
6053 'vhdl-stutter-mode
|
|
6054 'vhdl-indent-tabs-mode
|
|
6055 'vhdl-compiler
|
|
6056 'vhdl-compiler-options
|
|
6057 'vhdl-upper-case-keywords
|
|
6058 'vhdl-upper-case-types
|
|
6059 'vhdl-upper-case-attributes
|
|
6060 'vhdl-upper-case-enum-values
|
|
6061 'vhdl-auto-align
|
|
6062 'vhdl-additional-empty-lines
|
|
6063 'vhdl-argument-list-indent
|
|
6064 'vhdl-conditions-in-parenthesis
|
|
6065 'vhdl-date-format
|
|
6066 'vhdl-header-file
|
|
6067 'vhdl-modify-date-prefix-string
|
|
6068 'vhdl-zero-string
|
|
6069 'vhdl-one-string
|
|
6070 'vhdl-self-insert-comments
|
|
6071 'vhdl-prompt-for-comments
|
|
6072 'vhdl-comment-column
|
|
6073 'vhdl-end-comment-column
|
|
6074 'vhdl-highlight-names
|
|
6075 'vhdl-highlight-keywords
|
|
6076 'vhdl-highlight-signals
|
|
6077 'vhdl-highlight-case-sensitive
|
|
6078 'vhdl-use-default-colors
|
|
6079 'vhdl-use-default-faces
|
|
6080 'vhdl-clock-signal-syntax
|
|
6081 'vhdl-reset-signal-syntax
|
|
6082 'vhdl-control-signal-syntax
|
|
6083 'vhdl-data-signal-syntax
|
|
6084 'vhdl-test-signal-syntax
|
|
6085 'vhdl-source-file-menu
|
|
6086 'vhdl-index-menu
|
|
6087 'vhdl-hideshow-menu
|
|
6088 'vhdl-print-two-column
|
|
6089 'vhdl-intelligent-tab
|
|
6090 'vhdl-template-key-binding-prefix
|
|
6091 'vhdl-word-completion-in-minibuffer
|
|
6092 'vhdl-underscore-is-part-of-word
|
|
6093 'vhdl-mode-hook
|
|
6094 )
|
|
6095 (function
|
|
6096 (lambda ()
|
|
6097 (insert
|
|
6098 (if vhdl-special-indent-hook
|
|
6099 (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
|
|
6100 "vhdl-special-indent-hook is set to '"
|
|
6101 (format "%s" vhdl-special-indent-hook)
|
|
6102 ".\nPerhaps this is your problem?\n"
|
|
6103 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
|
|
6104 "\n")
|
|
6105 (format "vhdl-emacs-features: %s\n" vhdl-emacs-features)
|
|
6106 )))
|
|
6107 nil
|
|
6108 "Dear VHDL Mode maintainers,"
|
|
6109 )))
|
|
6110
|
|
6111
|
|
6112 ;; ############################################################################
|
|
6113
|
|
6114 (provide 'vhdl-mode)
|
|
6115
|
|
6116 ;;; vhdl-mode.el ends here
|