mirror of
https://github.com/amix/vimrc
synced 2025-07-07 08:45:00 +08:00
I don't know how to ignore autoformatting *.h.in files, so change into autoformat files manually.
This commit is contained in:
128
sources_non_forked/vim-cmake/autoload/cmake/build.vim
Normal file
128
sources_non_forked/vim-cmake/autoload/cmake/build.vim
Normal file
@ -0,0 +1,128 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/build.vim
|
||||
" Description: Functions for building a project
|
||||
" ==============================================================================
|
||||
|
||||
let s:build = {}
|
||||
|
||||
let s:buildsys = cmake#buildsys#Get()
|
||||
let s:const = cmake#const#Get()
|
||||
let s:logger = cmake#logger#Get()
|
||||
let s:quickfix = cmake#quickfix#Get()
|
||||
let s:system = cmake#system#Get()
|
||||
let s:terminal = cmake#terminal#Get()
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Private functions and callbacks
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Get dictionary of build arguments from command-line string.
|
||||
"
|
||||
" Params:
|
||||
" argstring : String
|
||||
" command-line arguments, like target and additional build options
|
||||
"
|
||||
" Returns:
|
||||
" Dictionary
|
||||
" CMake build options, target and native options
|
||||
"
|
||||
" Example:
|
||||
" argstring = --jobs 4 all -- VERBOSE=1
|
||||
" return = {
|
||||
" \ 'cmake_build_options': ['--jobs', '4'],
|
||||
" \ 'target': ['--target', 'all'],
|
||||
" \ 'native_build_options': ['VERBOSE=1']
|
||||
" \ }
|
||||
"
|
||||
function! s:GetBuildArgs(argstring) abort
|
||||
let l:argdict = {}
|
||||
let l:arglist = split(a:argstring)
|
||||
" Search arguments for one that matches the name of a target.
|
||||
for l:t in s:buildsys.GetTargets()
|
||||
let l:match_res = match(l:arglist, '\m\C^' . l:t)
|
||||
if l:match_res != -1
|
||||
" If found, get target and remove from list of arguments.
|
||||
let l:target = l:arglist[l:match_res]
|
||||
let l:argdict['target'] = ['--target', l:target]
|
||||
call remove(l:arglist, l:match_res)
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
" Search for command-line native build tool arguments.
|
||||
let l:match_res = match(l:arglist, '\m\C^--$')
|
||||
if l:match_res != -1
|
||||
" Get command-line native build tool arguments and remove from list.
|
||||
let l:argdict['native_build_options'] = l:arglist[l:match_res+1:]
|
||||
" Remove from list of other arguments.
|
||||
call remove(l:arglist, l:match_res, -1)
|
||||
endif
|
||||
" Get command-line CMake arguments.
|
||||
let l:argdict['cmake_build_options'] = l:arglist
|
||||
return l:argdict
|
||||
endfunction
|
||||
|
||||
" Generate quickfix list after running build command.
|
||||
"
|
||||
function! s:GenerateQuickfix() abort
|
||||
call s:quickfix.Generate(s:terminal.GetOutput())
|
||||
endfunction
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Build a project using the generated buildsystem.
|
||||
"
|
||||
" Params:
|
||||
" clean : Boolean
|
||||
" whether to clean before building
|
||||
" argstring : String
|
||||
" build target and other options
|
||||
"
|
||||
function! s:build.Build(clean, argstring) abort
|
||||
call s:logger.LogDebug('Invoked: build.Build(%s, %s)',
|
||||
\ a:clean, string(a:argstring))
|
||||
let l:path_to_current_config = s:buildsys.GetPathToCurrentConfig()
|
||||
let l:build_dir = s:system.Path([l:path_to_current_config], v:true)
|
||||
let l:command = [g:cmake_command, '--build', l:build_dir]
|
||||
let l:options = {}
|
||||
" Parse additional options.
|
||||
let l:options = s:GetBuildArgs(a:argstring)
|
||||
" Add CMake build options to the command.
|
||||
let l:command += g:cmake_build_options
|
||||
let l:command += get(l:options, 'cmake_build_options', [])
|
||||
if a:clean
|
||||
let l:command += ['--clean-first']
|
||||
endif
|
||||
" Add target to the command, if any was provided.
|
||||
let l:command += get(l:options, 'target', [])
|
||||
" Add native build tool options to the command.
|
||||
if len(g:cmake_native_build_options) > 0 ||
|
||||
\ len(get(l:options, 'native_build_options', [])) > 0
|
||||
let l:command += ['--']
|
||||
let l:command += g:cmake_native_build_options
|
||||
let l:command += get(l:options, 'native_build_options', [])
|
||||
endif
|
||||
" Run build command.
|
||||
call s:terminal.Run(l:command, 'build',
|
||||
\ [function('s:GenerateQuickfix')],
|
||||
\ [function('s:GenerateQuickfix')],
|
||||
\ ['CMakeBuildSucceeded'], ['CMakeBuildFailed']
|
||||
\ )
|
||||
endfunction
|
||||
|
||||
" Install a project.
|
||||
"
|
||||
function! s:build.Install() abort
|
||||
call s:logger.LogDebug('Invoked: build.Install()')
|
||||
let l:path_to_current_config = s:buildsys.GetPathToCurrentConfig()
|
||||
let l:build_dir = s:system.Path([l:path_to_current_config], v:true)
|
||||
let l:command = [g:cmake_command, '--install', l:build_dir]
|
||||
call s:terminal.Run(l:command, 'install', [], [], [], [])
|
||||
endfunction
|
||||
|
||||
" Get build 'object'.
|
||||
"
|
||||
function! cmake#build#Get() abort
|
||||
return s:build
|
||||
endfunction
|
443
sources_non_forked/vim-cmake/autoload/cmake/buildsys.vim
Normal file
443
sources_non_forked/vim-cmake/autoload/cmake/buildsys.vim
Normal file
@ -0,0 +1,443 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/buildsys.vim
|
||||
" Description: Functions for generating the buildsystem
|
||||
" ==============================================================================
|
||||
|
||||
let s:buildsys = {}
|
||||
let s:buildsys.cmake_version = 0
|
||||
let s:buildsys.project_root = ''
|
||||
let s:buildsys.current_config = ''
|
||||
let s:buildsys.path_to_current_config = ''
|
||||
let s:buildsys.configs = []
|
||||
let s:buildsys.targets = []
|
||||
|
||||
let s:logger = cmake#logger#Get()
|
||||
let s:statusline = cmake#statusline#Get()
|
||||
let s:system = cmake#system#Get()
|
||||
let s:terminal = cmake#terminal#Get()
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Private functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Find project root by looking for g:cmake_root_markers upwards.
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" escaped path to the root of the project
|
||||
"
|
||||
function! s:FindProjectRoot() abort
|
||||
let l:root = getcwd()
|
||||
let l:escaped_cwd = fnameescape(getcwd())
|
||||
for l:marker in g:cmake_root_markers
|
||||
" Search CWD upward for l:marker, assuming it is a file.
|
||||
let l:marker_path = findfile(l:marker, l:escaped_cwd . ';' . $HOME)
|
||||
if len(l:marker_path) > 0
|
||||
" If found, strip l:marker from it.
|
||||
let l:root = fnamemodify(l:marker_path, ':h')
|
||||
break
|
||||
endif
|
||||
" Search CWD upward for l:marker, assuming it is a directory.
|
||||
let l:marker_path = finddir(l:marker, l:escaped_cwd . ';' . $HOME)
|
||||
if len(l:marker_path) > 0
|
||||
" If found, strip l:marker from it.
|
||||
let l:root = fnamemodify(l:marker_path, ':h')
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return l:root
|
||||
endfunction
|
||||
|
||||
" Get absolute path to location where the build directory is located.
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" path to build directory location
|
||||
"
|
||||
function! s:GetBuildDirLocation() abort
|
||||
return s:system.Path(
|
||||
\ [s:buildsys.project_root, g:cmake_build_dir_location], v:false)
|
||||
endfunction
|
||||
|
||||
" Find CMake variable in list of options.
|
||||
"
|
||||
" Params:
|
||||
" opts : List
|
||||
" list of options
|
||||
" variable : String
|
||||
" variable to find
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" value of the CMake variable, or an empty string if the variable was
|
||||
" not found
|
||||
"
|
||||
" Example:
|
||||
" to find the variable 'CMAKE_BUILD_TYPE', which would be passed by the user
|
||||
" as '-D CMAKE_BUILD_TYPE=<value>', call
|
||||
" s:FindVarInOpts(opts, 'CMAKE_BUILD_TYPE')
|
||||
"
|
||||
function! s:FindVarInOpts(opts, variable) abort
|
||||
if len(a:opts) > 0
|
||||
" Search the list of command-line options for an entry matching
|
||||
" '-D <variable>=<value>' or '-D <variable>:<type>=<value>' or
|
||||
" '-D<variable>=<value>' or '-D<variable>:<type>=<value>'.
|
||||
let l:opt = matchstr(a:opts, '\m\C-D\s*' . a:variable)
|
||||
" If found, return the value, otherwise return an empty string.
|
||||
if len(l:opt) > 0
|
||||
return split(l:opt, '=')[1]
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Process build configuration.
|
||||
"
|
||||
" Params:
|
||||
" opts : List
|
||||
" list of options
|
||||
"
|
||||
function! s:ProcessBuildConfig(opts) abort
|
||||
let l:config = s:buildsys.current_config
|
||||
" Check if the first entry of the list of command-line options starts with a
|
||||
" letter (and not with a dash), in which case the user will have passed the
|
||||
" name of the build configuration as the first option.
|
||||
if (len(a:opts) > 0) && (match(a:opts[0], '\m\C^\w') >= 0)
|
||||
" Update build config name and remove from list of options.
|
||||
let l:config = a:opts[0]
|
||||
call s:SetCurrentConfig(l:config)
|
||||
call remove(a:opts, 0)
|
||||
endif
|
||||
" If the list of command-line options does not contain an explicit value for
|
||||
" the 'CMAKE_BUILD_TYPE' variable, add it.
|
||||
if s:FindVarInOpts(a:opts, 'CMAKE_BUILD_TYPE') ==# ''
|
||||
call add(a:opts, '-D CMAKE_BUILD_TYPE=' . l:config)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Get list of command-line options from string of arguments.
|
||||
"
|
||||
" Params:
|
||||
" argstring : String
|
||||
" string containing command-line arguments
|
||||
"
|
||||
" Returns:
|
||||
" List
|
||||
" list of unprocessed command-line options
|
||||
"
|
||||
" Example:
|
||||
" an argument string like the following
|
||||
" 'Debug -D VAR_A=1 -DVAR_B=0 -Wdev -U VAR_C'
|
||||
" results in a list of options like the following
|
||||
" ['Debug', '-D VAR_A=1', '-DVAR_B=0', '-Wdev', '-U VAR_C']
|
||||
"
|
||||
function! s:ArgStringToOptList(argstring) abort
|
||||
let l:opts = []
|
||||
for l:arg in split(a:argstring)
|
||||
" If list of options is empty, append first argument.
|
||||
if len(l:opts) == 0
|
||||
call add(l:opts, l:arg)
|
||||
" If argument starts with a dash, append it to the list of options.
|
||||
elseif match(l:arg, '\m\C^-') >= 0
|
||||
call add(l:opts, l:arg)
|
||||
" If argument does not start with a dash, it must belong to the last
|
||||
" option that was added to the list, thus extend that option.
|
||||
else
|
||||
let l:opts[-1] = join([l:opts[-1], l:arg])
|
||||
endif
|
||||
endfor
|
||||
return l:opts
|
||||
endfunction
|
||||
|
||||
" Process string of arguments and return parsed options.
|
||||
"
|
||||
" Params:
|
||||
" argstring : String
|
||||
" string containing command-line arguments
|
||||
"
|
||||
" Returns:
|
||||
" Dictionary
|
||||
" opts : List
|
||||
" list of options
|
||||
" source_dir : String
|
||||
" path to source directory
|
||||
" build_dir : String
|
||||
" path to build directory
|
||||
"
|
||||
function! s:ProcessArgString(argstring) abort
|
||||
let l:opts = s:ArgStringToOptList(a:argstring)
|
||||
call s:ProcessBuildConfig(l:opts)
|
||||
" If compile commands are to be exported, and the
|
||||
" 'CMAKE_EXPORT_COMPILE_COMMANDS' variable is not set, set it.
|
||||
if g:cmake_link_compile_commands
|
||||
if s:FindVarInOpts(l:opts, 'CMAKE_EXPORT_COMPILE_COMMANDS') ==# ''
|
||||
call add(l:opts, '-D CMAKE_EXPORT_COMPILE_COMMANDS=ON')
|
||||
endif
|
||||
endif
|
||||
" Set source and build directories. Must be done after processing the build
|
||||
" configuration so that the current build configuration is up to date before
|
||||
" setting the build directory.
|
||||
let l:source_dir = s:system.Path([s:buildsys.project_root], v:true)
|
||||
let l:build_dir = s:system.Path([s:buildsys.path_to_current_config], v:true)
|
||||
" Return dictionary of options.
|
||||
let l:optdict = {}
|
||||
let l:optdict.opts = l:opts
|
||||
let l:optdict.source_dir = l:source_dir
|
||||
let l:optdict.build_dir = l:build_dir
|
||||
return l:optdict
|
||||
endfunction
|
||||
|
||||
" Refresh list of build configuration directories.
|
||||
"
|
||||
function! s:RefreshConfigs() abort
|
||||
" List of directories inside of which a CMakeCache file is found.
|
||||
let l:cache_dirs = findfile(
|
||||
\ 'CMakeCache.txt',
|
||||
\ s:GetBuildDirLocation() . '/**1',
|
||||
\ -1)
|
||||
" Transform paths to just names of directories. These will be the names of
|
||||
" existing configuration directories.
|
||||
call map(l:cache_dirs, {_, val -> fnamemodify(val, ':h:t')})
|
||||
let s:buildsys.configs = l:cache_dirs
|
||||
call s:logger.LogDebug('Build configs: %s', s:buildsys.configs)
|
||||
endfunction
|
||||
|
||||
" Callback for RefreshTargets().
|
||||
"
|
||||
function! s:RefreshTargetsCb(...) abort
|
||||
let l:data = s:system.ExtractStdoutCallbackData(a:000)
|
||||
for l:line in l:data
|
||||
if match(l:line, '\m\C\.\.\.\s') == 0
|
||||
let l:target = split(l:line)[1]
|
||||
let s:buildsys.targets += [l:target]
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Refresh list of available CMake targets.
|
||||
"
|
||||
function! s:RefreshTargets() abort
|
||||
let s:buildsys.targets = []
|
||||
let l:build_dir = s:buildsys.path_to_current_config
|
||||
let l:command = [g:cmake_command,
|
||||
\ '--build', l:build_dir,
|
||||
\ '--target', 'help'
|
||||
\ ]
|
||||
call s:system.JobRun(
|
||||
\ l:command, v:true, function('s:RefreshTargetsCb'), v:null, v:false)
|
||||
endfunction
|
||||
|
||||
" Check if build configuration directory exists.
|
||||
"
|
||||
" Params:
|
||||
" config : String
|
||||
" configuration to check
|
||||
"
|
||||
" Returns:
|
||||
" Boolean
|
||||
" v:true if the build configuration exists, v:false otherwise
|
||||
"
|
||||
function! s:ConfigExists(config) abort
|
||||
return index(s:buildsys.configs, a:config) >= 0
|
||||
endfunction
|
||||
|
||||
" Set current build configuration.
|
||||
"
|
||||
" Params:
|
||||
" config : String
|
||||
" build configuration name
|
||||
"
|
||||
function! s:SetCurrentConfig(config) abort
|
||||
let s:buildsys.current_config = a:config
|
||||
let l:path = s:system.Path([s:GetBuildDirLocation(), a:config], v:false)
|
||||
let s:buildsys.path_to_current_config = l:path
|
||||
call s:logger.LogInfo('Current config: %s (%s)',
|
||||
\ s:buildsys.current_config,
|
||||
\ s:buildsys.path_to_current_config
|
||||
\ )
|
||||
call s:statusline.SetBuildInfo(s:buildsys.current_config)
|
||||
endfunction
|
||||
|
||||
" Link compile commands from source directory to build directory.
|
||||
"
|
||||
function! s:LinkCompileCommands() abort
|
||||
if !g:cmake_link_compile_commands
|
||||
return
|
||||
endif
|
||||
let l:target = s:system.Path(
|
||||
\ [s:buildsys.path_to_current_config, 'compile_commands.json'],
|
||||
\ v:true
|
||||
\ )
|
||||
let l:link = s:system.Path(
|
||||
\ [s:buildsys.project_root, 'compile_commands.json'],
|
||||
\ v:true,
|
||||
\ )
|
||||
let l:command = [g:cmake_command, '-E', 'create_symlink', l:target, l:link]
|
||||
call s:system.JobRun(l:command, v:true, v:null, v:null, v:false)
|
||||
endfunction
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Generate a buildsystem for the project using CMake.
|
||||
"
|
||||
" Params:
|
||||
" clean : Boolean
|
||||
" whether to clean before generating
|
||||
" argstring : String
|
||||
" build configuration and additional CMake options
|
||||
"
|
||||
function! s:buildsys.Generate(clean, argstring) abort
|
||||
call s:logger.LogDebug('Invoked: buildsys.Generate(%s, %s)',
|
||||
\ a:clean, string(a:argstring))
|
||||
let l:command = [g:cmake_command]
|
||||
let l:optdict = s:ProcessArgString(a:argstring)
|
||||
" Construct command.
|
||||
call extend(l:command, g:cmake_generate_options)
|
||||
call extend(l:command, l:optdict.opts)
|
||||
if l:self.cmake_version < 313
|
||||
call add(l:command, '-H' . l:optdict.source_dir)
|
||||
call add(l:command, '-B' . l:optdict.build_dir)
|
||||
else
|
||||
call add(l:command, '-S ' . l:optdict.source_dir)
|
||||
call add(l:command, '-B ' . l:optdict.build_dir)
|
||||
endif
|
||||
" Clean project buildsystem, if requested.
|
||||
if a:clean
|
||||
call l:self.Clean()
|
||||
endif
|
||||
" Run generate command.
|
||||
call s:terminal.Run(
|
||||
\ l:command, 'generate',
|
||||
\ [
|
||||
\ function('s:RefreshConfigs'),
|
||||
\ function('s:RefreshTargets'),
|
||||
\ function('s:LinkCompileCommands')
|
||||
\ ],
|
||||
\ [function('s:RefreshConfigs')],
|
||||
\ [], []
|
||||
\ )
|
||||
endfunction
|
||||
|
||||
" Clean buildsystem.
|
||||
"
|
||||
function! s:buildsys.Clean() abort
|
||||
call s:logger.LogDebug('Invoked: buildsys.Clean()')
|
||||
if isdirectory(l:self.path_to_current_config)
|
||||
call delete(l:self.path_to_current_config, 'rf')
|
||||
endif
|
||||
call s:RefreshConfigs()
|
||||
endfunction
|
||||
|
||||
" Set current build configuration after checking that the configuration exists.
|
||||
"
|
||||
" Params:
|
||||
" config : String
|
||||
" build configuration name
|
||||
"
|
||||
function! s:buildsys.Switch(config) abort
|
||||
call s:logger.LogDebug('Invoked: buildsys.Switch(%s)', a:config)
|
||||
" Check that config exists.
|
||||
if !s:ConfigExists(a:config)
|
||||
call s:logger.EchoError(
|
||||
\ "Build configuration '%s' not found, run ':CMakeGenerate %s'",
|
||||
\ a:config, a:config)
|
||||
call s:logger.LogError(
|
||||
\ "Build configuration '%s' not found, run ':CMakeGenerate %s'",
|
||||
\ a:config, a:config)
|
||||
return
|
||||
endif
|
||||
call s:SetCurrentConfig(a:config)
|
||||
call s:LinkCompileCommands()
|
||||
endfunction
|
||||
|
||||
" Get list of configuration directories (containing a buildsystem).
|
||||
"
|
||||
" Returns:
|
||||
" List
|
||||
" list of existing configuration directories
|
||||
"
|
||||
function! s:buildsys.GetConfigs() abort
|
||||
return l:self.configs
|
||||
endfunction
|
||||
|
||||
" Get list of available build targets.
|
||||
"
|
||||
" Returns:
|
||||
" List
|
||||
" list of available build targets
|
||||
"
|
||||
function! s:buildsys.GetTargets() abort
|
||||
if len(l:self.targets) == 0
|
||||
call s:RefreshTargets()
|
||||
endif
|
||||
return l:self.targets
|
||||
endfunction
|
||||
|
||||
" Get current build configuration.
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" build configuration
|
||||
"
|
||||
function! s:buildsys.GetCurrentConfig() abort
|
||||
return l:self.current_config
|
||||
endfunction
|
||||
|
||||
" Get path to CMake source directory of current project.
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" path to CMake source directory
|
||||
"
|
||||
function! s:buildsys.GetSourceDir() abort
|
||||
return l:self.project_root
|
||||
endfunction
|
||||
|
||||
" Get path to current build configuration.
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" path to build configuration
|
||||
"
|
||||
function! s:buildsys.GetPathToCurrentConfig() abort
|
||||
return l:self.path_to_current_config
|
||||
endfunction
|
||||
|
||||
" Get buildsys 'object'.
|
||||
"
|
||||
function! cmake#buildsys#Get() abort
|
||||
return s:buildsys
|
||||
endfunction
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Initialization
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
function! s:GetCMakeVersionCb(...) abort
|
||||
let l:data = s:system.ExtractStdoutCallbackData(a:000)
|
||||
for l:line in l:data
|
||||
if match(l:line, '\m\C^cmake\S* version') == 0
|
||||
let l:version_str = split(split(l:line)[2], '\.')
|
||||
let l:major = str2nr(l:version_str[0])
|
||||
let l:minor = str2nr(l:version_str[1])
|
||||
let s:buildsys.cmake_version = l:major * 100 + l:minor
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Get CMake version. The version is stored as MAJOR * 100 + MINOR (e.g., version
|
||||
" 3.13.3 would result in 313).
|
||||
let s:command = [g:cmake_command, '--version']
|
||||
call s:system.JobRun(
|
||||
\ s:command, v:true, function('s:GetCMakeVersionCb'), v:null, v:false)
|
||||
|
||||
" Must be done before any other initial configuration.
|
||||
let s:buildsys.project_root = s:system.Path([s:FindProjectRoot()], v:false)
|
||||
call s:logger.LogInfo('Project root: %s', s:buildsys.project_root)
|
||||
|
||||
call s:SetCurrentConfig(g:cmake_default_config)
|
||||
call s:RefreshConfigs()
|
47
sources_non_forked/vim-cmake/autoload/cmake/const.vim
Normal file
47
sources_non_forked/vim-cmake/autoload/cmake/const.vim
Normal file
@ -0,0 +1,47 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/const.vim
|
||||
" Description: Constants and definitions
|
||||
" ==============================================================================
|
||||
|
||||
let s:const = {}
|
||||
|
||||
let s:const.plugin_version = '0.7.1'
|
||||
|
||||
let s:const.plugin_news = {
|
||||
\ '0.2.0': ['Vim-CMake has a new feature, run `:help cmake-switch`'],
|
||||
\ '0.3.0': ['Vim-CMake has a new feature, run `:help cmake-quickfix`'],
|
||||
\ '0.4.0': ['Vim-CMake has a new config option `g:cmake_generate_options`'],
|
||||
\ '0.5.0': ['Vim-CMake has a new feature, run `:help cmake-events`'],
|
||||
\ '0.6.0': [
|
||||
\ 'Vim-CMake has a new config option `g:cmake_build_dir_location`',
|
||||
\ 'Vim-CMake has improved :CMakeGenerate, run `:help cmake-generate`'
|
||||
\ ],
|
||||
\ '0.7.0': [
|
||||
\ 'Vim-CMake has new command `:CMakeStop`, run `:help cmake-stop`',
|
||||
\ 'Vim-CMake has a new config option `g:cmake_console_echo_cmd`'
|
||||
\ ],
|
||||
\ }
|
||||
|
||||
let s:const.config_vars = {
|
||||
\ 'cmake_command' : 'cmake',
|
||||
\ 'cmake_default_config' : 'Debug',
|
||||
\ 'cmake_build_dir_location' : '.',
|
||||
\ 'cmake_generate_options' : [],
|
||||
\ 'cmake_build_options' : [],
|
||||
\ 'cmake_native_build_options' : [],
|
||||
\ 'cmake_console_size' : 15,
|
||||
\ 'cmake_console_position' : 'botright',
|
||||
\ 'cmake_console_echo_cmd' : 1,
|
||||
\ 'cmake_jump' : 0,
|
||||
\ 'cmake_jump_on_completion' : 0,
|
||||
\ 'cmake_jump_on_error' : 1,
|
||||
\ 'cmake_link_compile_commands' : 0,
|
||||
\ 'cmake_root_markers' : ['.git', '.svn'],
|
||||
\ 'cmake_log_file' : '',
|
||||
\ }
|
||||
|
||||
" Get const 'object'.
|
||||
"
|
||||
function! cmake#const#Get() abort
|
||||
return s:const
|
||||
endfunction
|
132
sources_non_forked/vim-cmake/autoload/cmake/logger.vim
Normal file
132
sources_non_forked/vim-cmake/autoload/cmake/logger.vim
Normal file
@ -0,0 +1,132 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/logger.vim
|
||||
" Description: Logger
|
||||
" ==============================================================================
|
||||
|
||||
let s:logger = {}
|
||||
|
||||
function! s:Echo(fmt, arglist) abort
|
||||
" Trick to convert list (a:arglist) into arguments for printf().
|
||||
let l:PrintfPartial = function('printf', [a:fmt] + a:arglist)
|
||||
echomsg '[Vim-CMake] ' . l:PrintfPartial()
|
||||
endfunction
|
||||
|
||||
function! s:Log(fmt, level, arglist) abort
|
||||
" Trick to convert list (a:arglist) into arguments for printf().
|
||||
let l:PrintfPartial = function('printf', [a:fmt] + a:arglist)
|
||||
let l:logstring = printf(
|
||||
\ '[%s] [%5s] %s',
|
||||
\ strftime('%Y-%m-%d %T'),
|
||||
\ a:level,
|
||||
\ l:PrintfPartial()
|
||||
\ )
|
||||
call writefile([l:logstring], g:cmake_log_file, 'a')
|
||||
endfunction
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Log a debug message.
|
||||
"
|
||||
" Params:
|
||||
" fmt : String
|
||||
" printf-like format string (see :help printf())
|
||||
" ... :
|
||||
" list of arguments to replace placeholders in format string
|
||||
"
|
||||
function! s:logger.LogDebug(fmt, ...) abort
|
||||
if g:cmake_log_file !=# ''
|
||||
call s:Log(a:fmt, 'DEBUG', a:000)
|
||||
end
|
||||
endfunction
|
||||
|
||||
" Log an information message.
|
||||
"
|
||||
" Params:
|
||||
" fmt : String
|
||||
" printf-like format string (see :help printf())
|
||||
" ... :
|
||||
" list of arguments to replace placeholders in format string
|
||||
"
|
||||
function! s:logger.LogInfo(fmt, ...) abort
|
||||
if g:cmake_log_file !=# ''
|
||||
call s:Log(a:fmt, 'INFO', a:000)
|
||||
end
|
||||
endfunction
|
||||
|
||||
" Log a warning message.
|
||||
"
|
||||
" Params:
|
||||
" fmt : String
|
||||
" printf-like format string (see :help printf())
|
||||
" ... :
|
||||
" list of arguments to replace placeholders in format string
|
||||
"
|
||||
function! s:logger.LogWarn(fmt, ...) abort
|
||||
if g:cmake_log_file !=# ''
|
||||
call s:Log(a:fmt, 'WARN', a:000)
|
||||
end
|
||||
endfunction
|
||||
|
||||
" Log an error message.
|
||||
"
|
||||
" Params:
|
||||
" fmt : String
|
||||
" printf-like format string (see :help printf())
|
||||
" ... :
|
||||
" list of arguments to replace placeholders in format string
|
||||
"
|
||||
function! s:logger.LogError(fmt, ...) abort
|
||||
if g:cmake_log_file !=# ''
|
||||
call s:Log(a:fmt, 'ERROR', a:000)
|
||||
end
|
||||
endfunction
|
||||
|
||||
" Echo an information message.
|
||||
"
|
||||
" Params:
|
||||
" fmt : String
|
||||
" printf-like format string (see :help printf())
|
||||
" ... :
|
||||
" list of arguments to replace placeholders in format string
|
||||
"
|
||||
function! s:logger.EchoInfo(fmt, ...) abort
|
||||
echohl MoreMsg
|
||||
call s:Echo(a:fmt, a:000)
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
" Echo a warning message.
|
||||
"
|
||||
" Params:
|
||||
" fmt : String
|
||||
" printf-like format string (see :help printf())
|
||||
" ... :
|
||||
" list of arguments to replace placeholders in format string
|
||||
"
|
||||
function! s:logger.EchoWarn(fmt, ...) abort
|
||||
echohl WarningMsg
|
||||
call s:Echo(a:fmt, a:000)
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
" Echo an error message.
|
||||
"
|
||||
" Params:
|
||||
" fmt : String
|
||||
" printf-like format string (see :help printf())
|
||||
" ... :
|
||||
" list of arguments to replace placeholders in format string
|
||||
"
|
||||
function! s:logger.EchoError(fmt, ...) abort
|
||||
echohl Error
|
||||
call s:Echo(a:fmt, a:000)
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
" Get logger 'object'
|
||||
"
|
||||
function! cmake#logger#Get() abort
|
||||
return s:logger
|
||||
endfunction
|
56
sources_non_forked/vim-cmake/autoload/cmake/quickfix.vim
Normal file
56
sources_non_forked/vim-cmake/autoload/cmake/quickfix.vim
Normal file
@ -0,0 +1,56 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/quickfix.vim
|
||||
" Description: Functions for populating the quickfix window
|
||||
" ==============================================================================
|
||||
|
||||
let s:quickfix = {}
|
||||
let s:quickfix.list = {}
|
||||
let s:quickfix.list.items = []
|
||||
let s:quickfix.list.title = 'CMakeBuild'
|
||||
let s:quickfix.id = -1
|
||||
|
||||
let s:filters = [
|
||||
\ 'v:val.valid == 1',
|
||||
\ 'filereadable(bufname(v:val.bufnr))',
|
||||
\ ]
|
||||
|
||||
let s:logger = cmake#logger#Get()
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Generate Quickfix list from lines
|
||||
"
|
||||
" Params:
|
||||
" lines_to_parse : List
|
||||
" list of lines to parse to generate Quickfix list
|
||||
"
|
||||
function! s:quickfix.Generate(lines_to_parse) abort
|
||||
call s:logger.LogDebug('Invoked: s:quickfix.Generate()')
|
||||
" Create a list of quickfix items from the output of the last command.
|
||||
let l:list = getqflist({'lines': a:lines_to_parse})
|
||||
let l:self.list.items = filter(l:list.items, join(s:filters, ' && '))
|
||||
" If a quickfix list for Vim-CMake exists, make that list active and replace
|
||||
" its items with the new ones.
|
||||
if getqflist({'id': l:self.id}).id == l:self.id
|
||||
let l:current = getqflist({'nr': 0}).nr
|
||||
let l:target = getqflist({'id': l:self.id, 'nr': 0}).nr
|
||||
if l:current > l:target
|
||||
execute 'silent colder ' . (l:current - l:target)
|
||||
elseif l:current < l:target
|
||||
execute 'silent cnewer ' . (l:target - l:current)
|
||||
endif
|
||||
call setqflist([], 'r', {'items': l:self.list.items})
|
||||
call s:logger.LogDebug('Replaced existing Quickfix list')
|
||||
" Otherwise, create a new quickfix list.
|
||||
else
|
||||
call setqflist([], ' ', l:self.list)
|
||||
call s:logger.LogDebug('Created new Quickfix list')
|
||||
endif
|
||||
let l:self.id = getqflist({'nr': 0, 'id': 0}).id
|
||||
endfunction
|
||||
|
||||
function! cmake#quickfix#Get() abort
|
||||
return s:quickfix
|
||||
endfunction
|
84
sources_non_forked/vim-cmake/autoload/cmake/statusline.vim
Normal file
84
sources_non_forked/vim-cmake/autoload/cmake/statusline.vim
Normal file
@ -0,0 +1,84 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/statusline.vim
|
||||
" Description: Functions for handling statusline information
|
||||
" ==============================================================================
|
||||
|
||||
let s:statusline = {}
|
||||
let s:statusline.build_info = ''
|
||||
let s:statusline.cmd_info = ''
|
||||
|
||||
let s:logger = cmake#logger#Get()
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Set build info string for statusline/airline.
|
||||
"
|
||||
" Params:
|
||||
" build_info : String
|
||||
" statusline build info
|
||||
"
|
||||
function! s:statusline.SetBuildInfo(build_info) abort
|
||||
call s:logger.LogDebug('Invoked: statusline.SetBuildInfo(%s)', a:build_info)
|
||||
let l:self.build_info = a:build_info
|
||||
endfunction
|
||||
|
||||
" Set command info string for statusline/airline.
|
||||
"
|
||||
" Params:
|
||||
" cmd_info : String
|
||||
" statusline command info
|
||||
"
|
||||
function! s:statusline.SetCmdInfo(cmd_info) abort
|
||||
call s:logger.LogDebug('Invoked: statusline.SetCmdInfo(%s)', a:cmd_info)
|
||||
let l:self.cmd_info = a:cmd_info
|
||||
endfunction
|
||||
|
||||
" Force a refresh of the statusline/airline.
|
||||
"
|
||||
function! s:statusline.Refresh() abort
|
||||
if exists('g:loaded_airline') && g:loaded_airline
|
||||
execute 'AirlineRefresh!'
|
||||
else
|
||||
execute 'redrawstatus!'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Get build info string for statusline/airline.
|
||||
"
|
||||
" Params:
|
||||
" active : Number
|
||||
" whether called for the statusline of an active window
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" statusline build info
|
||||
"
|
||||
function! cmake#statusline#GetBuildInfo(active) abort
|
||||
if a:active
|
||||
return s:statusline.build_info
|
||||
else
|
||||
return '[' . s:statusline.build_info . ']'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Get command info string for statusline/airline.
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" statusline command info (command currently running)
|
||||
"
|
||||
function! cmake#statusline#GetCmdInfo() abort
|
||||
if len(s:statusline.cmd_info) > 0
|
||||
return s:statusline.cmd_info
|
||||
else
|
||||
return ' '
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Get statusline 'object'.
|
||||
"
|
||||
function! cmake#statusline#Get() abort
|
||||
return s:statusline
|
||||
endfunction
|
256
sources_non_forked/vim-cmake/autoload/cmake/system.vim
Normal file
256
sources_non_forked/vim-cmake/autoload/cmake/system.vim
Normal file
@ -0,0 +1,256 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/system.vim
|
||||
" Description: System abstraction layer
|
||||
" ==============================================================================
|
||||
|
||||
let s:system = {}
|
||||
|
||||
let s:stdout_partial_line = {}
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Private functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
function! s:ManipulateCommand(command) abort
|
||||
let l:ret_command = []
|
||||
for l:arg in a:command
|
||||
" Remove double quotes around argument that are quoted. For instance,
|
||||
" '-G "Unix Makefiles"' results in '-G Unix Makefiles'.
|
||||
let l:quotes_regex = '\m\C\(^\|[^"\\]\)"\([^"]\|$\)'
|
||||
let l:arg = substitute(l:arg, l:quotes_regex, '\1\2', 'g')
|
||||
" Split arguments that are composed of an option (short '-O' or long
|
||||
" '--option') and a follow-up string, where the option and the string
|
||||
" are separated by a space.
|
||||
let l:split_regex = '\m\C^\(-\w\|--\w\+\)\s\(.\+\)'
|
||||
let l:match_list = matchlist(l:arg, l:split_regex)
|
||||
if len(l:match_list) > 0
|
||||
call add(l:ret_command, l:match_list[1])
|
||||
call add(l:ret_command, l:match_list[2])
|
||||
else
|
||||
call add(l:ret_command, l:arg)
|
||||
endif
|
||||
endfor
|
||||
return l:ret_command
|
||||
endfunction
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Generate escaped path string from list of components.
|
||||
"
|
||||
" Params:
|
||||
" components : List
|
||||
" list of path components (strings)
|
||||
" relative : Boolean
|
||||
" whether to have the path relative to the current directory or absolute
|
||||
"
|
||||
" Returns:
|
||||
" String
|
||||
" escaped path string with appropriate path separators
|
||||
"
|
||||
function! s:system.Path(components, relative) abort
|
||||
let l:components = a:components
|
||||
let l:separator = has('win32') ? '\' : '/'
|
||||
" Join path components and get absolute path.
|
||||
let l:path = join(l:components, l:separator)
|
||||
let l:path = simplify(l:path)
|
||||
let l:path = fnamemodify(l:path, ':p')
|
||||
" If path ends with separator, remove separator from path.
|
||||
if match(l:path, '\m\C\' . l:separator . '$') != -1
|
||||
let l:path = fnamemodify(l:path, ':h')
|
||||
endif
|
||||
" Reduce to relative path if requested.
|
||||
if a:relative
|
||||
" For some reason, reducing the path to relative returns an empty string
|
||||
" if the path happens to be the same as CWD. Thus, only reduce the path
|
||||
" to relative when it is not CWD, otherwise just return '.'.
|
||||
if l:path ==# getcwd()
|
||||
let l:path = '.'
|
||||
else
|
||||
let l:path = fnamemodify(l:path, ':.')
|
||||
endif
|
||||
endif
|
||||
" Simplify and escape path.
|
||||
let l:path = simplify(l:path)
|
||||
let l:path = fnameescape(l:path)
|
||||
return l:path
|
||||
endfunction
|
||||
|
||||
" Run arbitrary job in the background.
|
||||
"
|
||||
" Params:
|
||||
" command : List
|
||||
" the command to be run, as a list of command and arguments
|
||||
" wait : Boolean
|
||||
" whether to wait for completion
|
||||
" stdout_cb : Funcref
|
||||
" stdout callback (can be v:null), which should take a variable number
|
||||
" of arguments, and from which s:system.ExtractStdoutCallbackData(a:000)
|
||||
" can be called to retrieve the stdout string
|
||||
" exit_cb : Funcref
|
||||
" exit callback (can be v:null), which should take a variable number of
|
||||
" arguments, and from which s:system.ExtractExitCallbackData(a:000) can
|
||||
" be called to retrieve the exit code
|
||||
" pty : Boolean
|
||||
" whether to allocate a pseudo terminal for the job
|
||||
"
|
||||
" Return:
|
||||
" Number
|
||||
" job id
|
||||
"
|
||||
function! s:system.JobRun(command, wait, stdout_cb, exit_cb, pty) abort
|
||||
let l:options = {}
|
||||
let l:options['pty'] = a:pty
|
||||
let l:command = s:ManipulateCommand(a:command)
|
||||
if has('nvim')
|
||||
if a:stdout_cb isnot# v:null
|
||||
let l:options['on_stdout'] = a:stdout_cb
|
||||
endif
|
||||
if a:exit_cb isnot# v:null
|
||||
let l:options['on_exit'] = a:exit_cb
|
||||
endif
|
||||
" In some cases, the PTY in MS-Windows (ConPTY) uses ANSI escape
|
||||
" sequences to move the cursor position (ESC[<n>;<m>H) rather than
|
||||
" inseting newline characters. Setting the width of the PTY to be very
|
||||
" large and the height to be as small as possible (but larger than 1)
|
||||
" seems to circumvent this problem. Hacky, but it seems to work.
|
||||
if has('win32')
|
||||
let l:options['width'] = 10000
|
||||
let l:options['height'] = 2
|
||||
endif
|
||||
let l:job_id = jobstart(l:command, l:options)
|
||||
else
|
||||
if a:stdout_cb isnot# v:null
|
||||
let l:options['out_cb'] = a:stdout_cb
|
||||
endif
|
||||
if a:exit_cb isnot# v:null
|
||||
let l:options['exit_cb'] = a:exit_cb
|
||||
endif
|
||||
let l:job_id = job_start(l:command, l:options)
|
||||
endif
|
||||
" Wait for job to complete, if requested.
|
||||
if a:wait
|
||||
call l:self.JobWait(l:job_id)
|
||||
endif
|
||||
return l:job_id
|
||||
endfunction
|
||||
|
||||
" Wait for job to complete.
|
||||
"
|
||||
" Params:
|
||||
" job_id : Number
|
||||
" job id
|
||||
"
|
||||
function! s:system.JobWait(job_id) abort
|
||||
if has('nvim')
|
||||
call jobwait([a:job_id])
|
||||
else
|
||||
while job_status(a:job_id) ==# 'run'
|
||||
execute 'sleep 5m'
|
||||
endwhile
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Wait for job's channel to be closed.
|
||||
"
|
||||
" Params:
|
||||
" job_id : Number
|
||||
" job id
|
||||
"
|
||||
function! s:system.ChannelWait(job_id) abort
|
||||
" Only makes sense in Vim currently.
|
||||
if !has('nvim')
|
||||
let l:chan_id = job_getchannel(a:job_id)
|
||||
while ch_status(l:chan_id, {'part': 'out'}) !=# 'closed'
|
||||
execute 'sleep 5m'
|
||||
endwhile
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Stop job.
|
||||
"
|
||||
" Params:
|
||||
" job_id : Number
|
||||
" job id
|
||||
"
|
||||
function! s:system.JobStop(job_id) abort
|
||||
try
|
||||
if has('nvim')
|
||||
call jobstop(a:job_id)
|
||||
else
|
||||
call job_stop(a:job_id)
|
||||
endif
|
||||
catch /.*/
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Extract data from a job's stdout callback.
|
||||
"
|
||||
" Params:
|
||||
" cb_arglist : List
|
||||
" variable-size list of arguments as passed to the callback, which will
|
||||
" differ between Neovim and Vim
|
||||
"
|
||||
" Returns:
|
||||
" List
|
||||
" stdout data, as a list of strings
|
||||
"
|
||||
function! s:system.ExtractStdoutCallbackData(cb_arglist) abort
|
||||
let l:channel = a:cb_arglist[0]
|
||||
let l:data = a:cb_arglist[1]
|
||||
if has('nvim')
|
||||
let l:eof = (l:data == [''])
|
||||
" In Neovim, remove all the CR characters, which are returned when a
|
||||
" pseudo terminal is allocated for the job.
|
||||
call map(l:data, {_, val -> substitute(val, '\m\C\r', '', 'g')})
|
||||
" The first and the last lines may be partial lines, thus they need to
|
||||
" be joined on consecutive iterations. See :help channel-lines.
|
||||
" When this function is called for the first time for a particular
|
||||
" channel, allocate an empty partial line for that channel.
|
||||
if !has_key(s:stdout_partial_line, l:channel)
|
||||
let s:stdout_partial_line[l:channel] = ''
|
||||
endif
|
||||
" Append first entry of output list to partial line.
|
||||
let s:stdout_partial_line[l:channel] .= remove(l:data, 0)
|
||||
" If output list contains more entries, they are all complete lines
|
||||
" except for the last entry. Return the saved partial line (which is now
|
||||
" complete) and all the complete lines from the list, and save a new
|
||||
" partial line (the last entry of the list).
|
||||
if len(l:data) > 0
|
||||
call insert(l:data, s:stdout_partial_line[l:channel])
|
||||
let s:stdout_partial_line[l:channel] = remove(l:data, -1)
|
||||
endif
|
||||
" At the end of the stream of a channel, remove the dictionary entry for
|
||||
" that channel.
|
||||
if l:eof
|
||||
call remove(s:stdout_partial_line, l:channel)
|
||||
endif
|
||||
else
|
||||
" In Vim, l:data is a string, so we transform it to a list (consisting
|
||||
" of a single element).
|
||||
let l:data = [l:data]
|
||||
endif
|
||||
return l:data
|
||||
endfunction
|
||||
|
||||
" Extract data from a system's exit callback.
|
||||
"
|
||||
" Params:
|
||||
" cb_arglist : List
|
||||
" variable-size list of arguments as passed to the callback, which will
|
||||
" differ between Neovim and Vim
|
||||
"
|
||||
" Returns:
|
||||
" Number
|
||||
" exit code
|
||||
"
|
||||
function! s:system.ExtractExitCallbackData(cb_arglist) abort
|
||||
return a:cb_arglist[1]
|
||||
endfunction
|
||||
|
||||
" Get system 'object'.
|
||||
"
|
||||
function! cmake#system#Get() abort
|
||||
return s:system
|
||||
endfunction
|
472
sources_non_forked/vim-cmake/autoload/cmake/terminal.vim
Normal file
472
sources_non_forked/vim-cmake/autoload/cmake/terminal.vim
Normal file
@ -0,0 +1,472 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/terminal.vim
|
||||
" Description: Terminal abstraction layer
|
||||
" ==============================================================================
|
||||
|
||||
let s:terminal = {}
|
||||
let s:terminal.console_buffer = -1
|
||||
let s:terminal.console_cmd_info = {
|
||||
\ 'generate': 'Generating buildsystem...',
|
||||
\ 'build': 'Building...',
|
||||
\ 'install': 'Installing...',
|
||||
\ 'NONE': '',
|
||||
\ }
|
||||
let s:terminal.console_cmd = {
|
||||
\ 'id': -1,
|
||||
\ 'running': v:false,
|
||||
\ 'callbacks': [],
|
||||
\ 'callbacks_err': [],
|
||||
\ 'autocmds': [],
|
||||
\ 'autocmds_err': [],
|
||||
\ }
|
||||
let s:terminal.console_cmd_output = []
|
||||
|
||||
let s:term_tty = ''
|
||||
let s:term_id = -1
|
||||
let s:term_chan_id = -1
|
||||
let s:exit_term_mode = 0
|
||||
|
||||
let s:logger = cmake#logger#Get()
|
||||
let s:statusline = cmake#statusline#Get()
|
||||
let s:system = cmake#system#Get()
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" ANSI sequence filters
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
" https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
|
||||
|
||||
let s:ansi_esc = '\e'
|
||||
let s:ansi_csi = s:ansi_esc . '\['
|
||||
let s:ansi_st = '\(\%x07\|\\\)'
|
||||
|
||||
let s:pre_echo_filter = ''
|
||||
let s:post_echo_filter = ''
|
||||
let s:post_echo_rep_pat = ''
|
||||
let s:post_echo_rep_sub = ''
|
||||
|
||||
" In ConPTY (MS-Windows), remove ANSI sequences that mess up the terminal before
|
||||
" echoing data to the terminal:
|
||||
" - 'erase screen' sequences
|
||||
" - 'move cursor' sequences
|
||||
if has('win32')
|
||||
let s:pre_echo_filter = s:pre_echo_filter
|
||||
\ . '\(' . s:ansi_csi . '\d*J' . '\)'
|
||||
\ . '\|\(' . s:ansi_csi . '\(\d\+;\)*\d*H' . '\)'
|
||||
endif
|
||||
|
||||
" Remove ANSI sequences for coloring and style after echoing to the terminal.
|
||||
let s:post_echo_filter .= '\(' . s:ansi_csi . '\(\d\+;\)*\d*m' . '\)'
|
||||
|
||||
" Remove additional ANSI sequences returened by ConPTY (MS-Windows) after
|
||||
" echoing to the terminal:
|
||||
" - 'erase from cursor' sequences
|
||||
" - 'erase from cursor to EOL' sequences
|
||||
" - 'hide/show cursor' sequences
|
||||
" - 'console title' sequences
|
||||
if has('win32')
|
||||
let s:post_echo_filter = s:post_echo_filter
|
||||
\ . '\|\(' . s:ansi_csi . '\d*X' . '\)'
|
||||
\ . '\|\(' . s:ansi_csi . 'K' . '\)'
|
||||
\ . '\|\(' . s:ansi_csi . '?25[hl]' . '\)'
|
||||
\ . '\|\(' . s:ansi_esc . '\]' . '0;.*' . s:ansi_st . '\)'
|
||||
endif
|
||||
|
||||
" Replace 'move forward' sequences with spaces in ConPTY (MS-Windows) after
|
||||
" echoing to the terminal
|
||||
if has('win32')
|
||||
let s:post_echo_rep_pat .= s:ansi_csi . '\(\d*\)C'
|
||||
let s:post_echo_rep_sub .= '\=repeat('' '', submatch(1))'
|
||||
endif
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Private functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Callback for the stdout of the command running in the Vim-CMake console.
|
||||
"
|
||||
function! s:ConsoleCmdStdoutCb(...) abort
|
||||
let l:data = s:system.ExtractStdoutCallbackData(a:000)
|
||||
call s:FilterStdoutPreEcho(l:data)
|
||||
call s:TermEcho(l:data)
|
||||
call s:FilterStdoutPostEcho(l:data)
|
||||
" Save console output to list.
|
||||
let s:terminal.console_cmd_output += l:data
|
||||
endfunction
|
||||
|
||||
" Callback for the end of the command running in the Vim-CMake console.
|
||||
"
|
||||
function! s:ConsoleCmdExitCb(...) abort
|
||||
call s:logger.LogDebug('Invoked console exit callback')
|
||||
" Waiting for the job's channel to be closed ensures that all output has
|
||||
" been processed. This is useful in Vim, where buffered stdout may still
|
||||
" come in after entering this function.
|
||||
call s:system.ChannelWait(s:terminal.console_cmd.id)
|
||||
let l:error = s:system.ExtractExitCallbackData(a:000)
|
||||
call s:OnCompleteCommand(l:error, v:false)
|
||||
endfunction
|
||||
|
||||
" Enter terminal mode.
|
||||
"
|
||||
function! s:EnterTermMode() abort
|
||||
if mode() !=# 't'
|
||||
execute 'normal! i'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Exit terminal mode.
|
||||
"
|
||||
function! s:ExitTermMode() abort
|
||||
if mode() ==# 't'
|
||||
call feedkeys("\<C-\>\<C-N>", 'n')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Define actions to perform when completing/stopping a command.
|
||||
"
|
||||
function! s:OnCompleteCommand(error, stopped) abort
|
||||
if a:error == 0
|
||||
let l:callbacks = s:terminal.console_cmd.callbacks
|
||||
let l:autocmds = s:terminal.console_cmd.autocmds
|
||||
else
|
||||
let l:callbacks = s:terminal.console_cmd.callbacks_err
|
||||
let l:autocmds = s:terminal.console_cmd.autocmds_err
|
||||
endif
|
||||
" Reset state
|
||||
let s:terminal.console_cmd.id = -1
|
||||
let s:terminal.console_cmd.running = v:false
|
||||
let s:terminal.console_cmd.callbacks = []
|
||||
let s:terminal.console_cmd.callbacks_err = []
|
||||
let s:terminal.console_cmd.autocmds = []
|
||||
let s:terminal.console_cmd.autocmds_err = []
|
||||
" Append empty line to terminal.
|
||||
call s:TermEcho([''])
|
||||
" Exit terminal mode if inside the Vim-CMake console window (useful for
|
||||
" Vim). Otherwise the terminal mode is exited after WinEnter event.
|
||||
if win_getid() == bufwinid(s:terminal.console_buffer)
|
||||
call s:ExitTermMode()
|
||||
else
|
||||
let s:exit_term_mode = 1
|
||||
endif
|
||||
" Update statusline.
|
||||
call s:statusline.SetCmdInfo(s:terminal.console_cmd_info['NONE'])
|
||||
call s:statusline.Refresh()
|
||||
" The rest of the tasks are not to be carried out if the running command was
|
||||
" stopped by the user.
|
||||
if a:stopped
|
||||
return
|
||||
endif
|
||||
" Focus Vim-CMake console window, if requested.
|
||||
if g:cmake_jump_on_completion
|
||||
call s:terminal.Focus()
|
||||
else
|
||||
if a:error != 0 && g:cmake_jump_on_error
|
||||
call s:terminal.Focus()
|
||||
endif
|
||||
endif
|
||||
" Handle callbacks and autocmds.
|
||||
" Note: Funcref variable names must start with a capital.
|
||||
for l:Callback in l:callbacks
|
||||
call s:logger.LogDebug('Callback invoked: %s()', l:Callback)
|
||||
call l:Callback()
|
||||
endfor
|
||||
for l:autocmd in l:autocmds
|
||||
call s:logger.LogDebug('Executing autocmd %s', l:autocmd)
|
||||
execute 'doautocmd <nomodeline> User ' . l:autocmd
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Define actions to perform when entering the Vim-CMake console window.
|
||||
"
|
||||
function! s:OnEnterConsoleWindow() abort
|
||||
if winnr() == bufwinnr(s:terminal.console_buffer) && s:exit_term_mode
|
||||
let s:exit_term_mode = 0
|
||||
call s:ExitTermMode()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Start arbitrary command with output to be displayed in Vim-CMake console.
|
||||
"
|
||||
" Params:
|
||||
" command : List
|
||||
" the command to be run, as a list of command and arguments
|
||||
"
|
||||
" Return:
|
||||
" Number
|
||||
" job id
|
||||
"
|
||||
function! s:ConsoleCmdStart(command) abort
|
||||
let l:console_win_id = bufwinid(s:terminal.console_buffer)
|
||||
" For Vim, must go back into Terminal-Job mode for the command's output to
|
||||
" be appended to the buffer.
|
||||
if !has('nvim')
|
||||
call win_execute(l:console_win_id, 'call s:EnterTermMode()', '')
|
||||
endif
|
||||
" Run command.
|
||||
let l:job_id = s:system.JobRun(
|
||||
\ a:command, v:false, function('s:ConsoleCmdStdoutCb'),
|
||||
\ function('s:ConsoleCmdExitCb'), v:true)
|
||||
" For Neovim, scroll manually to the end of the terminal buffer while the
|
||||
" command's output is being appended.
|
||||
if has('nvim')
|
||||
let l:buffer_length = nvim_buf_line_count(s:terminal.console_buffer)
|
||||
call nvim_win_set_cursor(l:console_win_id, [l:buffer_length, 0])
|
||||
endif
|
||||
return l:job_id
|
||||
endfunction
|
||||
|
||||
" Create Vim-CMake window.
|
||||
"
|
||||
" Returns:
|
||||
" Number
|
||||
" number of the created window
|
||||
"
|
||||
function! s:CreateConsoleWindow() abort
|
||||
execute join([g:cmake_console_position, g:cmake_console_size . 'split'])
|
||||
setlocal winfixheight
|
||||
setlocal winfixwidth
|
||||
call s:logger.LogDebug('Created console window')
|
||||
endfunction
|
||||
|
||||
" Create Vim-CMake buffer and apply local settings.
|
||||
"
|
||||
" Returns:
|
||||
" Number
|
||||
" number of the created buffer
|
||||
"
|
||||
function! s:CreateConsoleBuffer() abort
|
||||
execute 'enew'
|
||||
call s:TermSetup()
|
||||
nnoremap <buffer> <silent> cg :CMakeGenerate<CR>
|
||||
nnoremap <buffer> <silent> cb :CMakeBuild<CR>
|
||||
nnoremap <buffer> <silent> ci :CMakeInstall<CR>
|
||||
nnoremap <buffer> <silent> cq :CMakeClose<CR>
|
||||
nnoremap <buffer> <silent> <C-C> :CMakeStop<CR>
|
||||
setlocal nonumber
|
||||
setlocal norelativenumber
|
||||
setlocal signcolumn=auto
|
||||
setlocal nobuflisted
|
||||
setlocal filetype=vimcmake
|
||||
setlocal statusline=[CMake]
|
||||
setlocal statusline+=\ %{cmake#statusline#GetBuildInfo(0)}
|
||||
setlocal statusline+=\ %{cmake#statusline#GetCmdInfo()}
|
||||
" Avoid error E37 on :CMakeClose in some Vim instances.
|
||||
setlocal bufhidden=hide
|
||||
augroup cmake
|
||||
autocmd WinEnter <buffer> call s:OnEnterConsoleWindow()
|
||||
augroup END
|
||||
return bufnr()
|
||||
call s:logger.LogDebug('Created console buffer')
|
||||
endfunction
|
||||
|
||||
" Setup Vim-CMake console terminal.
|
||||
"
|
||||
function! s:TermSetup() abort
|
||||
" Open job-less terminal to echo command outputs to.
|
||||
let l:options = {}
|
||||
if has('nvim')
|
||||
let s:term_chan_id = nvim_open_term(bufnr(''), l:options)
|
||||
else
|
||||
let l:options['curwin'] = 1
|
||||
let l:term = term_start('NONE', l:options)
|
||||
let s:term_id = term_getjob(l:term)
|
||||
let s:term_tty = job_info(s:term_id)['tty_in']
|
||||
call term_setkill(l:term, 'term')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Echo strings to terminal.
|
||||
"
|
||||
" Params:
|
||||
" data : List
|
||||
" list of strings to echo
|
||||
"
|
||||
function! s:TermEcho(data) abort
|
||||
if len(a:data) == 0
|
||||
return
|
||||
endif
|
||||
if has('nvim')
|
||||
call chansend(s:term_chan_id, join(a:data, "\r\n") . "\r\n")
|
||||
else
|
||||
call writefile(a:data, s:term_tty)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Filter stdout data to remove ANSI sequences that should not be sent to the
|
||||
" console terminal.
|
||||
"
|
||||
" Params:
|
||||
" data : List
|
||||
" list of stdout strings to filter (filtering is done in-place)
|
||||
"
|
||||
function! s:FilterStdoutPreEcho(data) abort
|
||||
if s:pre_echo_filter !=# ''
|
||||
call map(a:data, {_, val -> substitute(
|
||||
\ val, s:pre_echo_filter, '', 'g')})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Filter stdout data to remove remaining ANSI sequences after sending the data
|
||||
" to the console terminal.
|
||||
"
|
||||
" Params:
|
||||
" data : List
|
||||
" list of stdout strings to filter (filtering is done in-place)
|
||||
"
|
||||
function! s:FilterStdoutPostEcho(data) abort
|
||||
if s:post_echo_filter !=# ''
|
||||
call map(a:data, {_, val -> substitute(
|
||||
\ val, s:post_echo_filter, '', 'g')})
|
||||
endif
|
||||
if s:post_echo_rep_pat !=# ''
|
||||
call map(a:data, {_, val -> substitute(
|
||||
\ val, s:post_echo_rep_pat, s:post_echo_rep_sub, 'g')})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Open Vim-CMake console window.
|
||||
"
|
||||
" Params:
|
||||
" clear : Boolean
|
||||
" if set, a new buffer is created and the old one is deleted
|
||||
"
|
||||
function! s:terminal.Open(clear) abort
|
||||
call s:logger.LogDebug('Invoked: terminal.Open(%s)', a:clear)
|
||||
let l:original_win_id = win_getid()
|
||||
let l:cmake_win_id = bufwinid(l:self.console_buffer)
|
||||
if l:cmake_win_id == -1
|
||||
" If a Vim-CMake window does not exist, create it.
|
||||
call s:CreateConsoleWindow()
|
||||
if bufexists(l:self.console_buffer)
|
||||
" If a Vim-CMake buffer exists, open it in the Vim-CMake window, or
|
||||
" delete it if a:clear is set.
|
||||
if !a:clear
|
||||
execute 'b ' . l:self.console_buffer
|
||||
call win_gotoid(l:original_win_id)
|
||||
return
|
||||
else
|
||||
execute 'bd! ' . l:self.console_buffer
|
||||
endif
|
||||
endif
|
||||
" Create Vim-CMake buffer if none exist, or if the old one was deleted.
|
||||
let l:self.console_buffer = s:CreateConsoleBuffer()
|
||||
else
|
||||
" If a Vim-CMake window exists, and a:clear is set, create a new
|
||||
" Vim-CMake buffer and delete the old one.
|
||||
if a:clear
|
||||
let l:old_buffer = l:self.console_buffer
|
||||
call l:self.Focus()
|
||||
let l:self.console_buffer = s:CreateConsoleBuffer()
|
||||
if bufexists(l:old_buffer) && l:old_buffer != l:self.console_buffer
|
||||
execute 'bd! ' . l:old_buffer
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if l:original_win_id != win_getid()
|
||||
call win_gotoid(l:original_win_id)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Focus Vim-CMake console window.
|
||||
"
|
||||
function! s:terminal.Focus() abort
|
||||
call s:logger.LogDebug('Invoked: terminal.Focus()')
|
||||
call win_gotoid(bufwinid(l:self.console_buffer))
|
||||
endfunction
|
||||
|
||||
" Close Vim-CMake console window.
|
||||
"
|
||||
function! s:terminal.Close() abort
|
||||
call s:logger.LogDebug('Invoked: terminal.Close()')
|
||||
if bufexists(l:self.console_buffer)
|
||||
let l:cmake_win_id = bufwinid(l:self.console_buffer)
|
||||
if l:cmake_win_id != -1
|
||||
execute win_id2win(l:cmake_win_id) . 'wincmd q'
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Run arbitrary command in the Vim-CMake console.
|
||||
"
|
||||
" Params:
|
||||
" command : List
|
||||
" the command to be run, as a list of command and arguments
|
||||
" tag : String
|
||||
" command tag, must be an item of keys(l:self.console_cmd_info)
|
||||
" cbs : List
|
||||
" list of callbacks (Funcref) to be invoked upon successful completion
|
||||
" of the command
|
||||
" cbs_err : List
|
||||
" list of callbacks (Funcref) to be invoked upon unsuccessful completion
|
||||
" of the command
|
||||
" aus : List
|
||||
" list of autocmds (String) to be invoked upon successful completion of
|
||||
" the command
|
||||
" aus_err : List
|
||||
" list of autocmds (String) to be invoked upon unsuccessful completion
|
||||
" of the command
|
||||
"
|
||||
function! s:terminal.Run(command, tag, cbs, cbs_err, aus, aus_err) abort
|
||||
call s:logger.LogDebug('Invoked: terminal.Run(%s, %s, %s, %s, %s, %s)',
|
||||
\ a:command, string(a:tag), a:cbs, a:cbs_err, a:aus, a:aus_err)
|
||||
call assert_notequal(index(keys(l:self.console_cmd_info), a:tag), -1)
|
||||
" Prevent executing this function when a command is already running
|
||||
if l:self.console_cmd.running
|
||||
call s:logger.EchoError('Another CMake command is already running')
|
||||
call s:logger.LogError('Another CMake command is already running')
|
||||
return
|
||||
endif
|
||||
let l:self.console_cmd.running = v:true
|
||||
let l:self.console_cmd.callbacks = a:cbs
|
||||
let l:self.console_cmd.callbacks_err = a:cbs_err
|
||||
let l:self.console_cmd.autocmds = a:aus
|
||||
let l:self.console_cmd.autocmds_err = a:aus_err
|
||||
let l:self.console_cmd_output = []
|
||||
" Open Vim-CMake console window.
|
||||
call l:self.Open(v:false)
|
||||
" Echo start message to terminal.
|
||||
if g:cmake_console_echo_cmd
|
||||
call s:TermEcho([printf(
|
||||
\ '%sRunning command: %s%s',
|
||||
\ "\e[1;35m",
|
||||
\ join(a:command),
|
||||
\ "\e[0m")
|
||||
\ ])
|
||||
endif
|
||||
" Run command.
|
||||
call s:statusline.SetCmdInfo(l:self.console_cmd_info[a:tag])
|
||||
let l:self.console_cmd.id = s:ConsoleCmdStart(a:command)
|
||||
" Jump to Vim-CMake console window if requested.
|
||||
if g:cmake_jump
|
||||
call l:self.Focus()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Stop command currently running in the Vim-CMake console.
|
||||
"
|
||||
function! s:terminal.Stop() abort
|
||||
call s:logger.LogDebug('Invoked: terminal.Stop()')
|
||||
call s:system.JobStop(l:self.console_cmd.id)
|
||||
call s:OnCompleteCommand(0, v:true)
|
||||
endfunction
|
||||
|
||||
" Get output from the last command run.
|
||||
"
|
||||
" Returns
|
||||
" List:
|
||||
" output from the last command, as a list of strings
|
||||
"
|
||||
function! s:terminal.GetOutput() abort
|
||||
return l:self.console_cmd_output
|
||||
endfunction
|
||||
|
||||
" Get terminal 'object'.
|
||||
"
|
||||
function! cmake#terminal#Get() abort
|
||||
return s:terminal
|
||||
endfunction
|
81
sources_non_forked/vim-cmake/autoload/cmake/util.vim
Normal file
81
sources_non_forked/vim-cmake/autoload/cmake/util.vim
Normal file
@ -0,0 +1,81 @@
|
||||
" ==============================================================================
|
||||
" Location: autoload/cmake/util.vim
|
||||
" Description: Utility functions
|
||||
" ==============================================================================
|
||||
|
||||
let s:logger = cmake#logger#Get()
|
||||
let s:system = cmake#system#Get()
|
||||
|
||||
let s:repo_dir = expand('<sfile>:p:h:h:h')
|
||||
let s:data_dir = s:system.Path([s:repo_dir, '.data'], v:false)
|
||||
let s:data_file = s:system.Path([s:data_dir, 'previous-version.bin'], v:false)
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Private functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
function! s:VersionToNumber(_, version) abort
|
||||
let l:version = split(a:version, '\.')
|
||||
let l:major = str2nr(l:version[0])
|
||||
let l:minor = str2nr(l:version[1])
|
||||
let l:patch = str2nr(l:version[2])
|
||||
let l:number = l:major * 10000 + l:minor * 100 + l:patch
|
||||
return l:number
|
||||
endfunction
|
||||
|
||||
function! s:NumberToVersion(number) abort
|
||||
let l:major = a:number / 10000
|
||||
let l:minor = (a:number - l:major * 10000) / 100
|
||||
let l:patch = a:number - l:major * 10000 - l:minor * 100
|
||||
let l:version = l:major . '.' . l:minor . '.' . l:patch
|
||||
return l:version
|
||||
endfunction
|
||||
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Public functions
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
" Print news of newer Vim-CMake versions.
|
||||
"
|
||||
" Params:
|
||||
" current_version : String
|
||||
" current version of the plugin (in the format <major>.<minor>.<patch>)
|
||||
" news : Dictionary
|
||||
" dictionary of news, where a key identifies a version (in the format
|
||||
" <major>.<minor>.<patch>), and a value is a string containing the news
|
||||
" to print for a version
|
||||
"
|
||||
function! cmake#util#PrintNews(current_version, news) abort
|
||||
" Make a list of all version numbers, transform to integers, and sort.
|
||||
let l:all_version_numbers = keys(a:news)
|
||||
call map(l:all_version_numbers, function('s:VersionToNumber'))
|
||||
call sort(l:all_version_numbers)
|
||||
try
|
||||
" Try to read previous version number from file.
|
||||
let l:line = readfile(s:data_file, 'b')
|
||||
catch /.*/
|
||||
" Store current version number.
|
||||
try
|
||||
call mkdir(s:data_dir, 'p')
|
||||
call writefile([a:current_version], s:data_file, 'b')
|
||||
catch /.*/
|
||||
endtry
|
||||
return
|
||||
endtry
|
||||
" Get previous version number from file, then write current version number.
|
||||
let l:previous_version_number = s:VersionToNumber('', l:line[0])
|
||||
if l:previous_version_number < s:VersionToNumber('', a:current_version)
|
||||
try
|
||||
call writefile([a:current_version], s:data_file, 'b')
|
||||
catch /.*/
|
||||
endtry
|
||||
endif
|
||||
" Print updates for newer versions.
|
||||
for l:number in l:all_version_numbers
|
||||
if l:number > l:previous_version_number
|
||||
for l:news_item in a:news[s:NumberToVersion(l:number)]
|
||||
call s:logger.EchoInfo(l:news_item)
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
Reference in New Issue
Block a user