1% -*- SLang -*- ruby.sl 2 3% Author: MAEDA Shugo (shugo@po.aianet.ne.jp) 4% Version: 0.03 5 6% `Ruby mode for Jed' is FREESOFTWARE. 7% Please use AT YOUR OWN RISK. 8 9% [What's ruby?] 10% 11% Ruby is the interpreted scripting language for quick and 12% easy object-oriented programming. It has many features to 13% process text files and to do system management tasks (as in 14% perl). It is simple, straight-forward, and extensible. 15% 16% The ruby distribution can be found on 17% 18% ftp://ftp.netlab.co.jp/pub/lang/ruby/ 19 20% [Install] 21% 22% Please add these lines to your `.jedrc' file. 23% 24% ~/.jedrc 25% 26% % amount of space to indent within block. 27% variable ruby_indent_level = 2; 28% 29% % Load ruby mode when openning `.rb' files. 30% autoload("ruby_mode", "ruby"); 31% add_mode_for_extension ("ruby", "rb"); 32 33variable ruby_mode_version = "0.0.3"; 34 35!if (is_defined ("ruby_indent_level")) 36{ 37 variable ruby_indent_level = 2; 38} 39 40define ruby_show_version() 41{ 42 message(Sprintf("ruby mode for Jed version %s", ruby_mode_version, 1)); 43} 44 45define ruby_indent_to(n) 46{ 47 variable step; 48 49 step = what_column(); 50 bol_skip_white(); 51 step -= what_column(); 52 if (what_column != n) { 53 bol_trim (); 54 n--; 55 whitespace (n); 56 } 57 if (step > 0) go_right(step); 58} 59 60define ruby_looking_keyword_at(keyword) 61{ 62 push_spot; 63 EXIT_BLOCK { 64 pop_spot; 65 } 66 67 if (looking_at(keyword)) { 68 go_right(strlen(keyword)); 69 return (orelse 70 { looking_at(" ") } 71 { looking_at("\t") } 72 { looking_at(";") } 73 { eolp() } 74 ); 75 } else { 76 return 0; 77 } 78} 79 80define ruby_calculate_indent() 81{ 82 variable indent = 0; 83 variable extra_indent = 0; 84 variable ch; 85 variable par_level; 86 87 CASE_SEARCH = 0; 88 push_spot(); 89 EXIT_BLOCK { 90 pop_spot(); 91 } 92 93 bol_skip_white(); 94 indent = what_column(); 95 if (orelse 96 { ruby_looking_keyword_at("end") } 97 { ruby_looking_keyword_at("else") } 98 { ruby_looking_keyword_at("elsif") } 99 { ruby_looking_keyword_at("rescue") } 100 { ruby_looking_keyword_at("ensure") } 101 { ruby_looking_keyword_at("when") } 102 { looking_at("}") } 103 ) { 104 extra_indent -= ruby_indent_level; 105 } 106 !if (up_1()) return indent; 107 108 eol(); 109 par_level = 0; 110 forever { 111 if (eolp()) { 112 forever { 113 bol(); 114 if (looking_at("#")) { 115 !if (up_1()) return indent; 116 eol(); 117 } else { 118 eol(); 119 break; 120 } 121 } 122 } 123 go_left_1(); 124 ch = what_char(); 125 if (ch == ')') { 126 par_level--; 127 } else if (ch == '(') { 128 par_level++; 129 if (par_level == 1) return what_column() + 1; 130 } 131 132 if (bolp() and (par_level == 0)) { 133 skip_white(); 134 indent = what_column(); 135 break; 136 } 137 } 138 139 if (looking_at("#")) return what_column(); 140 141 if (orelse 142 { ruby_looking_keyword_at("class") } 143 { ruby_looking_keyword_at("module") } 144 { ruby_looking_keyword_at("def") } 145 { ruby_looking_keyword_at("if") } 146 { ruby_looking_keyword_at("else") } 147 { ruby_looking_keyword_at("elsif") } 148 { ruby_looking_keyword_at("unless") } 149 { ruby_looking_keyword_at("case") } 150 { ruby_looking_keyword_at("when") } 151 { ruby_looking_keyword_at("while") } 152 { ruby_looking_keyword_at("until") } 153 { ruby_looking_keyword_at("for") } 154 { ruby_looking_keyword_at("begin") } 155 { ruby_looking_keyword_at("rescue") } 156 { ruby_looking_keyword_at("ensure") } 157 ) { 158 eol(); 159 bskip_white(); 160 !if (orelse 161 { blooking_at(" end") } 162 { blooking_at("\tend") } 163 ) { 164 extra_indent += ruby_indent_level; 165 } 166 } else { 167 eol(); 168 bskip_white(); 169 if (blooking_at("{")) 170 extra_indent += ruby_indent_level; 171 else if (blooking_at("|")) 172 extra_indent += ruby_indent_level; 173 else if (blooking_at(" do")) 174 extra_indent += ruby_indent_level; 175 } 176 177 return indent + extra_indent; 178} 179 180define ruby_indent_line() 181{ 182 ruby_indent_to(ruby_calculate_indent()); 183} 184 185define ruby_newline_and_indent() 186{ 187 variable step; 188 step = what_column(); 189 bol_skip_white(); 190 step -= what_column(); 191 if (orelse 192 { looking_at("end") } 193 { looking_at("else") } 194 { looking_at("elsif") } 195 { looking_at("rescue") } 196 { looking_at("ensure") } 197 { looking_at("when") } 198 { looking_at("}") } 199 ) { 200 ruby_indent_line(); 201 } 202 go_right(step); 203 newline(); 204 ruby_indent_line(); 205} 206 207define ruby_self_insert_cmd() 208{ 209 variable step; 210 211% insert(LAST_CHAR); 212 insert(char(LAST_CHAR)); 213 step = what_column(); 214 bol_skip_white(); 215 step -= what_column(); 216 if (orelse 217 { looking_at("end") } 218 { looking_at("else") } 219 { looking_at("elsif") } 220 { looking_at("rescue") } 221 { looking_at("ensure") } 222 { looking_at("when") } 223 { looking_at("}") } 224 ) { 225 ruby_indent_line(); 226 } 227 go_right(step); 228} 229 230% Define keymap. 231$1 = "ruby"; 232!if (keymap_p($1)) make_keymap($1); 233definekey ("ruby_show_version", "^Cv", $1); 234definekey ("ruby_self_insert_cmd", "0", $1); 235definekey ("ruby_self_insert_cmd", "1", $1); 236definekey ("ruby_self_insert_cmd", "2", $1); 237definekey ("ruby_self_insert_cmd", "3", $1); 238definekey ("ruby_self_insert_cmd", "4", $1); 239definekey ("ruby_self_insert_cmd", "5", $1); 240definekey ("ruby_self_insert_cmd", "6", $1); 241definekey ("ruby_self_insert_cmd", "7", $1); 242definekey ("ruby_self_insert_cmd", "8", $1); 243definekey ("ruby_self_insert_cmd", "9", $1); 244definekey ("ruby_self_insert_cmd", "a", $1); 245definekey ("ruby_self_insert_cmd", "b", $1); 246definekey ("ruby_self_insert_cmd", "c", $1); 247definekey ("ruby_self_insert_cmd", "d", $1); 248definekey ("ruby_self_insert_cmd", "e", $1); 249definekey ("ruby_self_insert_cmd", "f", $1); 250definekey ("ruby_self_insert_cmd", "g", $1); 251definekey ("ruby_self_insert_cmd", "h", $1); 252definekey ("ruby_self_insert_cmd", "i", $1); 253definekey ("ruby_self_insert_cmd", "j", $1); 254definekey ("ruby_self_insert_cmd", "k", $1); 255definekey ("ruby_self_insert_cmd", "l", $1); 256definekey ("ruby_self_insert_cmd", "m", $1); 257definekey ("ruby_self_insert_cmd", "n", $1); 258definekey ("ruby_self_insert_cmd", "o", $1); 259definekey ("ruby_self_insert_cmd", "p", $1); 260definekey ("ruby_self_insert_cmd", "q", $1); 261definekey ("ruby_self_insert_cmd", "r", $1); 262definekey ("ruby_self_insert_cmd", "s", $1); 263definekey ("ruby_self_insert_cmd", "t", $1); 264definekey ("ruby_self_insert_cmd", "u", $1); 265definekey ("ruby_self_insert_cmd", "v", $1); 266definekey ("ruby_self_insert_cmd", "w", $1); 267definekey ("ruby_self_insert_cmd", "x", $1); 268definekey ("ruby_self_insert_cmd", "y", $1); 269definekey ("ruby_self_insert_cmd", "z", $1); 270definekey ("ruby_self_insert_cmd", "A", $1); 271definekey ("ruby_self_insert_cmd", "B", $1); 272definekey ("ruby_self_insert_cmd", "C", $1); 273definekey ("ruby_self_insert_cmd", "D", $1); 274definekey ("ruby_self_insert_cmd", "E", $1); 275definekey ("ruby_self_insert_cmd", "F", $1); 276definekey ("ruby_self_insert_cmd", "G", $1); 277definekey ("ruby_self_insert_cmd", "H", $1); 278definekey ("ruby_self_insert_cmd", "I", $1); 279definekey ("ruby_self_insert_cmd", "J", $1); 280definekey ("ruby_self_insert_cmd", "K", $1); 281definekey ("ruby_self_insert_cmd", "L", $1); 282definekey ("ruby_self_insert_cmd", "M", $1); 283definekey ("ruby_self_insert_cmd", "N", $1); 284definekey ("ruby_self_insert_cmd", "O", $1); 285definekey ("ruby_self_insert_cmd", "P", $1); 286definekey ("ruby_self_insert_cmd", "Q", $1); 287definekey ("ruby_self_insert_cmd", "R", $1); 288definekey ("ruby_self_insert_cmd", "S", $1); 289definekey ("ruby_self_insert_cmd", "T", $1); 290definekey ("ruby_self_insert_cmd", "U", $1); 291definekey ("ruby_self_insert_cmd", "V", $1); 292definekey ("ruby_self_insert_cmd", "W", $1); 293definekey ("ruby_self_insert_cmd", "X", $1); 294definekey ("ruby_self_insert_cmd", "Y", $1); 295definekey ("ruby_self_insert_cmd", "Z", $1); 296definekey ("ruby_self_insert_cmd", "_", $1); 297definekey ("ruby_self_insert_cmd", "{", $1); 298definekey ("ruby_self_insert_cmd", "}", $1); 299definekey ("ruby_self_insert_cmd", ";", $1); 300 301% Create syntax table. 302create_syntax_table ($1); 303define_syntax ("#", Null_String, '%', $1); 304define_syntax ("([{<", ")]}>", '(', $1); 305define_syntax ('"', '"', $1); 306define_syntax ('\'', '\'', $1); 307define_syntax ('\\', '\\', $1); 308define_syntax ("$0-9a-zA-Z_", 'w', $1); 309define_syntax ("-+0-9a-fA-F.xXL", '0', $1); 310define_syntax (",;.?:", ',', $1); 311define_syntax ("%-+/&*=<>|!~^", '+', $1); 312set_syntax_flags ($1, 4); 313 314#ifdef HAS_DFA_SYNTAX 315enable_highlight_cache("ruby.dfa", $1); 316define_highlight_rule("#.*$", "comment", $1); 317define_highlight_rule("([\\$%&@\\*]|\\$#)[A-Za-z_0-9]+", "normal", $1); 318define_highlight_rule(strcat("\\$([_\\./,\"\\\\#\\*\\?\\]\\[;!@:\\$<>\\(\\)", 319 "%=\\-~\\^\\|&`'\\+]|\\^[A-Z])"), "normal", $1); 320define_highlight_rule("[A-Za-z_][A-Za-z_0-9]*", "Knormal", $1); 321define_highlight_rule("[0-9]+(\\.[0-9]+)?([Ee][\\+\\-]?[0-9]*)?", "number", 322 $1); 323define_highlight_rule("0[xX][0-9A-Fa-f]*", "number", $1); 324define_highlight_rule("[\\(\\[\\{\\<\\>\\}\\]\\),;\\.\\?:]", "delimiter", $1); 325define_highlight_rule("[%\\-\\+/&\\*=<>\\|!~\\^]", "operator", $1); 326define_highlight_rule("-[A-Za-z]", "keyword0", $1); 327define_highlight_rule("'[^']*'", "string", $1); 328define_highlight_rule("'[^']*$", "string", $1); 329define_highlight_rule("\"([^\"\\\\]|\\\\.)*\"", "string", $1); 330define_highlight_rule("\"([^\"\\\\]|\\\\.)*\\\\?$", "string", $1); 331define_highlight_rule("m?/([^/\\\\]|\\\\.)*/[gio]*", "string", $1); 332define_highlight_rule("m/([^/\\\\]|\\\\.)*\\\\?$", "string", $1); 333define_highlight_rule("s/([^/\\\\]|\\\\.)*(/([^/\\\\]|\\\\.)*)?/[geio]*", 334 "string", $1); 335define_highlight_rule("s/([^/\\\\]|\\\\.)*(/([^/\\\\]|\\\\.)*)?\\\\?$", 336 "string", $1); 337define_highlight_rule("(tr|y)/([^/\\\\]|\\\\.)*(/([^/\\\\]|\\\\.)*)?/[cds]*", 338 "string", $1); 339define_highlight_rule("(tr|y)/([^/\\\\]|\\\\.)*(/([^/\\\\]|\\\\.)*)?\\\\?$", 340 "string", $1); 341define_highlight_rule(".", "normal", $1); 342build_highlight_table ($1); 343#endif 344 345% Type 0 keywords 346() = define_keywords_n ($1, "doifinor", 2, 0); 347() = define_keywords_n ($1, "anddefendfornilnot", 3, 0); 348() = define_keywords_n ($1, "caseelsefailloadloopnextredoselfthenwhen", 4, 0); 349() = define_keywords_n ($1, "aliasbeginbreakclasselsifraiseretrysuperundefuntilwhileyield", 5, 0); 350() = define_keywords_n ($1, "ensuremodulerescuereturnunless", 6, 0); 351() = define_keywords_n ($1, "includerequire", 7, 0); 352() = define_keywords_n ($1, "autoload", 8, 0); 353% Type 1 keywords (commonly used libc functions) 354() = define_keywords_n($1, "TRUEtrue", 4, 1); 355() = define_keywords_n($1, "FALSEfalse", 5, 1); 356 357define ruby_mode() 358{ 359 variable kmap = "ruby"; 360 set_mode(kmap, 2); 361 use_keymap(kmap); 362 use_syntax_table(kmap); 363 set_buffer_hook("indent_hook", "ruby_indent_line"); 364 set_buffer_hook("newline_indent_hook", "ruby_newline_and_indent"); 365 runhooks("ruby_mode_hook"); 366} 367