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 [![Travis (Linux)](https://travis-ci.org/vhdirk/vim-cmake.svg?branch=master)](https://travis-ci.org/vhdirk/vim-cmake) [![AppVeyor (Windows)](https://ci.appveyor.com/api/projects/status/ns1o9252o2rrmv6g?svg=true)](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; }