├── README.md ├── README.md.erb ├── Rakefile ├── colors └── detailed.vim ├── img ├── go.png ├── javascript-handlebars.js.png ├── misbehaving-detailed.png ├── pry-method.png ├── ruby-unrealistically-packed-syntax.png └── vim-detailed.png └── test ├── app └── models │ └── omni.rb ├── config └── environment.rb ├── default-omni-vim ├── demo.js ├── demo.rb ├── edit-detailed-vim ├── example.c ├── example.go ├── ft └── sh ├── mux ├── omni-vim └── vim-detailed-dev-layout /README.md: -------------------------------------------------------------------------------- 1 | # vim-detailed 2 | 3 | ![behaving](img/vim-detailed.png) 4 | 5 | 6 | 7 | So many 256-color schemes merely shift the palette around, displaying only 8 8 | colors (even though they're a *different* set of 8 colors than default). 9 | 10 | This scheme is more detailed than that. 11 | 12 | Your eyes will learn to pick up on subtler patterns without requiring as 13 | much from your conscious mind. Instead of the goal being merely looking 14 | cool, the goal is to maximize info bandwidth from the computer to the brain. 15 | The regexes, for example, are much easier to pick out. The overall feel of a 16 | given file becomes much more intuitively recognizeable (you'll know you're 17 | in foo.rb, not bar.rb, without having to read any text). Certain bits will 18 | "pop" into being the right colors, such as the difference between 19 | "RUBY_VERISON" and "RUBY_VERSION", or # encoding: utf-8 20 | 21 | ## 256 Color Requirement 22 | 23 | If you aren't getting 256 colors, you aren't getting detailed.vim. 24 | Typically, you'll have to make sure your `$TERM` variable is set right. This 25 | can get un-set by some programs, such as tmux. So you can force it to 26 | something like: 27 | 28 | export TERM=screen-256color 29 | # or: 30 | export TERM=xterm-256color 31 | 32 | If these are unavailable on the target system, you might have to place a 33 | terminfo file in `~/.terminfo/` -or- you can be totally gross and force it 34 | with `:set &t_Co=256` in vim. But don't be gross. It's uncouth. 35 | 36 | ## Download 37 | 38 | If using Pathogen, 39 | 40 | cd ~/.vim/bundle && git clone https://github.com/rking/vim-detailed 41 | 42 | If using no vim plugin manager: 43 | 44 | mkdir -p ~/.vim/colors/ && cd $_ && wget https://raw.github.com/rking/vim-detailed/master/colors/detailed.vim 45 | 46 | ## Setup 47 | 48 | In your ~/.vimrc (or ~/.vim/plugin/colorscheme.vim if you like to organize): 49 | 50 | colo detailed 51 | 52 | This enables it globally. If you want to just do it for a trial, as long as 53 | you have done one of the steps in the "Download" section, above, you can do: 54 | 55 | vim foo.rb +colo\ detailed 56 | 57 | Or, from within vim: 58 | 59 | :colo detailed 60 | 61 | 62 | ## Language Support So Far 63 | 64 | - Ruby: 113 details detailed. 65 | - C: 12 details detailed. 66 | - Go: 10 details detailed. 67 | - Diff: 10 details detailed. 68 | - Javascript: 4 details detailed. 69 | - Vim: 4 details detailed. 70 | 71 | 72 | Note that for fully supported languages (Ruby), you get the whole experience of having the subtle color shades that fingerprint and lint the code when you glance at it. 73 | 74 | For the lesser grades mentioned above, you should get a bit more, but know that the `syntax/[yourlang].vim` has to have enough semantic parsing to make this possible. If you want to go further, you can certainly get a patch in that enhances the syntax parsing inside vim-detailed's `colors/detailed.vim` file. 75 | 76 | For all other languages, even the ones not listed above, you should at least get: 77 | - Rainbow parens/brackets/curlies (which can be very helpful when the syntax gets deep) 78 | - Quiet comments (grey, because "a comment is a lie waiting to happen") 79 | - Strings with gray background (so it looks like a solid chunk) 80 | - Muted colorcolumn (gray instead of GIANT LOUD RED) 81 | - A color palette somewhat consistent with the detailed ones 82 | 83 | ## Issues: 84 | 85 | # rking/vim-detailed open issues 86 | 13 More troubleshooting help? 3 87 | 11 Smart Here-docs 1 88 | 9 Detail Python [actual-user-request] 4 89 | 7 Handle t_Co != 256 90 | 6 Pygments Companion 91 | 3 Distinguish Foo and Bar of "class Foo < Bar" 92 | 93 | 94 | ## Troubleshooting 95 | 96 | This is wrong: 97 | 98 | ![misbehaving](img/misbehaving-detailed.png) 99 | -------------------------------------------------------------------------------- /README.md.erb: -------------------------------------------------------------------------------- 1 | # vim-detailed 2 | 3 | ![behaving](img/vim-detailed.png) 4 | 5 | <%= `rake parse_readme`.sub /Source repo.*/, '' %> 6 | 7 | <%= `rake lang_stats` %> 8 | 9 | Note that for fully supported languages (Ruby), you get the whole experience of having the subtle color shades that fingerprint and lint the code when you glance at it. 10 | 11 | For the lesser grades mentioned above, you should get a bit more, but know that the `syntax/[yourlang].vim` has to have enough semantic parsing to make this possible. If you want to go further, you can certainly get a patch in that enhances the syntax parsing inside vim-detailed's `colors/detailed.vim` file. 12 | 13 | For all other languages, even the ones not listed above, you should at least get: 14 | - Rainbow parens/brackets/curlies (which can be very helpful when the syntax gets deep) 15 | - Quiet comments (grey, because "a comment is a lie waiting to happen") 16 | - Strings with gray background (so it looks like a solid chunk) 17 | - Muted colorcolumn (gray instead of GIANT LOUD RED) 18 | - A color palette somewhat consistent with the detailed ones 19 | 20 | ## Issues: 21 | 22 | <%= `ghi list` %> 23 | 24 | ## Troubleshooting 25 | 26 | This is wrong: 27 | 28 | ![misbehaving](img/misbehaving-detailed.png) 29 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | task :default => [ :readme ] 2 | 3 | task :readme do 4 | sh 'erb < README.md.erb > README.md' 5 | sh 'git diff' 6 | end 7 | 8 | def detailed_dot_vim_contents 9 | File.read 'colors/detailed.vim' 10 | end 11 | 12 | def parse_readme 13 | text = detailed_dot_vim_contents 14 | text.sub! /\n\n.*/m, '' 15 | text.gsub! /^" ?/, '' 16 | end 17 | task :parse_readme do 18 | puts parse_readme 19 | end 20 | 21 | def lang_stats 22 | text = detailed_dot_vim_contents 23 | lang_specific_funcs = text.scan( 24 | /fun! s:([^_]+)_syntax_and_highlights(.*?)endfun/m) 25 | stats = lang_specific_funcs.map do |lang,body| 26 | [lang.capitalize, body.split(/\n+/).size] 27 | end.sort_by{|k,v| -v}.map do |lang, body_size| 28 | "- #{lang}: #{body_size} details detailed." 29 | end 30 | (['## Language Support So Far', ''] + stats).join "\n" 31 | end 32 | task :lang_stats do 33 | puts lang_stats 34 | end 35 | 36 | task :vimorg do 37 | docs = parse_readme + "\n\n" + lang_stats + "\n\n" + `ghi list` 38 | docs.gsub! '##', '//' 39 | puts docs 40 | IO.popen 'xsel', 'w' do |io| io.puts docs end 41 | warn 'http://www.vim.org/scripts/edit_script.php?script_id=4297' 42 | end 43 | -------------------------------------------------------------------------------- /colors/detailed.vim: -------------------------------------------------------------------------------- 1 | " Source repo: http://github.com/rking/vim-detailed 2 | " 3 | " So many 256-color schemes merely shift the palette around, displaying only 8 4 | " colors (even though they're a *different* set of 8 colors than default). 5 | " 6 | " This scheme is more detailed than that. 7 | " 8 | " Your eyes will learn to pick up on subtler patterns without requiring as 9 | " much from your conscious mind. Instead of the goal being merely looking 10 | " cool, the goal is to maximize info bandwidth from the computer to the brain. 11 | " The regexes, for example, are much easier to pick out. The overall feel of a 12 | " given file becomes much more intuitively recognizeable (you'll know you're 13 | " in foo.rb, not bar.rb, without having to read any text). Certain bits will 14 | " "pop" into being the right colors, such as the difference between 15 | " "RUBY_VERISON" and "RUBY_VERSION", or # encoding: utf-8 16 | " 17 | " ## 256 Color Requirement 18 | " 19 | " If you aren't getting 256 colors, you aren't getting detailed.vim. 20 | " Typically, you'll have to make sure your `$TERM` variable is set right. This 21 | " can get un-set by some programs, such as tmux. So you can force it to 22 | " something like: 23 | " 24 | " export TERM=screen-256color 25 | " # or: 26 | " export TERM=xterm-256color 27 | " 28 | " If these are unavailable on the target system, you might have to place a 29 | " terminfo file in `~/.terminfo/` -or- you can be totally gross and force it 30 | " with `:set &t_Co=256` in vim. But don't be gross. It's uncouth. 31 | " 32 | " ## Download 33 | " 34 | " If using Pathogen, 35 | " 36 | " cd ~/.vim/bundle && git clone https://github.com/rking/vim-detailed 37 | " 38 | " If using no vim plugin manager: 39 | " 40 | " mkdir -p ~/.vim/colors/ && cd $_ && wget https://raw.github.com/rking/vim-detailed/master/colors/detailed.vim 41 | " 42 | " ## Setup 43 | " 44 | " In your ~/.vimrc (or ~/.vim/plugin/colorscheme.vim if you like to organize): 45 | " 46 | " colo detailed 47 | " 48 | " This enables it globally. If you want to just do it for a trial, as long as 49 | " you have done one of the steps in the "Download" section, above, you can do: 50 | " 51 | " vim foo.rb +colo\ detailed 52 | " 53 | " Or, from within vim: 54 | " 55 | " :colo detailed 56 | 57 | let colors_name = 'detailed' 58 | 59 | " Prevent any screwy setting from causing errors: 60 | let s:save_cpo = &cpo | set cpo&vim 61 | 62 | " Turn on moar syntaks! 63 | let ruby_operators = 1 64 | 65 | " If you don't have this, rails.vim will zap the matchers when it resets 66 | " syntax for its own additions: 67 | au Syntax * call s:fatpacked_rainbow_parens() 68 | au Syntax * call s:detailed_syntax_addtions() 69 | 70 | au Syntax ruby call s:ruby_syntax_and_highlights() 71 | au Syntax c call s:c_syntax_and_highlights() 72 | au Syntax diff call s:diff_syntax_and_highlights() 73 | au Syntax vim call s:vim_syntax_and_highlights() 74 | au Syntax javascript call s:javascript_syntax_and_highlights() 75 | au Syntax go call s:go_syntax_and_highlights() 76 | 77 | " Show detailed syntax stack 78 | nmap dets :call SynStack() 79 | fun! SynStack() 80 | echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') 81 | endfun 82 | 83 | " Color Palette {{{ 84 | 85 | " Boring ctermfg ⇒ guifg map {{{ 86 | let s:cterm_gui_map = { 87 | \0: '000000', 88 | \1: 'ff0000', 89 | \2: '00ff00', 90 | \3: 'ffff00', 91 | \4: '0000ff', 92 | \5: 'ff00ff', 93 | \6: '00ffff', 94 | \16: '000000', 95 | \17: '00005f', 96 | \18: '000087', 97 | \19: '0000af', 98 | \20: '0000d7', 99 | \21: '0000ff', 100 | \22: '005f00', 101 | \23: '005f5f', 102 | \24: '005f87', 103 | \25: '005faf', 104 | \26: '005fd7', 105 | \27: '005fff', 106 | \28: '008700', 107 | \29: '00875f', 108 | \30: '008787', 109 | \31: '0087af', 110 | \32: '0087d7', 111 | \33: '0087ff', 112 | \34: '00af00', 113 | \35: '00af5f', 114 | \36: '00af87', 115 | \37: '00afaf', 116 | \38: '00afd7', 117 | \39: '00afff', 118 | \40: '00d700', 119 | \41: '00d75f', 120 | \42: '00d787', 121 | \43: '00d7af', 122 | \44: '00d7d7', 123 | \45: '00d7ff', 124 | \46: '00ff00', 125 | \47: '00ff5f', 126 | \48: '00ff87', 127 | \49: '00ffaf', 128 | \50: '00ffd7', 129 | \51: '00ffff', 130 | \52: '5f0000', 131 | \53: '5f005f', 132 | \54: '5f0087', 133 | \55: '5f00af', 134 | \56: '5f00d7', 135 | \57: '5f00ff', 136 | \58: '5f5f00', 137 | \59: '5f5f5f', 138 | \60: '5f5f87', 139 | \61: '5f5faf', 140 | \62: '5f5fd7', 141 | \63: '5f5fff', 142 | \64: '5f8700', 143 | \65: '5f875f', 144 | \66: '5f8787', 145 | \67: '5f87af', 146 | \68: '5f87d7', 147 | \69: '5f87ff', 148 | \70: '5faf00', 149 | \71: '5faf5f', 150 | \72: '5faf87', 151 | \73: '5fafaf', 152 | \74: '5fafd7', 153 | \75: '5fafff', 154 | \76: '5fd700', 155 | \77: '5fd75f', 156 | \78: '5fd787', 157 | \79: '5fd7af', 158 | \80: '5fd7d7', 159 | \81: '5fd7ff', 160 | \82: '5fff00', 161 | \83: '5fff5f', 162 | \84: '5fff87', 163 | \85: '5fffaf', 164 | \86: '5fffd7', 165 | \87: '5fffff', 166 | \88: '870000', 167 | \89: '87005f', 168 | \90: '870087', 169 | \91: '8700af', 170 | \92: '8700d7', 171 | \93: '8700ff', 172 | \94: '875f00', 173 | \95: '875f5f', 174 | \96: '875f87', 175 | \97: '875faf', 176 | \98: '875fd7', 177 | \99: '875fff', 178 | \100: '878700', 179 | \101: '87875f', 180 | \102: '878787', 181 | \103: '8787af', 182 | \104: '8787d7', 183 | \105: '8787ff', 184 | \106: '87af00', 185 | \107: '87af5f', 186 | \108: '87af87', 187 | \109: '87afaf', 188 | \110: '87afd7', 189 | \111: '87afff', 190 | \112: '87d700', 191 | \113: '87d75f', 192 | \114: '87d787', 193 | \115: '87d7af', 194 | \116: '87d7d7', 195 | \117: '87d7ff', 196 | \118: '87ff00', 197 | \119: '87ff5f', 198 | \120: '87ff87', 199 | \121: '87ffaf', 200 | \122: '87ffd7', 201 | \123: '87ffff', 202 | \124: 'af0000', 203 | \125: 'af005f', 204 | \126: 'af0087', 205 | \127: 'af00af', 206 | \128: 'af00d7', 207 | \129: 'af00ff', 208 | \130: 'af5f00', 209 | \131: 'af5f5f', 210 | \132: 'af5f87', 211 | \133: 'af5faf', 212 | \134: 'af5fd7', 213 | \135: 'af5fff', 214 | \136: 'af8700', 215 | \137: 'af875f', 216 | \138: 'af8787', 217 | \139: 'af87af', 218 | \140: 'af87d7', 219 | \141: 'af87ff', 220 | \142: 'afaf00', 221 | \143: 'afaf5f', 222 | \144: 'afaf87', 223 | \145: 'afafaf', 224 | \146: 'afafd7', 225 | \147: 'afafff', 226 | \148: 'afd700', 227 | \149: 'afd75f', 228 | \150: 'afd787', 229 | \151: 'afd7af', 230 | \152: 'afd7d7', 231 | \153: 'afd7ff', 232 | \154: 'afff00', 233 | \155: 'afff5f', 234 | \156: 'afff87', 235 | \157: 'afffaf', 236 | \158: 'afffd7', 237 | \159: 'afffff', 238 | \160: 'd70000', 239 | \161: 'd7005f', 240 | \162: 'd70087', 241 | \163: 'd700af', 242 | \164: 'd700d7', 243 | \165: 'd700ff', 244 | \166: 'd75f00', 245 | \167: 'd75f5f', 246 | \168: 'd75f87', 247 | \169: 'd75faf', 248 | \170: 'd75fd7', 249 | \171: 'd75fff', 250 | \172: 'd78700', 251 | \173: 'd7875f', 252 | \174: 'd78787', 253 | \175: 'd787af', 254 | \176: 'd787d7', 255 | \177: 'd787ff', 256 | \178: 'd7af00', 257 | \179: 'd7af5f', 258 | \180: 'd7af87', 259 | \181: 'd7afaf', 260 | \182: 'd7afd7', 261 | \183: 'd7afff', 262 | \184: 'd7d700', 263 | \185: 'd7d75f', 264 | \186: 'd7d787', 265 | \187: 'd7d7af', 266 | \188: 'd7d7d7', 267 | \189: 'd7d7ff', 268 | \190: 'd7ff00', 269 | \191: 'd7ff5f', 270 | \192: 'd7ff87', 271 | \193: 'd7ffaf', 272 | \194: 'd7ffd7', 273 | \195: 'd7ffff', 274 | \196: 'ff0000', 275 | \197: 'ff005f', 276 | \198: 'ff0087', 277 | \199: 'ff00af', 278 | \200: 'ff00d7', 279 | \201: 'ff00ff', 280 | \202: 'ff5f00', 281 | \203: 'ff5f5f', 282 | \204: 'ff5f87', 283 | \205: 'ff5faf', 284 | \206: 'ff5fd7', 285 | \207: 'ff5fff', 286 | \208: 'ff8700', 287 | \209: 'ff875f', 288 | \210: 'ff8787', 289 | \211: 'ff87af', 290 | \212: 'ff87d7', 291 | \213: 'ff87ff', 292 | \214: 'ffaf00', 293 | \215: 'ffaf5f', 294 | \216: 'ffaf87', 295 | \217: 'ffafaf', 296 | \218: 'ffafd7', 297 | \219: 'ffafff', 298 | \220: 'ffd700', 299 | \221: 'ffd75f', 300 | \222: 'ffd787', 301 | \223: 'ffd7af', 302 | \224: 'ffd7d7', 303 | \225: 'ffd7ff', 304 | \226: 'ffff00', 305 | \227: 'ffff5f', 306 | \228: 'ffff87', 307 | \229: 'ffffaf', 308 | \230: 'ffffd7', 309 | \231: 'ffffff', 310 | \232: '080808', 311 | \233: '121212', 312 | \234: '1c1c1c', 313 | \235: '262626', 314 | \236: '303030', 315 | \237: '3a3a3a', 316 | \238: '444444', 317 | \239: '4e4e4e', 318 | \240: '585858', 319 | \241: '626262', 320 | \242: '6c6c6c', 321 | \243: '767676', 322 | \244: '808080', 323 | \245: '8a8a8a', 324 | \246: '949494', 325 | \247: '9e9e9e', 326 | \248: 'a8a8a8', 327 | \249: 'b2b2b2', 328 | \250: 'bcbcbc', 329 | \251: 'c6c6c6', 330 | \252: 'd0d0d0', 331 | \253: 'dadada', 332 | \254: 'e4e4e4', 333 | \255: 'eeeeee', 334 | \} 335 | " }}} 336 | 337 | let s:c = { 338 | \'basic8_red (TODO: use this)': 1, 339 | \'basic8_green': 2, 340 | \'basic8_yellow': 3, 341 | \'basic8_blue (TODO: use this)': 4, 342 | \'basic8_magenta': 5, 343 | \'basic8_cyan': 6, 344 | \'basic8_black': 0, 345 | \'red52': 52, 346 | \'red88': 88, 347 | \'red124': 124, 348 | \'red160': 160, 349 | \'red161': 161, 350 | \'red196': 196, 351 | \'yellow58': 58, 352 | \'yellow100': 100, 353 | \'yellow136 (TODO: use this)': 136, 354 | \'yellow142 (TODO: use this)': 142, 355 | \'yellow148': 148, 356 | \'yellow149': 149, 357 | \'yellow190': 190, 358 | \'yellow220 (TODO: use this)': 220, 359 | \'yellow228': 228, 360 | \'orange208': 208, 361 | \'orange178': 178, 362 | \'orange180': 180, 363 | \'orange222': 222, 364 | \'light_yellow230': 229, 365 | \'graygreen (TODO: use this)': 23, 366 | \'green22': 22, 367 | \'green23': 23, 368 | \'green28': 28, 369 | \'green34': 34, 370 | \'green37': 37, 371 | \'green71': 71, 372 | \'green76': 76, 373 | \'green84': 84, 374 | \'green114': 114, 375 | \'green123': 123, 376 | \'seafoam': 30, 377 | \'seafoam2 (TODO: use this)': 35, 378 | \'teal50': 50, 379 | \'blue17 (TODO: use this)': 17, 380 | \'blue19 (TODO: use this)': 19, 381 | \'blue20 (TODO: use this)': 20, 382 | \'blue25': 25, 383 | \'blue27': 27, 384 | \'blue33': 33, 385 | \'blue37': 37, 386 | \'blue75': 75, 387 | \'blue87': 87, 388 | \'lavender104': 104, 389 | \'purple53': 53, 390 | \'purple89 (TODO: use this)': 89, 391 | \'purple90': 90, 392 | \'purple95 (TODO: use this)': 95, 393 | \'purple99 (TODO: use this)': 79, 394 | \'purple125': 125, 395 | \'purple126': 126, 396 | \'purple127': 127, 397 | \'purple131': 131, 398 | \'purple132': 132, 399 | \'purple139': 139, 400 | \'purple134': 134, 401 | \'purple141 (TODO: use this)': 141, 402 | \'purple161 (TODO: use this)': 161, 403 | \'purple201': 201, 404 | \'purple224': 224, 405 | \'purple225': 225, 406 | \'gray16': 16, 407 | \'gray232': 232, 408 | \'gray233': 233, 409 | \'gray234': 234, 410 | \'gray235': 235, 411 | \'gray236': 236, 412 | \'gray237': 237, 413 | \'gray238': 238, 414 | \'gray239': 239, 415 | \'gray240': 240, 416 | \'gray241': 241, 417 | \'gray242': 242, 418 | \'gray243': 243, 419 | \'gray244': 244, 420 | \'gray245': 245, 421 | \'gray246': 246, 422 | \'gray247': 247, 423 | \'gray248': 248, 424 | \'gray249': 249, 425 | \'gray250': 250, 426 | \'gray251': 251, 427 | \'gray252': 252, 428 | \'gray253': 253, 429 | \'gray254': 254, 430 | \'gray255': 255, 431 | \} 432 | 433 | " }}} 434 | 435 | " :hi funcs {{{ 436 | fun! s:color_for(id, fgbg) 437 | let num = s:c[a:id] 438 | let gui = s:cterm_gui_map[l:num] 439 | return 'cterm'.a:fgbg.'='.l:num.' gui'.a:fgbg.'=#'.l:gui 440 | endfun 441 | 442 | fun! s:fg(group, fg) 443 | exe 'hi '.a:group.' '.s:color_for(a:fg,'fg') 444 | endfun 445 | 446 | fun! s:bg(group, bg) 447 | exe 'hi '.a:group.' '.s:color_for(a:bg,'bg') 448 | endfun 449 | 450 | fun! s:fgbg(group, fg, bg) 451 | exe 'hi '.a:group.' '.s:color_for(a:fg,'fg').' '.s:color_for(a:bg,'bg') 452 | endfun 453 | 454 | fun! s:bold(group) 455 | exe 'hi '.a:group.' cterm=bold gui=bold' 456 | endfun 457 | 458 | fun! s:bold_fg(group, fg) 459 | call s:fg(a:group, a:fg) 460 | call s:bold(a:group) 461 | endfun 462 | 463 | fun! s:bold_fgbg(group, fg, bg) 464 | call s:fgbg(a:group, a:fg, a:bg) 465 | call s:bold(a:group) 466 | endfun 467 | 468 | fun! s:underline_fgbg(group, fg, bg) 469 | exe 'hi '.a:group.' ctermfg='.s:c[a:fg].' ' 470 | \s:color_for(a:bg,'bg').' cterm=underline,bold gui=underline,bold' 471 | endfun 472 | 473 | fun! s:make_obvious(group) 474 | call s:fgbg(a:group, 'green84', 'red160') 475 | endfun 476 | " }}} 477 | 478 | " For now, force darkness. If you're a big fan of white bg's, let me know, and 479 | " we can collaborate on a solution. 480 | set bg=dark 481 | call s:fgbg('Normal', 'gray254', 'gray232') 482 | 483 | " Basic/Default-like Palette {{{ 484 | hi SpecialKey term=bold ctermfg=81 guifg=Cyan 485 | hi NonText term=bold ctermfg=12 gui=bold guifg=Blue 486 | hi Directory term=bold ctermfg=159 guifg=Cyan 487 | hi ErrorMsg term=standout ctermfg=15 ctermbg=1 guifg=White guibg=Red 488 | hi IncSearch term=reverse cterm=reverse gui=reverse 489 | hi MoreMsg term=bold ctermfg=121 gui=bold guifg=SeaGreen 490 | hi ModeMsg term=bold cterm=bold gui=bold 491 | hi LineNr gui=NONE term=NONE guifg=#005f87 ctermfg=24 492 | hi CursorLineNr term=bold ctermfg=11 gui=bold guifg=Yellow 493 | hi Question term=standout ctermfg=121 gui=bold guifg=Green 494 | hi StatusLine term=bold,reverse cterm=bold,reverse gui=bold,reverse 495 | hi StatusLineNC term=reverse cterm=reverse gui=reverse 496 | hi VertSplit term=reverse cterm=reverse gui=reverse 497 | hi Title term=bold ctermfg=225 gui=bold guifg=Magenta 498 | hi WarningMsg term=standout ctermfg=224 guifg=Red 499 | hi WildMenu term=standout ctermfg=0 ctermbg=11 guifg=Black guibg=Yellow 500 | hi FoldColumn term=standout ctermfg=14 ctermbg=242 guifg=Cyan guibg=Grey 501 | hi SpellBad term=reverse ctermbg=9 gui=undercurl guisp=Red 502 | hi SpellCap term=reverse ctermbg=12 gui=undercurl guisp=Blue 503 | hi SpellRare term=reverse ctermbg=13 gui=undercurl guisp=Magenta 504 | hi SpellLocal term=underline ctermbg=14 gui=undercurl guisp=Cyan 505 | hi TabLine term=underline cterm=underline ctermfg=15 ctermbg=242 gui=underline guibg=DarkGrey 506 | hi TabLineSel term=bold cterm=bold gui=bold 507 | hi TabLineFill term=reverse cterm=reverse gui=reverse 508 | hi CursorColumn term=reverse ctermbg=242 guibg=Grey40 509 | hi Constant term=underline ctermfg=13 guifg=#ffa0a0 510 | hi Special term=bold ctermfg=224 guifg=Orange 511 | hi Identifier term=underline cterm=bold ctermfg=14 guifg=#40ffff 512 | hi Statement term=bold ctermfg=11 gui=bold guifg=#ffff60 513 | hi PreProc term=underline ctermfg=81 guifg=#ff80ff 514 | hi Type term=underline ctermfg=121 gui=bold guifg=#60ff60 515 | hi Underlined term=underline cterm=underline ctermfg=81 gui=underline guifg=#80a0ff 516 | hi Ignore ctermfg=0 guifg=bg 517 | hi Error term=reverse ctermfg=15 ctermbg=9 guifg=White guibg=Red 518 | hi Todo term=standout ctermfg=0 ctermbg=11 guifg=Blue guibg=Yellow 519 | 520 | call s:fg('Comment', 'gray242') " In my books, comments should be quiet. 521 | " }}} 522 | 523 | " Generic links {{{ 524 | hi link String detailedString 525 | hi link Character Constant 526 | hi link Number detailedInteger 527 | hi link Boolean detailedBoolean 528 | hi link Float detailedFloat 529 | hi link Function Identifier 530 | hi link Conditional Statement 531 | hi link Repeat detailedRepeat 532 | hi link Label Statement 533 | hi link Operator Statement 534 | hi link Keyword Statement 535 | hi link Include PreProc 536 | hi link Define PreProc 537 | hi link Macro PreProc 538 | hi link PreCondit PreProc 539 | hi link StorageClass Type 540 | hi link Structure Type 541 | hi link Typedef Type 542 | hi link Tag Special 543 | hi link SpecialChar Special 544 | hi link Delimiter Special 545 | hi link SpecialComment Special 546 | hi link Debug Special 547 | "}}} 548 | 549 | " s:detailed_colors — the good stuff {{{ 550 | fun! s:detailed_colors() 551 | call s:diff_syntax_and_highlights() " For vimdiff, which uses other filetypes 552 | 553 | call s:underline_fgbg('MatchParen', 'gray255', 'gray243') 554 | 555 | " For :set colorcolumn=80 556 | call s:fgbg('ColorColumn', 'gray254', 'gray233') 557 | 558 | " For the Syntastic and quickfixsigns plugins: 559 | call s:bg('SignColumn', 'gray233') 560 | 561 | "* Distinguish between each of TODO/FIXME/XXX 562 | call s:fgbg('detailedTodo', 'green76', 'gray238') 563 | call s:fgbg('detailedFixme', 'gray232', 'orange208') 564 | call s:fgbg('detailedXxx', 'gray235', 'red196') 565 | 566 | call s:fgbg('Error', 'gray235', 'red196') 567 | call s:underline_fgbg('Search', 'gray254', 'gray235') 568 | 569 | call s:fgbg('Folded', 'blue37', 'gray237') 570 | 571 | " ^P (completion) menu 572 | call s:fgbg('Pmenu', 'gray232', 'gray246') 573 | call s:fgbg('PmenuSel', 'gray232', 'green28') 574 | call s:bg('PmenuSbar', 'gray234') 575 | call s:bg('PmenuThumb', 'gray232') 576 | 577 | " Visual selections 578 | call s:bg('Visual', 'green22') 579 | hi VisualNOS term=bold,underline cterm=bold,underline gui=bold,underline 580 | 581 | " Tone this one down a bit. The color lowers contrast and is too obtrusive. 582 | call s:bg('Conceal', 'gray235') 583 | 584 | " https://github.com/bitc/vim-bad-whitespace 585 | call s:fgbg('BadWhitespace', 'gray238', 'yellow58') 586 | 587 | call s:fg('detailedConstant', 'green34') 588 | 589 | call s:bold_fg('detailedClass', 'purple126') 590 | call s:fg('detailedModule', 'purple126') 591 | call s:fg('detailedDefine', 'green23') 592 | call s:fg('detailedInclude', 'purple53') 593 | call s:fg('detailedDeclaration', 'yellow100') " Originally for go lang 594 | call s:fg('detailedDeclType', 'green37') " Originally for go lang 595 | 596 | call s:bold_fg('detailedFunction', 'blue27') 597 | 598 | call s:fg('detailedInstanceVariable', 'blue75') 599 | 600 | call s:fgbg('detailedString', 'purple125', 'gray233') 601 | call s:fgbg('detailedInterpolatedString', 'purple126', 'gray233') 602 | call s:bold_fgbg('detailedExecutedString', 'green34', 'purple53') 603 | call s:fgbg('detailedRawString', 'red160', 'gray233') 604 | call s:fg('detailedStringDelimiter', 'blue33') 605 | call s:fg('detailedInterpolationDelimiter', 'gray244') 606 | 607 | call s:fg('detailedRegexpSpecial', 'seafoam') 608 | 609 | call s:fg('detailedRegexpCharClass', 'basic8_green') 610 | call s:fg('detailedRegexpQuantifier', 'yellow148') 611 | call s:bold_fg('detailedRegexpEscape', 'purple90') 612 | call s:fg('detailedRegexpAnchor', 'purple90') 613 | call s:fg('detailedRegexpDot', 'green34') 614 | call s:bold_fg('detailedRegexpDelimiter', 'red88') 615 | call s:fgbg('rubyRegexp', 'red160', 'gray233') 616 | call s:fg('detailedASCIICode', 'green71') 617 | 618 | call s:fg('detailedPseudoVariable', 'purple125') 619 | call s:fg('detailedInteger', 'purple134') 620 | call s:fg('detailedFloat', 'purple132') 621 | call s:bold_fg('detailedImaginary', 'purple139') 622 | 623 | call s:fg('detailedBlockArgument', 'blue87') 624 | call s:fg('detailedSymbol', 'lavender104') 625 | call s:bold_fg('detailedBlockParameter', 'basic8_cyan') 626 | call s:fg('detailedBlockParameterList', 'blue25') 627 | call s:bold_fg('detailedPredefinedConstant', 'green22') 628 | call s:bold_fg('detailedPredefinedVariable', 'blue37') 629 | call s:fg('detailedBoolean', 'purple131') 630 | call s:fg('detailedOperator', 'green123') 631 | call s:fg('detailedAccess', 'yellow100') 632 | call s:fg('detailedAttribute', 'orange178') " attr_{accessor,reader,writer} 633 | call s:fg('detailedEval', 'yellow190') 634 | 635 | " Blocks: 636 | " (basic) 637 | call s:fg('detailedMethodBlock', 'green114') 638 | call s:fg('detailedBlock', 'purple225') 639 | call s:fg('detailedBlockExpression', 'orange180') 640 | " (conditionals) 641 | call s:fg('detailedControl', 'orange178') 642 | call s:bold_fg('Conditional', 'basic8_yellow') 643 | call s:bold_fg('detailedConditionalModifier', 'yellow148') " 'Yoda if' 644 | call s:fg('detailedConditionalExpression', 'light_yellow230') 645 | " (loops) 646 | call s:bold_fg('detailedRepeat', 'orange178') 647 | call s:bold_fg('detailedRepeatModifier', 'yellow149') " …while/until 648 | call s:fg('detailedRepeatExpression', 'orange222') 649 | 650 | call s:fg('detailedSharpBang', 'gray251') 651 | " hi rubyMultilineComment cleared 652 | call s:fg('detailedDataDirective', 'purple201') 653 | call s:fg('detailedData', 'gray245') 654 | 655 | call s:bold_fg('detailedDirective', 'green22') 656 | 657 | "* `fail`/`raise`/`exit` were yellow by default, but here a more warny orange. 658 | call s:fg('Exception', 'orange208') 659 | "* class `@@vars` get ugly, cautionary color: they are troublesome. 660 | call s:fgbg('rubyClassVariable', 'blue75', 'red52') 661 | "* global `$vars` also get a bit of ugliness. Everyone knows they're iffy. 662 | call s:fgbg('rubyGlobalVariable', 'red161', 'gray234') 663 | 664 | " rails.vim niceness: 665 | call s:fg('detailedRailsARAssociationMethod', 'teal50') 666 | 667 | " detailed.vim especialties: 668 | call s:fg('detailedInitialize', 'green84') 669 | hi link detailedEncodingDirective detailedDirective 670 | 671 | hi link detailedExits Exception 672 | endfun 673 | 674 | fun! s:diff_syntax_and_highlights() 675 | " vimdiff uses Diff* 676 | call s:bg('DiffChange', 'gray240') 677 | call s:bg('DiffText', 'gray232') 678 | call s:bg('DiffAdd', 'green23') 679 | call s:bg('DiffDelete', 'yellow58') 680 | " ft=diff syntax uses diff* 681 | call s:fg('diffAdded', 'green34') 682 | call s:fg('diffRemoved', 'yellow58') 683 | " diffFile 684 | endfun 685 | 686 | fun! s:c_syntax_and_highlights() 687 | hi link cRepeat detailedRepeat 688 | hi link cUserLabel detailedRepeat 689 | hi link cInclude detailedModule 690 | hi link cStatement detailedControl " return goto asm continue break 691 | hi link cConstant detailedConstant 692 | hi link cNumber detailedInteger 693 | " Since the C details came after Ruby, the names could be redone a bit: 694 | hi link cIncluded detailedString 695 | hi link cStructure detailedClass 696 | hi link cStorageClass detailedClass 697 | hi link cOperator detailedDefine 698 | endfun 699 | 700 | fun! s:go_syntax_and_highlights() 701 | 702 | " hi link goBlock detailedBlock 703 | hi link goDirective detailedDirective 704 | hi link goDeclaration detailedDeclaration 705 | hi link goDeclType detailedDeclType 706 | hi link goConstants detailedBoolean 707 | hi link goStatement detailedControl 708 | hi link goRawString detailedRawString 709 | hi link goImaginary detailedImaginary 710 | hi link goSpaceError BadWhitespace 711 | endfun 712 | 713 | fun! s:vim_syntax_and_highlights() 714 | hi link vimFuncKey detailedDefine 715 | hi link vimFunction detailedFunction 716 | "hi link vimFuncBody detailedDefine 717 | endfun 718 | 719 | fun! s:javascript_syntax_and_highlights() 720 | hi link javascriptFunction detailedDefine 721 | hi link javascriptIdentifier Type 722 | hi link javascriptRailsFunction detailedInstanceVariable 723 | endfun 724 | 725 | fun! s:detailed_syntax_addtions() 726 | call s:detailed_colors() 727 | 728 | " TODO - somehow make the detail{Todo,Fixme,Xxx} work for non-ruby langs. 729 | " E.g., shTodo overrides them, so it will need something like: 730 | " syn match rubyComment "#.*" contains=rubySharpBang,rubySpaceError, 731 | " \rubyFirstAndSecondCommentLine,detailedTodo,detailedFixme,detailedXxx,@Spell 732 | syn keyword detailedTodo TODO contained 733 | syn keyword detailedFixme FIXME contained 734 | syn keyword detailedXxx XXX contained 735 | endfun 736 | call s:detailed_syntax_addtions() " Hrm, can this not be done with aucmd? 737 | 738 | fun! s:ruby_syntax_and_highlights() 739 | " Steal this back from the too-generic 'rubyControl': 740 | syn match detailedExits "\<\%(exit!\|\%(abort\|at_exit\|exit\|fork\|trap\)\>[?!]\@!\)" 741 | 742 | " TODO: also handle %(…), etc 743 | syn region detailedInterpolatedString matchgroup=detailedInterpolatedStringDelimiter start="\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial,@Spell fold 744 | " TODO: Also, %x(). Anything else? 745 | syn region detailedExecutedString matchgroup=detailedExecutedStringDelimiter start="`" end="`" skip="\\\\\|\\`" contains=@rubyStringSpecial fold 746 | 747 | " The default syntax/ruby.vim gets this way wrong (only does 2 chars and is 748 | " transparent): 749 | syn match rubyBlockArgument "&[_[:lower:]][_[:alnum:]]*" contains=NONE display 750 | " Bonus! 751 | syn match rubyInitialize '\' contained containedin=rubyMethodDeclaration 752 | 753 | syn match rubyEncodingDirective "\cencoding: *utf-8" contained 754 | 755 | " TODO - make this more elegant. 756 | syn match rubyFirstAndSecondCommentLine '\%^#.*' 757 | \ contains=rubyEncodingDirective contained 758 | syn match rubyFirstAndSecondCommentLine '\%^#.*\n#.*' 759 | \ contains=rubyEncodingDirective contained 760 | 761 | syn match rubyComment "#.*" contains=rubySharpBang,rubySpaceError, 762 | \rubyFirstAndSecondCommentLine,detailedTodo,detailedFixme,detailedXxx,@Spell 763 | 764 | hi link rubyConditional Conditional 765 | hi link rubyExceptional rubyConditional " No-show. 766 | hi link rubyMethodExceptional rubyDefine " And another. 767 | hi link rubyStringEscape Special 768 | hi link rubyQuoteEscape rubyStringEscape 769 | hi link rubyInvalidVariable Error 770 | hi link rubyNoInterpolation rubyString " E.g. \#{} inside a string. 771 | hi link rubyException Exception 772 | hi link rubyKeyword Keyword 773 | hi link rubyConstant detailedConstant 774 | hi link rubyEncodingDirective detailedEncodingDirective 775 | hi link rubyInitialize detailedInitialize 776 | hi link rubyRailsARAssociationMethod detailedRailsARAssociationMethod 777 | hi link rubySpaceError BadWhitespace 778 | hi link rubyData detailedData 779 | hi link rubyDataDirective detailedDataDirective 780 | hi link rubyDocumentation Comment 781 | hi link rubyComment Comment 782 | hi link rubyFirstAndSecondCommentLine rubySharpBang 783 | hi link rubySharpBang detailedSharpBang 784 | hi link rubyDoBlock rubyRepeatExpression 785 | hi link rubyRepeatExpression detailedRepeatExpression 786 | hi link rubyRepeatModifier detailedRepeatModifier 787 | hi link rubyRepeat detailedRepeat 788 | hi link rubyCaseExpression rubyConditionalExpression 789 | hi link rubyConditionalExpression detailedConditionalExpression 790 | hi link rubyConditionalModifier detailedConditionalModifier 791 | hi link rubyControl detailedControl 792 | hi link rubyBlockExpression detailedBlockExpression 793 | hi link rubyBlock detailedBlock 794 | hi link rubyMethodBlock detailedMethodBlock 795 | hi link rubyEval detailedEval 796 | hi link rubyAttribute detailedAttribute 797 | hi link rubyAccess detailedAccess 798 | hi link rubyBeginEnd Statement " TODO 799 | hi link rubyPseudoOperator rubyOperator " -= /= **= *= etc 800 | hi link rubyOperator detailedOperator 801 | hi link rubyBoolean detailedBoolean 802 | hi link rubyPredefinedVariable detailedPredefinedVariable 803 | hi link rubyPredefinedConstant detailedPredefinedConstant 804 | hi link rubyBlockParameterList detailedBlockParameterList 805 | hi link rubyBlockParameter detailedBlockParameter 806 | hi link rubySymbol detailedSymbol 807 | hi link rubyBlockArgument detailedBlockArgument 808 | hi link rubyFloat detailedFloat 809 | hi link rubyInteger detailedInteger 810 | hi link rubyPseudoVariable detailedPseudoVariable 811 | hi link rubyASCIICode detailedASCIICode 812 | hi link rubyRegexpDelimiter detailedRegexpDelimiter 813 | hi link rubyRegexpDot detailedRegexpDot 814 | hi link rubyRegexpAnchor detailedRegexpAnchor 815 | hi link rubyRegexpEscape detailedRegexpEscape 816 | hi link rubyRegexpQuantifier detailedRegexpQuantifier 817 | hi link rubyRegexpCharClass detailedRegexpCharClass 818 | hi link rubyRegexpComment Comment 819 | hi link rubyRegexpSpecial detailedRegexpSpecial 820 | hi link rubyInterpolationDelimiter detailedInterpolationDelimiter 821 | hi link rubyStringDelimiter detailedStringDelimiter 822 | hi link rubyInstanceVariable detailedInstanceVariable 823 | hi link rubyFunction detailedFunction 824 | hi link rubyInclude detailedInclude 825 | hi link rubyDefine detailedDefine 826 | hi link rubyModule detailedModule 827 | hi link rubyClass detailedClass 828 | 829 | " Only linked highlights, not actual syntax: 830 | " call s:make_obvious('rubyIdentifier') 831 | " call s:make_obvious('rubyError') 832 | 833 | " Pretty much just the leftover default: 834 | " call s:make_obvious('rubyLocalVariableOrMethod') 835 | 836 | " Gets all [{()}] within any {}'s. Not very useful AFAICT: 837 | " call s:make_obvious('rubyCurlyBlock') 838 | 839 | " These mess up on first ] of [a[1]]. Seems plain busted. 840 | " call s:make_obvious('rubyArrayDelimiter') 841 | " call s:make_obvious('rubyArrayLiteral') 842 | 843 | " Mere implementation details, AFAICT: 844 | " call s:make_obvious('rubyNestedParentheses') 845 | " call s:make_obvious('rubyNestedCurlyBraces') 846 | " call s:make_obvious('rubyNestedAngleBrackets') 847 | " call s:make_obvious('rubyNestedSquareBrackets') 848 | " call s:make_obvious('rubyDelimEscape') 849 | " call s:make_obvious('rubySymbolDelimiter') 850 | 851 | " No-show: call s:make_obvious('rubyMethodDeclaration') 852 | " Not quite sure why these don't show up: 853 | " call s:make_obvious('rubyRegexpParens') 854 | " call s:make_obvious('rubyRegexpBrackets') 855 | " XXX no clue why this wont show up: call s:make_obvious('rubyHeredocStart') 856 | " TODO: fix these: call s:make_obvious('rubyAliasDeclaration2') 857 | " call s:make_obvious('rubyAliasDeclaration') 858 | " TODO! call s:make_obvious('rubyClassDeclaration') 859 | " call s:make_obvious('rubyDeclaration') 860 | " call s:make_obvious('rubyModuleDeclaration') 861 | " TODO: call s:make_obvious('rubyOptionalDo') 862 | " TODO: call s:make_obvious('rubyOptionalDoLine') 863 | endfun 864 | " }}} 865 | 866 | " Rainbow-Parens Improved {{{ 867 | " Inlined from v2.3 of http://www.vim.org/scripts/script.php?script_id=4176 868 | " 1. to remove the external dep, 2. to work around vim-rails resetting it. 869 | " Thanks! 870 | fun! s:fatpacked_rainbow_parens() 871 | let guifgs = exists('g:rainbow_guifgs')? g:rainbow_guifgs : [ 872 | \ 'DarkOrchid3', 'RoyalBlue3', 'SeaGreen3', 873 | \ 'DarkOrange3', 'FireBrick', 874 | \ ] 875 | 876 | " From Pharo Smalltalk: 877 | " Black, Green, Purple, Maroon, LightGreen, Orange, Red, Blue 878 | let ctermfgs = exists('g:rainbow_ctermfgs')? g:rainbow_ctermfgs : [ 879 | \ '241', '22', '56', '124', '72', '166', '126', '38', ] 880 | 881 | let max = has('gui_running')? len(guifgs) : len(ctermfgs) 882 | 883 | let cmd = 'syn region %s matchgroup=%s start=/%s/ end=/%s/ containedin=%s contains=%s' 884 | let str = 'TOP' 885 | for each in range(1, max) 886 | let str .= ',lv'.each 887 | endfor 888 | for [left , right] in [['(',')'],['\[','\]'],['{','}']] 889 | for each in range(1, max - 1) 890 | exe printf(cmd, 'lv'.each, 'lv'.each.'c', left, right, 'lv'.(each+1) , str) 891 | endfor 892 | exe printf(cmd, 'lv'.max, 'lv'.max.'c', left, right, 'lv1' , str) 893 | endfor 894 | 895 | for id in range(1 , max) 896 | let ctermfg = ctermfgs[(max - id) % len(ctermfgs)] 897 | let guifg = guifgs[(max - id) % len(guifgs)] 898 | exe 'hi default lv'.id.'c ctermfg='.ctermfg.' guifg='.guifg 899 | endfor 900 | endfun 901 | " }}} 902 | 903 | let &cpo = s:save_cpo 904 | 905 | " vim:foldmethod=marker 906 | -------------------------------------------------------------------------------- /img/go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rking/vim-detailed/5096fc19c5ee22d19add5759d37c0194a196a3ba/img/go.png -------------------------------------------------------------------------------- /img/javascript-handlebars.js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rking/vim-detailed/5096fc19c5ee22d19add5759d37c0194a196a3ba/img/javascript-handlebars.js.png -------------------------------------------------------------------------------- /img/misbehaving-detailed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rking/vim-detailed/5096fc19c5ee22d19add5759d37c0194a196a3ba/img/misbehaving-detailed.png -------------------------------------------------------------------------------- /img/pry-method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rking/vim-detailed/5096fc19c5ee22d19add5759d37c0194a196a3ba/img/pry-method.png -------------------------------------------------------------------------------- /img/ruby-unrealistically-packed-syntax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rking/vim-detailed/5096fc19c5ee22d19add5759d37c0194a196a3ba/img/ruby-unrealistically-packed-syntax.png -------------------------------------------------------------------------------- /img/vim-detailed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rking/vim-detailed/5096fc19c5ee22d19add5759d37c0194a196a3ba/img/vim-detailed.png -------------------------------------------------------------------------------- /test/app/models/omni.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # encoding: utf-8 3 | require 'ostruct' # A plain Comment. 4 | 5 | module Outer 6 | class Thing < ActiveRecord::Base 7 | include HelperDeal 8 | attr_accessor :hair 9 | has_many :trinkets 10 | alias new_name old_name 11 | @@foo = $bar = @baz = buz = 2 + 1 12 | 13 | def initialize 14 | lvar = { key: 231.0, 123 => ((true)), 'key3' => { nes: 'ted' } } 15 | @ivar = lvar.gsub /^a.c{3}[^e-f](\(g\th|i(?:j)k)(?#comment)$/i, 'hi \1' 16 | puts 'hi!' while 3 < @ivar 17 | arr << 'hi' << "hih#{i}" << `hi` 18 | end 19 | 20 | private 21 | def a_method arg1, *arg2 = nil, &hihi 22 | raise 55 if hi.(?\C-m) % arg3[0]; eval 'String' or exit 23 | $stderr.puts "hi #{arg1}" 24 | begin; inside_block_code rescue StandardError => e; warn 'Oops...' end 25 | 10.times do |i| inside_block_code end 26 | for i in [1,2,3]; inside_loop_code end 27 | if x; inside_if_code end 28 | case 1 when true then inside_case_code end 29 | inside_method_code 30 | end 31 | 32 | DATA.inside_class_code <<-EOT 33 | Heeere, doccy d\xf6ccy. 34 | EOT 35 | end 36 | end 37 | top_level_code 38 | 39 | [a[2], 2. asdf] # TODO: fix rubyArrayDelimiter/rubyArrayLiteral 40 | 41 | $% # TODO FIXME XXX 42 | __END__ 43 | Data here. 44 | -------------------------------------------------------------------------------- /test/config/environment.rb: -------------------------------------------------------------------------------- 1 | # This is only here to fool vim-rails into syntax highlighting "has_many", etc. 2 | -------------------------------------------------------------------------------- /test/default-omni-vim: -------------------------------------------------------------------------------- 1 | view -u NONE test/app/models/omni.rb +'syntax on' 2 | -------------------------------------------------------------------------------- /test/demo.js: -------------------------------------------------------------------------------- 1 | // lib/handlebars/browser-prefix.js 2 | var Handlebars = {}; 3 | 4 | (function(Handlebars, undefined) { 5 | ; 6 | // lib/handlebars/base.js 7 | 8 | Handlebars.VERSION = "1.0.0-rc.3"; 9 | Handlebars.COMPILER_REVISION = 3; 10 | 11 | Handlebars.REVISION_CHANGES = { 12 | 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it 13 | 2: '== 1.0.0-rc.3', 14 | 3: '>= 1.0.0-rc.4' 15 | }; 16 | 17 | Handlebars.helpers = {}; 18 | Handlebars.partials = {}; 19 | 20 | var toString = Object.prototype.toString, 21 | functionType = '[object Function]', 22 | objectType = '[object Object]'; 23 | 24 | Handlebars.registerHelper = function(name, fn, inverse) { 25 | if (toString.call(name) === objectType) { 26 | if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); } 27 | Handlebars.Utils.extend(this.helpers, name); 28 | } else { 29 | if (inverse) { fn.not = inverse; } 30 | this.helpers[name] = fn; 31 | } 32 | }; 33 | 34 | Handlebars.registerPartial = function(name, str) { 35 | if (toString.call(name) === objectType) { 36 | Handlebars.Utils.extend(this.partials, name); 37 | } else { 38 | this.partials[name] = str; 39 | } 40 | }; 41 | 42 | Handlebars.registerHelper('helperMissing', function(arg) { 43 | if(arguments.length === 2) { 44 | return undefined; 45 | } else { 46 | throw new Error("Could not find property '" + arg + "'"); 47 | } 48 | }); 49 | 50 | Handlebars.registerHelper('blockHelperMissing', function(context, options) { 51 | var inverse = options.inverse || function() {}, fn = options.fn; 52 | 53 | var type = toString.call(context); 54 | 55 | if(type === functionType) { context = context.call(this); } 56 | 57 | if(context === true) { 58 | return fn(this); 59 | } else if(context === false || context == null) { 60 | return inverse(this); 61 | } else if(type === "[object Array]") { 62 | if(context.length > 0) { 63 | return Handlebars.helpers.each(context, options); 64 | } else { 65 | return inverse(this); 66 | } 67 | } else { 68 | return fn(context); 69 | } 70 | }); 71 | 72 | Handlebars.K = function() {}; 73 | 74 | Handlebars.createFrame = Object.create || function(object) { 75 | Handlebars.K.prototype = object; 76 | var obj = new Handlebars.K(); 77 | Handlebars.K.prototype = null; 78 | return obj; 79 | }; 80 | 81 | Handlebars.logger = { 82 | DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3, 83 | 84 | methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'}, 85 | 86 | // can be overridden in the host environment 87 | log: function(level, obj) { 88 | if (Handlebars.logger.level <= level) { 89 | var method = Handlebars.logger.methodMap[level]; 90 | if (typeof console !== 'undefined' && console[method]) { 91 | console[method].call(console, obj); 92 | } 93 | } 94 | } 95 | }; 96 | 97 | Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); }; 98 | 99 | Handlebars.registerHelper('each', function(context, options) { 100 | var fn = options.fn, inverse = options.inverse; 101 | var i = 0, ret = "", data; 102 | 103 | if (options.data) { 104 | data = Handlebars.createFrame(options.data); 105 | } 106 | 107 | if(context && typeof context === 'object') { 108 | if(context instanceof Array){ 109 | for(var j = context.length; i 2) { 311 | expected.push("'" + this.terminals_[p] + "'"); 312 | } 313 | if (this.lexer.showPosition) { 314 | errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; 315 | } else { 316 | errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'"); 317 | } 318 | this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected}); 319 | } 320 | } 321 | if (action[0] instanceof Array && action.length > 1) { 322 | throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); 323 | } 324 | switch (action[0]) { 325 | case 1: 326 | stack.push(symbol); 327 | vstack.push(this.lexer.yytext); 328 | lstack.push(this.lexer.yylloc); 329 | stack.push(action[1]); 330 | symbol = null; 331 | if (!preErrorSymbol) { 332 | yyleng = this.lexer.yyleng; 333 | yytext = this.lexer.yytext; 334 | yylineno = this.lexer.yylineno; 335 | yyloc = this.lexer.yylloc; 336 | if (recovering > 0) 337 | recovering--; 338 | } else { 339 | symbol = preErrorSymbol; 340 | preErrorSymbol = null; 341 | } 342 | break; 343 | case 2: 344 | len = this.productions_[action[1]][1]; 345 | yyval.$ = vstack[vstack.length - len]; 346 | yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column}; 347 | if (ranges) { 348 | yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; 349 | } 350 | r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); 351 | if (typeof r !== "undefined") { 352 | return r; 353 | } 354 | if (len) { 355 | stack = stack.slice(0, -1 * len * 2); 356 | vstack = vstack.slice(0, -1 * len); 357 | lstack = lstack.slice(0, -1 * len); 358 | } 359 | stack.push(this.productions_[action[1]][0]); 360 | vstack.push(yyval.$); 361 | lstack.push(yyval._$); 362 | newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; 363 | stack.push(newState); 364 | break; 365 | case 3: 366 | return true; 367 | } 368 | } 369 | return true; 370 | } 371 | }; 372 | /* Jison generated lexer */ 373 | var lexer = (function(){ 374 | var lexer = ({EOF:1, 375 | parseError:function parseError(str, hash) { 376 | if (this.yy.parser) { 377 | this.yy.parser.parseError(str, hash); 378 | } else { 379 | throw new Error(str); 380 | } 381 | }, 382 | setInput:function (input) { 383 | this._input = input; 384 | this._more = this._less = this.done = false; 385 | this.yylineno = this.yyleng = 0; 386 | this.yytext = this.matched = this.match = ''; 387 | this.conditionStack = ['INITIAL']; 388 | this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0}; 389 | if (this.options.ranges) this.yylloc.range = [0,0]; 390 | this.offset = 0; 391 | return this; 392 | }, 393 | input:function () { 394 | var ch = this._input[0]; 395 | this.yytext += ch; 396 | this.yyleng++; 397 | this.offset++; 398 | this.match += ch; 399 | this.matched += ch; 400 | var lines = ch.match(/(?:\r\n?|\n).*/g); 401 | if (lines) { 402 | this.yylineno++; 403 | this.yylloc.last_line++; 404 | } else { 405 | this.yylloc.last_column++; 406 | } 407 | if (this.options.ranges) this.yylloc.range[1]++; 408 | 409 | this._input = this._input.slice(1); 410 | return ch; 411 | }, 412 | unput:function (ch) { 413 | var len = ch.length; 414 | var lines = ch.split(/(?:\r\n?|\n)/g); 415 | 416 | this._input = ch + this._input; 417 | this.yytext = this.yytext.substr(0, this.yytext.length-len-1); 418 | //this.yyleng -= len; 419 | this.offset -= len; 420 | var oldLines = this.match.split(/(?:\r\n?|\n)/g); 421 | this.match = this.match.substr(0, this.match.length-1); 422 | this.matched = this.matched.substr(0, this.matched.length-1); 423 | 424 | if (lines.length-1) this.yylineno -= lines.length-1; 425 | var r = this.yylloc.range; 426 | 427 | this.yylloc = {first_line: this.yylloc.first_line, 428 | last_line: this.yylineno+1, 429 | first_column: this.yylloc.first_column, 430 | last_column: lines ? 431 | (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length: 432 | this.yylloc.first_column - len 433 | }; 434 | 435 | if (this.options.ranges) { 436 | this.yylloc.range = [r[0], r[0] + this.yyleng - len]; 437 | } 438 | return this; 439 | }, 440 | more:function () { 441 | this._more = true; 442 | return this; 443 | }, 444 | less:function (n) { 445 | this.unput(this.match.slice(n)); 446 | }, 447 | pastInput:function () { 448 | var past = this.matched.substr(0, this.matched.length - this.match.length); 449 | return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); 450 | }, 451 | upcomingInput:function () { 452 | var next = this.match; 453 | if (next.length < 20) { 454 | next += this._input.substr(0, 20-next.length); 455 | } 456 | return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, ""); 457 | }, 458 | showPosition:function () { 459 | var pre = this.pastInput(); 460 | var c = new Array(pre.length + 1).join("-"); 461 | return pre + this.upcomingInput() + "\n" + c+"^"; 462 | }, 463 | next:function () { 464 | if (this.done) { 465 | return this.EOF; 466 | } 467 | if (!this._input) this.done = true; 468 | 469 | var token, 470 | match, 471 | tempMatch, 472 | index, 473 | col, 474 | lines; 475 | if (!this._more) { 476 | this.yytext = ''; 477 | this.match = ''; 478 | } 479 | var rules = this._currentRules(); 480 | for (var i=0;i < rules.length; i++) { 481 | tempMatch = this._input.match(this.rules[rules[i]]); 482 | if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { 483 | match = tempMatch; 484 | index = i; 485 | if (!this.options.flex) break; 486 | } 487 | } 488 | if (match) { 489 | lines = match[0].match(/(?:\r\n?|\n).*/g); 490 | if (lines) this.yylineno += lines.length; 491 | this.yylloc = {first_line: this.yylloc.last_line, 492 | last_line: this.yylineno+1, 493 | first_column: this.yylloc.last_column, 494 | last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length}; 495 | this.yytext += match[0]; 496 | this.match += match[0]; 497 | this.matches = match; 498 | this.yyleng = this.yytext.length; 499 | if (this.options.ranges) { 500 | this.yylloc.range = [this.offset, this.offset += this.yyleng]; 501 | } 502 | this._more = false; 503 | this._input = this._input.slice(match[0].length); 504 | this.matched += match[0]; 505 | token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]); 506 | if (this.done && this._input) this.done = false; 507 | if (token) return token; 508 | else return; 509 | } 510 | if (this._input === "") { 511 | return this.EOF; 512 | } else { 513 | return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), 514 | {text: "", token: null, line: this.yylineno}); 515 | } 516 | }, 517 | lex:function lex() { 518 | var r = this.next(); 519 | if (typeof r !== 'undefined') { 520 | return r; 521 | } else { 522 | return this.lex(); 523 | } 524 | }, 525 | begin:function begin(condition) { 526 | this.conditionStack.push(condition); 527 | }, 528 | popState:function popState() { 529 | return this.conditionStack.pop(); 530 | }, 531 | _currentRules:function _currentRules() { 532 | return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules; 533 | }, 534 | topState:function () { 535 | return this.conditionStack[this.conditionStack.length-2]; 536 | }, 537 | pushState:function begin(condition) { 538 | this.begin(condition); 539 | }}); 540 | lexer.options = {}; 541 | lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { 542 | 543 | var YYSTATE=YY_START 544 | switch($avoiding_name_collisions) { 545 | case 0: yy_.yytext = "\\"; return 14; 546 | break; 547 | case 1: 548 | if(yy_.yytext.slice(-1) !== "\\") this.begin("mu"); 549 | if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu"); 550 | if(yy_.yytext) return 14; 551 | 552 | break; 553 | case 2: return 14; 554 | break; 555 | case 3: 556 | if(yy_.yytext.slice(-1) !== "\\") this.popState(); 557 | if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1); 558 | return 14; 559 | 560 | break; 561 | case 4: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15; 562 | break; 563 | case 5: this.begin("par"); return 24; 564 | break; 565 | case 6: return 16; 566 | break; 567 | case 7: return 20; 568 | break; 569 | case 8: return 19; 570 | break; 571 | case 9: return 19; 572 | break; 573 | case 10: return 23; 574 | break; 575 | case 11: return 23; 576 | break; 577 | case 12: this.popState(); this.begin('com'); 578 | break; 579 | case 13: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15; 580 | break; 581 | case 14: return 22; 582 | break; 583 | case 15: return 36; 584 | break; 585 | case 16: return 35; 586 | break; 587 | case 17: return 35; 588 | break; 589 | case 18: return 39; 590 | break; 591 | case 19: /*ignore whitespace*/ 592 | break; 593 | case 20: this.popState(); return 18; 594 | break; 595 | case 21: this.popState(); return 18; 596 | break; 597 | case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 30; 598 | break; 599 | case 23: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 30; 600 | break; 601 | case 24: yy_.yytext = yy_.yytext.substr(1); return 28; 602 | break; 603 | case 25: return 32; 604 | break; 605 | case 26: return 32; 606 | break; 607 | case 27: return 31; 608 | break; 609 | case 28: return 35; 610 | break; 611 | case 29: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 35; 612 | break; 613 | case 30: return 'INVALID'; 614 | break; 615 | case 31: /*ignore whitespace*/ 616 | break; 617 | case 32: this.popState(); return 37; 618 | break; 619 | case 33: return 5; 620 | break; 621 | } 622 | }; 623 | lexer.rules = [/^(?:\\\\(?=(\{\{)))/,/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[}/ ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:-?[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$:-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-\/]+)/,/^(?:$)/]; 624 | lexer.conditions = {"mu":{"rules":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,33],"inclusive":false},"emu":{"rules":[3],"inclusive":false},"com":{"rules":[4],"inclusive":false},"par":{"rules":[31,32],"inclusive":false},"INITIAL":{"rules":[0,1,2,33],"inclusive":true}}; 625 | return lexer;})() 626 | parser.lexer = lexer; 627 | function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; 628 | return new Parser; 629 | })();; 630 | // lib/handlebars/compiler/base.js 631 | 632 | Handlebars.Parser = handlebars; 633 | 634 | Handlebars.parse = function(input) { 635 | 636 | // Just return if an already-compile AST was passed in. 637 | if(input.constructor === Handlebars.AST.ProgramNode) { return input; } 638 | 639 | Handlebars.Parser.yy = Handlebars.AST; 640 | return Handlebars.Parser.parse(input); 641 | }; 642 | ; 643 | // lib/handlebars/compiler/ast.js 644 | Handlebars.AST = {}; 645 | 646 | Handlebars.AST.ProgramNode = function(statements, inverse) { 647 | this.type = "program"; 648 | this.statements = statements; 649 | if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); } 650 | }; 651 | 652 | Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) { 653 | this.type = "mustache"; 654 | this.escaped = !unescaped; 655 | this.hash = hash; 656 | 657 | var id = this.id = rawParams[0]; 658 | var params = this.params = rawParams.slice(1); 659 | 660 | // a mustache is an eligible helper if: 661 | // * its id is simple (a single part, not `this` or `..`) 662 | var eligibleHelper = this.eligibleHelper = id.isSimple; 663 | 664 | // a mustache is definitely a helper if: 665 | // * it is an eligible helper, and 666 | // * it has at least one parameter or hash segment 667 | this.isHelper = eligibleHelper && (params.length || hash); 668 | 669 | // if a mustache is an eligible helper but not a definite 670 | // helper, it is ambiguous, and will be resolved in a later 671 | // pass or at runtime. 672 | }; 673 | 674 | Handlebars.AST.PartialNode = function(partialName, context) { 675 | this.type = "partial"; 676 | this.partialName = partialName; 677 | this.context = context; 678 | }; 679 | 680 | Handlebars.AST.BlockNode = function(mustache, program, inverse, close) { 681 | var verifyMatch = function(open, close) { 682 | if(open.original !== close.original) { 683 | throw new Handlebars.Exception(open.original + " doesn't match " + close.original); 684 | } 685 | }; 686 | 687 | verifyMatch(mustache.id, close); 688 | this.type = "block"; 689 | this.mustache = mustache; 690 | this.program = program; 691 | this.inverse = inverse; 692 | 693 | if (this.inverse && !this.program) { 694 | this.isInverse = true; 695 | } 696 | }; 697 | 698 | Handlebars.AST.ContentNode = function(string) { 699 | this.type = "content"; 700 | this.string = string; 701 | }; 702 | 703 | Handlebars.AST.HashNode = function(pairs) { 704 | this.type = "hash"; 705 | this.pairs = pairs; 706 | }; 707 | 708 | Handlebars.AST.IdNode = function(parts) { 709 | this.type = "ID"; 710 | this.original = parts.join("."); 711 | 712 | var dig = [], depth = 0; 713 | 714 | for(var i=0,l=parts.length; i 0) { throw new Handlebars.Exception("Invalid path: " + this.original); } 719 | else if (part === "..") { depth++; } 720 | else { this.isScoped = true; } 721 | } 722 | else { dig.push(part); } 723 | } 724 | 725 | this.parts = dig; 726 | this.string = dig.join('.'); 727 | this.depth = depth; 728 | 729 | // an ID is simple if it only has one part, and that part is not 730 | // `..` or `this`. 731 | this.isSimple = parts.length === 1 && !this.isScoped && depth === 0; 732 | 733 | this.stringModeValue = this.string; 734 | }; 735 | 736 | Handlebars.AST.PartialNameNode = function(name) { 737 | this.type = "PARTIAL_NAME"; 738 | this.name = name; 739 | }; 740 | 741 | Handlebars.AST.DataNode = function(id) { 742 | this.type = "DATA"; 743 | this.id = id; 744 | }; 745 | 746 | Handlebars.AST.StringNode = function(string) { 747 | this.type = "STRING"; 748 | this.string = string; 749 | this.stringModeValue = string; 750 | }; 751 | 752 | Handlebars.AST.IntegerNode = function(integer) { 753 | this.type = "INTEGER"; 754 | this.integer = integer; 755 | this.stringModeValue = Number(integer); 756 | }; 757 | 758 | Handlebars.AST.BooleanNode = function(bool) { 759 | this.type = "BOOLEAN"; 760 | this.bool = bool; 761 | this.stringModeValue = bool === "true"; 762 | }; 763 | 764 | Handlebars.AST.CommentNode = function(comment) { 765 | this.type = "comment"; 766 | this.comment = comment; 767 | }; 768 | ; 769 | // lib/handlebars/utils.js 770 | 771 | var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; 772 | 773 | Handlebars.Exception = function(message) { 774 | var tmp = Error.prototype.constructor.apply(this, arguments); 775 | 776 | // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. 777 | for (var idx = 0; idx < errorProps.length; idx++) { 778 | this[errorProps[idx]] = tmp[errorProps[idx]]; 779 | } 780 | }; 781 | Handlebars.Exception.prototype = new Error(); 782 | 783 | // Build out our basic SafeString type 784 | Handlebars.SafeString = function(string) { 785 | this.string = string; 786 | }; 787 | Handlebars.SafeString.prototype.toString = function() { 788 | return this.string.toString(); 789 | }; 790 | 791 | var escape = { 792 | "&": "&", 793 | "<": "<", 794 | ">": ">", 795 | '"': """, 796 | "'": "'", 797 | "`": "`" 798 | }; 799 | 800 | var badChars = /[&<>"'`]/g; 801 | var possible = /[&<>"'`]/; 802 | 803 | var escapeChar = function(chr) { 804 | return escape[chr] || "&"; 805 | }; 806 | 807 | Handlebars.Utils = { 808 | extend: function(obj, value) { 809 | for(var key in value) { 810 | if(value.hasOwnProperty(key)) { 811 | obj[key] = value[key]; 812 | } 813 | } 814 | }, 815 | 816 | escapeExpression: function(string) { 817 | // don't escape SafeStrings, since they're already safe 818 | if (string instanceof Handlebars.SafeString) { 819 | return string.toString(); 820 | } else if (string == null || string === false) { 821 | return ""; 822 | } 823 | 824 | // Force a string conversion as this will be done by the append regardless and 825 | // the regex test will do this transparently behind the scenes, causing issues if 826 | // an object's to string has escaped characters in it. 827 | string = string.toString(); 828 | 829 | if(!possible.test(string)) { return string; } 830 | return string.replace(badChars, escapeChar); 831 | }, 832 | 833 | isEmpty: function(value) { 834 | if (!value && value !== 0) { 835 | return true; 836 | } else if(toString.call(value) === "[object Array]" && value.length === 0) { 837 | return true; 838 | } else { 839 | return false; 840 | } 841 | } 842 | }; 843 | ; 844 | // lib/handlebars/compiler/compiler.js 845 | 846 | /*jshint eqnull:true*/ 847 | var Compiler = Handlebars.Compiler = function() {}; 848 | var JavaScriptCompiler = Handlebars.JavaScriptCompiler = function() {}; 849 | 850 | // the foundHelper register will disambiguate helper lookup from finding a 851 | // function in a context. This is necessary for mustache compatibility, which 852 | // requires that context functions in blocks are evaluated by blockHelperMissing, 853 | // and then proceed as if the resulting value was provided to blockHelperMissing. 854 | 855 | Compiler.prototype = { 856 | compiler: Compiler, 857 | 858 | disassemble: function() { 859 | var opcodes = this.opcodes, opcode, out = [], params, param; 860 | 861 | for (var i=0, l=opcodes.length; i 0) { 1364 | this.source[1] = this.source[1] + ", " + locals.join(", "); 1365 | } 1366 | 1367 | // Generate minimizer alias mappings 1368 | if (!this.isChild) { 1369 | for (var alias in this.context.aliases) { 1370 | this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias]; 1371 | } 1372 | } 1373 | 1374 | if (this.source[1]) { 1375 | this.source[1] = "var " + this.source[1].substring(2) + ";"; 1376 | } 1377 | 1378 | // Merge children 1379 | if (!this.isChild) { 1380 | this.source[1] += '\n' + this.context.programs.join('\n') + '\n'; 1381 | } 1382 | 1383 | if (!this.environment.isSimple) { 1384 | this.source.push("return buffer;"); 1385 | } 1386 | 1387 | var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"]; 1388 | 1389 | for(var i=0, l=this.environment.depths.list.length; i this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); } 1922 | return this.topStackName(); 1923 | }, 1924 | topStackName: function() { 1925 | return "stack" + this.stackSlot; 1926 | }, 1927 | flushInline: function() { 1928 | var inlineStack = this.inlineStack; 1929 | if (inlineStack.length) { 1930 | this.inlineStack = []; 1931 | for (var i = 0, len = inlineStack.length; i < len; i++) { 1932 | var entry = inlineStack[i]; 1933 | if (entry instanceof Literal) { 1934 | this.compileStack.push(entry); 1935 | } else { 1936 | this.pushStack(entry); 1937 | } 1938 | } 1939 | } 1940 | }, 1941 | isInline: function() { 1942 | return this.inlineStack.length; 1943 | }, 1944 | 1945 | popStack: function(wrapped) { 1946 | var inline = this.isInline(), 1947 | item = (inline ? this.inlineStack : this.compileStack).pop(); 1948 | 1949 | if (!wrapped && (item instanceof Literal)) { 1950 | return item.value; 1951 | } else { 1952 | if (!inline) { 1953 | this.stackSlot--; 1954 | } 1955 | return item; 1956 | } 1957 | }, 1958 | 1959 | topStack: function(wrapped) { 1960 | var stack = (this.isInline() ? this.inlineStack : this.compileStack), 1961 | item = stack[stack.length - 1]; 1962 | 1963 | if (!wrapped && (item instanceof Literal)) { 1964 | return item.value; 1965 | } else { 1966 | return item; 1967 | } 1968 | }, 1969 | 1970 | quotedString: function(str) { 1971 | return '"' + str 1972 | .replace(/\\/g, '\\\\') 1973 | .replace(/"/g, '\\"') 1974 | .replace(/\n/g, '\\n') 1975 | .replace(/\r/g, '\\r') 1976 | .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 1977 | .replace(/\u2029/g, '\\u2029') + '"'; 1978 | }, 1979 | 1980 | setupHelper: function(paramSize, name, missingParams) { 1981 | var params = []; 1982 | this.setupParams(paramSize, params, missingParams); 1983 | var foundHelper = this.nameLookup('helpers', name, 'helper'); 1984 | 1985 | return { 1986 | params: params, 1987 | name: foundHelper, 1988 | callParams: ["depth0"].concat(params).join(", "), 1989 | helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ") 1990 | }; 1991 | }, 1992 | 1993 | // the params and contexts arguments are passed in arrays 1994 | // to fill in 1995 | setupParams: function(paramSize, params, useRegister) { 1996 | var options = [], contexts = [], types = [], param, inverse, program; 1997 | 1998 | options.push("hash:" + this.popStack()); 1999 | 2000 | inverse = this.popStack(); 2001 | program = this.popStack(); 2002 | 2003 | // Avoid setting fn and inverse if neither are set. This allows 2004 | // helpers to do a check for `if (options.fn)` 2005 | if (program || inverse) { 2006 | if (!program) { 2007 | this.context.aliases.self = "this"; 2008 | program = "self.noop"; 2009 | } 2010 | 2011 | if (!inverse) { 2012 | this.context.aliases.self = "this"; 2013 | inverse = "self.noop"; 2014 | } 2015 | 2016 | options.push("inverse:" + inverse); 2017 | options.push("fn:" + program); 2018 | } 2019 | 2020 | for(var i=0; i :s/\\vhi \w+ (\\S*).*/call s:fg('\\1', '')/:noh" \ 4 | +'map :w:!tmux send -t0 :q C-m; tmux send -t0 C-p C-m' 5 | -------------------------------------------------------------------------------- /test/example.c: -------------------------------------------------------------------------------- 1 | void launch_job (job *j, int foreground) 2 | { 3 | process *p; 4 | pid_t pid; 5 | int mypipe[2], infile, outfile; 6 | 7 | infile = j->stdin; 8 | for (p = j->first_process; p; p = p->next) 9 | { 10 | /* Set up pipes, if necessary. */ 11 | if (p->next) 12 | { 13 | if (pipe (mypipe) < 0) 14 | { 15 | perror ("pipe"); 16 | exit (1); 17 | } 18 | outfile = mypipe[1]; 19 | } 20 | else 21 | outfile = j->stdout; 22 | 23 | /* Fork the child processes. */ 24 | pid = fork (); 25 | if (pid == 0) 26 | /* This is the child process. */ 27 | launch_process (p, j->pgid, infile, 28 | outfile, j->stderr, foreground); 29 | else if (pid < 0) 30 | { 31 | /* The fork failed. */ 32 | perror ("fork"); 33 | exit (1); 34 | } 35 | else 36 | { 37 | /* This is the parent process. */ 38 | p->pid = pid; 39 | if (shell_is_interactive) 40 | { 41 | if (!j->pgid) 42 | j->pgid = pid; 43 | setpgid (pid, j->pgid); 44 | } 45 | } 46 | 47 | /* Clean up after pipes. */ 48 | if (infile != j->stdin) 49 | close (infile); 50 | if (outfile != j->stdout) 51 | close (outfile); 52 | infile = mypipe[0]; 53 | } 54 | 55 | format_job_info (j, "launched"); 56 | 57 | if (!shell_is_interactive) 58 | wait_for_job (j); 59 | else if (foreground) 60 | put_job_in_foreground (j, 0); 61 | else 62 | put_job_in_background (j, 0); 63 | } 64 | -------------------------------------------------------------------------------- /test/example.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | io.Reader foo.Reader 6 | `raw string test` 'c' 10i 10 10.0 7 | 8 | package goplay 9 | 10 | import ( 11 | "bytes" 12 | "encoding/json" 13 | ) 14 | 15 | type fmtResponse struct { 16 | Body string 17 | Error string 18 | } 19 | 20 | func fmtHandler(w http.ResponseWriter, r *http.Request) { 21 | resp := new(fmtResponse) 22 | for a < b { 23 | a *= 2 24 | } 25 | body, err := gofmt(r.FormValue("body")) 26 | if err != nil { 27 | resp.Error = err.Error() 28 | } else { 29 | resp.Body = body 30 | } 31 | json.NewEncoder(w).Encode(resp) 32 | } 33 | 34 | func gofmt(body string) (string, error) { 35 | fset := token.NewFileSet() 36 | f, err := parser.ParseFile(fset, "prog.go", body, parser.ParseComments) 37 | if err != nil { 38 | return "", err 39 | } 40 | ast.SortImports(fset, f) 41 | var buf bytes.Buffer 42 | err = printer.Fprint(&buf, fset, f) 43 | if err != nil { 44 | return "", err 45 | } 46 | return buf.String(), nil 47 | } 48 | -------------------------------------------------------------------------------- /test/ft/sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | ## A comment 3 | # another 4 | echo Hi 5 | for n in a b c; do 6 | echo Bi 7 | done 8 | -------------------------------------------------------------------------------- /test/mux: -------------------------------------------------------------------------------- 1 | #!/bin/zsh -e 2 | tmux source `pwd`/test/vim-detailed-dev-layout &| 3 | ./test/omni-vim 4 | -------------------------------------------------------------------------------- /test/omni-vim: -------------------------------------------------------------------------------- 1 | vim test/app/models/omni.rb +'map dets' 2 | -------------------------------------------------------------------------------- /test/vim-detailed-dev-layout: -------------------------------------------------------------------------------- 1 | split-window -h 2 | send ./test/default-omni-vim C-m 3 | select-pane -L 4 | split-window 5 | send ./test/edit-detailed-vim C-m 6 | select-pane -R 7 | split-window 8 | send "vim /usr/share/vim/vim??/syntax/ruby.vim" C-m 9 | select-pane -L 10 | # vim:ft=tmux 11 | --------------------------------------------------------------------------------