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
23 changes: 23 additions & 0 deletions val_highlight/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
## Unreleased

### Added

* **`EditingSyntax`** — how a language is edited: its line and block
comment markers, bracket pairs and quote characters. Every built-in
language declares one; set `Grammar.editing` on your own, or let
`EditingSyntax.of` derive it from the grammar's `LineComment`,
`BlockComment` and `QuotedString` blocks. `Grammar.extend` takes an
`editing` argument.
* **`HighlightResult.matchingBracket`** — finds the matching bracket by
walking tokens, skipping brackets inside strings and comments.
* **`HighlightResult.isStringOrCommentAt`**, **`isCommentAt`** and
**`isInsideStringOrComment`** — tell code apart from strings and
comments, at a character or at a caret position. Interpolations inside
strings count as code.
* **`ScopeTable.isStringOrComment`** and **`isComment`** — the same
questions for a scope stack, answered from a table built once per stack.

### Changed

* Markdown highlights HTML comments (`<!-- -->`) as comments.

## 0.1.0

First release.
Expand Down
27 changes: 27 additions & 0 deletions val_highlight/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,28 @@ final document = IncrementalHighlighter(language: dartLanguage, text: source);
final updated = document.update(editedSource);
```

Results also answer the questions an editor asks, using the tokens, so
brackets and quotes inside strings and comments are never mistaken for
code:

```dart
result.matchingBracket(offset); // the matching bracket, or -1
result.isStringOrCommentAt(offset); // the character at offset
result.isInsideStringOrComment(caret); // text typed at a caret position
```

Each language also describes how it is edited — its comment markers,
bracket pairs and quote characters — as an `EditingSyntax`:

```dart
final syntax = EditingSyntax.of(pythonLanguage);
syntax.lineComment; // '#'
syntax.quotes; // '"\''
```

Set `editing:` on your own grammar, or leave it out and it is derived from
the grammar's `LineComment`, `BlockComment` and `QuotedString` blocks.

## 🔧 Changing a built-in language

```dart
Expand All @@ -178,6 +200,11 @@ final withTodos = dartLanguage.extend(

// Replace a named part of a grammar. `grammar.repository.keys` lists them.
final quiet = dartLanguage.extend(repository: {'numbers': []});

// Change how it is edited: comment markers, brackets and quotes.
final backticks = dartLanguage.extend(
editing: EditingSyntax.cStyle.copyWith(quotes: '"\'`'),
);
```

A new scope such as `todo` only needs a theme entry:
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/bash.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Bash and POSIX shell scripts.
const bashLanguage = Grammar(
name: 'bash',
editing: EditingSyntax(lineComment: '#', quotes: '"\'`'),
aliases: ['sh', 'shell', 'zsh', 'console'],
fileExtensions: ['sh', 'bash', 'zsh'],
shebangs: ['bash', 'sh', 'zsh', 'dash', 'ksh'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/batch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Windows batch files (`.bat`, `.cmd`).
const batchLanguage = Grammar(
name: 'batch',
editing: EditingSyntax(lineComment: 'REM', quotes: '"'),
aliases: ['bat', 'cmd', 'dos'],
fileExtensions: ['bat', 'cmd'],
caseInsensitive: true,
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/c.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const cCommonRules = <Rule>[
/// C.
const cLanguage = Grammar(
name: 'c',
editing: EditingSyntax.cStyle,
aliases: ['h'],
fileExtensions: ['c', 'h'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/clojure.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Clojure, ClojureScript and EDN.
const clojureLanguage = Grammar(
name: 'clojure',
editing: EditingSyntax(lineComment: ';', quotes: '"'),
aliases: ['clj', 'cljs', 'cljc', 'edn'],
fileExtensions: ['clj', 'cljs', 'cljc', 'edn'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/cmake.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const _controlCommands = [
/// CMake.
const cmakeLanguage = Grammar(
name: 'cmake',
editing: EditingSyntax(lineComment: '#', quotes: '"'),
aliases: ['cmakelists'],
fileExtensions: ['cmake'],
fileNames: ['CMakeLists.txt'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/cpp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'c.dart';
/// C++ (C++23).
const cppLanguage = Grammar(
name: 'cpp',
editing: EditingSyntax.cStyle,
aliases: ['c++', 'cxx', 'hpp', 'cc', 'hh'],
fileExtensions: ['cpp', 'cc', 'cxx', 'hpp', 'hh', 'hxx', 'ipp', 'ixx'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/csharp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// C# (12+).
const csharpLanguage = Grammar(
name: 'csharp',
editing: EditingSyntax.cStyle,
aliases: ['cs', 'c#'],
fileExtensions: ['cs', 'csx'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/css.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// CSS, including nesting and custom properties.
const cssLanguage = Grammar(
name: 'css',
editing: EditingSyntax(blockComment: ('/*', '*/')),
fileExtensions: ['css'],
caseInsensitive: true,
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Dart.
const dartLanguage = Grammar(
name: 'dart',
editing: EditingSyntax.cStyle,
fileExtensions: ['dart'],
rules: [
IncludeRule('comments'),
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/diff.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Unified and git diffs.
const diffLanguage = Grammar(
name: 'diff',
editing: EditingSyntax.none,
aliases: ['patch'],
fileExtensions: ['diff', 'patch'],
signatures: [r'^@@ -\d+(?:,\d+)? \+\d+(?:,\d+)? @@', r'^diff --git '],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/dockerfile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import '../advanced.dart';
/// following `\` continuations. Heredocs (`RUN <<EOF … EOF`) are strings.
const dockerfileLanguage = Grammar(
name: 'dockerfile',
editing: EditingSyntax.hashStyle,
aliases: ['docker', 'containerfile'],
fileExtensions: ['dockerfile'],
fileNames: ['Dockerfile', 'Containerfile'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/elixir.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Elixir.
const elixirLanguage = Grammar(
name: 'elixir',
editing: EditingSyntax.hashStyle,
aliases: ['ex', 'exs'],
fileExtensions: ['ex', 'exs', 'heex'],
fileNames: ['mix.lock'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/erlang.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Erlang.
const erlangLanguage = Grammar(
name: 'erlang',
editing: EditingSyntax(lineComment: '%'),
aliases: ['erl'],
fileExtensions: ['erl', 'hrl', 'escript'],
fileNames: ['rebar.config'],
Expand Down
5 changes: 5 additions & 0 deletions val_highlight/lib/languages/fsharp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import '../advanced.dart';
/// F#.
const fsharpLanguage = Grammar(
name: 'fsharp',
editing: EditingSyntax(
lineComment: '//',
blockComment: ('(*', '*)'),
quotes: '"',
),
aliases: ['fs', 'f#'],
fileExtensions: ['fs', 'fsi', 'fsx'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/generic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import '../advanced.dart';
/// `allLanguagesRegistry()` and of `CodeView` when no language is given.
const genericLanguage = Grammar(
name: 'generic',
editing: EditingSyntax.cStyle,
detectable: false,
rules: [
TokenRule(r'^#!.*$', scope: Scopes.meta),
Expand Down
5 changes: 5 additions & 0 deletions val_highlight/lib/languages/go.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import '../advanced.dart';
/// Go.
const goLanguage = Grammar(
name: 'go',
editing: EditingSyntax(
lineComment: '//',
blockComment: ('/*', '*/'),
quotes: '"\'`',
),
aliases: ['golang'],
fileExtensions: ['go'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/graphql.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// GraphQL queries and schema definitions.
const graphqlLanguage = Grammar(
name: 'graphql',
editing: EditingSyntax(lineComment: '#', quotes: '"'),
aliases: ['gql'],
fileExtensions: ['graphql', 'gql', 'graphqls'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/groovy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Groovy, including Gradle build scripts (`build.gradle`).
const groovyLanguage = Grammar(
name: 'groovy',
editing: EditingSyntax.cStyle,
aliases: ['gradle'],
fileExtensions: ['groovy', 'gradle', 'gvy', 'gy', 'gsh'],
fileNames: ['Jenkinsfile'],
Expand Down
5 changes: 5 additions & 0 deletions val_highlight/lib/languages/haskell.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import '../advanced.dart';
/// Haskell.
const haskellLanguage = Grammar(
name: 'haskell',
editing: EditingSyntax(
lineComment: '--',
blockComment: ('{-', '-}'),
quotes: '"',
),
aliases: ['hs'],
fileExtensions: ['hs', 'lhs'],
signatures: [
Expand Down
5 changes: 5 additions & 0 deletions val_highlight/lib/languages/hcl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import '../advanced.dart';
/// HCL, including Terraform and OpenTofu configuration.
const hclLanguage = Grammar(
name: 'hcl',
editing: EditingSyntax(
lineComment: '#',
blockComment: ('/*', '*/'),
quotes: '"',
),
aliases: ['terraform', 'tf', 'opentofu'],
fileExtensions: ['tf', 'tfvars', 'hcl'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/html.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'javascript.dart';
/// HTML, with embedded CSS in `<style>` and JavaScript in `<script>`.
const htmlLanguage = Grammar(
name: 'html',
editing: EditingSyntax.markupStyle,
// Vue and Svelte single-file components are HTML with embedded script and
// style elements.
aliases: ['htm', 'xhtml', 'vue', 'svelte'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/ini.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// INI files and Java `.properties` files.
const iniLanguage = Grammar(
name: 'ini',
editing: EditingSyntax(lineComment: ';'),
aliases: ['properties', 'conf', 'cfg', 'editorconfig', 'gitconfig'],
fileExtensions: ['ini', 'cfg', 'conf', 'properties', 'editorconfig'],
fileNames: ['.editorconfig', '.gitconfig', 'gradle.properties'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/java.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Java (21+), including records, sealed types and text blocks.
const javaLanguage = Grammar(
name: 'java',
editing: EditingSyntax.cStyle,
aliases: ['jsp'],
fileExtensions: ['java'],
signatures: [
Expand Down
5 changes: 5 additions & 0 deletions val_highlight/lib/languages/javascript.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import '../src/languages/ecmascript.dart';
/// JavaScript, including JSX-free modern syntax.
const javascriptLanguage = Grammar(
name: 'javascript',
editing: EditingSyntax(
lineComment: '//',
blockComment: ('/*', '*/'),
quotes: '"\'`',
),
aliases: ['js', 'mjs', 'cjs'],
fileExtensions: ['js', 'mjs', 'cjs'],
shebangs: ['node', 'deno', 'bun'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/json.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// JSON, including the comments allowed by JSONC.
const jsonLanguage = Grammar(
name: 'json',
editing: EditingSyntax(quotes: '"'),
aliases: ['jsonc'],
fileExtensions: ['json', 'jsonc'],
signatures: [
Expand Down
5 changes: 5 additions & 0 deletions val_highlight/lib/languages/jsx.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import '../src/languages/ecmascript.dart';
/// JavaScript with JSX elements, as used by React.
const jsxLanguage = Grammar(
name: 'jsx',
editing: EditingSyntax(
lineComment: '//',
blockComment: ('/*', '*/'),
quotes: '"\'`',
),
aliases: ['react'],
fileExtensions: ['jsx'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/julia.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Julia.
const juliaLanguage = Grammar(
name: 'julia',
editing: EditingSyntax(lineComment: '#', blockComment: ('#=', '=#')),
aliases: ['jl'],
fileExtensions: ['jl'],
shebangs: ['julia'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/kotlin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Kotlin, including Kotlin script (`.kts`, such as `build.gradle.kts`).
const kotlinLanguage = Grammar(
name: 'kotlin',
editing: EditingSyntax.cStyle,
aliases: ['kt', 'kts'],
fileExtensions: ['kt', 'kts'],
shebangs: ['kotlin'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/latex.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// LaTeX and TeX.
const latexLanguage = Grammar(
name: 'latex',
editing: EditingSyntax(lineComment: '%', quotes: ''),
aliases: ['tex'],
fileExtensions: ['tex', 'sty', 'cls', 'ltx', 'bib'],
// Inline math can wrap across lines, but never across a blank line.
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/less.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const _atRules =
/// Less.
const lessLanguage = Grammar(
name: 'less',
editing: EditingSyntax.cStyle,
fileExtensions: ['less'],
caseInsensitive: true,
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/lua.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Lua 5.4, including Luau-style usage in game and editor scripts.
const luaLanguage = Grammar(
name: 'lua',
editing: EditingSyntax(lineComment: '--', blockComment: ('--[[', ']]')),
aliases: ['luau'],
fileExtensions: ['lua', 'luau', 'rockspec'],
shebangs: ['lua', 'luajit'],
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/makefile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// Make (GNU make syntax).
const makefileLanguage = Grammar(
name: 'makefile',
editing: EditingSyntax.hashStyle,
aliases: ['make', 'mk', 'mak'],
fileExtensions: ['mk', 'mak'],
fileNames: ['Makefile', 'GNUmakefile', 'makefile'],
Expand Down
2 changes: 2 additions & 0 deletions val_highlight/lib/languages/markdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import '../advanced.dart';
/// registry; otherwise their content is scoped as [Scopes.code].
const markdownLanguage = Grammar(
name: 'markdown',
editing: EditingSyntax(blockComment: ('<!--', '-->'), quotes: '`'),
aliases: ['md', 'mkdown', 'mkd'],
fileExtensions: ['md', 'markdown', 'mkd'],
// Inline code can wrap across lines, but never across a blank line.
Expand Down Expand Up @@ -39,6 +40,7 @@ const markdownLanguage = Grammar(
endReferencesBegin: true,
rules: [TokenRule(r'[^\n]+', scope: Scopes.code)],
),
BlockComment('<!--', '-->'),
TokenRule(r'^#{1,6}(?=[ \t]|$).*$', scope: Scopes.heading),
TokenRule(r'^.+\n(?:=+|-+)[ \t]*$', scope: Scopes.heading),
TokenRule(r'^[ \t]*(?:[-*_][ \t]*){3,}$', scope: Scopes.meta),
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/nasm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// x86 assembly in NASM/YASM syntax.
const nasmLanguage = Grammar(
name: 'nasm',
editing: EditingSyntax(lineComment: ';', quotes: '"\'`'),
aliases: ['asm', 'x86asm', 'assembly'],
fileExtensions: ['asm', 'nasm', 's'],
caseInsensitive: true,
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/nginx.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const _blocks =
/// nginx configuration.
const nginxLanguage = Grammar(
name: 'nginx',
editing: EditingSyntax.hashStyle,
aliases: ['nginxconf'],
fileNames: ['nginx.conf'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/objectivec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'c.dart';
/// Objective-C and Objective-C++.
const objectiveCLanguage = Grammar(
name: 'objectivec',
editing: EditingSyntax.cStyle,
aliases: ['objc', 'objective-c', 'obj-c', 'objectivecpp', 'objc++'],
fileExtensions: ['m', 'mm'],
signatures: [
Expand Down
1 change: 1 addition & 0 deletions val_highlight/lib/languages/ocaml.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import '../advanced.dart';
/// OCaml.
const ocamlLanguage = Grammar(
name: 'ocaml',
editing: EditingSyntax(blockComment: ('(*', '*)'), quotes: '"'),
aliases: ['ml'],
fileExtensions: ['ml', 'mli'],
signatures: [
Expand Down
Loading
Loading