1% VHDL mode -* SLang -*- 2% 3% This is a simple vhdl mode. First it implements a highlighting scheme. 4% 5% modified by Thei Wijnen 22-nov-2001: added: xor xnor with after alias select 6% modified by Thei Wijnen 21-mar-2002: added: generate transport rising_edge falling_edge 7% Modified by Thei Wijnen 10-Aug-2003: implemented indentation style and folding. 8% Modified by Thei Wijnen 06-Jun-2004: indent region, added more keywords. 9% Modified by Thei Wijnen 03-Mar-2005: allow mixed case, added more keywords. 10% 11% Loading this file, then executing 'vhdl_mode' will start 12% VHDL mode on the current buffer. 13 14custom_variable ("VHDL_Comment_String", "--"); 15custom_variable ("VHDL_Indent_Amount", 2); 16 17% 18% VHDL indent routine 19 20define vhdl_indent () 21{ 22 variable goal = 1; % start in column 1. 23 variable cs = CASE_SEARCH; 24 variable ch; 25 26 push_spot (); 27 push_spot (); 28 CASE_SEARCH = 0; % VHDL is not case sensitive 29 30 while (up_1 ()) 31 { 32 bol_skip_white(); 33 if (eolp() ) continue; 34 35 goal = what_column (); 36 if (goal == 1) continue; 37 38 if (looking_at("do ") 39 or looking_at("elsif ") or looking_at("elsif(") 40 or looking_at("else") ) 41 { 42 goal += VHDL_Indent_Amount; 43 } 44 else if (looking_at("if ") or looking_at("if(")) 45 { 46 if (ffind("then")) { goal += VHDL_Indent_Amount; } 47 } 48 else if (looking_at("for") or looking_at("for(")) 49 { 50 if (ffind("loop")) goal += VHDL_Indent_Amount; 51 } 52 else if (looking_at("when")) 53 { 54 if (ffind("=>")) goal += VHDL_Indent_Amount; 55 } 56 else if (looking_at("case")) 57 { 58 if (ffind("is")) goal += VHDL_Indent_Amount; 59 } 60 else if (looking_at("begin")) 61 { 62 goal += VHDL_Indent_Amount; 63 } 64 65% else if (looking_at("begin")) 66% { 67% push_spot (); 68% while (up_1 ()) 69% { 70% bol_skip_white(); 71% if (eolp() ) continue; 72% if (looking_at("variable ") or looking_at("process") ) 73% { 74% goal -= VHDL_Indent_Amount; 75% } 76% break; 77% } 78% pop_spot (); 79% } 80 81 break; 82 } 83 pop_spot (); 84 85 % now check current line 86 87 bol_skip_white(); 88% if (looking_at("begin")) 89% goal += VHDL_Indent_Amount; 90 91 if (looking_at("elsif") 92 or looking_at("else") 93 or looking_at("end") 94 or looking_at("when") 95% or looking_at("end if") 96% or looking_at("end process") 97% or looking_at("end loop") 98 ) 99 { 100 goal -= VHDL_Indent_Amount; 101 } 102 103 CASE_SEARCH = cs; % done getting indent 104 105 bol_skip_white (); 106 107 ch = char(what_char()); 108 switch (ch) 109%* { 110%* isdigit (ch) : % label 111%* 112%* if (what_column () >= 6) 113%* { 114%* bol_trim (); 115%* insert_single_space (); 116%* } 117%* X_USER_BLOCK1 (); 118%* } 119 { 120 not (bolp()) or eolp (): % general case 121 bol_trim (); 122 goal--; 123 insert_spaces (goal); 124 } 125 pop_spot (); 126 skip_white (); 127} 128 129 130define vhdl_newline () 131{ 132 variable p, cont; 133 134 if (bolp ()) 135 { 136 newline (); 137 return; 138 } 139 140 vhdl_indent (); 141 push_spot (); 142 bskip_white (); trim (); 143 pop_spot (); 144 145 newline (); 146 insert_single_space (); 147 vhdl_indent (); 148} 149 150 151% 152% Look for beginning of current subroutine/function 153 154define vhdl_beg_of_subprogram () 155{ 156 variable cs = CASE_SEARCH; 157 158 CASE_SEARCH = 0; 159 do 160 { 161 bol_skip_white (); 162 if (_get_point ()) 163 { 164 if (looking_at ("process") 165 or looking_at ("switch")) break; 166 } 167 } 168 while (up_1 ()); 169 CASE_SEARCH = cs; 170} 171 172% 173% Look for end of current subroutine/function 174 175define vhdl_end_of_subprogram () 176{ 177 variable cs = CASE_SEARCH; 178 CASE_SEARCH = 0; 179 180 do 181 { 182 bol_skip_white (); 183 if (looking_at ("end;") 184 or looking_at ("end process")) break; 185% { 186% go_right (3); 187% skip_white (); 188% if (eolp ()) break; 189% } 190 } 191 while (down_1 ()); 192 CASE_SEARCH = cs; 193} 194 195define vhdl_mark_subprogram () 196{ 197 vhdl_end_of_subprogram (); 198 go_down_1 (); 199 set_mark_cmd (); 200 vhdl_beg_of_subprogram (); 201 bol (); 202} 203 204 205% Indent the selected region (bound to \e^i) 206 207define vhdl_indent_region () 208{ 209 check_region(1); 210 pop_mark_1 (); 211 push_mark(); 212 vhdl_indent(); % set initial line indentation before narrowing 213 pop_spot(); 214 215 push_spot(); 216 go_up_1 (); 217 narrow(); 218 bob(); 219 220 flush("Indenting region..."); 221 while (down_1 ()) { % indent line by line (ie slowly) 222 vhdl_indent(); 223 % flush(Sprintf("Indenting line %d", what_line(), 1)); 224 } 225 flush("Indenting region... Done."); 226 227 widen(); 228 pop_spot(); 229} 230 231% 232% main entry point into the VHDL mode 233% 234% Set up syntax table 235 236$1 = "VHDL"; 237 238create_syntax_table ($1); 239define_syntax ("--","",'%', $1); % comments 240define_syntax ("([{", ")]}", '(', $1); % parentheses 241define_syntax ('"', '"', $1); % quoted strings 242%define_syntax ('\'', '\'', $1); % quoted characters (paired ') 243define_syntax ('\'', '\\', $1); % continuations 244define_syntax ("0-9a-zA-Z_", 'w', $1); % words 245define_syntax ("-+0-9a-fA-F.xXL", '0', $1); % numbers 246define_syntax (",;.?:=<>", ',', $1); % delimiters 247define_syntax ('#', '#', $1); % preprocessor 248define_syntax ("%-+/&*<>|!~^", '+', $1); % operators 249set_syntax_flags ($1, 8); % 250 251% Type 0 keywords 252 253() = define_keywords ($1, "ifinisofonorto", 2); 254() = define_keywords ($1, "absandendformapmaxminmodnornotoutremrunusexor", 3); 255() = define_keywords ($1, "casebodyelsefileloopnandnextopenportpurethentypewaitwhenwithxnor", 4); 256() = define_keywords ($1, "afteraliasbeginelsifgroupinoutlabeltraceuntilwhile", 5); 257() = define_keywords ($1, "accessassertassignbufferdowntoentityimpureothersrecordrejectreportreturnselectsharedsignal", 6); 258() = define_keywords ($1, "genericguardedlibraryliteralpackageprocesssubtype", 7); 259() = define_keywords ($1, "constantfunctiongenerateinertialregisterseverityvariable", 8); 260() = define_keywords ($1, "attributecomponentpostponedproceduretransport", 9); 261() = define_keywords ($1, "architecture", 12); 262() = define_keywords ($1, "configuration", 13); 263 264% Type 1 keywords - use for operator like keywords 265() = define_keywords_n ($1, "eqgegtleltne", 2, 1); 266() = define_keywords_n ($1, "lowposslasllsrasrlval", 3, 1); 267() = define_keywords_n ($1, "basehighleftnotepredsucctrue", 4, 1); 268() = define_keywords_n ($1, "erroreventfalseimagequietrangerightvalue", 5, 1); 269() = define_keywords_n ($1, "activeleftoflengthstable", 6, 1); 270() = define_keywords_n ($1, "delayeddrivingfailurerightofwarning", 7, 1); 271() = define_keywords_n ($1, "ascendingdecending", 9, 1); 272() = define_keywords_n ($1, "last_eventlast_value", 10, 1); 273() = define_keywords_n ($1, "last_activerising_edgetransaction", 11, 1); 274() = define_keywords_n ($1, "falling_edge", 12, 1); 275() = define_keywords_n ($1, "driving_valuereverse_range", 13, 1); 276 277% Type 2 keywords - use for type declarator keywords 278() = define_keywords_n ($1, "msnspsus", 2, 2); 279() = define_keywords_n ($1, "linetime", 4, 2); 280() = define_keywords_n ($1, "string", 6, 2); 281() = define_keywords_n ($1, "booleanintegernatural", 7, 2); 282() = define_keywords_n ($1, "unsigned", 8, 2); 283() = define_keywords_n ($1, "characterstd_logic", 9, 2); 284() = define_keywords_n ($1, "std_logic_vector", 16, 2); 285 286% Set up syntax table 287 288$1 = "VHDL"; 289!if (keymap_p ($1)) make_keymap ($1); 290 291definekey ("vhdl_beg_of_subprogram", "\e^A", $1); 292definekey ("vhdl_end_of_subprogram", "\e^E", $1); 293definekey ("vhdl_mark_subprogram", "\e^H", $1); 294definekey ("vhdl_indent_region", "\e^I", $1); 295 296%!%+ 297%\function{vhdl_mode} 298%\synopsis{vhdl_mode} 299%\description 300% Mode designed for the purpose of editing VHDL files. 301% After the mode is loaded, the hook 'vhdl_hook' is called. 302% Useful functions include 303% 304% Function: Default Binding: 305% vhdl_beg_of_subprogram ESC ^A 306% moves cursor to beginning of current function/process 307% vhdl_end_of_subprogram ESC ^E 308% moves cursor to end of current function/process 309% vhdl_mark_subprogram ESC ^H 310% mark the current function/process 311% 312% Variables include: 313% VHDL_Comment_String : string used by 'vhdl_comment' to 314% comment out a line. Default is "--". 315% VHDL_Indent_Amount : number of spaces to indent statements in 316% a block. The default is 2. 317%!%- 318 319define vhdl_mode () 320{ 321 variable mode = "VHDL"; 322 set_mode (mode, 0x4 | 0x10); 323 use_keymap (mode); 324 use_syntax_table (mode); 325 set_syntax_flags (mode, 0x01); 326 set_buffer_hook ("indent_hook", "vhdl_indent"); 327 set_buffer_hook ("newline_indent_hook", "vhdl_newline"); 328 mode_set_mode_info (mode, "fold_info", "--{{{\r--}}}\r\r"); 329 run_mode_hooks ("vhdl_mode_hook"); 330} 331 332