Provides V language support for Visual Studio Code.
- Syntax highlighting for
.v,.vsh,.vh,.vv, plusv.modfiles - Code snippets for quick coding, including a dozen
vebsnippets (vapp,vget,vpst,vpar,vctx,vtml,vif,vfor,vinc,vjsn,vmid,vctl) - Completion, diagnostics, navigation, inlay hints, and other language features via VLS
- Runnable CodeLens actions for
mainand tests (Run Main,Run File,Run Test,Debug Main) - Workspace build, run, and test tasks
- Test coverage highlighting and a status bar summary
- Code folding for blocks, import runs, and
//#regionmarkers - Document formatting with the configured compiler, deferring to VLS while the server is running
- Works in unsaved (
untitled), diff (git), andv.moddocuments, not just saved.vfiles
Install VLS and ensure the vls
executable is in PATH. Alternatively, set v.vls.command to its
absolute path. The extension starts VLS over stdio when a V workspace
is opened.
The VLS owner version-gates the server, serializes starts and restarts,
recovers a crashed server, and reports the state on the status bar.
V: Restart VLS restarts it; V: Open V Language Server Output shows
its log. An unsupported server version offers V: Update VLS when the
server names itself VLS, otherwise it points at the settings.
The available VLS settings are:
v.vls.enable: enable or disable VLSv.vls.command: path or command name for the VLS executablev.vls.args: additional command-line argumentsv.vls.inlayHints.enabled: enable or disable inlay hintsv.vls.inlayHints.variableTypes: show inlay type hintsv.vls.inlayHints.parameterNames: show inlay parameter-name hintsv.vls.diagnostics: enable or disable live diagnosticsv.vls.defines: compile-time defines VLS checks with, e.g.["-d", "flag"]v.vls.coverageDirectory: directory av -coveragerun recorded into; enables VLS "Generate test" actions for untested functionsv.vls.coverage.enabled: collect coverage during test tasks and highlight covered and uncovered executable linesv.executablePath: V compiler used by VLS and tasks; supports absolute paths,~,${env:NAME}, and${workspaceFolder}
Settings from the former VLS extension (vls.command, vls.args,
vls.vCommand, and its inlay hint, diagnostics, and coverage toggles) remain
effective until replaced by the corresponding v.* settings.
Use V: Build, V: Run, or V: Test in the Command Palette, or select a V
task from Tasks: Run Task. Build, Run, and Test operate on the workspace;
Run uses the active V module or script when one is open, and Test uses the
active _test.v file. The extension saves modified V files in the target
before running.
V: Run current file uses the same run task. For a .v file, it runs the
containing module; for a .vsh file, it runs the script. V: Build an optimized executable from current file builds the active file with v -prod.
VLS CodeLens actions such as Run Main, Run File, and Run Test use the
same tasks. Test runs collect coverage by default. Covered executable lines
are highlighted green and uncovered lines red. Click the coverage status
item or run V: Clear Test Coverage to remove the highlights.
Three more tasks run the gates that the rest of a change hangs on. Each works on the active file when one is open, and on the workspace otherwise.
V: Checkrunsv -check, which type-checks without producing a binaryV: Vetrunsv vet -W, which reports suspicious constructs and treats warnings as errors, so it is the one to use in CIV: Format Checkrunsv fmt -verify, which reports whether the formatter would change anything
All three surface through the vls problem matcher, so a failure lands in the
Problems panel at the right line rather than only in the task output.
- V: Generate Test File creates the
_test.vfile beside the source with onetest_function per public function, each with a placeholder assertion. It asks before overwriting an existing test file. - V: Toggle Test File jumps both directions: from a source file it opens
its
_test.vfile, and from a_test.vfile it opens the source beside it. - V: Generate Tests for Untested Functions plans new tests from a coverage
run: point
v.vls.coverageDirectory(orvls.json) at av -coveragedirectory and it appends onetest_per untested function. - V: Generate Test from Coverage asks the running VLS (
vls.generateTest, viav cover --write-tests) to write tests for the active file. - V: Fill Struct Fields fills an empty
Name{}literal with the fields of thestruct Namedeclared in the same file. - Every
_test.vfile also appears in the Test Explorer, with one item pertest_function. Running a test from there executesv teston its file withVTEST_ONLY_FNset to the selected function. A gutter lens over eachfn test_runs it through the same task path.
- Error Lens (
v.errorLens.*,V: Toggle Error Lens) decorates V diagnostics inline: full-line backgrounds per severity, problem-range highlights, and the message appended at the end of the line. Settings:enabled,enabledDiagnosticLevels(error,warning,info,hint),messageEnabled,messageMaxChars,messageTemplate($message,$severity,$source,$code), anddelay. - Path Intellisense (
v.pathIntellisense.*) completes file names inside string literals in.vfiles and inside template files. Settings:enabled,showHiddenFiles,autoSlashAfterDirectory,autoTriggerNextSuggestion,absolutePathToWorkspace, andmappings(supports${workspaceFolder}/${workspaceRoot}). - Import Cost (
v.importCost.*) annotates eachimportline with the module's source size, e.g.// 14.2 KB (312 lines, 6 files). V compiles whole programs, so this is module size, not a tree-shaken bundle delta. Settings:enabled,includeTests,cacheTtlMs.
Template files stay HTML — the extension injects VEB directive highlighting
(@if, @for, @else, @end, @include, @var, ${...}, @{...}) into
text.html.basic instead of replacing the language. Emmet, Tailwind CSS,
Prettier, ESLint and React extensions keep working.
Recognized templates: .html under templates/, plus .vhtml and .vtml
(which default to HTML via files.associations). Hovering a directive shows
its kind and the auto-detected script flavor; path completion works inside
template strings too.
Settings:
v.templates.jsxAutoDetect: auto-detect JSX/TSX in template script blocksv.templates.enableEmmet: recommend Emmet for HTML templatesv.templates.enableTailwind: recommend Tailwind CSS IntelliSense
For Tailwind, include ./templates/**/*.{html,vhtml,vtml} in your content
glob. React works inside <script type="text/babel"> blocks (JSX
auto-detected) or in dedicated .jsx/.tsx files.
- On a JSON file, V: Generate JSON Decoder infers V structs for the
document and opens them as an untitled V file, with a decode example
using
json2. V: Generate XML Decoder and V: Generate CSV Decoder do the same from XML (strict subset, struct shape only — vlib has no struct decoder, so the example loads the document for the query API) and CSV (columns typed across rows) files. TOML and YAML share the same core and follow once their parsers land as declared dependencies. - Protobuf, ASN.1, PEM, CBOR and raw binary payloads carry no field names without a schema, so struct inference does not apply to them; base64, hex, base32 and base58 are encodings, covered by V: Convert Selection Encoding instead.
- V: Generate C Output saves the active file, then shows the C the
compiler emits for it (
v -o - <file>); V compiles files rather than standard input, so an unsaved buffer cannot be translated as-is. - V: Translate C File to V with c2v translates the active
.cfile, offering to installc2vwhen it is missing. - V: Organize Imports sorts (and de-duplicates, where safe) the import block; V: Fill Struct Fields is also available as a refactor action.
- Hovering a non-decimal literal (
0x,0o,0b) shows its decimal value.
- V: Search VPM Modules, V: List Installed VPM Modules search and list modules from the V package manager.
- V: Share on Playground posts the active file to the V playground share API and copies/opens the link.
- V: Install or Update V and V: Update VLS build the pinned revision from source (managed builds, preferred over PATH once installed).
- V: Select V executable picks between the configured value, the compiler on PATH, and a managed build.
- V: Show V version prints
v version. - V: Show Environment Status reports which
vand which VLS the extension resolved, what versions they report, and whether the server is running. The answer is written to a document so it can be copied into a bug report. - V: Check for Updates checks once a day (workspace trust required).
- Settings:
v.tools.updateChannel(masterfollows the latest commit,releasefollows the latest tag),v.tools.checkForUpdates. - The status bar shows the resolved V and VLS separately, because VLS can be down while V works; a missing tool offers the fix on click.
The extension offers the V compiler to agents over the
Model Context Protocol, one server per
workspace folder. v mcp serve calls the V parser, checker and formatter in
process, so its answers hold for code that does not compile yet — which a
language server working from a failed parse cannot manage. It also carries the
standard library documentation, so an agent can look up a signature instead of
guessing one.
This needs a V that supports v mcp. The extension probes v mcp tools per
compiler and quietly offers nothing when the compiler is too old; a failed
probe is retried rather than cached, so installing a newer V mid-session is
picked up. Nothing is started until an agent calls a tool. v.mcp.* are
resource-scoped, so each workspace folder carries its own enable flag,
read-only mode, and root.
The server starts read-only by default, which registers no tool that writes a
file. Three of the eighteen tools write: v_rename_symbol, which defaults to a
dry run listing every position it would change; v_format, which reports its
diff before writing; and v_edit_replace, which has no preview at all — it
writes as soon as the range matches the text the agent passed back, so passing
that text is what approves the edit. Set v.mcp.readOnly to false to offer
them.
The settings are:
v.mcp.enable: offer the compiler to agents (defaulttrue)v.mcp.readOnly: start read-only, withholding the three writing tools (defaulttrue)v.mcp.root: directory the server resolves paths against; empty means each workspace folder
Agents outside VS Code can use the same server, and the skills the compiler
ships, without this extension. See v mcp --help and v skills --help.
VLS is offered as an MCP server over stdio (vls --mcp) when the configured
VLS answers an MCP handshake: compile checks, hover, definitions, references,
rename, symbols, and completion. The extension probes the binary before
registering anything, and quietly offers nothing when the installed VLS
cannot serve MCP (no VLS verified so far answers the handshake). One VLS
server per workspace folder sits behind v.vls.mcp.enable (default false,
resource-scoped). Both MCP providers (V Compiler, V Language Server)
appear in VS Code once enabled.
The compiler ships agent skills — the rules that make V code which looks right
fail to compile, the build and test loop, testing conventions, concurrency, the
memory model, and how to drive the MCP server. v skills installs them into
.agents/skills/<name>/, which VS Code, Claude Code, opencode and Copilot
already read, so one install improves every agent you use. A project install
lands in the repository and is shared with your team; a user install lands in
~/.agents/skills and applies to every project on the machine.
The extension adds commands around that rather than a copy of it:
V: Install V Agent Skillsreads the compiler's catalog, lets you pick skills and a scope, and runs the installV: Show V Agent Skill Statussays what is installed where and which copies have fallen behind the compiler'sV: Update V Agent Skillsrefreshes the ones that haveV: Remove V Agent Skillsremoves installed skills per scope (v skills remove, new in recent V)
Nothing is overwritten silently. v skills add refuses to replace an installed
skill unless --force is given, which the extension passes only for the
picked skills that are already installed; freshly picked skills install
without it, so one reinstall cannot overwrite the rest. v skills update
holds back a skill whose files were edited locally, and reports which one
and why.
These commands need a V that supports v skills. On an older compiler they
report that rather than doing nothing. Skills also work with agents outside VS
Code, without this extension; see v skills --help.
Known gaps and what would close them, cheapest first — the missing Test Explorer integration, the absent debugger, and the parts of the test suite that fail on Windows. See ROADMAP.md; please read it before opening a pull request so we do not duplicate each other.
The first time you open a V file, the extension offers a three-step walkthrough: install V, build and run a project, and run the check, vet and format gates. Each step completes when you run the command it describes, so the walkthrough walks you through the extension's own commands rather than asking you to read this file first.
First you will need to install Visual Studio Code >= 1.105.
In the command palette (Cmd+Shift+P) select Install Extensions and choose V.
Alternatively you can install the extension from the Marketplace.
Now open any .v, .vsh, .vh, or .vv file in VS Code.
Note: It is recommended to turn Auto Save on
in Visual Studio Code (File -> Auto Save) when using this extension.
V: Build,V: Run, andV: TestV: Check,V: Vet, andV: Format CheckV: Run current fileV: Format current fileV: Build an optimized executable from current fileV: Generate Test FileV: Toggle Test FileV: Generate Tests for Untested FunctionsV: Generate Test from CoverageV: Fill Struct FieldsV: Organize ImportsV: Clear Test CoverageV: Debug MainV: Generate JSON DecoderV: Generate XML DecoderV: Generate CSV DecoderV: Convert Selection EncodingV: Generate C OutputV: Translate C File to V with c2vV: Share on PlaygroundV: Search VPM ModulesV: List Installed VPM ModulesV: Install V Agent SkillsV: Show V Agent Skill StatusV: Update V Agent SkillsV: Remove V Agent SkillsV: Toggle Error LensV: Show V versionV: Select V executableV: Install or Update VV: Update VLSV: Restart VLSV: Open V Language Server OutputV: Show Environment StatusV: Check for Updates
You can access all of the above commands from the command palette (Cmd+Shift+P).
Clone this repository and run npm install to install the dependencies.
Then press F5 to open a new VS Code window with the extension loaded.
The build, test, and grammar-test commands, and the layout of src/, are
described in CONTRIBUTING.md.
Open the output console (Cmd+Shift+U) to see the debug output from the extension.
Run Cmd+Shift+P and select Preferences: Open User Settings to update settings.
Run npm test for logic checks and npm run test:vscode for an extension-host
check. The latter uses ~/code/vls/vls and ~/code/v/v by default and downloads
a local VS Code test build if CODE_EXECUTABLE is unset. Set VLS_BINARY and
V_BINARY to use other binaries. After npm run package, set
TEST_PACKAGED=1 when running npm run test:vscode to install and test the
VSIX in an isolated VS Code profile.
V programs can be debugged from the Run and Debug view. The extension contributes
a type: "v" debugger: it compiles the program with -g, then hands the
session to the C/C++ extension's cppdbg adapter, which requires both
ms-vscode.cpptools and gdb on PATH. A missing piece shows an install
hint instead of failing silently.
A default launch configuration is provided, so starting a debug session does not
require writing a launch.json by hand. The program field is the V source file
to debug; args, stopAtEntry and cwd are optional. miDebuggerPath names
the MI debugger (a path or a command on PATH, with ~ expanded) and MIMode
selects gdb or lldb; both default to gdb on PATH, which is what unblocks
macOS debugging where gdb is effectively unavailable. setupCommands passes
extra MI commands through after the printer setup, environment and envFile
set the program environment, and externalConsole runs it outside the
integrated terminal. See docs/TROUBLESHOOTING-DEBUGGING.md when a session
misbehaves.
Attach works the same way with "request": "attach": program names the
running binary for symbols (nothing is compiled), processId takes a PID
or ${command:pickProcess} for the adapter's picker, and sourceFileMap,
miDebuggerServerAddress and pipeTransport reach remote targets.
A Debug Main lens over fn main starts the same pipeline without a
launch configuration. Panics stop in the debugger instead of exiting:
debug builds trap on panic while a debugger is attached.
Hexadecimal display is per variable, not a launch option: in the Debug
Console, -exec -var-set-format <name> hex reformats a value (the
adapter has no showHex-style setting). Core dumps stay out of scope;
open one with a hand-written cppdbg config using coreDumpPath.
Each session loads GDB pretty printers for V values: strings show as text,
Option and Result show their payload, and arrays and maps summarize
their lengths. This needs a GDB with Python support; without it the session
still runs, only without the pretty display.
The extension is distributed under GPL-2.0-only because its task and coverage implementation comes from the VLS VS Code extension. Existing files covered by the MIT license retain that license.
Other extensions can resolve the V compiler through the extension's exports:
const v = vscode.extensions.getExtension("vlanguage.vscode-vlang")?.exports
const compiler = v?.resolveV(resource)resolveV returns the absolute path to the v binary the extension would use
for that resource, including the settings kept from the former VLS extension.
It returns undefined when the compiler cannot be resolved, which is not the
same as it being absent.
