diff options
| author | Karl Heuer | 1998-01-18 03:39:09 +0000 |
|---|---|---|
| committer | Karl Heuer | 1998-01-18 03:39:09 +0000 |
| commit | d2ddb974691b899deaf80e09f468ab04f186b8cc (patch) | |
| tree | 3e463fb043cc034815dd1078a49dd8fd9bd67a97 | |
| parent | d0ed5e526ec33c396e3b491d1cc93bdb7592652a (diff) | |
| download | emacs-d2ddb974691b899deaf80e09f468ab04f186b8cc.tar.gz emacs-d2ddb974691b899deaf80e09f468ab04f186b8cc.zip | |
Initial revision
| -rw-r--r-- | lisp/progmodes/vhdl-mode.el | 6116 |
1 files changed, 6116 insertions, 0 deletions
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el new file mode 100644 index 00000000000..a79bf25232f --- /dev/null +++ b/lisp/progmodes/vhdl-mode.el | |||
| @@ -0,0 +1,6116 @@ | |||
| 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 | ||