Vim Tips Wiki
mNo edit summary
(Insert TipProposed template)
Line 1: Line 1:
  +
{{TipProposed
  +
|id=0
  +
|previous=0
  +
|next=0
  +
|created=October 5, 2009
  +
|complexity=basic
  +
|author=Black panda
  +
|version=7.0
  +
|subpage=/200910
  +
|category1=
  +
|category2=
  +
}}
 
Here is the beginning of a script that helps indenting [[wikipedia:JavaFX|JavaFX]] source files. JavaFX is a new GUI-based scripting language developed by Sun Microsystems to compete with Adobe Flash and Microsoft Silverlight.
 
Here is the beginning of a script that helps indenting [[wikipedia:JavaFX|JavaFX]] source files. JavaFX is a new GUI-based scripting language developed by Sun Microsystems to compete with Adobe Flash and Microsoft Silverlight.
   
Line 11: Line 23:
 
let b:did_indent = 1
 
let b:did_indent = 1
 
setlocal indentkeys=0{,0},0],!^F,o,O,e
 
setlocal indentkeys=0{,0},0],!^F,o,O,e
 
 
   
 
"if exists("*GetFxIndent")
 
"if exists("*GetFxIndent")
Line 39: Line 49:
 
return lnum
 
return lnum
 
endfunction
 
endfunction
 
   
 
function! GetFxIndent()
 
function! GetFxIndent()
if v:lnum == 1
+
if v:lnum == 1
return indent(v:lnum)
+
return indent(v:lnum)
endif
+
endif
let theCIndent = cindent(v:lnum)
+
let theCIndent = cindent(v:lnum)
"call confirm(indent(v:lnum))
+
"call confirm(indent(v:lnum))
   
" If we're in the middle of a comment or at the end of a java-like
+
" If we're in the middle of a comment or at the end of a java-like
" statement or block, use cindent
+
" statement or block, use cindent
if getline(v:lnum) =~ '^\s*[\*/;]'
+
if getline(v:lnum) =~ '^\s*[\*/;]'
return theCIndent
+
return theCIndent
 
endif
  +
 
" find start of previous line, in case it was a continuation line
 
let lnum = SkipJavaFxBlanksAndComments(v:lnum - 1)
 
let prev_lnum = lnum
 
while prev_lnum > 1
 
let earlier_prev = SkipJavaFxBlanksAndComments(prev_lnum - 1)
 
if getline(earlier_prev) !~ '[\w\s],\s*$'
 
break
 
endif
 
endif
 
let prev_lnum = earlier_prev
 
endwhile
   
 
if getline(v:lnum) =~ '^\s*\]'
" find start of previous line, in case it was a continuation line
 
 
return indent(prev_lnum) - &sw
let lnum = SkipJavaFxBlanksAndComments(v:lnum - 1)
 
 
endif
let prev_lnum = lnum
 
while prev_lnum > 1
 
let earlier_prev = SkipJavaFxBlanksAndComments(prev_lnum - 1)
 
if getline(earlier_prev) !~ '[\w\s],\s*$'
 
break
 
endif
 
let prev_lnum = earlier_prev
 
endwhile
 
   
 
" take care of property-type format x: y
if getline(v:lnum) =~ '^\s*\]'
 
return indent(prev_lnum) - &sw
+
let captures = matchlist(getline(prev_lnum), '^\([^:]*\):\(.*\)$')
 
if ! empty(captures)
 
if captures[1] =~ '{' || captures[2] =~ '{'
 
if captures[2] =~ '}'
 
" this may be a complete block enclosure on one line
 
return indent(prev_lnum)
 
else
 
" a block is starting in the property.
 
return indent(prev_lnum) + &sw
 
endif
 
elseif captures[0] =~ '^\s*\%(\<var\>\|\<def\>\)'
 
" what we thought was a property-type format was really a
 
" declaration of a variable.
 
return theCIndent
 
elseif getline(v:lnum) =~ '^\s*}'
 
" the end of the property block
 
return indent(prev_lnum) - &sw
 
elseif captures[0] =~ '['
 
" the end of the property block
 
return indent(prev_lnum) + &sw
 
else
 
return indent(prev_lnum)
 
endif
 
endif
 
" take care of property-type format x: y
 
let captures = matchlist(getline(prev_lnum), '^\([^:]*\):\(.*\)$')
 
if ! empty(captures)
 
if captures[1] =~ '{' || captures[2] =~ '{'
 
if captures[2] =~ '}'
 
" this may be a complete block enclosure on one line
 
return indent(prev_lnum)
 
else
 
" a block is starting in the property.
 
return indent(prev_lnum) + &sw
 
endif
 
elseif captures[0] =~ '^\s*\%(\<var\>\|\<def\>\)'
 
" what we thought was a property-type format was really a
 
" declaration of a variable.
 
return theCIndent
 
elseif getline(v:lnum) =~ '^\s*}'
 
" the end of the property block
 
return indent(prev_lnum) - &sw
 
elseif captures[0] =~ '['
 
" the end of the property block
 
return indent(prev_lnum) + &sw
 
else
 
return indent(prev_lnum)
 
endif
 
 
" end of property-type format x: y check
 
" end of property-type format x: y check
elseif getline(prev_lnum) =~ '{'
+
elseif getline(prev_lnum) =~ '{'
" maybe it's a completely enclosed block.
+
" maybe it's a completely enclosed block.
" if so, we can keep the previus indent
+
" if so, we can keep the previus indent
if getline(prev_lnum) =~ '{[^}]\+}'
+
if getline(prev_lnum) =~ '{[^}]\+}'
return indent(prev_lnum)
+
return indent(prev_lnum)
else
+
else
return indent(prev_lnum) + &sw
+
return indent(prev_lnum) + &sw
endif
 
elseif getline(prev_lnum) =~ '^\s*}'
 
if getline(v:lnum) =~ '^\s*}'
 
return indent(prev_lnum) -&sw
 
else
 
return indent(prev_lnum)
 
endif
 
 
endif
 
endif
 
elseif getline(prev_lnum) =~ '^\s*}'
 
 
if getline(v:lnum) =~ '^\s*}'
return theCIndent
 
 
return indent(prev_lnum) -&sw
 
 
else
  +
return indent(prev_lnum)
 
endif
 
endif
 
return theCIndent
 
endfunction
 
endfunction
 
   
 
" Set the function to do the work.
 
" Set the function to do the work.
 
setlocal indentexpr=GetFxIndent()
 
setlocal indentexpr=GetFxIndent()
 
 
</pre>
 
</pre>
   

Revision as of 08:26, 18 October 2009

Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).

Please use new tips to discuss whether this page should be a permanent tip, or whether it should be merged to an existing tip.
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")
  finish
endif

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

"if exists("*GetFxIndent")
"    finish
"endif

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
      endwhile
      if getline(lnum) =~ '^\s*/\*'
        let lnum = lnum - 1
      else
        break
      endif
    elseif getline(lnum) =~ '^\s*//'
      let lnum = lnum - 1
    else
      break
    endif
  endwhile
  return lnum
endfunction

function! GetFxIndent()
  if v:lnum == 1
    return indent(v:lnum)
  endif
  let theCIndent = cindent(v:lnum)
  "call confirm(indent(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
  endif

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

  if getline(v:lnum) =~ '^\s*\]'
    return indent(prev_lnum) - &sw
  endif

  " take care of property-type format x: y
  let captures = matchlist(getline(prev_lnum), '^\([^:]*\):\(.*\)$')
  if ! empty(captures)
    if captures[1] =~ '{' || captures[2] =~ '{'
      if captures[2] =~ '}'
        " this may be a complete block enclosure on one line
        return indent(prev_lnum)
      else
        " a block is starting in the property.
        return indent(prev_lnum)  + &sw
      endif
    elseif captures[0] =~ '^\s*\%(\<var\>\|\<def\>\)'
      " what we thought was a property-type format was really a
      " declaration of a variable.
      return theCIndent
    elseif getline(v:lnum) =~ '^\s*}'
      " the end of the property block
      return indent(prev_lnum) - &sw
    elseif captures[0] =~ '['
      " the end of the property block
      return indent(prev_lnum) + &sw
    else
      return indent(prev_lnum)
    endif
    " end of property-type format x: y check
  elseif getline(prev_lnum) =~ '{'
    " maybe it's a completely enclosed block.
    " if so, we can keep the previus indent
    if getline(prev_lnum) =~ '{[^}]\+}'
      return indent(prev_lnum)
    else
      return indent(prev_lnum)  + &sw
    endif
  elseif getline(prev_lnum) =~ '^\s*}'
    if getline(v:lnum) =~  '^\s*}'
      return indent(prev_lnum) -&sw
    else
      return indent(prev_lnum)
    endif
  endif
  return theCIndent
endfunction

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

Comments

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 vim.org/scripts, 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)