Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and

## [Unreleased]

## [3.2.0] - 2026-09-08

### Added

- A formatter behind **Format Document** and **Format Selection**. It indents local blocks with the four spaces the compiler requires, repairs two space and mixed tab indentation, keeps wrapped lines aligned while moving them off a block indent, spaces operators and arguments, and leaves strings, comments and import paths untouched. Lines are never joined or split.
- `pinescript.format.enabled`, and `editor.defaultFormatter` for `[pinescript]`, so formatting works without picking a formatter.
- Quick fixes on compiler diagnostics: move a v4 built-in into its namespace, rename `study` to `indicator`, correct a misspelt name against the reference or the document, correct or remove a named argument, add the type keyword an `na` initialiser needs, widen a declared type, rename a variable that shadows a built-in throughout the file, and add a missing `//@version=6`.
- Tests for the formatter and the quick fixes, and a check that every snippet and fixture survives a formatting round trip unchanged.

### Changed

- Compiler diagnostics keep the placeholder values the compiler sends, which is what the quick fixes read.

## [3.1.0] - 2026-09-08

### Added
Expand Down
43 changes: 38 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<br>
</h1>

<h4 align="center">Completion, hover documentation, signature help, 97 snippets, themes and compiler diagnostics for TradingView Pine Script® v6 in Visual Studio Code.</h4>
<h4 align="center">Completion, hover documentation, signature help, formatting, quick fixes, 97 snippets and themes for TradingView Pine Script® v6 in Visual Studio Code.</h4>

<p align="center">
<a href="https://marketplace.visualstudio.com/items?itemName=ex-codes.pine-script-syntax-highlighter"><img src="https://vsmarketplacebadges.dev/version-short/ex-codes.pine-script-syntax-highlighter.svg?style=flat-square&label=marketplace&color=blue" alt="Marketplace version"></a>
Expand All @@ -21,7 +21,7 @@

## Why you will like it

Open a `.pine` file and the editor already knows the language: every v6 built-in completes with its signature, hovering anything shows the reference entry, parameter hints follow you through a call, and **97 snippets** turn a prefix and <kbd>Tab</kbd> into a full indicator, a strategy exit block or a Bollinger Bands section. Nothing leaves your machine unless you opt in, and the whole thing weighs less than a megabyte.
Open a `.pine` file and the editor already knows the language: every v6 built-in completes with its signature, hovering anything shows the reference entry, parameter hints follow you through a call, **Format Document** lays the script out the way Pine wants it, and **97 snippets** turn a prefix and <kbd>Tab</kbd> into a full indicator, a strategy exit block or a Bollinger Bands section. Nothing leaves your machine unless you opt in, and the whole thing weighs less than a megabyte.

## Quick start

Expand All @@ -30,7 +30,8 @@ Open a `.pine` file and the editor already knows the language: every v6 built-in
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 <kbd>Tab</kbd> to drop in a working building block.
6. Press <kbd>F1</kbd> and type `Pine Script:` to see the commands: new files from templates, docstrings, type annotations and the reference.
6. Press <kbd>Shift</kbd>+<kbd>Alt</kbd>+<kbd>F</kbd> (<kbd>Shift</kbd>+<kbd>Option</kbd>+<kbd>F</kbd> on macOS) to format the file: blocks get their four spaces, operators and arguments get their spacing, and nothing else moves.
7. Press <kbd>F1</kbd> and type `Pine Script:` to see the commands: new files from templates, docstrings, type annotations and the reference.

## Features

Expand Down Expand Up @@ -73,13 +74,43 @@ A few worth trying first:
- `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.

### 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:

```pine
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.
Expand Down Expand Up @@ -113,6 +144,7 @@ The grammar and the documentation data are generated from the v6 reference, so v
| `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 |

## Privacy

Expand Down Expand Up @@ -140,9 +172,10 @@ src/
reference.json full v6 documentation, generated by scripts/scrape-reference.mjs
extension/
core/ pure TypeScript: tokenizer, document model, completion context,
type inference, docstrings, templates, TradingView client
type inference, docstrings, formatter, quick fixes, templates,
TradingView client
providers/ VS Code adapters: completion, hover, signature help, symbols,
code actions, diagnostics, library index
formatting, code actions, diagnostics, library index
commands/ command implementations
scripts/
build-grammar.mjs compiles src/ into syntaxes/pinescript.tmLanguage.json and
Expand Down
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "pine-script-syntax-highlighter",
"displayName": "Pine Script Syntax Highlighter",
"description": "Pine Script v6 for Visual Studio Code: highlighting, completion, hover documentation, signature help, snippets, themes and compiler diagnostics.",
"version": "3.1.0",
"version": "3.2.0",
"publisher": "ex-codes",
"author": {
"name": "Yankı Küçük",
Expand Down Expand Up @@ -74,7 +74,8 @@
"[pinescript]": {
"editor.tabSize": 4,
"editor.insertSpaces": true,
"editor.detectIndentation": false
"editor.detectIndentation": false,
"editor.defaultFormatter": "ex-codes.pine-script-syntax-highlighter"
}
},
"configuration": {
Expand Down Expand Up @@ -109,6 +110,11 @@
"type": "boolean",
"default": false,
"description": "Send the document text to the TradingView compiler to show errors and warnings. Off by default because the full script leaves your machine."
},
"pinescript.format.enabled": {
"type": "boolean",
"default": true,
"description": "Format Pine documents on request, indenting blocks with four spaces and spacing operators and arguments."
}
}
},
Expand Down
5 changes: 4 additions & 1 deletion src/extension/core/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export interface CompileDiagnostic {
message: string;
severity: 'error' | 'warning';
code: string | null;
/** The compiler's own placeholder values, which the quick fixes read. */
ctx: Record<string, string> | undefined;
}

function render(issue: RawIssue): string {
Expand All @@ -19,7 +21,7 @@ function one(issue: RawIssue, severity: 'error' | 'warning', lineCount: number):
const startCol = Math.max(0, (issue.start?.column ?? 1) - 1);
const endLine = Math.min(maxLine, Math.max(0, (issue.end?.line ?? issue.start?.line ?? 1) - 1));
const endCol = endLine === line ? Math.max(startCol, (issue.end?.column ?? issue.start?.column ?? 1) - 1) : startCol;
return { line, startCol, endCol, message: render(issue), severity, code: issue.code ?? null };
return { line, startCol, endCol, message: render(issue), severity, code: issue.code ?? null, ctx: issue.ctx };
}

export function toDiagnostics(result: CompileResult, lineCount: number): CompileDiagnostic[] {
Expand All @@ -35,6 +37,7 @@ export function toDiagnostics(result: CompileResult, lineCount: number): Compile
message: result.reason ?? 'The TradingView compiler rejected the script.',
severity: 'error',
code: null,
ctx: undefined,
});
}
return out;
Expand Down
Loading
Loading