Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I define indents in vim based on curly braces?

I use https://github.com/cakebaker/scss-syntax.vim for syntax highlighting SCSS (or SASS) files on vim, which works very well for syntax highlighting. However, the plugin does not come with an indent file and am having trouble writing one.

I would like to set the indent to look like this:

enter image description here

However, if i do gg=G, I get:

enter image description here

I suspect that it does not understand nested indent based on braces. I tried all the different combinations of

set cindent

set nocindent

set autoindent

set smartindent

and tried to use the code from Tab key == 4 spaces and auto-indent after curly braces in Vim , including

set tabstop=2

set shiftwidth=2

set expandtab

...but nested braces indent never seems to work.

I believe that I might want to write a custom indent file, and all I need is indentation based on braces with nested levels. How should I go about this? If someone has an indentation file for filetypes with similar syntax, that will be great as well.

like image 815
chibicode Avatar asked Jan 28 '11 14:01

chibicode


1 Answers

This is a quick hack, based on the built-in perl indentation code (in indent/perl.vim). Hopefully you can use it to get what you want to do. See the more detailed comments in either the perl indentation code or another one of the files in the indent directory for more details.

setlocal indentexpr=GetMyIndent()
function! GetMyIndent()
    let cline = getline(v:lnum)

    " Find a non-blank line above the current line.
    let lnum = prevnonblank(v:lnum - 1)
    " Hit the start of the file, use zero indent.
    if lnum == 0
        return 0
    endif
    let line = getline(lnum)
    let ind = indent(lnum)

    " Indent blocks enclosed by {}, (), or []
    " Find a real opening brace
    let bracepos = match(line, '[(){}\[\]]', matchend(line, '^\s*[)}\]]'))
    while bracepos != -1
        let brace = strpart(line, bracepos, 1)
        if brace == '(' || brace == '{' || brace == '['
            let ind = ind + &sw
        else
            let ind = ind - &sw
        endif
        let bracepos = match(line, '[(){}\[\]]', bracepos + 1)
    endwhile
    let bracepos = matchend(cline, '^\s*[)}\]]')
    if bracepos != -1
        let ind = ind - &sw
    endif

    return ind
endfunction

Save that file as ~/.vim/indent/something.vim where something is your file type (replace ~/.vim with the path to vimfiles if you're on Windows.

You might also want to stick this at the start of the file (but only if there isn't some other indent declaration that might be loaded first):

" Only load this indent file when no other was loaded.
if exists("b:did_indent")
    finish
endif
let b:did_indent = 1
like image 189
DrAl Avatar answered Sep 27 '22 21:09

DrAl