Перейти к содержимому

Vim как ide c

  • автор:

Blogs » Use Vim as a C/C++ IDE

This is a general guide for using SpaceVim as a C/C++ IDE, including layer configuration and usage. Each of the following sections will be covered:

  • Enable language layer
  • Syntax highlighting
  • code completion
  • alternate file jumping
  • code running
  • Syntax lint
  • code format
  • REPL support

Enable language layer

To add C/C++ language support in SpaceVim, you need to enable the lang#c layer. Press SPC f v d to open SpaceVim configuration file, and add following configuration:

[[layers]] name = "lang#c" 

for more info, you can read the lang#c layer documentation.

Syntax highlighting

The basic syntax highlighting is based on regular expression, If you want clang based syntax highlighting. Enable enable_clang_syntax_highlight layer option:

[[layers]] name = 'lang#c' enable_clang_syntax_highlight = true 

This option requires +python or +python3 enabled and libclang has been installed.

code completion

By default the autocomplete layer has been enabled, so after loading lang#c layer, the code completion for C/C++ language should works well.

If the autocomplete_method is deoplete , then Shougo/deoplete-clangx will be loaded in lang#c layer.

If the autocomplete_method is asyncomplete , then wsdjeg/asyncomplete-clang.vim will be loaded.

If the autocomplete_method is neocomplete , Then Rip-Rip/clang_complete will be loaded.

You can check the value of autocomplete_method via :SPSet autocomplete_method .

alternate file jumping

To manage alternate files for a project, you may need to create a .project_alt.json file in the root of your project.

For example, add the following content into the .project_alt.json file:

 "*.c": "alternate": "<>.h">, "*.h": "alternate": "<>.c"> > 

With this configuration, you can jump between alternate files via command :A

code running

The default code running key binding is SPC l r . It will compile and run current file asynchronously. And the stdout will be shown on a runner buffer.

c-cpp-runner

The default runner compile option is defineded in clang_std and clang_flag option. If you want to use c11 , you can change clang_std option to:

[[layers]] name = "lang#c" [layers.clang_std] cpp = "c11" 

You can also create a .clang file in the root directory of you project. Within this file, all compile option should be defineded in it. for example:

-I/home/test -I/user/std/include 

Syntax lint

The checker layer provides syntax checking for many programming languages. Including C/C++, and the default plugin is neomake. The default lint for C/C++ is gcc / g++ . These commands also read configuration in .clang file.

code format

In order to be able to format C/C++ files, you need to install uncrustify , clangformat or astyle . The key binding SPC b f is defineded in format layer which is loaded by default. In this layer, the default format engine is neoformat .

REPL support

Start a igcc inferior REPL process with SPC l s i . After the REPL process being started, you can send code to inferior process, all key bindings prefix with SPC l s , including sending line, sending selection or even send whole buffer.

Vim как ide c

— insertion of various types of comments (file prologue, function descriptions, file section headers
keyword comments, date, time, . )
— insertion of empty control statements (if-else, while, do-while, switch, . )
— insertion of various preprocessor directives
— insertion of C-idioms (enum+typedef, loops, complete main, empty function, file open dialogs, . )
— insertion of C++ -idioms ( frames for simple classes and template classes, try-catch blocks,
file open dialogs, output manipulators, ios flags, . )
— use and organize your own collection of code snippets
— compile / link / run support for one-file projects (without a makefile)
— run buffer through splint
— personalization of comments (name, email, . )
— menus can be switched on and off (via the Tools menu)

DOCUMENTATION
———————————————————
This plug-in comes with a help file (csupport.txt). Read it with

** PLEASE READ THE DOCUMENTATION **

Editing actions differ for different modes! There are a lot of features which
can be configured or customized to match your needs.

(Please help us keep track of all the issues and name your report/request «C-Support: «)

To enable the tools for cmake or doxygen, add these lines to ~/.vimrc :

let g:C_UseTool_cmake = ‘yes’
let g:C_UseTool_doxygen = ‘yes’

For how to enable the Doxygen templates, see Chapter 1.10.1 of the documentation:

script versions (upload new version)

Click on the package to download.

package script version date Vim version user release notes
c-support.zip 6.2 2016-08-27 7.3 Fritz Mehner — Add ‘g:C_CustomTemplateFile’.
— Add template personalization file and setup wizard.
— Respect ‘g:Xterm_Executable’ and ‘g:Xterm_Options’.
(‘g:C_XtermDefaults’ still works for backwards compatibility.)
— Remove unused ‘g:C_GuiTemplateBrowser’.
— Change ‘Run -> link’ and ‘Run -> run’, do not produce object file anymore.
— Add submenu ‘Comments -> all sections’.
— Add submenu ‘Preprocessor -> include POSIX header’.
— New and reworked templates.
— Minor changes and bugfixes.
cvim.zip 6.1.1 2014-04-21 7.0 Fritz Mehner — Added ‘C_SetMapLeader’ and ‘C_ResetMapLeader’.
— Bugfix: Resetting maplocalleader in filetype plug-in after setting it to the
value of g:C_MapLeader.
— Bugfix: Setup of local templates in case of global installation.
— Bugfix: Better compatibility with custom mappings
(use «normal!» and «noremap» consistently).
— ‘Help->show manual’ shows man page text with appropriate width (UNIX only).
— Extended the documentation.
cvim.zip 6.1 2013-12-28 7.0 Fritz Mehner — Map renamed: \rme -> \re.
— New global variable g:C_InsertFileHeader (suppress file description comment for new files).
— Two new ex commands: CCmdlineArgs, CMakeCmdlineArgs.
— ‘Run->cmd. line arg.’ : tab expansion (files/directories)for all arguments.
— Bugfix: template ‘file description header’ not loading (thanks to Marco Lasczok).
— Bugfix: unnecessary characters in one template.
— Prototype picker improved.
— Toggle non-C-comments.
— Run debugger.
— Some global variables now changeable on the fly.
— Menus now show the correct mapleader.
— Bugfix: g:C_LoadMenus now works.
— Bugfix: Prevent unnecessary rereading of the template library.
— Added Doxygen templates and ‘Doxygen->brief, after member’.
— Added help menu entries: help English, help Doxygen
— Improved «adjust end-of-line comment».
— Bugfix: Setup of local templates in case of global installation.
— Bugfix: Map and menu entry ‘Snippets->edit global templates’.
— Several internal improvements.
cvim.zip 6.0 2012-08-20 7.0 Fritz Mehner ++ The plug-in version 6.0+ is a rewriting of version 5.19.
++ The template syntax has changed!

— New template system (many thanks to Wolfgang Mehner)
— A few new hotkeys and menu item.
— A few hotkeys and menu items renamed.

If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to the maillist. Help Bram help Uganda.
Vim at Github

Make Vim as your C/C++ IDE

Cover

This procedure can be very similar for VSCode and Fleet editors. In this case, you should only create the compile_commands.json file, and this procedure is illustrated in the bear subsection, but I suggest you read the whole post.

It happened to me in the past that I had to configure Vim to manage C projects with some external library, and after lots of useless attempts, I gave up setting it up. I am currently attending a university course called Advanced in Operating Systems. I am using a STM32 microcontroller and ST provides an “Eclipse 2010 based” IDE with lots of proprietary libraries, but as a Vim programmer writing even 10 lines of code on this IDE made me frustrated. So, I decided to try again, and as you can imagine if you are reading this blog post, I succeeded!

Requirements

  1. Make sure use Vim >= 8.1.1719 or Neovim >= 0.4.0 and make
  2. Install nodejs >= 14.14:

curl -sL install-node.vercel.app/lts | bash

Configuration

coc

Firstly, you should have a coc.nvim plug-in installed. I am currently using vim-plug as plug-in manager, but you can use any other.

In my case, I added it to my .vimrc file

Plug 'https://github.com/neoclide/coc.nvim' 

and run :PlugInstall

After that restart Vimand make sure you have installed two important extensions, which are coc-json and coc-tsserver using :CocList extensions , if not run :CocInstall coc-json coc-tsserver

coc-clangd

As you can imagine, coc-clangd is an extension of coc.nvim like the previous two, and you can install it just by running :CocInstall coc-clangd , after that coc-clangd will try to find clangd from your $PATH , if not found, you can run :CocCommand clangd.install to install the latest release from GitHub.

At this point, you should be able to create ~/.vim/coc-settings.json file and add the code below to it

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
< "languageserver": < "ccls": < "command": "ccls", "args": ["--log-file=/tmp/ccls.log", "-v=1"], "filetypes": ["c", "cc", "cpp", "c++", "objc", "objcpp"], "rootPatterns": [".ccls", "compile_commands.json"], "initializationOptions": < "cache": < "directory": "/tmp/ccls" >, "client": < "snippetSupport": true > > > >, "clangd.path": "~/.config/coc/extensions/coc-clangd-data/install/15.0.6/clangd_15.0.6/bin/clangd", > 

Obviusly, you should change the value of the “clangd.path” field with your version, it may be something like «clangd.path»: «~/.config/coc/extensions/coc-clangd-data/install//clangd_/bin/clangd» (note on the string).

I do not want to bore you by explaining whole fields of the json file, the only thing I would like to say to you is that this code is used to specify the type of language server ( ccls in this case) and its behavior.

ccls

Basically, ccls , which originates from cquery , is a C/C++/Objective-C language server.

  • code completition (with both signature help and snippets)
  • definition/reference, and other cross references
  • diagnostics and code actions
  • semantic highlighting and preprocessor skipped regions
  • diagnostics and code actions
  • semantic highlighting and preprocessor skipped regions

and the other many usefull things.

You must install it because, as you can see in the coc-settings.json , the language server specified is ccls .

You can do it using your package manager, in my case

sudo apt-get install ccls 

Setup

Typically, ccls indexes an entire project. In order for this to work properly, ccls needs to be able to obtain the source file list and their compilation command lines.

How ccls obtains sources and compilation commands

There are two main ways this happens:

  1. Provide compile_commands.json at the project root
  2. Provide a .ccls file.

If neither exists, then when ccls starts it will not index anything: instead it will wait for LSP clients to open files and index only those files.

I prefer use the first one, and to do that if you are using Makefile as build system for your C/C++ project you can generate compile_commands.json automatically with bear command, I will explain in detail how in the next paragraph.

If you are not using Makefile as build system, there are lots of ways to generate this file, for example with CMake , compiledb , scan-build and so on. I suggest you to take a look here.

bear

Bear is a tool that generates a compilation database for clang tooling. The compilation database is our compile_commands.json , a simple json file.

The JSON compilation database is used in the clang project to provide information on how a single compilation unit is processed. With this, it is easy to re-run the compilation with alternate programs.

Some build system natively supports the generation of JSON compilation database. For projects which does not use such build tool, Bear generates the JSON file during the build process.

You can install it using your package manager, in my case

sudo apt-get install bear 

Use case

Consider this simple C project, but it can be extended to much larger projects.

I assure you that it works exactly as in the case I am going to illustrate now, the only important thing is to write your makefile correctly, but this is also obvious because otherwise your project would not compile. 😀

1 2 3 4 5 6 
. ├── inc/ │ └── main.h ├── src/ │ └── main.c └── Makefile 
1 2 3 
// main.h #define TEST "test" 
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 
// main.c #include "main.h" #include int main() < int *ptrarray[4]; int w = 100, x = 200, y = 300, z = 400; ptrarray[0] = &w; ptrarray[1] = &x; ptrarray[2] = &y; ptrarray[3] = &z; for (int i = 0; i< 4; i++) < printf("The value %d has the adddress %d\n", *ptrarray[i], ptrarray[i]); > printf("I am printing a variable of main.h file %d", &TEST); return 0; > 

It is a silly file that prints the values and memory area of the elements of an array.

 1 2 3 4 5 6 7 8 9 10 11 
CC = gcc CFLAGS = -Wall INC_DIR = inc SRC_DIR = src SRC_FILES = $(wildcard $(SRC_DIR)/*.c) INC_FILES = $(wildcard $(INC_DIR)/*.h) main: $(SRC_FILES) $(INC_FILES) $(CC) $(CFLAGS) $(SRC_FILES) -o main -I$(INC_DIR) 

But, the main problem is that Vim, specially ccls and coc tells me that I have an error in line 1 of the main.c , and as you can imagine, the error is main.h file not found , and this problem is difficult to manage manually, and it becomes even more difficult to manage if the project uses external libraries.

This problem is also blocking all the LSP features, for example go-to-definition, go-to-implementation etc…

To solve it, we just have to run the

bear -- make 

command, and it will generate the compile_commands.json and there will be no more errors.

1 2 3 4 5 6 7 8 
. ├── inc/ │ └── main.h ├── src/ │ └── main.c ├── compile_commands.json ├── main* └── Makefile 

and compile_commands.json will be something like this

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
[ < "arguments": [ "/usr/bin/gcc", "-c", "-Wall", "-Iinc", "-o", "main", "src/main.c" ], "directory": "/home/c_project", "file": "/home/c_project/src/main.c", "output": "/home/c_project/main" > ] 

For bigger projects, so for example the one I am currently working on for the Advanced in OS course that uses a lot of external libraries, this file can reach even 600 lines.

Author Federico Bruzzone

Использование Vim в качестве C/C++ IDE

Привет, Хабрахабр. Меня зовут Алексей и я занимаюсь тем, что разрабатываю встраиваемые операционные системы.

Сегодня я хочу рассказать, как я использую Vim в качестве IDE для C/C++ проектов.

Несмотря на то, что я использую Vim для C/C++, многие из рекоммендаций довольно общие и могут использоваться в любом проекте.

Первый шаг

Для начала, мы хотим иметь место, где можно будет сохранять настройки для своего проекта. Глобальный .vimrc нам не подходит, так как проектов много и они разные, а значит, каждый из них имеет свои специфические настройки.

В Vim есть подходящая для нас опция — exrc. Она говорит vim’у искать дополнительный .vimrc в текущей рабочей директории. Таким образом, мы можем иметь один файлик в корне каждого проекта с его специфическими настройками.

Так как vim будет подключать .vimrc из любой директории, из которой вы его запустите, желательно предпринять некоторые меры защиты и установить опцию secure. В основном, она запрещает внешним .vimrc писать что-то в файлы, выполнять комманды шелла и отображает маппинги, которые создаются.

В общем, нам нужно добавить следующие две строчки в наш главный .vimrc:

set exrc set secure 
Настройки конкретного проекта

После того, как мы получили возможность сохранять опции для каждого проекта в отдельности, почему бы нам этим не заняться.

У всех проектов есть какие-то свои правила касательно тех же отступов, так что просто пеместите нужные настройки в .vimrc в корне вашего проекта:

set tabstop=4 set softtabstop=4 set shiftwidth=4 set noexpandtab 

Кроме этого, я стараюсь держать свои строки в пределах 110 символов. Но так как это очень специфично и сильно зависит от контекста, я не могу доверить такое важное дело как разбиение строк какому-либо редактору (даже vim). Но vim может помочь мне просто подсветив нужный столбец.

set colorcolumn=110 highlight ColorColumn ctermbg=darkgray 
Определений типов файлов

По умолчанию, Vim предпологает, что все .h файлы это C++. Однако, часть моих проектов написаны на чистом C. Поэтому я хочу, чтобы тип файла был C. Кроме того, в моих проектах используется doxygen, так что я не против включить очень клевую подсветку doxygen в vim.

Для того, нужно добавить пару строк в локальный .vimrc:

augroup project autocmd! autocmd BufRead,BufNewFile *.h,*.c set filetype=c.doxygen augroup END 
Установка переменной path

В vim есть чудесная комманда gf (и родственные к ней), которая открывает файл, чье имя находится под курсором. Это неимоверно полезно при навигации по заголовочным файлам.

По умолчанию, vim смотрит файлы в текущей папке, а так же в /usr/include. Однако почти все проекты имеют заголовочные файлы, которые хранятся в других папках. Поэтому, нужно установить переменную path, которая содержит список папок для поиска, разделенный запятыми.

let &path.="src/include,/usr/include/AL," 
Заметка

Джавистам следует обратить внимание на опцию includeexpr. Она содержит выражение, которое будет использовано для преобразования строки в имя файла. Следующая строка заменяет все точки на слеши для gf. Таким образом, можно прыгать по import’ам.

set includeexpr=substitute(v:fname,'\\.','/','g') 
Автодополнение

Лучший(Устарело. Сейчас я использую YouCompleteMe. Обратитесь к моему посту за деталями) Хороший плагин для автодополнения C/C++ кода, который я нашел, это clang_complete (инструкции для установки смотри на страничке плагина).

Он использует clang для того, чтобы сгенерировать список дополнений. И работает отлично для C и C++ (а так же еще пары языков).

Для того, чтобы clang знал о ваших папках с заголовочными файлами, нужно добавить -I и -D флаги в файл .clang_complete в корне вашего проекта. После этого, clang_complete будет автоматически вызываться при нажатии «.» или «->».

Подсказка

Если path опция уже заполнена, то можно легко вставить список I-флагов с помощью следующей нехитрой комбинации клавиш

"='-I'.substitute(&path, ',', '\n-I', 'g')p
Другие clang плагины

Clang не просто компилятор, а еще и набор полезных библиотек для анализа и манипуляций с кодом. Таким образом, это очень хорошая основа для разнообразных плагинов. Так что в ближайшем будующем можно ожидать множество основаных на нем плагинов.

Навигатор

Для того чтобы отображать дерево проекта можно воспользоваться либо отдельными плагинами (NERD Tree например), либо встроеным netrw.

Я не использую ни один из способов, так как мне вполне комфортно выбирать файлы прямо из коммандного режима vim. (если установить wildmode в longest:list,full , то vim показывает подходящие файлы как нормальный шелл)

Настройка системы сборки

После того, как мы разобрались с редактированием и навигацией по файлам, можно собирать проект. В vim есть комманда make. По умолчанию, она запускает make в текущей директории и парсит вывод на наличие ошибок.

Фактическая комманда для выполнения хранится в makeprg. Если проект собирается в другой папке, использует другие параметры make или вообще использует другую систему сборки, нужно просто изменить makeprg чтобы отобразить это:

set makeprg=make\ -C\ ../build\ -j9 

После этого, можно собирать проект просто напечатав :make .
Но так как нам этого мало, можно повесить эту комманду на одну из ненужных кнопок. Например:

nnoremap :make!

(«!» предотвращает от прыгания на первую ошибку)

Настройки системы запуска

После того, как проект собран, вполне логично запустить его. Vim может запускать любую программу, для этого всего лишь нужно добавить восклицательный знак перед ее именем в коммандном режиме. Так, чтобы запустить мою супер-пупер программу, нужно набрать . /my_great_program .

Конечно, это тоже нужно упростить!

nnoremap . /my_great_program
Система контроля версий

Так как vim предоставляет прямой доступ к коммандной строке, я не использую какой-либо специальный плагин для этих задач и просто управляю своим git-деревом прямо из шелла.

Но я должен отметить, что есть множество отличных vim плагинов для работы с разными системами контроля версий.
Например, fugitive. Если вы работаете с git, вы абсолютно должны посмотреть вимкасты fugitive.

Забытый пункт: отладка

Так как я чувствую себя комфортно в command-line gdb, да и специфика операционных систем делает почти невозможным отладку их отладчиками, за прошедший год я запускал gdb лишь однажды. В основном, все мои проекты я отлаживаю обычными print’ами и капелькой мозгов. Так что в моем vim нет ничего, чтобы напоминало отладчик.

Однако, я должен сказать, что существуют несколько плагинов для интеграции gdb и vim. Например, clewn, gdbvim.

Итог

После серии несложных оперций, vim превратился в вполне себе сносную IDE. Буду рад услышать о дополнительных настройках, которые облегчили вашу жизнь в vim и позволили лучше интегрировать его с окружающими инструментами.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *