Vim Tips Wiki

JavaFX indent plugin

Redirected from VimTip1635

1,626pages on
this wiki
Add New Page
Talk22 Share
Tip 1635 Printable Monobook Previous Next

created October 5, 2009 · complexity basic · author Black panda · version 7.0

Here is the beginning of a script that helps indenting JavaFX source files. JavaFX is a new GUI-based scripting language developed by Sun Microsystems to compete with Adobe Flash and Microsoft Silverlight.

Please help to improve the code so that it can be included as a plugin at Vim scripts.

set debug=msg,throw
if exists("b:did_indent")

let b:did_indent = 1
setlocal indentkeys=0{,0},0],!^F,o,O,e

"if exists("*GetFxIndent")
"    finish

" removes JavaFX quoted strings from a line
function! s:removeQuotedStrings(orig_line)
    "todo needs to be more robust
    "right now it barely handles double and single quotes, but
    "there could be code interpolation.
    " see

    let quote1 = matchstr(a:orig_line, "['\"]")

    if empty(quote1)
        return a:orig_line

    let escaped_quote = '\\' . quote1

    " replace escaped quotes, for example '\\"'
    let line = substitute(a:orig_line, escaped_quote, '__', "g")
"    call confirm('-->' . line)

    " match the quoted token, for example: /'[^']\+'/
    let quote_pattern = quote1 . '[^' . quote1 . ']\+' . quote1

"    call confirm(quote_pattern)
    return substitute(line, quote_pattern, '""', "g")

function! s:SkipJavaFxBlanksAndComments(startline)
    let lnum = a:startline
    while lnum > 1
        let lnum = prevnonblank(lnum)
        if getline(lnum) =~ '\*/\s*$'
            while getline(lnum) !~ '/\*' && lnum > 1
                let lnum = lnum - 1
            if getline(lnum) =~ '^\s*/\*'
                let lnum = lnum - 1
        elseif getline(lnum) =~ '^\s*//'
            let lnum = lnum - 1
    return lnum

" meant to matche the property syntax  x : y
let s:property_regex =  '^\s*\(\%(\i\|\s\)\+\):\(.*\)$'

function! GetFxIndent()
    if v:lnum == 1
        return indent(v:lnum)
    let theCIndent = cindent(v:lnum)

    " If we're in the middle of a comment or at the end of a java-like
    " statement or block, use cindent
    if getline(v:lnum) =~ '^\s*[\*/;]'
        return theCIndent

    " find start of previous line, in case it was a continuation line
    let lnum = s:SkipJavaFxBlanksAndComments(v:lnum - 1)
    let prev_lnum = lnum
    while prev_lnum > 1
        let earlier_prev = s:SkipJavaFxBlanksAndComments(prev_lnum - 1)
        if getline(earlier_prev) !~ '\%(\i\|\s\),\s*$'
        let prev_lnum = earlier_prev

"    call confirm('current indent is: ' . indent(v:lnum) .
"                \     "\ncindent wants it to be: " . theCIndent .
"                \     "\nprevious line num: " . prev_lnum)

    " let's get rid of the contents of the strings in the line.
    let current_line = s:removeQuotedStrings(getline(v:lnum))
    let prev_line = s:removeQuotedStrings(getline(prev_lnum))

"    call confirm('prev_line is: ' . prev_line)
    if current_line =~ '^\s*\]'
        return indent(prev_lnum) - &sw

    " take care of property-type format x: y
    let captures = matchlist(prev_line, s:property_regex)

    if ! empty(captures)
"        call confirm(string(captures))
        if captures[1] =~ '{' || captures[2] =~ '{'
"            call confirm("if1")
            if captures[2] =~ '}'
"                call confirm("if2")
                " this may be a complete block enclosure on one line
                return indent(prev_lnum)
"                call confirm("if3")
                " a block is starting in the property.
                return indent(prev_lnum)  + &sw
"            call confirm("if4")
        elseif captures[0] =~ '^\s*\<\%(var\|def\)\>'
"            call confirm("if5")
            " what we thought was a property-type format was really a
            " declaration of a variable.
            return theCIndent
        elseif current_line =~ '^\s*}'
"                call confirm("if6")
            " the end of the property block
            return indent(prev_lnum) - &sw
        elseif captures[0] =~ '['
"            call confirm("if7")
            " the end of the property block
            return indent(prev_lnum) + &sw
"            call confirm("if8")
            return indent(prev_lnum)
        " end of property-type format x: y check on prev_line

"        call confirm("if9")
    elseif current_line =~ '^\s*}'
"        call confirm("if9a")
        return indent(prev_lnum) -&sw
    elseif prev_line =~ '{'
"        call confirm("if10")
        " maybe it's a completely enclosed block.
        " if so, we can keep the previus indent
        if prev_line =~ '{[^}]\+}'
"            call confirm("if11")
            return indent(prev_lnum)
            return indent(prev_lnum) + &sw

    elseif prev_line =~ '^\s*}'
"        call confirm("if12")
        if current_line =~  '^\s*}'
"            call confirm("if13")
            "return indent(prev_lnum) -&sw
            "return theCIndent
"            call confirm("if14")
            return indent(prev_lnum)
    elseif match(current_line, s:property_regex) > -1
"        call confirm("if15")
        return indent(prev_lnum)

"    call confirm('normal flow')
    return theCIndent

" Set the function to do the work.
setlocal indentexpr=GetFxIndent()


This tip arose from a discussion on the vim_dev mailing list. The aim of posting the script here is to seek feedback to improve the code. Black panda may decide to upload the plugin to, and in three months or so, we can evaluate whether to keep this script here.

Please make any fixes to the code, or add comments on the talk page. JohnBeckett 04:24, October 8, 2009 (UTC)

Ad blocker interference detected!

Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.