This page looks best with JavaScript enabled

Debugging and autocompletion for Unreal Engine 4 and 5 projects in (Neo)Vim

 ·  ☕ 6 min read

Autocompletion

For autocompletion there are two options:

  1. coc (Vim, Neovim)
  2. LSP (Neovim only)

In my experience, coc is easier to set up. If you want to get started as quickly as possible, this is your best bet.

Coc

  1. Install coc.vim, e.g. with vim-plug inside .vimrc: Plug 'neoclide/coc.nvim'
  2. Run :CocInstall coc-clangd

You will likely have to familiarize yourself with coc’s shortcuts first or customize it as you see fit.

LSP

Setting up LSP takes a bit of time but for those that already have it up and running, there is probably not much to do. To keep this short, I will not explain the setup process. However, feel free to copy my Neovim config from my dotfiles. I have also set up some extra features for clangd in my config, if you are interested.
If you wish to start from sratch, check out the server configuration for clangd and the completion plugin nvim-cmp as a starting point.

Creating the compile database

No matter which option you pick, you must do the following steps first:

  1. In UE
    • go to Edit - Editor Preferences - General - Source Code - Source Code Editor and select Visual Studio Code
    • go to File - Refresh Visual Studio Code Project
  2. Create a symlink from your project’s root directory to myProject/.vscode/compileCommands_myProject.json
    ln -s .vscode/compileCommands_myProject.json compile_commands.json

If you open your project in (Neo)vim and you are greeted by tons of error messages after you have successfully set up either coc or lsp, you might have to modify your compile_commands.json. For this purpose, I have created a file called clang-flags.txt that contains a bunch of compile flags which improve the experience drastically. The files look like this:

-std=c++20
-ferror-limit=0
-Wall
-Wextra
-Wpedantic
-Wshadow-all
-Wno-unused-parameter

Yes, C++20 is not even supported by UE, yet this got rid of many false error messages.

Now you need to modify your compile_commands.json to use clang-flags.txt. Using (Neo)vim to modify the file is easy but making a little script to automate this process is probably worth it in the long run. Add @/path/to/my/clang-flags.txt after clang++.

{
	"file": "/home/User/MyGame/Plugins/UEGitPlugin/Source/GitSourceControl/Private/GitSourceControlMenu.cpp",
	"command": "clang++ @/path/to/my/clang-flags.txt /home/User/MyGame/Plugins/UEGitPlugin/Source/GitSourceControl/Private/GitSourceControlMenu.cpp @/home/User/MyGame/.vscode/compileCommands_MyGame/GitSourceControl.4.rsp",
	"directory": "/home/User/unrealengine/Engine/Source"
},

Another option to eliminate false error messages is using your own clang instead of the one that UE ships with by default. Clang 14 is working well for me. All you need to do is to remove the path before clang++ as shown in the code snippet above. To check if everything is working, simply run the command entry of some arbitrary file in your terminal. You might still get some errors but for the most part you should see a relatively lengthy compilation process. This is also equivalent to the time it will take until you get any completion results inside of (Neo)vim.

Debugging

  1. Install vimspector, e.g.
    Plug 'puremourning/vimspector'
  2. Configure debugging vimspector keybinds or simply add let g:vimspector_enable_mappings = 'HUMAN' to your .vimrc.
  3. Create a .vimspector.json inside of your project’s root directory (simply refer to the myProjectEditor (DebugGame) entry in myProject/.vscode/launch.json), e.g.
{
  "configurations": {
    "Launch": {
      "adapter": "vscode-cpptools",
      "configuration": {
        "request": "launch",
        "program": "/path/to/UnrealEngine/Engine/Binaries/Linux/UE4Editor-Linux-DebugGame",
        "args": [ "/path/to/myProject/myProject.uproject" ],
        "cwd": "/path/to/UnrealEngine",
        "externalConsole": true,
        "MIDebuggerPath": "/usr/bin/gdb",
        "MIMode": "gdb"
      }
    }
  }
}
  1. Compile a debug build
    path/to/UnrealEngine/Engine/Build/BatchFiles/Linux/Build.sh myProject Linux DebugGame '/path/to/myProject/myProject.uproject' -waitmutex
  2. Set a breakpoint (F9) and start debugging (F5) in Vim and your project will open in a new instance for debugging.

If you just wish to compile your project refer to the following entries in myProject/.vscode/tasks.json:
path/to/UnrealEngine/Engine/Build/BatchFiles/Linux/Build.sh myProject Linux Development '/path/to/myProject/myProject.uproject' -waitmutex
For anything else building and debugging-related simply refer to tasks.json and launch.json in myProject/.vscode.

I am currently trying to set up nvim-dap for Neovim. As soon as it’s working, I will add the instructions here.

ue4-cli

I highly recommend using ue4-cli. This application is primarily used for compiling your project from the terminal but it can do a bunch of other neat things like running automation tests, generating IDE project files, cleaning your build files, and even packaging your build. It also works for UE5 if you set the engine path manually (at the time of writing, this is still a bug). I defined a function in my .zshrc to act as a wrapper for ue4-cli which adds all of the automation that I like to have in my workflow.

Ctags

Navigating engine source code is not possible with coc or lsp because it requires a compile database of the engine, which I was not able to create. However, ctags will take care of that. Simply install universal-ctags (e.g. with your package manager) and run the following command:

ctags -R --c++-kinds=+p --fields=+iaS --extras=+q --languages=C++ /path/to/your/unrealengine/Engine/Source

When the cursor is over a symbol that was found by ctags, Ctrl+] will let you jump to the tag using the newly generated tags file. I usually run the command above in my project’s root directory, so that no additional configuration is required for (N)vim to find the file.

Clang-tidy

Yes, you can even get static analysis in your code. All you need is a file named .clang-tidy in your project’s root directory. Creating this file was quite the hassle since a lot of the tests that clang-tidy runs just don’t make any sense when working with Unreal Engine and trying to follow the guidelines. As a starting point, you can use my version:

---
Checks:          'clang-diagnostic-*,misc-*,readability-*,bugprone-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,-modernize-use-trailing-return-type,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-readability-avoid-const-params-in-decls,-misc-unused-parameters,-readability-named-parameter,-readability-magic-numbers,-misc-non-private-member-variables-in-classes,-cppcoreguidelines-non-private-member-variables-in-classes,-cppcoreguidelines-avoid-magic-numbers,-modernize-use-auto,-cppcoreguidelines-pro-type-union-access,-bugprone-easily-swappable-parameters'
WarningsAsErrors: false
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
FormatStyle:     google
CheckOptions:
  - key:             cert-dcl16-c.NewSuffixes
    value:           'L;LL;LU;LLU'
  - key:             cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
    value:           '0'
  - key:             cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
    value:           '1'
  - key:             cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
    value:           '1'
  - key:             google-readability-braces-around-statements.ShortStatementLines
    value:           '1'
  - key:             google-readability-function-size.StatementThreshold
    value:           '800'
  - key:             google-readability-namespace-comments.ShortNamespaceLines
    value:           '10'
  - key:             google-readability-namespace-comments.SpacesBeforeComments
    value:           '2'
  - key:             modernize-loop-convert.MaxCopySize
    value:           '16'
  - key:             modernize-loop-convert.MinConfidence
    value:           reasonable
  - key:             modernize-loop-convert.NamingStyle
    value:           CamelCase
  - key:             modernize-pass-by-value.IncludeStyle
    value:           llvm
  - key:             modernize-replace-auto-ptr.IncludeStyle
    value:           llvm
  - key:             modernize-use-nullptr.NullMacros
    value:           'NULL'
...

Clang-format

Consider using a .clang-format to automatically format your code in all of your projects. This one is probably the best you can find online. Simply place it in your project’s root directory.
One thing I disliked about having .clang-format in the root directory is that it would format everything, including the Plugins folder. As a quick workaround, I put the following .clang-format in the Plugins folder:

DisableFormat: true
SortIncludes: false

Misc

If you are on Arch and experience long loading times when starting the editor (UE4 only) follow the instructions on the Arch Wiki. It really makes a difference.

Let me know if you have any suggestions or ideas to make UE development in (Neo)vim even better.

Tested on

OS - Arch Linux
VIM - Vi IMproved 8.2
NVIM - 0.7.2
coc.nvim - 0.0.80
clangd - 12.0.1
Unreal - 4.28
Vimspector - Build 1284234985

==================================================================================================================================================
copy from https://gist.githubusercontent.com/chillpert/1a76ae8e9cfafb36d3bf9e343d32fedc/raw/8d85a97119b159ef31bf9c5d78a7ef4f39c5b2dc/vim-unreal.md

Share on

James
WRITTEN BY
James
Unity Developer