Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,52 @@ With Vundle
" inside .vimrc
Plugin 'pboettch/vim-cmake-syntax'

## Indentation

There is also an indent file which can do some intelligent alignment.

### Control-statements

For control-keywords (`if`, `while`, `foreach`, `macro`, etc) it automatically adds a
`shiftwidth()` (and substracts it for a `end`-keyword).

### Command arguments

For commands (so everything which has arguments between parenthesis `(...)`) is tries to do the following:

Either it aligns all arguments on a new line in the same column as the opening parenthesis if the first argument is on the
same line as the command:

```cmake
add_custom_target(TARGET name
DEPENDS target
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
```

or it indents it with one additional `shiftwidth()` if the first argument is on a new line

```cmake
add_custom_target(
TARGET name
DEPENDS target
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
```

This is achieved by letting `g:cmake_indent_align_command_arguments` to be 1.

By setting it to 0 (the default) in your vimrc-file the standard behavior is achieved.

```cmake
add_custom_target(TARGET name
DEPENDS target
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
```

### Comments

By setting `g:cmake_indent_align_comments_to_first_column` to 1 (default: 0) comment will always be aligned to the
zero column - otherwise they will aligned as normal line with a statement.

## Test

There is a ever growing test-suite based on ctest located in test/
Expand Down
123 changes: 78 additions & 45 deletions indent/cmake.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
" Author: Andy Cedilnik <[email protected]>
" Maintainer: Dimitri Merejkowsky <[email protected]>
" Former Maintainer: Karthik Krishnan <[email protected]>
" Last Change: 2017 Aug 30
" Last Change: 2017 Sep 24
"
" Licence: The CMake license applies to this file. See
" https://cmake.org/licensing
Expand All @@ -14,9 +14,6 @@ if exists("b:did_indent")
endif
let b:did_indent = 1

let s:keepcpo= &cpo
set cpo&vim

setlocal indentexpr=CMakeGetIndent(v:lnum)
setlocal indentkeys+==ENDIF(,ENDFOREACH(,ENDMACRO(,ELSE(,ELSEIF(,ENDWHILE(

Expand All @@ -25,13 +22,55 @@ if exists("*CMakeGetIndent")
finish
endif

let s:keepcpo= &cpo
set cpo&vim

let s:or = '\|'
" Regular expressions used by line indentation function.
let s:cmake_regex_comment = '#.*'
let s:cmake_regex_identifier = '[A-Za-z][A-Za-z0-9_]*'
let s:cmake_regex_quoted = '"\([^"\\]\|\\.\)*"'
let s:cmake_regex_arguments = '\(' . s:cmake_regex_quoted .
\ s:or . '\$(' . s:cmake_regex_identifier . ')' .
\ s:or . '[^()\\#"]' . s:or . '\\.' . '\)*'

let s:cmake_indent_comment_line = '^\s*' . s:cmake_regex_comment
let s:cmake_indent_open_regex = '^\s*' . s:cmake_regex_identifier .
\ '\s*(' . s:cmake_regex_arguments .
\ '\(' . s:cmake_regex_comment . '\)\?$'

let s:cmake_indent_close_regex = '^' . s:cmake_regex_arguments .
\ '\zs)\s*' .
\ '\(' . s:cmake_regex_comment . '\)\?$'

let s:cmake_indent_begin_regex = '^\s*\(IF\|MACRO\|FOREACH\|ELSE\|ELSEIF\|WHILE\|FUNCTION\)\s*('
let s:cmake_indent_end_regex = '^\s*\(ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ELSEIF\|ENDWHILE\|ENDFUNCTION\)\s*('

if !exists('g:cmake_indent_align_command_arguments')
let g:cmake_indent_align_command_arguments = 0
endif

if !exists('g:cmake_indent_align_comments_to_first_column')
let g:cmake_indent_align_comments_to_first_column = 0
endif

fun! CMakeGetIndent(lnum)
let this_line = getline(a:lnum)

" Find a non-blank line above the current line.
let lnum = a:lnum
let lnum = prevnonblank(lnum - 1)
let previous_line = getline(lnum)
let lnum = a:lnum - 1

" Find a non-blank/non-comment line above the current line.
while lnum > 0
let lnum = prevnonblank(lnum)
let previous_line = getline(lnum)

" ignore comments (# only, lua-like comment TODO)
if previous_line !~? s:cmake_indent_comment_line
break
endif

let lnum -= 1
endwhile

" Hit the start of the file, use zero indent.
if lnum == 0
Expand All @@ -40,46 +79,40 @@ fun! CMakeGetIndent(lnum)

let ind = indent(lnum)

let or = '\|'
" Regular expressions used by line indentation function.
let cmake_regex_comment = '#.*'
let cmake_regex_identifier = '[A-Za-z][A-Za-z0-9_]*'
let cmake_regex_quoted = '"\([^"\\]\|\\.\)*"'
let cmake_regex_arguments = '\(' . cmake_regex_quoted .
\ or . '\$(' . cmake_regex_identifier . ')' .
\ or . '[^()\\#"]' . or . '\\.' . '\)*'

let cmake_indent_comment_line = '^\s*' . cmake_regex_comment
let cmake_indent_blank_regex = '^\s*$'
let cmake_indent_open_regex = '^\s*' . cmake_regex_identifier .
\ '\s*(' . cmake_regex_arguments .
\ '\(' . cmake_regex_comment . '\)\?$'

let cmake_indent_close_regex = '^' . cmake_regex_arguments .
\ ')\s*' .
\ '\(' . cmake_regex_comment . '\)\?$'

let cmake_indent_begin_regex = '^\s*\(IF\|MACRO\|FOREACH\|ELSE\|ELSEIF\|WHILE\|FUNCTION\)\s*('
let cmake_indent_end_regex = '^\s*\(ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ELSEIF\|ENDWHILE\|ENDFUNCTION\)\s*('

" Add
if previous_line =~? cmake_indent_comment_line " Handle comments
let ind = ind
else
if previous_line =~? cmake_indent_begin_regex
let ind = ind + shiftwidth()
endif
if previous_line =~? cmake_indent_open_regex
let ind = ind + shiftwidth()
endif
if previous_line =~? s:cmake_indent_open_regex " open parenthesis
if previous_line !~? s:cmake_indent_close_regex " closing parenthesis is not on the same line
call cursor(lnum, 1)
let s = searchpos('(\s*$') " find '(' with nothing or only spaces until the end of the line
if s[0] == lnum
let ind += shiftwidth()
else " an argument after the keyword
call cursor(lnum, 1)
let s = searchpos('(') " find position of first '('
if g:cmake_indent_align_command_arguments == 0 " old behavior
let ind += shiftwidth()
else
let ind = s[1]
endif
endif
endif
elseif previous_line =~? s:cmake_indent_close_regex " close parenthesis
call cursor(lnum, strlen(previous_line))
let pairpos = searchpos(s:cmake_indent_open_regex, 'nbz') " find corresponding open paren
if pairpos[0] != 0
let ind = indent(pairpos[0])
endif
endif

" Subtract
if this_line =~? cmake_indent_end_regex
let ind = ind - shiftwidth()
if previous_line =~? s:cmake_indent_begin_regex " control begin block
let ind = ind + shiftwidth()
endif
if previous_line =~? cmake_indent_close_regex
let ind = ind - shiftwidth()

if this_line =~? s:cmake_indent_end_regex " control end block
let ind = ind - shiftwidth()
elseif this_line =~? s:cmake_indent_comment_line
if g:cmake_indent_align_comments_to_first_column == 1
let ind = 0
endif
endif

return ind
Expand Down
13 changes: 12 additions & 1 deletion test/.vimrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@
" remove user's .vimrc - what else?
set runtimepath-=~/.vimrc

" add .. as vim-plugin-path (for syntax)
" add .. as vim-plugin-path (for syntax and indent)
set runtimepath^=../

" nocompat is needed for html-output
set nocompatible

source ../syntax/cmake.vim
source ../indent/cmake.vim

set expandtab
set nocopyindent
set nopreserveindent
set nosmartindent
set softtabstop=0
set shiftwidth=4
set tabstop=4

syntax on
2 changes: 2 additions & 0 deletions test/if-endif-indent.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
if(HELLO)
endif()
6 changes: 6 additions & 0 deletions test/if-endif-indent.cmake.html.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<body>
<pre id='vimCodeElement'>
<span class="Statement">if</span>(HELLO)
<span class="Statement">endif</span>()
</pre>
</body>
6 changes: 6 additions & 0 deletions test/indent1.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set_property(TARGET foo APPEND PROPERTY
INCLUDE_DIRECTORIES ${BAR}

# closing parens "forgotten"

message(STATUS "Hello World")
10 changes: 10 additions & 0 deletions test/indent1.cmake.html.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<body>
<pre id='vimCodeElement'>
<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span>
<span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span>

<span class="Comment"># closing parens &quot;forgotten&quot;</span>

<span class="Identifier">message</span>(<span class="ModeMsg">STATUS</span> <span class="Constant">&quot;Hello World&quot;</span>)
</pre>
</body>
8 changes: 8 additions & 0 deletions test/indent2.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set_property(TARGET foo APPEND PROPERTY
INCLUDE_DIRECTORIES ${BAR})
message(STATUS "Hello World")


set_property(TARGET foo APPEND PROPERTY
INCLUDE_DIRECTORIES ${BAR})
message(STATUS "Hello World")
12 changes: 12 additions & 0 deletions test/indent2.cmake.html.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<body>
<pre id='vimCodeElement'>
<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span>
<span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span>)
<span class="Identifier">message</span>(<span class="ModeMsg">STATUS</span> <span class="Constant">&quot;Hello World&quot;</span>)


<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span>
<span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span>)
<span class="Identifier">message</span>(<span class="ModeMsg">STATUS</span> <span class="Constant">&quot;Hello World&quot;</span>)
</pre>
</body>
2 changes: 2 additions & 0 deletions test/indent3.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
set_property(TARGET foo APPEND PROPERTY INCLUDE_DIRECTORIES ${BAR})
message(STATUS "Hello World")
6 changes: 6 additions & 0 deletions test/indent3.cmake.html.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<body>
<pre id='vimCodeElement'>
<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span> <span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span>)
<span class="Identifier">message</span>(<span class="ModeMsg">STATUS</span> <span class="Constant">&quot;Hello World&quot;</span>)
</pre>
</body>
40 changes: 40 additions & 0 deletions test/indent4-align-comment-zero-col.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
set_property(TARGET foo APPEND PROPERTY
INCLUDE_DIRECTORIES ${BAR})

message(STATUS "Hello World")

set_property(TARGET foo APPEND PROPERTY # with comment
INCLUDE_DIRECTORIES ${BAR} "()")

if(VAR)
set_property(TARGET foo APPEND PROPERTY # with comment
INCLUDE_DIRECTORIES ${BAR})

message(STATUS "Hello World")

set_property(TARGET foo APPEND PROPERTY
# with comment
INCLUDE_DIRECTORIES ${BAR})
endif()

if(VAR)
set_property(TARGET
HELLO
HELLO)
endif()

if(VAR)
set_property(
TARGET
HELLO
HELLO)
endif()

add_custom_command(tout # )
#add_custom_command(
hallo
)

message(STATUS "Hello" #[[Bracket Comment]] "second")

add_custom_command() # TODO this will wrongly align to ( due to bracket-comment
44 changes: 44 additions & 0 deletions test/indent4-align-comment-zero-col.cmake.html.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<body>
<pre id='vimCodeElement'>
<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span>
<span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span>)

<span class="Identifier">message</span>(<span class="ModeMsg">STATUS</span> <span class="Constant">&quot;Hello World&quot;</span>)

<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span> <span class="Comment"># with comment</span>
<span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span> <span class="Constant">&quot;()&quot;</span>)

<span class="Statement">if</span>(<span class="ModeMsg">VAR</span>)
<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span> <span class="Comment"># with comment</span>
<span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span>)

<span class="Identifier">message</span>(<span class="ModeMsg">STATUS</span> <span class="Constant">&quot;Hello World&quot;</span>)

<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span> foo <span class="ModeMsg">APPEND</span> <span class="ModeMsg">PROPERTY</span>
<span class="Comment"># with comment</span>
<span class="ModeMsg">INCLUDE_DIRECTORIES</span> <span class="Type">${BAR}</span>)
<span class="Statement">endif</span>()

<span class="Statement">if</span>(<span class="ModeMsg">VAR</span>)
<span class="Identifier">set_property</span>(<span class="ModeMsg">TARGET</span>
HELLO
HELLO)
<span class="Statement">endif</span>()

<span class="Statement">if</span>(<span class="ModeMsg">VAR</span>)
<span class="Identifier">set_property</span>(
<span class="ModeMsg">TARGET</span>
HELLO
HELLO)
<span class="Statement">endif</span>()

<span class="Identifier">add_custom_command</span>(tout <span class="Comment"># )</span>
<span class="Comment">#add_custom_command(</span>
hallo
)

<span class="Identifier">message</span>(<span class="ModeMsg">STATUS</span> <span class="Constant">&quot;Hello&quot;</span> <span class="Comment">#[[Bracket Comment]]</span> <span class="Constant">&quot;second&quot;</span>)

<span class="Identifier">add_custom_command</span>() <span class="Comment"># </span><span class="TODO">TODO</span><span class="Comment"> this will wrongly align to ( due to bracket-comment</span>
</pre>
</body>
2 changes: 2 additions & 0 deletions test/indent4-align-comment-zero-col.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let g:cmake_indent_align_command_arguments = 1
let g:cmake_indent_align_comments_to_first_column = 1
1 change: 1 addition & 0 deletions test/indent4-align.cmake
Loading