/
1KoT1
/
cpp_tools
Обзор
Документация
Войти
/
1KoT1
/
cpp_tools
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
autoload/cpp_tools.vim
226 строк
7 KB
Vasilii Pochkaenko
fix(create_class): code duplication at the CallConfigured function
23 июн 2026, 00:28
23 июн 2026, 00:28
812ca7c
Код
Авторство
О чём код?
function! s:ParseCreateLine(line) abort let l:line = trim(a:line) let l:rest = matchstr(l:line, '^create class\s\+\zs.*') if empty(l:rest) throw 'cpp_tools: expected "create class [ns::...] ClassName" on current line' endif let l:space_idx = strridx(l:rest, ' ') if l:space_idx < 0 let l:class_name = l:rest let l:namespaces = [] else let l:ns_str = strpart(l:rest, 0, l:space_idx) let l:class_name = strpart(l:rest, l:space_idx + 1) let l:namespaces = [] for l:piece in split(l:ns_str, '::') if !empty(l:piece) call add(l:namespaces, l:piece) endif endfor endif if empty(l:class_name) throw 'cpp_tools: expected class name' endif return [l:namespaces, l:class_name] endfunction function! cpp_tools#CallConfigured(func_ref, args) abort if type(a:func_ref) == v:t_func return call(a:func_ref, a:args) endif if !exists('*' . a:func_ref) throw 'cpp_tools: function not found: ' . a:func_ref endif return call(function(a:func_ref), a:args) endfunction function! s:EnsureHeaderOpen(header_path) abort if bufnr(fnamemodify(a:header_path, ':p')) < 0 execute 'edit' fnameescape(a:header_path) endif endfunction " cpp_tools#HeaderPath(root, namespaces, class_name) {{{1 " " A default builder for the header path. " Return the header path. " " root Project root directory. " namespaces List of namespace components (may be empty). " class_name Unqualified class name. " " Path: {root}/include[/ns/...]/{class_name}.h " " }}} function! cpp_tools#HeaderPath(root, namespaces, class_name) abort let l:path = a:root . '/include' if !empty(a:namespaces) let l:path .= '/' . join(a:namespaces, '/') endif return l:path . '/' . a:class_name . '.h' endfunction " cpp_tools#SourcePath(root, namespaces, class_name) {{{1 " " A default builder for the source path. " Return the source path. " " root Project root directory. " namespaces List of namespace components (may be empty). " class_name Unqualified class name. " " Path: {root}/src[/ns/...]/{class_name}.cpp " " }}} function! cpp_tools#SourcePath(root, namespaces, class_name) abort let l:path = a:root . '/src' if !empty(a:namespaces) let l:path .= '/' . join(a:namespaces, '/') endif return l:path . '/' . a:class_name . '.cpp' endfunction " cpp_tools#FillSource(path, namespaces, class_name) {{{1 " " Write a minimal .cpp skeleton to {path}. " " path Destination file path. " namespaces List of namespace components (may be empty). " class_name Unqualified class name. " " The file contains a #include of the matching header and empty " nested namespace blocks. " " }}} function! cpp_tools#FillSource(path, namespaces, class_name) abort let l:header_rel = empty(a:namespaces) \ ? a:class_name . '.h' \ : join(a:namespaces, '/') . '/' . a:class_name . '.h' let l:lines = [ \ '#include "' . l:header_rel . '"', \ '', \ ] for l:ns in a:namespaces call add(l:lines, 'namespace ' . l:ns . ' {') endfor call add(l:lines, '') call add(l:lines, '') for l:ns in reverse(copy(a:namespaces)) call add(l:lines, '} // namespace ' . l:ns) endfor call writefile(l:lines, a:path) endfunction " cpp_tools#FillHeader(path, namespaces, class_name) {{{1 " " Create the header file and start class snippet insertion. " " path Destination file path. " namespaces List of namespace components (may be empty). " class_name Unqualified class name (unused by default impl). " " Opens {path} and triggers the "cla" snippet via |feedkeys()|. " It depends the UltiSnippet plugin. " " }}} function! cpp_tools#FillHeader(path, namespaces, class_name) abort execute 'edit' fnameescape(a:path) call feedkeys('icla' . "\<C-u>", 't') endfunction " cpp_tools#CreateClass() {{{1 " :CppToolsCreateClass " " Create header and source files for a C++ class. " " Input parameters: " The cursor must be on a line of the form: " > " create class [Namespaces] ClassName " < " create class Literal prefix (required). " Namespaces Nested C++ namespaces as ns1::ns2::... (optional; " any depth). Omit when the class is not in a namespace. " ClassName Class name (required; one identifier). " " Examples: " create class Widget " create class foo::bar Widget " " On success the line is removed from the buffer (saved when the buffer " has a file name and is |modifiable|). " " Behavior is configurable via these settings (each may be a |Funcref| " or an autoload function name): " |g:cpp_tools_create_class_header_path| — a name of a function which build a path to .h file " |g:cpp_tools_create_class_source_path| — a name of a function which build a path to .cpp file " |g:cpp_tools_create_class_fill_header| — a name of a function which initial a .h file content " |g:cpp_tools_create_class_fill_source| — a name of a function which initial a .cpp file content " |g:cpp_tools_project_root| — a name of a function which return a project root directory " |g:cpp_tools_create_class_update_cmake| — when non-zero, add .cpp to a cmake target " |g:cpp_tools_cmake_build_dir| — a name of a function which return cmake build directory " Aborts with an error if either target file already exists. " " }}} function! cpp_tools#CreateClass() abort try let [l:namespaces, l:class_name] = s:ParseCreateLine(getline('.')) call deletebufline(bufnr('%'), line('.'), line('.')) if bufname('%') !=# '' && &modifiable silent update endif let l:root = cpp_tools#CallConfigured(g:cpp_tools_project_root, []) let l:header_path = cpp_tools#CallConfigured( \ g:cpp_tools_create_class_header_path, \ [l:root, l:namespaces, l:class_name]) let l:source_path = cpp_tools#CallConfigured( \ g:cpp_tools_create_class_source_path, \ [l:root, l:namespaces, l:class_name]) let l:existing = [] if filereadable(l:header_path) call add(l:existing, l:header_path) endif if filereadable(l:source_path) call add(l:existing, l:source_path) endif if !empty(l:existing) throw 'cpp_tools: target file already exists: ' . join(l:existing, ', ') endif call mkdir(fnamemodify(l:header_path, ':h'), 'p') call mkdir(fnamemodify(l:source_path, ':h'), 'p') call cpp_tools#CallConfigured( \ g:cpp_tools_create_class_fill_source, \ [l:source_path, l:namespaces, l:class_name]) echom 'Created ' . l:source_path call cpp_tools#CallConfigured( \ g:cpp_tools_create_class_fill_header, \ [l:header_path, l:namespaces, l:class_name]) echom 'Created ' . l:header_path call s:EnsureHeaderOpen(l:header_path) if g:cpp_tools_create_class_update_cmake \ && cpp_tools#cmake#ProjectUsesCmake(l:root) call cpp_tools#cmake#AddCppToProject(l:root, l:source_path) endif catch echohl ErrorMsg echom v:exception echohl None endtry endfunction