Repository: vhdirk/vim-cmake
Branch: master
Commit: d4a6d1836987
Files: 11
Total size: 16.4 KB
Directory structure:
gitextract_vwq_bad1/
├── .gitignore
├── .travis.yml
├── README.md
├── appveyor.yml
├── doc/
│ └── cmake.txt
├── plugin/
│ └── cmake.vim
└── test/
├── .vimrc
├── cmake.vader
└── test project/
├── CMakeLists.txt
├── configure.h.cmake
└── main.cpp
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
test/test project/build/
doc/tags
================================================
FILE: .travis.yml
================================================
language: vim
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- kubuntu-backports
packages:
- g++-4.7
- cmake
before_script: |
git clone https://github.com/junegunn/vader.vim.git
script: |
vim -Nu 'test/.vimrc' -c 'Vader! test/cmake.vader'
================================================
FILE: README.md
================================================
# vim-cmake
[](https://travis-ci.org/vhdirk/vim-cmake)
[](https://ci.appveyor.com/project/vhdirk/vim-cmake)
vim-cmake is a Vim plugin to make working with CMake a little nicer.
I got tired of navigating to the build directory each time, and I also
disliked setting makeprg manually each time. This plugin does just that.
## Usage
### Commands
* `:CMake` searches for the closest directory named build in an upwards search,
and whenever one is found, it runs the cmake command there, assuming the CMakeLists.txt
file is just one directory above. Any arguments given to :CMake will be directly passed
on to the cmake command. It also sets the working directory of the make command, so
you can just use quickfix as with a normal Makefile project.
If you have the [AsyncRun plugin](https://github.com/skywind3000/asyncrun.vim)
installed, it will be used automatically and you will be able to check the
result of the cmake command in the quickfix as well.
* `:CMakeClean` deletes all files in the build directory. You can think of this as a CMake version of make clean.
* `:CMakeFindBuildDir` resets the build directory path set for the current buffer and then tries to find a new one. Useful if it previously found a wrong path to then reset it after a new build folder has been created for example.
### Variables
* `g:cmake_install_prefix` same as `-DCMAKE_INSTALL_PREFIX`
* `g:cmake_build_type` same as `-DCMAKE_BUILD_TYPE`
* `g:cmake_cxx_compiler` same as `-DCMAKE_CXX_COMPILER`. Changes will have no effect until you run :CMakeClean and then :CMake.
* `g:cmake_c_compiler` same as `-DCMAKE_C_COMPILER`. Changes will have no effect until you run :CMakeClean and then :CMake.
* `g:cmake_build_shared_libs` same as `-DBUILD_SHARED_LIBS`
* `g:cmake_toolchain_file` same as `-DCMAKE_TOOLCHAIN_FILE`
* `g:cmake_project_generator` same as `-G`. Changes will have no effect until you run :CMakeClean and then :CMake.
* `g:cmake_export_compile_commands` same as `-DCMAKE_EXPORT_COMPILE_COMMANDS`.
* `g:cmake_ycm_symlinks` create symlinks to the generated compilation database for use with [YouCompleteMe](https://github.com/Valloric/YouCompleteMe/).
* `b:build_dir` is the path to the cmake build directory for the current buffer. This variable is set with the first :CMake or :CMakeFindBuildDir call. Once found, it will not be searched for again unless you call :CMakeFindBuildDir. If automatic finding is not sufficient you can set this variable manually to the build dir of your choice.
## Installation
### Vim-pathogen
With [pathogen.vim](https://github.com/tpope/vim-pathogen) simply copy and paste:
cd ~/.vim/bundle
git clone git://github.com/vhdirk/vim-cmake.git
Once help tags have been generated, you can view the manual with
`:help cmake`.
### Vundle
With [Vundle.vim](https://github.com/VundleVim/Vundle.vim) simply add this repository to your plugins list:
Plugin 'vhdirk/vim-cmake'
## Acknowledgements
* Thanks to [Tim Pope](http://tpo.pe/), his plugins are really awesome.
* Thanks to [Junegunn Choi](https://junegunn.kr/), for [vader.vim](https://github.com/junegunn/vader.vim), which is the testing framework used for this plugin.
* Also thanks to
* @SteveDeFacto for extending this with more fine grained control.
* @snikulov for enhancing makeprg.
* @dapicester for allowing specifying targets.
* @thomasgubler for the build dir option.
* @antmd for fixing a bug with handing of spaces in directory names.
* @jmirabel for fixing concatenation of cmake arguments.
* @T4ng10r for the project generator option.
* @Squareys for a small overhaul of the project, the initial test and travis setup.
## License
Copyright (c) Dirk Van Haerenborgh, @SteveDeFacto. Distributed under the same terms as Vim itself.
See `:help license`.
================================================
FILE: appveyor.yml
================================================
os: Visual Studio 2015
install:
- cinst vim
- cinst cmake
- set PATH=%PATH%;C:\Program Files\CMake\bin
- git clone https://github.com/junegunn/vader.vim
build_script:
- vim -Nu test/.vimrc -c 'Vader! test/cmake.vader' --not-a-term
================================================
FILE: doc/cmake.txt
================================================
*cmake.txt* Vim plugin to make working with CMake a little nicer
Authors: Dirk Van Haerenborgh
Steven Batchelor
Jonathan Hale
License: Same terms as Vim itself (see |license|)
INTRODUCTION *cmake*
When working on a CMake project, this plugin provides a single command that
changes the makeprg make command's working directory to the closest 'build'
directory (see g:cmake_build_dir) upwards
COMMANDS *cmake-commands*
:CMake [args] Runs the cmake command as 'cmake ..', starting in
first directory called 'build', found in an upwards
search. All arguments are directly passed on to CMake.
Also modifies the :make command to build in
that directory.
:CMakeClean deletes all files in the build directory. You can
think of this as a CMake version of make clean.
:CMakeFindBuildDir resets the build directory path set for the current buffer
and then tries to find a new one. Useful if it previously
found a wrong path to then reset it after a new build folder
has been created for example.
VARIABLES *cmake-variables*
g:cmake_install_prefix same as -DCMAKE_INSTALL_PREFIX
g:cmake_build_type same as -DCMAKE_BUILD_TYPE
g:cmake_cxx_compiler same as -DCMAKE_CXX_COMPILER, however, this will have
no effect until you run :CMakeClean and :CMake.
g:cmake_c_compiler same as -DCMAKE_C_COMPILER, however, this will have
no effect until you run :CMakeClean and :CMake.
g:cmake_build_shared_libs same as -DBUILD_SHARED_LIBS
g:cmake_toolchain_file same as -DCMAKE_TOOLCHAIN_FILE
g:cmake_build_dir set the cmake 'build' directory, default: 'build'
g:cmake_project_generator set project generator, however, this will have
no effect until you run :CMakeClean and :CMake.
g:cmake_usr_args custom user arguments. Ex: 'let g:cmake_usr_args="-DDEBUG=YES"'
b:build_dir the path to the cmake build directory for the current buffer.
This variable is set with the first :CMake or :CMakeFindBuildDir call.
Once found, it will not be searched for again unless you call
:CMakeFindBuildDir. If automatic finding is not sufficient you can set
this variable manually to the build dir of your choice.
OPTIONS *cmake-options*
g:cmake_export_compile_commands same as -DCMAKE_EXPORT_COMPILE_COMMANDS=ON, useful for
exporting a compilation database to be used with YCM
(https://github.com/Valloric/YouCompleteMe#c-family-semantic-completion)
CMake only supports this flag with Ninja and Makefile generators.
g:cmake_ycm_symlinks create a symlink to the compile_commands.json file in the
root of the project (build/..) if the file is found.
================================================
FILE: plugin/cmake.vim
================================================
" cmake.vim - Vim plugin to make working with CMake a little nicer
" Maintainer: Dirk Van Haerenborgh
" Version: 0.2
let s:cmake_plugin_version = '0.2'
if exists("loaded_cmake_plugin")
finish
endif
" We set this variable here even though the plugin may not actually be loaded
" because the executable is not found. Otherwise the error message will be
" displayed more than once.
let loaded_cmake_plugin = 1
" Set option defaults
if !exists("g:cmake_export_compile_commands")
let g:cmake_export_compile_commands = 0
endif
if !exists("g:cmake_ycm_symlinks")
let g:cmake_ycm_symlinks = 0
endif
if !exists("g:cmake_use_smp")
let g:cmake_use_smp = 0
endif
if !executable("cmake")
echoerr "vim-cmake requires cmake executable. Please make sure it is installed and on PATH."
finish
endif
function! s:find_build_dir()
" Do not overwrite already found build_dir, may be set explicitly
" by user.
if exists("b:build_dir") && b:build_dir != ""
return 1
endif
let g:cmake_build_dir = get(g:, 'cmake_build_dir', 'build')
let b:build_dir = finddir(g:cmake_build_dir, ';')
if b:build_dir == ""
" Find build directory in path of current file
let b:build_dir = finddir(g:cmake_build_dir, s:fnameescape(expand("%:p:h")) . ';')
endif
if b:build_dir != ""
" expand() would expand "" to working directory, but we need
" this as an indicator that build was not found
let b:build_dir = fnamemodify(b:build_dir, ':p')
echom "Found cmake build directory: " . s:fnameescape(b:build_dir)
return 1
else
echom "Unable to find cmake build directory."
return 0
endif
endfunction
" Configure the cmake project in the currently set build dir.
"
" This will override any of the following variables if the
" corresponding vim variable is set:
" * CMAKE_INSTALL_PREFIX
" * CMAKE_BUILD_TYPE
" * CMAKE_BUILD_SHARED_LIBS
" If the project is not configured already, the following variables will be set
" whenever the corresponding vim variable for the following is set:
" * CMAKE_CXX_COMPILER
" * CMAKE_C_COMPILER
" * The generator (-G)
function! s:cmake_configure(cmake_vim_command_args)
exec 'cd' s:fnameescape(b:build_dir)
let l:argument = []
" Only change values of variables, if project is not configured
" already, otherwise we overwrite existing configuration.
let l:configured = filereadable("CMakeCache.txt")
if !l:configured
if exists("g:cmake_project_generator")
let l:argument += [ "-G \"" . g:cmake_project_generator . "\"" ]
endif
if exists("g:cmake_cxx_compiler")
let l:argument += [ "-DCMAKE_CXX_COMPILER:FILEPATH=" . g:cmake_cxx_compiler ]
endif
if exists("g:cmake_c_compiler")
let l:argument += [ "-DCMAKE_C_COMPILER:FILEPATH=" . g:cmake_c_compiler ]
endif
if exists("g:cmake_usr_args")
let l:argument+= [ g:cmake_usr_args ]
endif
endif
if exists("g:cmake_install_prefix")
let l:argument += [ "-DCMAKE_INSTALL_PREFIX:FILEPATH=" . g:cmake_install_prefix ]
endif
if exists("g:cmake_build_type" )
let l:argument += [ "-DCMAKE_BUILD_TYPE:STRING=" . g:cmake_build_type ]
endif
if exists("g:cmake_build_shared_libs")
let l:argument += [ "-DBUILD_SHARED_LIBS:BOOL=" . g:cmake_build_shared_libs ]
endif
if exists("g:cmake_toolchain_file")
let l:argument += [ "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=" . g:cmake_toolchain_file ]
endif
if g:cmake_export_compile_commands
let l:argument += [ "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" ]
endif
let l:argumentstr = join(l:argument, " ")
let l:escaped_build_dir=s:fnameescape(b:build_dir)
let l:home_dir = "-H".l:escaped_build_dir."/.."
let l:build_dir_path = "-B".l:escaped_build_dir
let s:cmd = 'cmake '.l:home_dir.' '.l:build_dir_path.' '.l:argumentstr . " " . join(a:cmake_vim_command_args)
echo s:cmd
if exists(":AsyncRun")
execute 'copen'
execute 'AsyncRun ' . s:cmd
execute 'wincmd p'
else
silent let s:res = system(s:cmd)
silent echo s:res
endif
" Create symbolic link to compilation database for use with YouCompleteMe
if g:cmake_ycm_symlinks && filereadable("compile_commands.json")
if has("win32")
exec "mklink" "../compile_commands.json" "compile_commands.json"
else
silent echo system("ln -s " . s:fnameescape(b:build_dir) ."/compile_commands.json ../compile_commands.json")
endif
echom "Created symlink to compilation database"
endif
exec 'cd -'
endfunction
" Utility function
" Thanks to tpope/vim-fugitive
function! s:fnameescape(file) abort
if exists('*fnameescape')
return fnameescape(a:file)
else
return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
endif
endfunction
function! s:find_smp()
if executable('nproc')
let l:nproc = system('nproc')
let b:smp = '-j' . substitute(l:nproc, '\n\+$', '', '')
return 1
endif
return 0
endfunction
command! -complete=customlist,ListTargets -nargs=1 Make :make
function! ListTargets(A, L, C)
if !exists("b:build_dir")
return []
endif
let all_targets = split(system("cmake --build ". b:build_dir . " --target help | awk ' NR > 1 {print $2}'"), '\n')
let targets = filter(all_targets, "v:val =~ '^" .. a:A .. "'")
return targets
endfunction
" Public Interface:
command! -nargs=? CMake call s:cmake()
command! CMakeClean call s:cmakeclean()
command! CMakeFindBuildDir call s:cmake_find_build_dir()
function! s:cmake_find_build_dir()
unlet! b:build_dir
call s:find_build_dir()
endfunction
function! s:cmake(...)
if !s:find_build_dir()
return
endif
if g:cmake_use_smp && s:find_smp()
let l:smp = ' ' . shellescape(b:smp)
else
let l:smp = ''
endif
let &makeprg = 'cmake --build ' . shellescape(b:build_dir) . l:smp . ' --target'
call s:cmake_configure(a:000)
endfunction
function! s:cmakeclean()
if !s:find_build_dir()
return
endif
silent echo system("rm -r '" . b:build_dir. "'/*")
echom "Build directory has been cleaned."
endfunction
================================================
FILE: test/.vimrc
================================================
filetype off
set rtp+=vader.vim
set rtp+=.
filetype plugin indent on
syntax enable
================================================
FILE: test/cmake.vader
================================================
Before:
" Ensure we are in the test directory
if isdirectory("test")
cd test
endif
if !exists("test_dir")
let test_dir = fnamemodify(getcwd(), ':p')
endif
Assert !isdirectory("test project/tmp-build"), "TEST ERROR: build directory was not properly deleted"
echo system("mkdir 'test project/tmp-build'")
Assert isdirectory("test project/tmp-build"), "TEST ERROR: build directory was not created"
" Under travis CI the entire project is in a build/ directory
" which will make the search from cwd always return a result.
" To be able to test searching build dir from current file, the
" build dir needs to be named differently as a workaround.
let g:cmake_build_dir = "tmp-build"
After:
exec "cd" fnameescape(test_dir)
echo system("rm -rf 'test project/tmp-build'")
echo system("rm -f 'test project/compile_commands.json'")
Execute (Find build directory from working dir):
cd test\ project
CMake
Assert filereadable("tmp-build/CMakeCache.txt"), "CMakeCache.txt should be generated"
Assert !filereadable("tmp-build/compile_commands.json"), "Compile commands should not be exported by default"
Execute (Find build directory from currently open file):
e test\ project/CMakeLists.txt
CMake
Assert filereadable("test project/tmp-build/CMakeCache.txt"), "CMakeCache.txt should be generated"
Execute (Create symlink to compilation database):
let g:cmake_export_compile_commands = 1
let g:cmake_ycm_symlinks = 1
cd test\ project
CMake
" Exporting compile commands does not work with Visual Studio generator
if !has("win32") && !has("win32unix")
Assert filereadable("tmp-build/compile_commands.json"), "Compile commands should be exported"
Assert filereadable(resolve("compile_commands.json")), "A symlink should be generated"
endif
Execute (Open already configured cmake project):
cd test\ project/tmp-build
silent !cmake .. -DWITH_BYE=ON
e ../CMakeLists.txt
CMake
silent make
enew
if has("win32") || has("win32unix")
read !Debug/hello.exe
else
read !./hello
endif
Expect:
Hello World
Bye World
================================================
FILE: test/test project/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 2.8.12)
project(HelloWorld)
option(WITH_BYE "Print bye world" OFF)
configure_file(configure.h.cmake configure.h)
add_executable(hello main.cpp)
target_include_directories(hello PRIVATE ${CMAKE_BINARY_DIR})
================================================
FILE: test/test project/configure.h.cmake
================================================
#cmakedefine WITH_BYE
================================================
FILE: test/test project/main.cpp
================================================
#include
#include "configure.h"
int main() {
std::cout << "Hello World" << std::endl;
#ifdef WITH_BYE
std::cout << "Bye World" << std::endl;
#endif
return 0;
}