AutoFlip is a display-only C++ type viewer for current Vim 9.x. It has two modes:
prefer-autodisplays a safeautospelling over an explicit local-variable type. Its default level uses clang-tidymodernize-use-auto; opt-in levels also accept increasingly broad clangd AST-proven local declarations.show-deduced-typesdisplays clangd's inferred type over the sourceautospelling.
AutoFlip never applies an edit. The buffer, undo history, saved file, search, yanks, macros, navigation, and Git diff continue to use the original source. Only Vim conceal matches and virtual text change what a window displays.
This real Vim/vim-lsp/clangd session shows a clang-tidy iterator replacement,
AST-proven copy replacements, selective cursor reveal, show-deduced-types,
and the untouched source returning on disable:
Every AutoFlip view below is display-only; the source remains exactly as shown in its source block.
Authority: clang-tidy modernize-use-auto, delivered by clangd.
Source:
std::vector<int>::iterator it = values.begin();AutoFlip view:
auto it = values.begin();Authority: additional structured-AST proof from clangd.
Source:
Stage next = current;AutoFlip view:
auto next = current;Authority: clangd's deduced-type inlay hint.
Source:
auto answer = 42;AutoFlip view:
int answer = 42;The package/repository name is vim-autoflip; its Vim command and display
prefix is AutoFlip, and its Vim9script/global namespace is autoflip. This
is a deliberate breaking identity with no compatibility aliases. Remove an
earlier installed copy, update the plugin-manager path and configuration names,
restart Vim, and regenerate help tags after upgrading.
- current Vim 9.x with
+vim9script,+textprop,+conceal,+channel, and+job; - vim-lsp, loaded as a required dependency;
- clangd attached to the C++ buffer through vim-lsp;
- an accurate
compile_commands.json(or equivalent clangd configuration); - clang-tidy's
modernize-use-autoenabled forprefer-auto; - clangd deduced-type inlay hints enabled for
show-deduced-types.
Neovim, legacy Vim, Coc, direct clangd process management, and heuristic type deduction are intentionally unsupported.
With vim-plug, load vim-lsp before AutoFlip:
Plug 'prabirshrestha/vim-lsp'
Plug 'xpac27/vim-autoflip'Or copy/clone this repository below a Vim package start directory. Run
:helptags ALL after installation.
A minimal vim-lsp clangd registration is:
if executable('clangd')
au User lsp_setup call lsp#register_server({
\ 'name': 'clangd',
\ 'cmd': {server_info -> ['clangd', '--background-index', '--clang-tidy']},
\ 'allowlist': ['c', 'cpp', 'objc', 'objcpp'],
\ })
endifvim-lsp-settings may register clangd instead. Keep clangd in the registered
server name so AutoFlip can conservatively identify it. AutoFlip makes its own
raw inlay-hint request; vim-lsp's renderer can remain disabled (its default):
let g:lsp_inlay_hints_enabled = 0clang-tidy also publishes modernize-use-auto diagnostics that vim-lsp may
show beside AutoFlip's replacement. To hide this redundant text, disable all
diagnostic virtual text before vim-lsp loads; signs, highlights, diagnostic
lists, and AutoFlip continue to work:
let g:lsp_diagnostics_virtual_text_enabled = 0In the project root, enable the clang-tidy check and deduced-type hints:
# .clangd
Diagnostics:
ClangTidy:
Add: [modernize-use-auto]
InlayHints:
DeducedTypes: YesSome clangd installations enable clang-tidy without the launch flag; using
--clang-tidy explicitly is the clearest known-good setup. AutoFlip does not
invent compiler flags. Fix compilation database problems in the project.
AutoFlip is opt-in. Open a supported C++ file and run:
:AutoFlipEnable
:AutoFlipMode prefer-auto
:AutoFlipPreferAutoLevel clang-tidy
:AutoFlipPreferAutoLevel best-effort
:AutoFlipMode show-deduced-types
:AutoFlipRefresh
:AutoFlipReveal
:AutoFlipStatus
:AutoFlipDisable:AutoFlipToggle switches the current buffer on or off. Insert mode reveals
the original spelling by default. Moving onto a concealed type keeps its
original spelling visible until the cursor leaves that source range; every
other substitution remains concealed. No mappings are installed; an optional
user mapping is:
nnoremap <leader>av <Cmd>AutoFlipToggle<CR>Set globals before the plugin loads:
let g:autoflip_enabled_by_default = v:false
let g:autoflip_mode = 'prefer-auto'
let g:autoflip_debounce_ms = 300
let g:autoflip_reveal_on_insert = v:true
let g:autoflip_reveal_under_cursor = v:true
let g:autoflip_max_visible_lines = 300
let g:autoflip_type_name_limit = 80
let g:autoflip_prefer_auto_level = 'clang-tidy'
let g:autoflip_max_ast_requests = 40g:autoflip_type_name_limit is fail-closed: a longer clangd label is skipped,
not cut into a potentially misleading C++ type.
After an edit, views on byte-identical source lines remain rendered while the debounced request is pending. Views on edited or shifted lines are removed immediately and clangd's accepted reply remains authoritative.
Diagnostic updates queue a follow-up refresh without invalidating the LSP reply already in flight.
g:autoflip_prefer_auto_level selects one of two policies:
clang-tidy(default) renders only direct clang-tidymodernize-use-autocode actions.best-effortretains clang-tidy results and additionally scans the bounded visible range for simple localType [*|&] name = initializer;declarations. The initializer may continue onto later visible lines. Each nomination must pass exact clangd AST declaration/range checks, compatible canonical-type checks, and a conversion-free expression check before rendering.
g:autoflip_max_ast_requests bounds best-effort AST requests per refresh; zero
disables its additional substitutions while retaining clang-tidy results.
Start with :AutoFlipStatus.
vim-lsp is not installed: install/load vim-lsp before AutoFlip.no running clangd server is attached: check vim-lsp registration and:LspStatus/:CheckHealthif available.does not advertise code actions: update/configure clangd and vim-lsp.does not advertise inlay hints: use a current clangd with standardinlayHintProvidersupport.does not advertise AST support:best-effortrequires clangd'sastProviderprotocol extension; useclang-tidywith an older server.0 substitutions: inspect clangd diagnostics,.clangd, the compilation database, and the conservative limitations below. This is not an error.- duplicated inlay hints: disable vim-lsp's renderer with
g:lsp_inlay_hints_enabled = 0.
For vim-lsp protocol logs:
let g:lsp_log_verbose = 1
let g:lsp_log_file = '/tmp/vim-lsp.log'- Only
.cc,.cpp,.cxx,.h,.hh,.hpp, and.hxxC++ files and simple initialized local variables are targeted. - Conservative
prefer-autoaccepts direct, single-editWorkspaceEditcode actions only. Command-backed or multi-file fixes are ignored. best-effortaccepts only simple initialized local declarations with an optional leadingconstand one*or&declarator. It skips rvalue references, declarations without a terminating visible;, macros, multi-declarators, implicit conversions, incompatible AST ranges/types, and unknown expression shapes.show-deduced-typescurrently accepts simpleauto name = ...declarations. Direct-list initialization, function returns, parameters, fields, aliases, structured bindings, macros, and ambiguous declarations are ignored.- Cursor reveal removes only the selected TypeView, but that selection appears as source in every split showing the buffer because virtual text is buffer-owned. Insert and explicit command reveal intentionally expose all types. Conceal matches and option restoration remain independently tracked for each window.
- Lazy-loading the AutoFlip runtime itself after clangd has already published diagnostics can omit clang-tidy candidates until clangd publishes again. Normal startup loading, including later manual enable, caches them safely.
- AutoFlip recognizes an attached server whose vim-lsp name or info name
contains
clangd.
The supported user API is the :AutoFlip... command family, the nine
g:autoflip_... configuration variables above, and the AutoFlipAuto and
AutoFlipDeducedType highlight groups. The b:autoflip_state dictionary and
autoload module exports are implementation details and may change. Version 1
does not emit User autocommands or install mappings.
See :help autoflip, features, and
architecture for the complete behavior.
Run all deterministic checks without a personal Vim configuration:
make checkThe optional real-clangd test is described in test/README.md; it skips when
vim-lsp or clangd is unavailable.
