Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Pine Script Syntax HighlighterNew to Visual Studio Code? Get it now.
Pine Script Syntax Highlighter

Pine Script Syntax Highlighter

ex-codes

|
84,484 installs
| (2) | Free
Pine Script v6 for Visual Studio Code: highlighting, completion, hover documentation, signature help, snippets, themes and compiler diagnostics.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info


Pine Script
Pine Script Syntax Highlighter

Completion, navigation, hover documentation, signature help, formatting, offline checks, colour swatches, 97 snippets and themes for TradingView Pine Script® v6 in Visual Studio Code.

Marketplace version Installs Rating CI Issues License

Example

Why you will like it

Open a .pine file and the editor already knows the language: every v6 built-in completes with its signature, F12 jumps to your own declarations, F2 renames a symbol everywhere, hovering anything shows the reference entry, Format Document lays the script out the way Pine wants it, problems are flagged as you type without your code leaving the machine, colours show a swatch you can click, and 97 snippets turn a prefix and Tab into a full indicator, a strategy exit block or a Bollinger Bands section.

Quick start

  1. Install Pine Script Syntax Highlighter from the Marketplace.
  2. Create a file named my-script.pine and type indicator, then press Tab. A complete v6 indicator appears with the title, short title, overlay flag and an input ready to fill in; Tab moves between the fields.
  3. Type ta. to see the whole namespace with documentation, pick ta.sma, and watch the parameter hints as you write the arguments.
  4. Hover over input.int, ta.crossover or your own function to read what it does.
  5. Try bb, sltp, table or request.security.tuple with Tab to drop in a working building block.
  6. Press Shift+Alt+F (Shift+Option+F on macOS) to format the file: blocks get their four spaces, operators and arguments get their spacing, and nothing else moves.
  7. Put the cursor on one of your own functions and press F12 to jump to it, Shift+F12 to list every call, or F2 to rename it everywhere at once.
  8. Press F1 and type Pine Script: to see the commands: new files from templates, docstrings, type annotations, converting an old script to v6, and the reference.

Features

Completion that knows Pine

  • Built-in functions, variables and constants from every v6 namespace (ta, math, str, array, matrix, map, request, strategy, label, line, box, table, polyline, chart, log, and the rest), each with its documentation and signature.
  • Keywords, type names and qualifiers, and your own functions, methods, types, enums and variables as soon as you declare them.
  • Named arguments inside a call, //@ annotations at the start of a comment, and import paths that complete user, library and version.
  • Function items insert a call and open parameter hints, so a long strategy.exit() is a matter of tabbing through its parameters.

Navigation through your own code

  • Go to Definition (F12) on a function, method, type, enum, enum member, variable, parameter or import alias jumps to where you declared it.
  • Find All References (Shift+F12) lists every use, and the occurrences under the cursor are highlighted as you move around.
  • Rename Symbol (F2) renames a declaration and every use of it in one edit. It understands scope, so a global length is not touched when a function takes its own length parameter, and it leaves named arguments, import paths and type fields alone. Renaming a built-in is refused rather than half done.

Documentation where the cursor is

  • Hover on a built-in shows the signature, description, parameters, return value and a link to the reference entry. Hover on your own symbol shows its declaration and its //@ docs. Hover on an import line shows a card for the library.
  • Signature help lists the overloads, highlights the active parameter and keeps up when you switch to named arguments.
  • Open Reference jumps to the v6 reference page for the built-in under the cursor.

97 snippets, from a header to a complete strategy block

Every snippet targets Pine Script v6, uses placeholders you can tab through, and inserts code that compiles as-is. Type the prefix and press Tab, or pick it from the completion list.

Group Prefixes
Script skeletons indicator, strategy, library, indicator.full, strategy.full, header, version, import, export
Declarations and control flow fn, fntuple, method, type, typemethod, enum, enuminput, var, varip, if, switch, switchcond, for, forin, forby, forbreak, while, once, runtime.error, log
Comments and documentation section, divider, notes, date, todo, docfn, doctype, docenum, docvar, alertmsg
Inputs input.int, input.float, input.bool, input.string, input.source, input.color, input.timeframe, input.symbol, input.session, input.time, input.price, input.text_area, inputs.inline, inputs.group
Plots and drawings plot, plotshape, plotchar, plotarrow, plotcandle, plotbar, bgcolor, barcolor, hline, fill, gradient, label.new, line.new, box.new, table, polyline, debug
Alerts alertcondition, alert, alert.json
Requests, time and sessions request.security, request.security.tuple, request.security.confirmed, request.security_lower_tf, secfn, session, newbar, backtest, islast
Strategy strategy.entry, strategy.exit, strategy.close, position, sltp, trail
Technical analysis cross, mafn, bb, rsi, atrstop, breakout
Collections array, map, matrix

A few worth trying first:

  • strategy.full writes a strategy() call with every commonly used parameter on its own line, with choices for quantity type, currency and commission type.
  • sltp adds percent based stop loss and take profit inputs and the two strategy.exit() calls that use them.
  • request.security.confirmed inserts the non-repainting form of a higher timeframe request; request.security.tuple fetches open, high, low and close in one call.
  • bb, rsi and mafn are complete, plotted indicator sections. mafn includes a moving average function selected by a string input.
  • table creates a table once and fills it on the last bar; debug prints any value in a label on the last bar.
  • section, notes and date keep long scripts readable; docfn and doctype write the //@ blocks the outline and hover use.

Formatting that respects how Pine reads a file

Format Document and Format Selection work out of the box; turn on editor.formatOnSave if you want it automatic.

Pine is indentation sensitive, so the formatter is deliberately conservative: it never joins or splits a line, and it never moves code between lines. What it does do:

  • Indents every local block with exactly four spaces per level, the only width the compiler accepts. A two space block, or a file that mixes tabs and spaces, comes out correct. If your editor is set to tabs, it indents with tabs instead.
  • Keeps a wrapped line aligned where you put it, and shifts it off a block indent when Pine would otherwise read it as a new block. Wrapping a long strategy() call across ten lines stays exactly as you aligned it.
  • Puts single spaces around operators and after commas, removes them inside brackets, and keeps close[1], ta.sma, array.new<float>() and import user/lib/1 tight.
  • Leaves strings, comments and triple-quoted blocks byte for byte alone, including the gap in front of a trailing comment.
  • Trims trailing whitespace, caps runs of blank lines at two, and ends the file with a single newline.

Padding used to align a column of assignments is collapsed to one space, which is the one change that is a matter of taste.

Every snippet in this extension and every test fixture has been run through the formatter and back through the TradingView compiler: none of them changed meaning, and formatting twice gives the same file.

Checks that never leave your machine

Every Pine document is checked as you type, using the reference data that ships with the extension. This is on by default because nothing is sent anywhere; the TradingView compiler is still a separate, opt-in setting.

Rule What it catches
missing-version / old-version No //@version, or one older than v6. Both offer a fix.
legacy-name A bare v4 name that moved into a namespace: sma, security, tostring, abs. Offers the v6 name.
local-scope-call plot, hline, fill, bgcolor, alertcondition and friends inside an if, for or function body, which the compiler rejects.
unknown-argument A named argument the function does not take, including options dropped between versions such as transp. Suggests the near miss.
duplicate-argument The same named argument passed twice.
unused-variable / unused-parameter / unused-import Declarations nothing reads, shown faded rather than as warnings.

Turn the whole thing off with pinescript.lint.enabled, or silence single rules with pinescript.lint.disabledRules.

Pine Script: Convert to v6 applies the version, legacy-name and argument fixes across the whole file in one go, which is most of the work of bringing an old script forward. It says exactly what it changed, including any argument it had to remove, and it is a single undo.

Colours you can see and click

Every colour a script names gets a swatch in the gutter of the line: hex literals such as #FF9800, the built-in constants, color.new(color.blue, 25) and color.rgb(255, 152, 0, 40). Click one to open the colour picker; the value is written back as a hex literal or a color.rgb() call, transparency included.

Highlighting that knows your symbols

On top of the grammar, the extension tells the editor which identifiers are yours. Parameters inside a function body, enum members, type fields and import aliases are coloured for what they are rather than guessed at from their spelling. Both bundled themes carry matching colours; other themes pick it up through the standard token types.

Structure, libraries and diagnostics

  • Outline. Functions, methods, types with fields, enums with members and top-level variables in the Outline view and breadcrumbs.
  • Libraries. Workspace files that call library() are indexed: their exports complete after the import alias and show up on hover. With pinescript.libraries.remote on, import completion also lists published TradingView libraries and hover shows their exports.
  • Compiler diagnostics (opt-in). Set pinescript.diagnostics.remote to true to send the document to the TradingView compiler and see its errors and warnings inline, on open, on save and shortly after you stop typing.
  • Quick fixes. With diagnostics on, the lightbulb offers a fix for the mistakes the compiler reports most: a v4 name that moved into a namespace (sma → ta.sma, security → request.security), study → indicator, a misspelt built-in or one of your own names, a misspelt or removed argument (titel → title, drop transp), a variable initialised with na that needs a type keyword, a declared type that is too narrow, a name that hides a built-in (renamed everywhere at once), and a missing //@version=6.
  • Commands. New Indicator / Strategy / Library from a template, Generate Docstring (also a lightbulb on declarations), Add Type Annotations for untyped declarations, Open Reference for the built-in under the cursor.

Bringing an old script forward is mostly clicking the lightbulb. This one goes from eight compiler complaints to a clean compile:

study("Legacy", overlay=true)            //@version=6
ma = sma(src, len)                       indicator("Legacy", overlay = true)
daily = security(tickerid, "D", close)   ma = ta.sma(src, len)
int slow = ta.ema(close, 50)      ==>    daily = request.security(tickerid, "D", close)
open = 1                                 float slow = ta.ema(close, 50)
holder = na                              openValue = 1
plot(ma, color=color.blue, transp=40)    float holder = na
                                         plot(ma, color = color.blue)

Highlighting and themes

  • A grammar generated from the v6 reference: every namespace, keyword, annotation, triple-quoted string, format placeholder and hex color gets its own scope, so any theme works and the two bundled ones shine.
  • Pine Dark and Pine Light are tuned for every scope the grammar produces and are checked in CI so that no token is left uncolored.
  • Folding, bracket matching, auto-closing pairs, comment toggling and four-space indentation are configured for .pine files out of the box.

Files ending in .pine or .pinescript, or starting with //@version=, are recognized automatically.

Pine Script v6 compatibility

The grammar and the documentation data are generated from the v6 reference, so v6 behaviors such as dynamic request.*() calls with series string arguments, short-circuit and/or, point-based text sizes, text.format_bold / text.format_italic, order trimming and negative array indices are covered wherever they have syntax to highlight or document. They are compiler behaviors; the extension does not emulate them.

Commands

Command What it does
Pine Script: New Indicator Opens an untitled document from the indicator template
Pine Script: New Strategy Opens an untitled document from the strategy template
Pine Script: New Library Opens an untitled document from the library template
Pine Script: Generate Docstring Inserts or completes //@function, //@param, //@returns, //@type, //@field, //@enum for the declaration at the cursor
Pine Script: Add Type Annotations Prefixes untyped declarations with their inferred type in the selection or the whole file
Pine Script: Open Reference Opens the v6 reference at the built-in under the cursor
Pine Script: Convert to v6 Adds or raises the version pragma and rewrites the v4 names that moved into namespaces

Settings

Setting Default Meaning
pinescript.completion.enabled true Completion provider
pinescript.hover.enabled true Hover provider
pinescript.signatureHelp.enabled true Parameter hints
pinescript.libraries.local.include **/*.pine Glob for workspace library discovery
pinescript.libraries.remote true Look up published libraries on TradingView for import completion and hover
pinescript.diagnostics.remote false Send the document to the TradingView compiler for diagnostics
pinescript.format.enabled true Format Document and Format Selection
pinescript.lint.enabled true Offline checks; nothing is sent anywhere
pinescript.lint.disabledRules [] Rule names the offline checker should skip

Privacy

Everything works offline. Two features talk to TradingView, both through undocumented endpoints that may change:

  • With pinescript.libraries.remote on, the prefix you type after import and the ids of imported libraries are sent to fetch library metadata and source.
  • With pinescript.diagnostics.remote on, the full text of each open Pine document is sent to the compiler on open, on save and 600 ms after you stop typing.

Nothing else leaves your machine. When a request fails, the feature is paused for five minutes and the reason is written to the "Pine Script" output channel.

Recommended companions

  • vscode-icons for a .pine file icon.

How it works

src/
  grammar.mjs           grammar rules, expressed as data
  data/
    functions.json      built-in functions, grouped by namespace (grammar source)
    variables.json      built-in variables, grouped by namespace (grammar source)
    constants.json      built-in constants, grouped by namespace (grammar source)
    annotations.json    compiler annotations
    reference.json      full v6 documentation, generated by scripts/scrape-reference.mjs
  extension/
    core/               pure TypeScript: tokenizer, document model, completion context,
                        symbol resolution, type inference, docstrings, formatter,
                        offline rules, quick fixes, colours, semantic tokens, templates,
                        TradingView client
    providers/          VS Code adapters: completion, hover, signature help, symbols,
                        navigation, formatting, colours, semantic tokens, code actions,
                        diagnostics, offline checks, library index
    commands/           command implementations
scripts/
  build-grammar.mjs     compiles src/ into syntaxes/pinescript.tmLanguage.json and
                        checks it against reference.json
  build-extension.mjs   bundles src/extension into dist/extension.cjs with esbuild
  scrape-reference.mjs  regenerates src/data/reference.json (maintainers, needs network)
  check-themes.mjs      verifies both themes cover every grammar scope
themes/                 Pine Dark and Pine Light
tests/
  core/                 vitest suites for src/extension and the snippet catalogue
  unit/                 scope assertions (vscode-tmgrammar-test)
  snapshots/            full-file snapshots (vscode-tmgrammar-snap)

syntaxes/pinescript.tmLanguage.json, src/data/reference.json and dist/ are generated. Do not edit them by hand.

Development

git clone https://github.com/yankikucuk/pine-script-syntax-highlighter.git
cd pine-script-syntax-highlighter
npm install
npm run build        # grammar + extension bundle
npm run watch        # rebuild the bundle on change
npm test             # grammar and theme checks, type check, core and grammar tests
npm run package      # build the .vsix

Press F5 in VS Code to launch an Extension Development Host with the extension loaded. Use Developer: Inspect Editor Tokens and Scopes to see which scope a token receives.

See CONTRIBUTING.md for the pull request checklist and CHANGELOG.md for release history.

License

MIT © Yankı Küçük

Pine Script® is a registered trademark of TradingView, Inc. This project is not affiliated with TradingView.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft