While writing a syntax parser using ruby treetop library for a work project I discovered the need to use ruby filetype for syntax highlighting etc a file ending in .treetop (treetop uses polyglot to look for and compile the grammar on runtime but the grammar file has to end in .treetop).

I could have used some configuration in my .vimrc file to associate this file extension with ruby filetype but I want to try the embedded configuration which I have seen other used but never used myself.

After some search I found the reference article below and was by just adding the following file in the .treetop file I was able to desired functionality:

” from benji fisher to turn on the matchit plugin automatically and more
filetype plugin on

” explicity map file extension .t to perl syntax instead of tads
” which is autodetected by filetype plugin on
” This line should always be after filetype plugin
autocmd BufNewFile,BufRead *.t set syntax=perl

” to show real tabs and spaces in file
set list
set listchars=tab:>-,trail:^,eol:$
“set listchars=tab:>-,trail:-

“to add spaces instead of tabs
set expandtab

” evil, bad! — hard tabs should be 8 chars… –lindes
” set tabstop=4
” _but_ we can use this:
set smarttab

“make the background light
set background=light

“show matching parens
set showmatch

“show row and column number
set ruler

” allow backspacing over everything in insert mode
set backspace=indent,eol,start

Thank you Daniel Wong for introducing me to vim tabs. It was instant pay off on encouraging Daniel to use either use a real programmers’ editor like Vim or Emacs instead of gedit and teaching him the basic Vim (once he choose my choice of text editor on his own, I did not pressure him, honest).

This morning I was in a mode to do a regex kata and thought it would be interesting to see if I can substitute CamelCase (I call it JavaCase for fun) to underscore_separated_words (I did a search and could not find a good word for this so) I will call it ruby_case.

Here is how I started (note in my setting of vim you have to escape parens \):

:%s/\([a-z]\)\([A-Z]\)/\1_\2/gc

The above matches lowercase letter followed by uppercase letter and captures them then replaces them with underscore between them.

:%s/\(\l\)\(\u\)/\1_\2/gc

I found that Vim has metacharacters for upper (\u) and lowercase (\l). So above become cleaner version of the previous, call it refactoring. (JavaCase => Java_Case)

:%s/\(\l\)\(\u\)/\1_\L\2/gc

I found how to change an uppercase capture to lowercase. But this was leaving first character of the word still uppercase (JavaCase => Java_case)

:%s/\(\<\u\).*\(\l\)\(\u\)/\L\1\2_\L\3/gc

In this attempt to capture the first letter and lower case it I lost the letters in between. (JavaCase => ja_case)

:%s/\(\<\u.*\)\(\l\)\(\u\)/\L\1\2_\L\3/gc

Finally, I got what I wanted. (JavaCase => java_case) Hurray!

But I notice the match is greedy, so if there are multiple CamelCase on the same line this would fail.

For now I will leave this as an exercise for the reader as I am out of time for now, when I have a solution I will add it here.

This was a fun little exercise and I enjoyed it very much. Now I can find and solve a problem like this every morning it will jump start the day.

Now when I start an if block and hit enter the second line starts with the appropriate indentation and when I type end the editor automatically indents it to the previous indentation level of the appropriate block of code.

I had seen other vim experts do this but couldn’t remember how they did. Today I finally search and found how to insert the output of a unix/linux command directly in a vim buffer(without copy-pasting).