From 7a1b69f1537fad8b2d78cee94754cfa38d343618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dai=20L=C3=B3pez?= Date: Sat, 25 Jul 2026 22:55:02 -0600 Subject: [PATCH 01/16] feat: regenerate the syntax from the tree-sitter grammar dictionary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrites the plugin around keywords.json, a pinned copy of the dictionary the tree-sitter-gnuplot grammar emits, so both projects recognise the same 724 keywords with the same abbreviation minimums. The abbreviation system now costs no regexes at all. Vim's `syn keyword` already understands `xran[ge]` as "xran plus an optional tail", which is exactly what a (keyword, min_chars) pair means, so the whole table becomes plain keyword lists. The previous file expressed the same idea with variable-width lookbehind — patterns like `\v(((un)?set|show) .*)@<=()` — roughly 150 of which are replaced by generated lists. Two bugs the rewrite removes: - ftdetect never worked. `au ... *.pal, *.plt, ...` is a comma-separated pattern list, so the space after each comma started a new pattern; Vim parsed the remainder as a command and raised `E20: Mark not set`. No filetype was set for any extension. - Four `syn match` patterns opened with `"\n(` instead of `"\v(`, so they matched a literal newline and never fired: two style boxplot rules, one terminal-name rule and one png option rule. Also adds ftplugin (commentstring, comments, formatoptions, iskeyword), datablock and format-specifier highlighting, `:help gnuplot`, and a headless test suite built on Vim's own assert_* that runs under both Vim and Neovim. Groups are emitted in reverse-priority order because Vim resolves a keyword defined twice to the last definition: `p` is both `p[lot]` and `p[oints]`, and the command verb is the more valuable of the two to get right. --- .editorconfig | 15 + .gitattributes | 5 + .github/CODE_OF_CONDUCT.md | 132 + .github/CONTRIBUTING.md | 60 + .github/FUNDING.yml | 1 + .github/ISSUE_TEMPLATE/bug.yml | 44 + .github/ISSUE_TEMPLATE/config.yml | 1 + .github/ISSUE_TEMPLATE/feature.yml | 19 + .github/PULL_REQUEST_TEMPLATE.md | 12 + .github/SECURITY.md | 16 + .github/dependabot.yml | 8 + .github/workflows/ci.yml | 56 + .github/workflows/dependabot-auto-merge.yml | 29 + .github/workflows/pr.yml | 30 + .gitignore | 3 + README.md | 128 +- doc/gnuplot.txt | 103 + ftdetect/gnuplot.vim | 10 +- ftplugin/gnuplot.vim | 29 + keywords.json | 5400 +++++++++++++++++++ package.json | 12 + scripts/gen-syntax.mjs | 167 + syntax/gnuplot.vim | 808 +-- tests/run.vim | 100 + 24 files changed, 6595 insertions(+), 593 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/CODE_OF_CONDUCT.md create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/FUNDING.yml create mode 100644 .github/ISSUE_TEMPLATE/bug.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/SECURITY.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/dependabot-auto-merge.yml create mode 100644 .github/workflows/pr.yml create mode 100644 .gitignore create mode 100644 doc/gnuplot.txt create mode 100644 ftplugin/gnuplot.vim create mode 100644 keywords.json create mode 100644 package.json create mode 100644 scripts/gen-syntax.mjs create mode 100644 tests/run.vim diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0ecbc60 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[*.vim] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3db3ea7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text=auto eol=lf + +# Generated from keywords.json — collapse it in review diffs. +syntax/gnuplot.vim linguist-generated=false +keywords.json linguist-generated=true diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b261da5 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +dpezto@icloud.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..a8deb0f --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,60 @@ +# Contributing + +Thanks for helping out. Small, focused PRs merge fastest. + +## Where a change belongs + +`syntax/gnuplot.vim` has two halves. Everything between the generated markers +comes from `keywords.json` and must not be hand edited — CI fails if the +committed block does not match what the generator produces. Everything outside +the markers (comments, strings, numbers, operators, control-flow words, the +highlight links) is hand maintained and edited directly. + +To add or correct a keyword, fix it upstream in +[tree-sitter-gnuplot](https://github.com/dpezto/tree-sitter-gnuplot), copy the +refreshed `keywords.json` here, and regenerate. Keeping the two in step is the +point of the arrangement; patching the generated block locally defeats it. + +## Development + +```sh +npm run gen:syntax # regenerate from keywords.json +npm run check:syntax # what CI runs +nvim --headless -u NONE -S tests/run.vim # assertions +vim -es -u NONE -S tests/run.vim # same, under Vim +``` + +`tests/run.vim` uses Vim's own `assert_*` functions and exits non-zero if +anything lands in `v:errors`. Add a case for any behaviour a change could +break. The assertions read the raw syntax group under a given word rather than +the translated highlight group, because Vim collapses `Conditional`, `Repeat` +and `Keyword` into `Statement`, which would make most of them vacuous. + +Verify claims about what gnuplot accepts against a real gnuplot, and check by +resolution rather than acceptance: gnuplot takes an ambiguous abbreviation and +silently resolves it to whichever entry comes first in its own table, so +`set encoding iso` succeeding does not mean `iso` names the encoding you meant. + +## Commits and PR titles + +PRs are squash-merged, so **PR titles must follow +[Conventional Commits](https://www.conventionalcommits.org)** (`feat: …`, +`fix: …`, `docs: …`). CI checks the title. + +## AI-assisted contributions + +AI assistance (Copilot, Claude, etc.) is welcome, with three rules: + +1. **Disclose it** in the PR description (a one-liner is fine). +2. **You must understand and have tested the change yourself** — run the + assertions locally. You are the author; "the model wrote it" is not a review + response. +3. **No unreviewed dumps.** Large AI-generated diffs with no accompanying + reasoning, and AI-generated bug reports without a reproducible snippet, will + be closed. + +## Bug reports + +A minimal gnuplot snippet (confirmed accepted by `gnuplot` itself) plus what +you expected the highlighting to be turns a week of back-and-forth into a +same-day fix. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..b7a1e20 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [dpezto] diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..00d0114 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,44 @@ +name: Bug report +description: A gnuplot construct highlights wrong, or not at all +labels: [bug] +body: + - type: input + id: version + attributes: + label: gnuplot.vim version / commit + placeholder: "a commit SHA" + validations: + required: true + - type: input + id: editor + attributes: + label: Editor + placeholder: "Neovim 0.12 / Vim 9.1" + validations: + required: true + - type: textarea + id: snippet + attributes: + label: Minimal gnuplot snippet + description: Smallest input that highlights wrong. Confirm it is accepted by `gnuplot` itself. + render: gnuplot + validations: + required: true + - type: textarea + id: behavior + attributes: + label: Expected vs actual + description: >- + Which word, and what it should be versus what it is. `:echo + synIDattr(synID(line("."), col("."), 1), "name")` with the cursor on the + word gives the group it currently gets. + validations: + required: true + - type: checkboxes + id: known + attributes: + label: Known limits + description: See the "Known limits" section of the README. + options: + - label: This is not a single-letter abbreviation that means two things (`p`, `f`) + - label: This is not an option head whose minimum is stricter upstream (`set xr`) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml new file mode 100644 index 0000000..a254f83 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -0,0 +1,19 @@ +name: Feature request +description: A gnuplot command/option not yet supported, or a query improvement +labels: [enhancement] +body: + - type: textarea + id: problem + attributes: + label: What's missing + description: The gnuplot syntax or highlight/fold/injection behavior the grammar doesn't handle yet. + validations: + required: true + - type: textarea + id: example + attributes: + label: Example + description: A gnuplot snippet showing the construct, and (if known) the relevant section of the gnuplot 6 docs. + render: gnuplot + validations: + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..370d802 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,12 @@ + + +## What & why + +## Checklist + +- [ ] `npm run check:syntax` passes — the generated block matches `keywords.json` +- [ ] `nvim --headless -u NONE -S tests/run.vim` passes +- [ ] Added or extended a case in `tests/run.vim` for the new behaviour +- [ ] Any claim about what gnuplot accepts was checked against a real gnuplot, + by resolution rather than acceptance +- [ ] AI assistance disclosed (if any) — see [CONTRIBUTING](CONTRIBUTING.md) diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..f809c59 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,16 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security vulnerabilities privately via +[GitHub's private vulnerability reporting](https://github.com/dpezto/gnuplot.vim/security/advisories/new) +rather than filing a public issue. + +This is a parser grammar (no server component, no runtime secrets). The main +risk surface is: + +- The external scanner (`src/scanner.c`): a crafted input causing out-of-bounds + reads / unbounded memory during parsing in an embedding editor. +- Supply-chain issues in CI (GitHub Actions dependencies). + +Expect an initial response within a few days; this is a solo-maintained project. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..01aa1cc --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + cooldown: + default-days: 5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..dae45ba --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,56 @@ +name: ci +on: + push: + branches: [main] + pull_request: +permissions: + contents: read +jobs: + actionlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: reviewdog/action-actionlint@50842263c20a7c46bd0065b9e624d3c569db061e # v1 + + # vint catches deprecated/unportable VimL that still loads without error + vint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-python@e9d6f990972a57673cdb72ec29e19d42ba28880f # v6 + with: + python-version: "3.x" + - run: pip install vim-vint + - run: vint --style-problem ftdetect ftplugin syntax tests + + # syntax/gnuplot.vim is generated from keywords.json; a hand edit inside the + # markers, or a refreshed dictionary, must not land without regenerating. + generated: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6 + with: + node-version: lts/* + - run: node scripts/gen-syntax.mjs --check + + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + editor: [vim, neovim] + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: rhysd/action-setup-vim@febef33995d6649302e9d88dda81e071b68f16a7 # v1 + id: vim + with: + neovim: ${{ matrix.editor == 'neovim' }} + version: stable + # Both editors run the same assertions; the script calls cquit! on + # failure, which is what fails the job. + - if: matrix.editor == 'neovim' + run: ${{ steps.vim.outputs.executable }} --headless -u NONE -S tests/run.vim + - if: matrix.editor == 'vim' + run: ${{ steps.vim.outputs.executable }} -es -u NONE -S tests/run.vim diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 0000000..26ab331 --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,29 @@ +name: dependabot auto-merge + +# Enable auto-merge on Dependabot PRs for patch/minor bumps. Auto-merge waits +# for the required status checks (branch protection on main) before merging, so +# a bump that breaks CI is never merged. Major bumps are left for manual review. +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + if: github.actor == 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - name: Fetch Dependabot metadata + id: meta + uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Enable auto-merge for patch/minor + if: >- + steps.meta.outputs.update-type == 'version-update:semver-patch' + || steps.meta.outputs.update-type == 'version-update:semver-minor' + run: gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..7ce75c3 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,30 @@ +name: pr + +on: + pull_request_target: + types: [opened, edited, synchronize, reopened, ready_for_review] + +permissions: + pull-requests: read + +jobs: + # Conventional-commit PR titles: squash merges stay parseable by tooling + title: + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + build + chore + ci + docs + feat + fix + perf + refactor + revert + style + test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d5f2fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +.DS_Store +doc/tags diff --git a/README.md b/README.md index 95499b2..28da68e 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,74 @@ -# Gnuplot syntax highlighting for Vim -[![PRs Welcome][prs-badge]](https://makeapullrequest.com) +# gnuplot.vim -I built this package from the ground up as a follow up to the work made by [James Eberle](https://www.vim.org/scripts/script.php?script_id=1737) and [Andrew Rasmussen](https://www.vim.org/scripts/script.php?script_id=4873). +Syntax highlighting for [gnuplot](http://www.gnuplot.info) 6 scripts. -## Notice -The aim of this package is to provide up-to-date support for gnuplot syntax. I'm basing the support for gnuplot 5.5 which is currently in development. +The keyword lists are generated from `keywords.json`, a pinned copy of the +dictionary emitted by the +[tree-sitter-gnuplot](https://github.com/dpezto/tree-sitter-gnuplot) grammar, +so both projects recognise the same words with the same abbreviation rules. -## Installation +## Install -### Using a plugin manager -This plugin follows the standard runtime path structure, and as such it can be installed with a variety of plugin managers: +Standard runtime path layout, so any plugin manager works: -| Plugin Manager | Install with... | -| ------------- | ------------- | -| [Pathogen][1] | `git clone https://github.com/dpezto/gnuplot.vim ~/.vim/bundle/gnuplot` | -| [Vundle][2] | `Plugin 'dpezto/gnuplot.vim'` | -| [Plug][3] | `Plug 'dpezto/gnuplot.vim'` | -| [minpac][4] | `call minpac#add('dpezto/gnuplot.vim')` | -| pack feature (native Vim 8 package feature)| `git clone https://github.com/dpezto/gnuplot.vim ~/.vim/pack/plugins/start/gnuplot` | +| Manager | Install with | +| --- | --- | +| [lazy.nvim](https://github.com/folke/lazy.nvim) | `{ "dpezto/gnuplot.vim" }` | +| [vim-plug](https://github.com/junegunn/vim-plug) | `Plug 'dpezto/gnuplot.vim'` | +| [Vundle](https://github.com/VundleVim/Vundle.vim) | `Plugin 'dpezto/gnuplot.vim'` | +| [minpac](https://github.com/k-takata/minpac) | `call minpac#add('dpezto/gnuplot.vim')` | +| [pathogen](https://github.com/tpope/vim-pathogen) | `git clone https://github.com/dpezto/gnuplot.vim ~/.vim/bundle/gnuplot` | +| native packages | `git clone https://github.com/dpezto/gnuplot.vim ~/.vim/pack/plugins/start/gnuplot` | -### Manual installation -In order to have vim automatically detect gnuplot files, you need to have -[`ftplugins`](http://vimhelp.appspot.com/usr_05.txt.html#ftplugins) enabled (e.g. by having this line in your [`.vimrc`](http://vimhelp.appspot.com/starting.txt.html#.vimrc) file: +No configuration is needed. `:help gnuplot` documents the highlight groups. -```vim -:filetype plugin on -``` +## What it recognises -The plugin already sets up some logic to detect gnuplot files. In order that the -gnuplot filetype plugin is loaded correctly, vim needs to be enabled to load -[`filetype-plugins`](http://vimhelp.appspot.com/filetype.txt.html#filetype-plugins). This can be ensured by putting a line like this in your -[`.vimrc`](http://vimhelp.appspot.com/starting.txt.html#.vimrc): +`.gnu`, `.gnuplot`, `.gp`, `.gpi`, `.pal`, `.plot` and `.plt`, plus any file +whose first line is a shebang naming gnuplot. -```vim -:filetype plugin on -``` -(see also [:filetype-plugin-on](http://vimhelp.appspot.com/filetype.txt.html#:filetype-plugin-on)). - -In case this did not work, you need to setup vim like this: - -To have Vim automatically detect gnuplot files, you need to do the following. - -1. Create your user runtime directory if you do not have one yet. This - directory needs to be in your 'runtime' path. In Unix this would - typically the ~/.vim directory, while in Windows this is usually your - ~/vimfiles directory. Use :echo expand("~") to find out, what Vim thinks - your user directory is. - To create this directory, you can do: - ```vim - :!mkdir ~/.vim - ``` - for Unix and - ```vim - :!mkdir ~/vimfiles - ``` - for Windows. - -2. In that directory you create a file that will detect gnuplot files. -```vim -if exists("did_load_filetypes") - finish -endif -augroup filetypedetect -au! BufNewFile,BufRead *.plt,*.plot,*.gnuplot,*.gnu,*.gp setf gnuplot -augroup END -``` +Highlighting covers commands, set/show options and their suboptions, toggles, +enumerated values, plot styles, plot-element modifiers, terminal names, the +built-in function and variable sets, datablocks, macros, numbers with unit +suffixes, and both string flavours. + +### Abbreviations + +gnuplot lets most keywords be shortened, and so does this plugin — `set xran` +highlights exactly like `set xrange`. The generated lists spell that as +`xran[ge]`, which is `:syn-keyword`'s own notation for an optional tail, so the +whole abbreviation system is carried over without a single regular expression. -You save this file as "filetype.vim" in your user runtime diretory: -```vim -:w ~/.vim/filetype.vim +## Known limits + +Vim keywords carry no context, so a word meaning two things in gnuplot gets one +colour. `p` starts a plot command and also names the `points` style; the command +wins. `f` is the `fit` command, so in `f(x) = x**2` the `f` reads as a command +rather than a function definition. + +Some option heads are currently stricter than gnuplot: the dictionary records +`xrange` with a four character minimum, so `set xr` goes unhighlighted even +though gnuplot accepts it. That is a property of the upstream dictionary and is +fixed there rather than patched here. + +## Development + +```sh +npm run gen:syntax # regenerate from keywords.json +npm run check:syntax # fail if the committed file is stale +nvim --headless -u NONE -S tests/run.vim # run the assertions ``` -3. To be able to use your new filetype.vim detection, you need to restart Vim. Vim will then load the gnuplot filetype plugin for all files whose names end with .plt, .plot, .gnuplot, .gnu, .gp. +Only the block between the generated markers in `syntax/gnuplot.vim` is +machine written; the rest of the file is hand maintained. To pick up new +keywords, copy `keywords.json` from the grammar repository and regenerate. + +## Credits -## Status -This began as a personal project since I prefer the results of the plots made with gnuplot, so most of the syntax currently in the file is for my use case. Despite this, the package can handle almost all use cases of gnuplot. I'm looking forward to refine the syntax highlighting. +A ground-up rewrite following earlier work by +[James Eberle](https://www.vim.org/scripts/script.php?script_id=1737) and +[Andrew Rasmussen](https://www.vim.org/scripts/script.php?script_id=4873). -[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIGlkPSJzdmcyIiB3aWR0aD0iNjQ1IiBoZWlnaHQ9IjU4NSIgdmVyc2lvbj0iMS4wIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPiA8ZyBpZD0ibGF5ZXIxIj4gIDxwYXRoIGlkPSJwYXRoMjQxNyIgZD0ibTI5Ny4zIDU1MC44N2MtMTMuNzc1LTE1LjQzNi00OC4xNzEtNDUuNTMtNzYuNDM1LTY2Ljg3NC04My43NDQtNjMuMjQyLTk1LjE0Mi03Mi4zOTQtMTI5LjE0LTEwMy43LTYyLjY4NS01Ny43Mi04OS4zMDYtMTE1LjcxLTg5LjIxNC0xOTQuMzQgMC4wNDQ1MTItMzguMzg0IDIuNjYwOC01My4xNzIgMTMuNDEtNzUuNzk3IDE4LjIzNy0zOC4zODYgNDUuMS02Ni45MDkgNzkuNDQ1LTg0LjM1NSAyNC4zMjUtMTIuMzU2IDM2LjMyMy0xNy44NDUgNzYuOTQ0LTE4LjA3IDQyLjQ5My0wLjIzNDgzIDUxLjQzOSA0LjcxOTcgNzYuNDM1IDE4LjQ1MiAzMC40MjUgMTYuNzE0IDYxLjc0IDUyLjQzNiA2OC4yMTMgNzcuODExbDMuOTk4MSAxNS42NzIgOS44NTk2LTIxLjU4NWM1NS43MTYtMTIxLjk3IDIzMy42LTEyMC4xNSAyOTUuNSAzLjAzMTYgMTkuNjM4IDM5LjA3NiAyMS43OTQgMTIyLjUxIDQuMzgwMSAxNjkuNTEtMjIuNzE1IDYxLjMwOS02NS4zOCAxMDguMDUtMTY0LjAxIDE3OS42OC02NC42ODEgNDYuOTc0LTEzNy44OCAxMTguMDUtMTQyLjk4IDEyOC4wMy01LjkxNTUgMTEuNTg4LTAuMjgyMTYgMS44MTU5LTI2LjQwOC0yNy40NjF6IiBmaWxsPSIjZGQ1MDRmIi8%2BIDwvZz48L3N2Zz4%3D +## License -[1]: https://github.com/tpope/vim-pathogen -[2]: https://github.com/VundleVim/Vundle.vim -[3]: https://github.com/junegunn/vim-plug -[4]: https://github.com/k-takata/minpac/ +[MIT](LICENSE) diff --git a/doc/gnuplot.txt b/doc/gnuplot.txt new file mode 100644 index 0000000..f82a05e --- /dev/null +++ b/doc/gnuplot.txt @@ -0,0 +1,103 @@ +*gnuplot.txt* Syntax highlighting for gnuplot 6 + +============================================================================== +CONTENTS *gnuplot-contents* + + 1. Introduction ........................... |gnuplot-introduction| + 2. Filetype detection ..................... |gnuplot-ftdetect| + 3. Highlight groups ....................... |gnuplot-groups| + 4. Abbreviations .......................... |gnuplot-abbreviations| + 5. Known limits ........................... |gnuplot-limits| + 6. Regenerating ........................... |gnuplot-regenerating| + +============================================================================== +1. INTRODUCTION *gnuplot-introduction* + +Syntax highlighting for gnuplot 6 scripts. + +The keyword lists are generated from `keywords.json`, a pinned copy of the +dictionary emitted by the tree-sitter-gnuplot grammar. Both projects therefore +recognise the same words with the same abbreviation rules. + +============================================================================== +2. FILETYPE DETECTION *gnuplot-ftdetect* + +The filetype is set for these extensions: > + + .gnu .gnuplot .gp .gpi .pal .plot .plt + +and for any file whose first line is a shebang naming gnuplot: > + + #!/usr/bin/env gnuplot + +Note that the stock Vim and Neovim runtimes claim `.gp` and `.gpi` for +PARI/GP. Detection uses |:setf|, which does not override a filetype another +runtime file already set, so on those two extensions whichever detection runs +first wins. + +============================================================================== +3. HIGHLIGHT GROUPS *gnuplot-groups* + +The groups mirror the capture taxonomy of the tree-sitter grammar, where an +alias names the clause family a word belongs to rather than the word itself. + + gnuplotCommand command verb (plot, set, splot) + gnuplotOption set/show option head and its suboptions + gnuplotFlag toggles, {no}X forms, coordinate systems + gnuplotValue enumerated values (degrees, comma, cspline) + gnuplotAttribute plot-element modifier (with, using, title) + gnuplotStyle plot style name (lines, boxes, pm3d) + gnuplotConditional if, else + gnuplotRepeat do, while, for, in + + gnuplotComment gnuplotTodo gnuplotString gnuplotEscape gnuplotFormat + gnuplotDatablock gnuplotDatablockName gnuplotMacro gnuplotNumber + gnuplotConstant gnuplotBuiltinVar gnuplotFunction gnuplotBuiltinFunction + gnuplotOperator gnuplotShell + +Each links to a standard group, so any colorscheme handles them. Override a +link in your |vimrc| after the syntax loads: > + + autocmd ColorScheme * hi link gnuplotStyle Special + +============================================================================== +4. ABBREVIATIONS *gnuplot-abbreviations* + +gnuplot lets most keywords be shortened, and the plugin follows the same +minimums. `set xran [0:1]` and `set xrange [0:1]` highlight identically +because the generated list spells the keyword `xran[ge]`, which is |:syn-keyword|'s +own notation for an optional tail. No regular expressions are involved. + +============================================================================== +5. KNOWN LIMITS *gnuplot-limits* + +Vim keywords carry no context, so a word that means two things in gnuplot gets +one colour. `p` opens a plot command and also names the `points` style; the +command wins. `f` is the `fit` command, so `f(x) = x**2` colours `f` as a +command rather than a function definition. + +Where a word belongs to several tiers the generator picks one, preferring, in +order: command, option, style, attribute, value, flag. + +Some option heads are currently stricter than gnuplot: the dictionary records +`xrange` with a minimum of four characters, so `set xr` is not highlighted even +though gnuplot accepts it. This is a property of the upstream dictionary and is +fixed there, not here. + +============================================================================== +6. REGENERATING *gnuplot-regenerating* + +After refreshing `keywords.json` from the grammar: > + + npm run gen:syntax + +Only the block between the generated markers in `syntax/gnuplot.vim` changes; +everything else in that file is hand written. CI runs +`npm run check:syntax` and fails if the committed file is stale. + +Run the assertions with: > + + nvim --headless -u NONE -S tests/run.vim + vim -es -u NONE -S tests/run.vim + +vim:tw=78:ts=8:ft=help:norl: diff --git a/ftdetect/gnuplot.vim b/ftdetect/gnuplot.vim index 2428fa6..7502397 100644 --- a/ftdetect/gnuplot.vim +++ b/ftdetect/gnuplot.vim @@ -1,2 +1,8 @@ -" Install Filetype detection for Gnuplot files -au BufNewFile,BufRead *.pal, *.plt, *.plot, *.gnuplot, *.gnu, *.gp set filetype=gnuplot +" Filetype detection for gnuplot scripts. +" +" The pattern list is comma separated with no spaces: a space after a comma +" becomes part of the next pattern and stops it matching anything. +au BufNewFile,BufRead *.gnu,*.gnuplot,*.gp,*.gpi,*.pal,*.plot,*.plt setf gnuplot + +" Scripts run through `gnuplot` with a shebang. +au BufNewFile,BufRead * if getline(1) =~# '^#!.*\' | setf gnuplot | endif diff --git a/ftplugin/gnuplot.vim b/ftplugin/gnuplot.vim new file mode 100644 index 0000000..0e7ba73 --- /dev/null +++ b/ftplugin/gnuplot.vim @@ -0,0 +1,29 @@ +" Vim filetype plugin +" Language: gnuplot 6 +" Maintainer: Dai López Jacinto + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpo +set cpo&vim + +setlocal commentstring=#\ %s +setlocal comments=:# +setlocal formatoptions-=t +setlocal formatoptions+=croql + +" gnuplot identifiers and its built-in variables (GPVAL_TERM, STATS_mean_y) +" contain underscores. +setlocal iskeyword+=_ + +" `set xrange [0:1]` and friends: treat brackets as matched pairs. +setlocal matchpairs+=<:> + +let b:undo_ftplugin = 'setlocal commentstring< comments< formatoptions<' + \ . ' iskeyword< matchpairs<' + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/keywords.json b/keywords.json new file mode 100644 index 0000000..f32d74d --- /dev/null +++ b/keywords.json @@ -0,0 +1,5400 @@ +{ + "$comment": "Generated by scripts/gen-keywords.mjs from src/scanner.c and grammar.js — do not edit. Gnuplot keyword dictionary for downstream tooling; entries cover only tokens that are opaque tier symbols in the parse tables.", + "keywords": [ + { + "kw": "absolute", + "tier": "arg", + "min": 1, + "parents": [ + "boxwidth" + ] + }, + { + "kw": "add", + "tier": "arg", + "min": 3 + }, + { + "kw": "angle", + "tier": "arg", + "min": 5, + "parents": [ + "arrow" + ] + }, + { + "kw": "append", + "tier": "arg", + "min": 6, + "parents": [ + "cmd_history" + ] + }, + { + "kw": "arc", + "tier": "arg", + "min": 3 + }, + { + "kw": "aspect", + "tier": "arg", + "min": 6 + }, + { + "kw": "at", + "tier": "arg", + "min": 2 + }, + { + "kw": "auto", + "tier": "arg", + "min": 4, + "parents": [ + "key" + ] + }, + { + "kw": "autofreq", + "tier": "arg", + "min": 4, + "parents": [ + "tics_opts" + ] + }, + { + "kw": "autojustify", + "tier": "arg", + "min": 2, + "parents": [ + "tics_opts" + ] + }, + { + "kw": "autotitle", + "tier": "arg", + "min": 1, + "no": true, + "parents": [ + "key" + ] + }, + { + "kw": "azimuth", + "tier": "arg", + "min": 7 + }, + { + "kw": "bmargin", + "tier": "arg", + "min": 2 + }, + { + "kw": "border", + "tier": "arg", + "min": 2, + "parents": [ + "_pm3d", + "border", + "colorbox", + "fill_style", + "style" + ] + }, + { + "kw": "bottom", + "tier": "arg", + "min": 3 + }, + { + "kw": "bs", + "tier": "arg", + "min": 2 + }, + { + "kw": "bspline", + "tier": "arg", + "min": 1, + "parents": [ + "cntrparam" + ] + }, + { + "kw": "by", + "tier": "arg", + "min": 2 + }, + { + "kw": "cbtics", + "tier": "arg", + "min": 6 + }, + { + "kw": "center", + "tier": "arg", + "min": 6 + }, + { + "kw": "charsize", + "tier": "arg", + "min": 8, + "parents": [ + "t_opts" + ] + }, + { + "kw": "clustered", + "tier": "arg", + "min": 5, + "parents": [ + "style" + ] + }, + { + "kw": "colormap", + "tier": "arg", + "min": 8, + "parents": [ + "palette" + ] + }, + { + "kw": "columnheader", + "tier": "arg", + "min": 3, + "parents": [ + "key", + "plot_element" + ] + }, + { + "kw": "columns", + "tier": "arg", + "min": 7, + "parents": [ + "key" + ] + }, + { + "kw": "columnstacked", + "tier": "arg", + "min": 7, + "parents": [ + "style" + ] + }, + { + "kw": "cubehelix", + "tier": "arg", + "min": 4 + }, + { + "kw": "cubicspline", + "tier": "arg", + "min": 1, + "parents": [ + "cntrparam" + ] + }, + { + "kw": "cycle", + "tier": "arg", + "min": 5 + }, + { + "kw": "cycles", + "tier": "arg", + "min": 6 + }, + { + "kw": "default", + "tier": "arg", + "min": 3, + "parents": [ + "colorbox", + "history", + "key", + "line_style", + "mxtics", + "t_opts", + "tics_opts" + ] + }, + { + "kw": "defined", + "tier": "arg", + "min": 3, + "parents": [ + "palette" + ] + }, + { + "kw": "degrees", + "tier": "arg", + "min": 1, + "parents": [ + "angles" + ] + }, + { + "kw": "delay", + "tier": "arg", + "min": 5 + }, + { + "kw": "discrete", + "tier": "arg", + "min": 8 + }, + { + "kw": "doubleclick", + "tier": "arg", + "min": 4, + "no": true, + "parents": [ + "mouse" + ] + }, + { + "kw": "errorbars", + "tier": "arg", + "min": 5, + "parents": [ + "style" + ] + }, + { + "kw": "file", + "tier": "arg", + "min": 4 + }, + { + "kw": "fillchar", + "tier": "arg", + "min": 8, + "parents": [ + "t_opts" + ] + }, + { + "kw": "firstlinetype", + "tier": "arg", + "min": 5, + "parents": [ + "contourfill" + ] + }, + { + "kw": "fit2rgbformulae", + "tier": "arg", + "min": 7, + "parents": [ + "palette" + ] + }, + { + "kw": "flush", + "tier": "arg", + "min": 5 + }, + { + "kw": "font", + "tier": "arg", + "min": 4 + }, + { + "kw": "fontscale", + "tier": "arg", + "min": 9 + }, + { + "kw": "fontsize", + "tier": "arg", + "min": 8, + "parents": [ + "t_opts" + ] + }, + { + "kw": "format", + "tier": "arg", + "min": 6, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "fraction", + "tier": "arg", + "min": 8 + }, + { + "kw": "from", + "tier": "arg", + "min": 4 + }, + { + "kw": "fsize", + "tier": "arg", + "min": 5 + }, + { + "kw": "function", + "tier": "arg", + "min": 8, + "parents": [ + "style" + ] + }, + { + "kw": "functions", + "tier": "arg", + "min": 4, + "parents": [ + "cmd_save", + "cmd_show", + "palette" + ] + }, + { + "kw": "gamma", + "tier": "arg", + "min": 5 + }, + { + "kw": "gap", + "tier": "arg", + "min": 3 + }, + { + "kw": "gradient", + "tier": "arg", + "min": 4, + "parents": [ + "palette" + ] + }, + { + "kw": "header", + "tier": "arg", + "min": 6, + "no": true + }, + { + "kw": "height", + "tier": "arg", + "min": 6, + "parents": [ + "key" + ] + }, + { + "kw": "horizontal", + "tier": "arg", + "min": 3, + "parents": [ + "colorbox", + "key" + ] + }, + { + "kw": "incremental", + "tier": "arg", + "min": 2, + "parents": [ + "cntrparam" + ] + }, + { + "kw": "inside", + "tier": "arg", + "min": 3, + "parents": [ + "key" + ] + }, + { + "kw": "insidecolor", + "tier": "arg", + "min": 6, + "no": true, + "parents": [ + "isosurface" + ] + }, + { + "kw": "interval", + "tier": "arg", + "min": 6 + }, + { + "kw": "jsdir", + "tier": "arg", + "min": 5 + }, + { + "kw": "keywidth", + "tier": "arg", + "min": 4, + "parents": [ + "key" + ] + }, + { + "kw": "labels", + "tier": "arg", + "min": 3, + "no": true, + "parents": [ + "mouse", + "plot_style", + "style" + ] + }, + { + "kw": "layerdefault", + "tier": "arg", + "min": 6, + "parents": [ + "grid" + ] + }, + { + "kw": "left", + "tier": "arg", + "min": 3 + }, + { + "kw": "Left", + "tier": "arg", + "min": 2, + "parents": [ + "key" + ] + }, + { + "kw": "levels", + "tier": "arg", + "min": 2, + "parents": [ + "cntrparam" + ] + }, + { + "kw": "limit", + "tier": "arg", + "min": 5 + }, + { + "kw": "limit_abs", + "tier": "arg", + "min": 9 + }, + { + "kw": "lmargin", + "tier": "arg", + "min": 2 + }, + { + "kw": "locale", + "tier": "arg", + "min": 6 + }, + { + "kw": "logfile", + "tier": "arg", + "min": 4, + "no": true, + "parents": [ + "fit" + ] + }, + { + "kw": "loop", + "tier": "arg", + "min": 4 + }, + { + "kw": "map", + "tier": "arg", + "min": 3 + }, + { + "kw": "margins", + "tier": "arg", + "min": 7, + "parents": [ + "margin" + ] + }, + { + "kw": "maxcolors", + "tier": "arg", + "min": 4, + "parents": [ + "palette" + ] + }, + { + "kw": "maxcols", + "tier": "arg", + "min": 6, + "parents": [ + "key" + ] + }, + { + "kw": "maxiter", + "tier": "arg", + "min": 7 + }, + { + "kw": "maxrows", + "tier": "arg", + "min": 6, + "parents": [ + "key" + ] + }, + { + "kw": "medianlinewidth", + "tier": "arg", + "min": 15 + }, + { + "kw": "mixed", + "tier": "arg", + "min": 3, + "parents": [ + "isosurface" + ] + }, + { + "kw": "mouseformat", + "tier": "arg", + "min": 11 + }, + { + "kw": "negative", + "tier": "arg", + "min": 3, + "parents": [ + "palette" + ] + }, + { + "kw": "new", + "tier": "arg", + "min": 3 + }, + { + "kw": "nokeyseparators", + "tier": "arg", + "min": 5, + "parents": [ + "style" + ] + }, + { + "kw": "numbers", + "tier": "arg", + "min": 3, + "parents": [ + "cmd_history", + "history" + ] + }, + { + "kw": "offset", + "tier": "arg", + "min": 3, + "no": true, + "parents": [ + "hidden3d" + ] + }, + { + "kw": "one", + "tier": "arg", + "min": 1, + "parents": [ + "clip" + ] + }, + { + "kw": "onecolor", + "tier": "arg", + "min": 8 + }, + { + "kw": "order", + "tier": "arg", + "min": 1, + "parents": [ + "cntrparam" + ] + }, + { + "kw": "origin", + "tier": "arg", + "min": 1, + "parents": [ + "_argument_set_show", + "colorbox" + ] + }, + { + "kw": "outside", + "tier": "arg", + "min": 4, + "parents": [ + "key" + ] + }, + { + "kw": "overlap", + "tier": "arg", + "min": 4, + "parents": [ + "jitter" + ] + }, + { + "kw": "palette", + "tier": "arg", + "min": 3, + "parents": [ + "colorspec", + "contourfill", + "line_style", + "palette", + "style_opts" + ] + }, + { + "kw": "palfuncparam", + "tier": "arg", + "min": 12, + "parents": [ + "t_opts" + ] + }, + { + "kw": "plotsize", + "tier": "arg", + "min": 8, + "parents": [ + "t_opts" + ] + }, + { + "kw": "point", + "tier": "arg", + "min": 5 + }, + { + "kw": "points", + "tier": "arg", + "min": 1, + "parents": [ + "clip", + "cntrparam" + ] + }, + { + "kw": "pointscale", + "tier": "arg", + "min": 10, + "parents": [ + "t_opts" + ] + }, + { + "kw": "pointsmax", + "tier": "arg", + "min": 9, + "parents": [ + "t_opts" + ] + }, + { + "kw": "polardistance", + "tier": "arg", + "min": 13, + "no": true + }, + { + "kw": "polardistancedeg", + "tier": "arg", + "min": 16, + "no": true + }, + { + "kw": "polardistancetan", + "tier": "arg", + "min": 16, + "no": true + }, + { + "kw": "positive", + "tier": "arg", + "min": 3, + "parents": [ + "palette" + ] + }, + { + "kw": "projection", + "tier": "arg", + "min": 10 + }, + { + "kw": "qnorm", + "tier": "arg", + "min": 5 + }, + { + "kw": "quality", + "tier": "arg", + "min": 7 + }, + { + "kw": "quiet", + "tier": "arg", + "min": 5, + "parents": [ + "cmd_history", + "fit" + ] + }, + { + "kw": "radial", + "tier": "arg", + "min": 1, + "parents": [ + "clip" + ] + }, + { + "kw": "radians", + "tier": "arg", + "min": 1, + "parents": [ + "angles" + ] + }, + { + "kw": "radius", + "tier": "arg", + "min": 3, + "parents": [ + "style" + ] + }, + { + "kw": "range", + "tier": "arg", + "min": 5, + "parents": [ + "paxis", + "xrange" + ] + }, + { + "kw": "ratio", + "tier": "arg", + "min": 2, + "no": true, + "parents": [ + "size" + ] + }, + { + "kw": "relative", + "tier": "arg", + "min": 1, + "parents": [ + "boxwidth" + ] + }, + { + "kw": "resolution", + "tier": "arg", + "min": 10 + }, + { + "kw": "rgbformulae", + "tier": "arg", + "min": 3, + "parents": [ + "palette" + ] + }, + { + "kw": "right", + "tier": "arg", + "min": 3, + "parents": [ + "style_opts" + ] + }, + { + "kw": "Right", + "tier": "arg", + "min": 2, + "parents": [ + "key" + ] + }, + { + "kw": "rmargin", + "tier": "arg", + "min": 2 + }, + { + "kw": "rowstacked", + "tier": "arg", + "min": 4, + "parents": [ + "style" + ] + }, + { + "kw": "rto", + "tier": "arg", + "min": 3 + }, + { + "kw": "ruler", + "tier": "arg", + "min": 5, + "no": true, + "parents": [ + "mouse" + ] + }, + { + "kw": "samplen", + "tier": "arg", + "min": 7 + }, + { + "kw": "saturation", + "tier": "arg", + "min": 10 + }, + { + "kw": "scale", + "tier": "arg", + "min": 5, + "parents": [ + "t_opts" + ] + }, + { + "kw": "separation", + "tier": "arg", + "min": 10 + }, + { + "kw": "size", + "tier": "arg", + "min": 1, + "parents": [ + "_argument_set_show", + "canvas_size", + "colorbox" + ] + }, + { + "kw": "sorted", + "tier": "arg", + "min": 6 + }, + { + "kw": "spacing", + "tier": "arg", + "min": 2 + }, + { + "kw": "spiderplot", + "tier": "arg", + "min": 6, + "parents": [ + "_argument_set_show", + "grid", + "style" + ] + }, + { + "kw": "spotlight", + "tier": "arg", + "min": 4 + }, + { + "kw": "spread", + "tier": "arg", + "min": 6 + }, + { + "kw": "start", + "tier": "arg", + "min": 5 + }, + { + "kw": "theta", + "tier": "arg", + "min": 5 + }, + { + "kw": "title", + "tier": "arg", + "min": 2, + "no": true, + "parents": [ + "key", + "multiplot", + "plot_element", + "style", + "t_opts", + "title" + ] + }, + { + "kw": "tmargin", + "tier": "arg", + "min": 2 + }, + { + "kw": "to", + "tier": "arg", + "min": 2 + }, + { + "kw": "top", + "tier": "arg", + "min": 2 + }, + { + "kw": "trianglepattern", + "tier": "arg", + "min": 15 + }, + { + "kw": "triangles", + "tier": "arg", + "min": 6, + "parents": [ + "isosurface" + ] + }, + { + "kw": "two", + "tier": "arg", + "min": 1, + "parents": [ + "clip" + ] + }, + { + "kw": "undefined", + "tier": "arg", + "min": 5, + "no": true, + "parents": [ + "hidden3d" + ] + }, + { + "kw": "units", + "tier": "arg", + "min": 5 + }, + { + "kw": "unsorted", + "tier": "arg", + "min": 8 + }, + { + "kw": "user", + "tier": "arg", + "min": 1, + "parents": [ + "colorbox" + ] + }, + { + "kw": "verbose", + "tier": "arg", + "min": 3, + "no": true, + "parents": [ + "mouse" + ] + }, + { + "kw": "width", + "tier": "arg", + "min": 3, + "parents": [ + "key", + "t_opts" + ] + }, + { + "kw": "window", + "tier": "arg", + "min": 6, + "parents": [ + "t_opts" + ] + }, + { + "kw": "wrap", + "tier": "arg", + "min": 4 + }, + { + "kw": "zoomcoordinates", + "tier": "arg", + "min": 6, + "no": true, + "parents": [ + "mouse" + ] + }, + { + "kw": "zoomfactors", + "tier": "arg", + "min": 6, + "parents": [ + "mouse" + ] + }, + { + "kw": "zoomjump", + "tier": "arg", + "min": 5, + "no": true, + "parents": [ + "mouse" + ] + }, + { + "kw": "ztics", + "tier": "arg", + "min": 5 + }, + { + "kw": "axes", + "tier": "attr", + "min": 4 + }, + { + "kw": "binrange", + "tier": "attr", + "min": 8 + }, + { + "kw": "bins", + "tier": "attr", + "min": 4 + }, + { + "kw": "binvalue", + "tier": "attr", + "min": 8 + }, + { + "kw": "binwidth", + "tier": "attr", + "min": 8 + }, + { + "kw": "every", + "tier": "attr", + "min": 5 + }, + { + "kw": "if", + "tier": "attr", + "min": 2 + }, + { + "kw": "index", + "tier": "attr", + "min": 1, + "parents": [ + "index" + ] + }, + { + "kw": "label", + "tier": "attr", + "min": 5, + "parents": [ + "_paxis_label", + "label", + "xlabel" + ] + }, + { + "kw": "notitle", + "tier": "attr", + "min": 3, + "parents": [ + "plot_element" + ] + }, + { + "kw": "perpendicular", + "tier": "attr", + "min": 13 + }, + { + "kw": "scan", + "tier": "attr", + "min": 4 + }, + { + "kw": "smooth", + "tier": "attr", + "min": 6 + }, + { + "kw": "title", + "tier": "attr", + "min": 1, + "parents": [ + "key", + "multiplot", + "plot_element", + "style", + "t_opts", + "title" + ] + }, + { + "kw": "using", + "tier": "attr", + "min": 1, + "parents": [ + "using" + ] + }, + { + "kw": "watch", + "tier": "attr", + "min": 5 + }, + { + "kw": "with", + "tier": "attr", + "min": 1, + "parents": [ + "plot_element" + ] + }, + { + "kw": "bind", + "tier": "cmd", + "min": 4 + }, + { + "kw": "break", + "tier": "cmd", + "min": 5 + }, + { + "kw": "call", + "tier": "cmd", + "min": 4 + }, + { + "kw": "cd", + "tier": "cmd", + "min": 2 + }, + { + "kw": "clear", + "tier": "cmd", + "min": 2 + }, + { + "kw": "continue", + "tier": "cmd", + "min": 8 + }, + { + "kw": "evaluate", + "tier": "cmd", + "min": 4 + }, + { + "kw": "exit", + "tier": "cmd", + "min": 2 + }, + { + "kw": "fit", + "tier": "cmd", + "min": 1 + }, + { + "kw": "help", + "tier": "cmd", + "min": 2 + }, + { + "kw": "history", + "tier": "cmd", + "min": 4, + "parents": [ + "_argument_set_show", + "cmd_history" + ] + }, + { + "kw": "import", + "tier": "cmd", + "min": 6 + }, + { + "kw": "load", + "tier": "cmd", + "min": 1 + }, + { + "kw": "lower", + "tier": "cmd", + "min": 3 + }, + { + "kw": "pause", + "tier": "cmd", + "min": 2 + }, + { + "kw": "plot", + "tier": "cmd", + "min": 1, + "parents": [ + "cmd_show" + ] + }, + { + "kw": "print", + "tier": "cmd", + "min": 2, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "printerror", + "tier": "cmd", + "min": 8 + }, + { + "kw": "pwd", + "tier": "cmd", + "min": 3 + }, + { + "kw": "quit", + "tier": "cmd", + "min": 1 + }, + { + "kw": "raise", + "tier": "cmd", + "min": 2, + "parents": [ + "t_opts" + ] + }, + { + "kw": "refresh", + "tier": "cmd", + "min": 3 + }, + { + "kw": "remultiplot", + "tier": "cmd", + "min": 7 + }, + { + "kw": "replot", + "tier": "cmd", + "min": 3 + }, + { + "kw": "reread", + "tier": "cmd", + "min": 6 + }, + { + "kw": "reset", + "tier": "cmd", + "min": 5, + "parents": [ + "t_opts" + ] + }, + { + "kw": "save", + "tier": "cmd", + "min": 2, + "parents": [ + "cmd_save" + ] + }, + { + "kw": "set", + "tier": "cmd", + "min": 2, + "parents": [ + "_set_multiplot", + "cmd_set" + ] + }, + { + "kw": "show", + "tier": "cmd", + "min": 2, + "parents": [ + "cmd_show" + ] + }, + { + "kw": "splot", + "tier": "cmd", + "min": 2 + }, + { + "kw": "stats", + "tier": "cmd", + "min": 5 + }, + { + "kw": "test", + "tier": "cmd", + "min": 4 + }, + { + "kw": "toggle", + "tier": "cmd", + "min": 6 + }, + { + "kw": "undefine", + "tier": "cmd", + "min": 3, + "parents": [ + "cmd_undefine" + ] + }, + { + "kw": "unset", + "tier": "cmd", + "min": 3, + "parents": [ + "_unset_multiplot", + "cmd_unset" + ] + }, + { + "kw": "vclear", + "tier": "cmd", + "min": 6 + }, + { + "kw": "warn", + "tier": "cmd", + "min": 4 + }, + { + "kw": "character", + "tier": "coord", + "min": 4, + "parents": [ + "position" + ] + }, + { + "kw": "first", + "tier": "coord", + "min": 3, + "parents": [ + "position" + ] + }, + { + "kw": "graph", + "tier": "coord", + "min": 2, + "parents": [ + "position" + ] + }, + { + "kw": "polar", + "tier": "coord", + "min": 5, + "parents": [ + "_argument_set_show", + "grid" + ] + }, + { + "kw": "screen", + "tier": "coord", + "min": 2, + "parents": [ + "position" + ] + }, + { + "kw": "second", + "tier": "coord", + "min": 3, + "parents": [ + "position" + ] + }, + { + "kw": "dashtype", + "tier": "dt", + "min": 5, + "alt": "dt" + }, + { + "kw": "fillcolor", + "tier": "fc", + "min": 5, + "alt": "fc", + "parents": [ + "style" + ] + }, + { + "kw": "altdiagonal", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "hidden3d" + ] + }, + { + "kw": "antialias", + "tier": "flag", + "min": 9, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "attributes", + "tier": "flag", + "min": 10, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "auxfile", + "tier": "flag", + "min": 7, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "back", + "tier": "flag", + "min": 2, + "parents": [ + "colorbox" + ] + }, + { + "kw": "backhead", + "tier": "flag", + "min": 8 + }, + { + "kw": "backheads", + "tier": "flag", + "min": 9 + }, + { + "kw": "behind", + "tier": "flag", + "min": 6 + }, + { + "kw": "bentover", + "tier": "flag", + "min": 4, + "no": true, + "parents": [ + "hidden3d" + ] + }, + { + "kw": "border", + "tier": "flag", + "min": 2, + "no": true, + "parents": [ + "_pm3d", + "border", + "colorbox", + "fill_style", + "style" + ] + }, + { + "kw": "box", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "key" + ] + }, + { + "kw": "boxed", + "tier": "flag", + "min": -2, + "no": true, + "parents": [ + "label_opts" + ] + }, + { + "kw": "clip", + "tier": "flag", + "min": 4, + "no": true, + "parents": [ + "ellipse", + "style", + "t_opts" + ] + }, + { + "kw": "clipcb", + "tier": "flag", + "min": 6, + "no": true, + "parents": [ + "_pm3d" + ] + }, + { + "kw": "columnheaders", + "tier": "flag", + "min": -3, + "no": true, + "parents": [ + "datafile" + ] + }, + { + "kw": "covariancevariables", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "fit" + ] + }, + { + "kw": "crop", + "tier": "flag", + "min": 4, + "no": true + }, + { + "kw": "ctrl", + "tier": "flag", + "min": 4, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "ctrlq", + "tier": "flag", + "min": 5, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "depthorder", + "tier": "flag", + "min": 5, + "parents": [ + "_pm3d" + ] + }, + { + "kw": "enhanced", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "key", + "label_opts", + "multiplot", + "plot_element", + "style_opts", + "termoption", + "tics_opts", + "title", + "xlabel" + ] + }, + { + "kw": "equal", + "tier": "flag", + "min": 5, + "no": true, + "parents": [ + "view" + ] + }, + { + "kw": "errorscaling", + "tier": "flag", + "min": 6, + "no": true, + "parents": [ + "fit" + ] + }, + { + "kw": "errorvariables", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "fit" + ] + }, + { + "kw": "extend", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "paxis", + "xrange" + ] + }, + { + "kw": "externalimages", + "tier": "flag", + "min": 14, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "feed", + "tier": "flag", + "min": 4, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "filled", + "tier": "flag", + "min": 6, + "no": true + }, + { + "kw": "front", + "tier": "flag", + "min": 2, + "parents": [ + "colorbox" + ] + }, + { + "kw": "ftriangles", + "tier": "flag", + "min": 10, + "no": true, + "parents": [ + "_pm3d" + ] + }, + { + "kw": "fulldoc", + "tier": "flag", + "min": 7, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "gparrows", + "tier": "flag", + "min": 8, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "gppoints", + "tier": "flag", + "min": 8, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "head", + "tier": "flag", + "min": 4, + "no": true + }, + { + "kw": "heads", + "tier": "flag", + "min": 5, + "no": true + }, + { + "kw": "hidden3d", + "tier": "flag", + "min": 2, + "no": true, + "parents": [ + "_argument_set_show", + "_pm3d" + ] + }, + { + "kw": "hypertext", + "tier": "flag", + "min": 9 + }, + { + "kw": "inlineimages", + "tier": "flag", + "min": 12, + "parents": [ + "t_opts" + ] + }, + { + "kw": "interactive", + "tier": "flag", + "min": 11 + }, + { + "kw": "interlace", + "tier": "flag", + "min": 5, + "no": true + }, + { + "kw": "invert", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "colorbox", + "key" + ] + }, + { + "kw": "lighting", + "tier": "flag", + "min": 5, + "no": true, + "parents": [ + "_pm3d" + ] + }, + { + "kw": "logscale", + "tier": "flag", + "min": 4, + "no": true, + "parents": [ + "logscale", + "tics_opts" + ] + }, + { + "kw": "mirror", + "tier": "flag", + "min": 2, + "no": true, + "parents": [ + "tics_opts" + ] + }, + { + "kw": "noanimate", + "tier": "flag", + "min": 9, + "parents": [ + "t_opts" + ] + }, + { + "kw": "noborder", + "tier": "flag", + "min": 4, + "parents": [ + "colorbox" + ] + }, + { + "kw": "nocontours", + "tier": "flag", + "min": 10 + }, + { + "kw": "noextend", + "tier": "flag", + "min": 5, + "parents": [ + "autoscale" + ] + }, + { + "kw": "nofpe_trap", + "tier": "flag", + "min": 10 + }, + { + "kw": "nogrid", + "tier": "flag", + "min": 6 + }, + { + "kw": "nohidden3d", + "tier": "flag", + "min": -2, + "parents": [ + "style_opts" + ] + }, + { + "kw": "nologfile", + "tier": "flag", + "min": 5, + "parents": [ + "fit" + ] + }, + { + "kw": "nopoint", + "tier": "flag", + "min": 7 + }, + { + "kw": "noproportional", + "tier": "flag", + "min": 14, + "parents": [ + "t_opts" + ] + }, + { + "kw": "nosurface", + "tier": "flag", + "min": 6, + "parents": [ + "style_opts" + ] + }, + { + "kw": "opaque", + "tier": "flag", + "min": 6, + "no": true, + "parents": [ + "key" + ] + }, + { + "kw": "originreset", + "tier": "flag", + "min": 11, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "outliers", + "tier": "flag", + "min": 4, + "no": true, + "parents": [ + "style" + ] + }, + { + "kw": "output", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "_argument_set_show", + "cmd_stats" + ] + }, + { + "kw": "persist", + "tier": "flag", + "min": 7, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "picenvironment", + "tier": "flag", + "min": 14, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "polar", + "tier": "flag", + "min": 2, + "no": true, + "parents": [ + "_argument_set_show", + "grid" + ] + }, + { + "kw": "prescale", + "tier": "flag", + "min": 8, + "no": true, + "parents": [ + "fit" + ] + }, + { + "kw": "psarrows", + "tier": "flag", + "min": 8 + }, + { + "kw": "pspoints", + "tier": "flag", + "min": 8, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "raise", + "tier": "flag", + "min": 5, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "rangelimited", + "tier": "flag", + "min": 5, + "no": true, + "parents": [ + "tics_opts" + ] + }, + { + "kw": "replotonresize", + "tier": "flag", + "min": 14, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "reverse", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "key", + "paxis", + "xrange" + ] + }, + { + "kw": "rotate", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "label_opts", + "style_opts", + "t_opts", + "tics_opts", + "timestamp", + "xlabel" + ] + }, + { + "kw": "rottext", + "tier": "flag", + "min": 7, + "no": true + }, + { + "kw": "scroll", + "tier": "flag", + "min": 6 + }, + { + "kw": "square", + "tier": "flag", + "min": 6, + "no": true, + "parents": [ + "size" + ] + }, + { + "kw": "standalone", + "tier": "flag", + "min": 10, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "tightboundingbox", + "tier": "flag", + "min": 16, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "tikzarrows", + "tier": "flag", + "min": 10, + "no": true, + "parents": [ + "t_opts" + ] + }, + { + "kw": "timestamp", + "tier": "flag", + "min": 9, + "no": true, + "parents": [ + "_argument_set_show", + "t_opts" + ] + }, + { + "kw": "transparent", + "tier": "flag", + "min": 5, + "no": true, + "parents": [ + "background", + "fill_style" + ] + }, + { + "kw": "truecolor", + "tier": "flag", + "min": 4, + "no": true + }, + { + "kw": "vertical", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "colorbox", + "grid", + "jitter", + "key" + ] + }, + { + "kw": "wedge", + "tier": "flag", + "min": 2, + "no": true, + "parents": [ + "object", + "style" + ] + }, + { + "kw": "writeback", + "tier": "flag", + "min": 3, + "no": true, + "parents": [ + "paxis", + "xrange" + ] + }, + { + "kw": "fillstyle", + "tier": "fs", + "min": 4, + "alt": "fs" + }, + { + "kw": "linecolor", + "tier": "lc", + "min": 5, + "alt": "lc" + }, + { + "kw": "linetype", + "tier": "lt", + "min": 8, + "alt": "lt" + }, + { + "kw": "acsplines", + "tier": "mod", + "min": -1, + "parents": [ + "smooth_options" + ] + }, + { + "kw": "all", + "tier": "mod", + "min": 3 + }, + { + "kw": "allwindows", + "tier": "mod", + "min": 3 + }, + { + "kw": "anchor", + "tier": "mod", + "min": 6 + }, + { + "kw": "ansi", + "tier": "mod", + "min": 4 + }, + { + "kw": "ansi256", + "tier": "mod", + "min": 7 + }, + { + "kw": "ansirgb", + "tier": "mod", + "min": 7 + }, + { + "kw": "any", + "tier": "mod", + "min": 3 + }, + { + "kw": "avg", + "tier": "mod", + "min": 3 + }, + { + "kw": "axis", + "tier": "mod", + "min": 4 + }, + { + "kw": "backward", + "tier": "mod", + "min": 2 + }, + { + "kw": "base", + "tier": "mod", + "min": 2, + "parents": [ + "contour" + ] + }, + { + "kw": "baseline", + "tier": "mod", + "min": 4 + }, + { + "kw": "bdefault", + "tier": "mod", + "min": 2, + "parents": [ + "colorbox" + ] + }, + { + "kw": "beveled", + "tier": "mod", + "min": 7 + }, + { + "kw": "bezier", + "tier": "mod", + "min": 6 + }, + { + "kw": "big", + "tier": "mod", + "min": 3 + }, + { + "kw": "bind", + "tier": "mod", + "min": 4 + }, + { + "kw": "blacktext", + "tier": "mod", + "min": 9, + "parents": [ + "t_opts" + ] + }, + { + "kw": "both", + "tier": "mod", + "min": 2, + "parents": [ + "contour" + ] + }, + { + "kw": "brief", + "tier": "mod", + "min": 5 + }, + { + "kw": "butt", + "tier": "mod", + "min": 4 + }, + { + "kw": "button1", + "tier": "mod", + "min": 7 + }, + { + "kw": "button2", + "tier": "mod", + "min": 7 + }, + { + "kw": "button3", + "tier": "mod", + "min": 7 + }, + { + "kw": "candlesticks", + "tier": "mod", + "min": 12, + "parents": [ + "plot_style" + ] + }, + { + "kw": "cartesian", + "tier": "mod", + "min": 9 + }, + { + "kw": "cauchy", + "tier": "mod", + "min": 6 + }, + { + "kw": "ccw", + "tier": "mod", + "min": 3 + }, + { + "kw": "circle", + "tier": "mod", + "min": 4, + "parents": [ + "object", + "style" + ] + }, + { + "kw": "classic", + "tier": "mod", + "min": 7 + }, + { + "kw": "clockwise", + "tier": "mod", + "min": 9 + }, + { + "kw": "close", + "tier": "mod", + "min": 5, + "parents": [ + "t_opts" + ] + }, + { + "kw": "cnormal", + "tier": "mod", + "min": 7 + }, + { + "kw": "color", + "tier": "mod", + "min": 5, + "parents": [ + "mono_color" + ] + }, + { + "kw": "colortext", + "tier": "mod", + "min": 9, + "parents": [ + "t_opts" + ] + }, + { + "kw": "colourtext", + "tier": "mod", + "min": 10, + "parents": [ + "t_opts" + ] + }, + { + "kw": "columnsfirst", + "tier": "mod", + "min": 12 + }, + { + "kw": "context", + "tier": "mod", + "min": 7, + "parents": [ + "t_opts" + ] + }, + { + "kw": "counterclockwise", + "tier": "mod", + "min": 16 + }, + { + "kw": "cp1250", + "tier": "mod", + "min": 6 + }, + { + "kw": "cp1251", + "tier": "mod", + "min": 6 + }, + { + "kw": "cp1252", + "tier": "mod", + "min": 6 + }, + { + "kw": "cp1254", + "tier": "mod", + "min": 6 + }, + { + "kw": "cp437", + "tier": "mod", + "min": 3 + }, + { + "kw": "cp850", + "tier": "mod", + "min": 5 + }, + { + "kw": "cp852", + "tier": "mod", + "min": 5 + }, + { + "kw": "cp950", + "tier": "mod", + "min": 5 + }, + { + "kw": "csplines", + "tier": "mod", + "min": -1, + "parents": [ + "smooth_options" + ] + }, + { + "kw": "cumulative", + "tier": "mod", + "min": 10 + }, + { + "kw": "cw", + "tier": "mod", + "min": 2 + }, + { + "kw": "cylindrical", + "tier": "mod", + "min": 11 + }, + { + "kw": "dashed", + "tier": "mod", + "min": 6, + "parents": [ + "t_opts" + ] + }, + { + "kw": "days", + "tier": "mod", + "min": 3, + "parents": [ + "mxtics" + ] + }, + { + "kw": "defaultplex", + "tier": "mod", + "min": 11, + "parents": [ + "t_opts" + ] + }, + { + "kw": "defaults", + "tier": "mod", + "min": 3, + "parents": [ + "encoding", + "hidden3d", + "style" + ] + }, + { + "kw": "downwards", + "tier": "mod", + "min": 9 + }, + { + "kw": "duplex", + "tier": "mod", + "min": 6, + "parents": [ + "t_opts" + ] + }, + { + "kw": "dynamic", + "tier": "mod", + "min": 7 + }, + { + "kw": "eject", + "tier": "mod", + "min": 5, + "parents": [ + "t_opts" + ] + }, + { + "kw": "ellipse", + "tier": "mod", + "min": 3, + "parents": [ + "object", + "style" + ] + }, + { + "kw": "empty", + "tier": "mod", + "min": 5 + }, + { + "kw": "eps", + "tier": "mod", + "min": 3, + "parents": [ + "t_opts" + ] + }, + { + "kw": "errors", + "tier": "mod", + "min": 6 + }, + { + "kw": "explicit", + "tier": "mod", + "min": 4 + }, + { + "kw": "financebars", + "tier": "mod", + "min": 11 + }, + { + "kw": "fit", + "tier": "mod", + "min": 3 + }, + { + "kw": "fix", + "tier": "mod", + "min": 3 + }, + { + "kw": "fixed", + "tier": "mod", + "min": 5 + }, + { + "kw": "float", + "tier": "mod", + "min": 5 + }, + { + "kw": "fnormal", + "tier": "mod", + "min": 7 + }, + { + "kw": "fortran", + "tier": "mod", + "min": 4, + "parents": [ + "datafile" + ] + }, + { + "kw": "forward", + "tier": "mod", + "min": 2 + }, + { + "kw": "frequency", + "tier": "mod", + "min": 9 + }, + { + "kw": "full", + "tier": "mod", + "min": 4, + "parents": [ + "cmd_history" + ] + }, + { + "kw": "fullwidth", + "tier": "mod", + "min": 9 + }, + { + "kw": "gauss", + "tier": "mod", + "min": 5 + }, + { + "kw": "geographic", + "tier": "mod", + "min": 3 + }, + { + "kw": "giant", + "tier": "mod", + "min": 5 + }, + { + "kw": "gnuplot", + "tier": "mod", + "min": 7 + }, + { + "kw": "gray", + "tier": "mod", + "min": 4 + }, + { + "kw": "grid", + "tier": "mod", + "min": 4, + "parents": [ + "grid" + ] + }, + { + "kw": "hann", + "tier": "mod", + "min": 4 + }, + { + "kw": "hex", + "tier": "mod", + "min": 3 + }, + { + "kw": "hours", + "tier": "mod", + "min": 4, + "parents": [ + "mxtics" + ] + }, + { + "kw": "implicit", + "tier": "mod", + "min": 3 + }, + { + "kw": "iso_8859_1", + "tier": "mod", + "min": 3 + }, + { + "kw": "iso_8859_15", + "tier": "mod", + "min": 11 + }, + { + "kw": "iso_8859_2", + "tier": "mod", + "min": 10 + }, + { + "kw": "iso_8859_9", + "tier": "mod", + "min": 10 + }, + { + "kw": "kdensity", + "tier": "mod", + "min": 8 + }, + { + "kw": "keepfix", + "tier": "mod", + "min": 4 + }, + { + "kw": "keypress", + "tier": "mod", + "min": 8 + }, + { + "kw": "koi8r", + "tier": "mod", + "min": 4 + }, + { + "kw": "koi8u", + "tier": "mod", + "min": 5 + }, + { + "kw": "landscape", + "tier": "mod", + "min": 9, + "parents": [ + "t_opts" + ] + }, + { + "kw": "large", + "tier": "mod", + "min": 5 + }, + { + "kw": "latex", + "tier": "mod", + "min": 5, + "parents": [ + "t_opts" + ] + }, + { + "kw": "level1", + "tier": "mod", + "min": 6 + }, + { + "kw": "level3", + "tier": "mod", + "min": 6 + }, + { + "kw": "leveldefault", + "tier": "mod", + "min": 12 + }, + { + "kw": "linear", + "tier": "mod", + "min": 2, + "parents": [ + "cntrparam" + ] + }, + { + "kw": "link", + "tier": "mod", + "min": 4, + "no": true + }, + { + "kw": "mcsplines", + "tier": "mod", + "min": 3, + "parents": [ + "smooth_options" + ] + }, + { + "kw": "medium", + "tier": "mod", + "min": 6 + }, + { + "kw": "minutes", + "tier": "mod", + "min": 4, + "parents": [ + "mxtics" + ] + }, + { + "kw": "mitered", + "tier": "mod", + "min": 7 + }, + { + "kw": "mono", + "tier": "mod", + "min": 4 + }, + { + "kw": "months", + "tier": "mod", + "min": 3, + "parents": [ + "mxtics" + ] + }, + { + "kw": "mouse", + "tier": "mod", + "min": 5, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "mpoints", + "tier": "mod", + "min": 7, + "parents": [ + "t_opts" + ] + }, + { + "kw": "nodraw", + "tier": "mod", + "min": 6 + }, + { + "kw": "none", + "tier": "mod", + "min": 4 + }, + { + "kw": "nops_allcF", + "tier": "mod", + "min": 10 + }, + { + "kw": "normalpoints", + "tier": "mod", + "min": 12, + "parents": [ + "t_opts" + ] + }, + { + "kw": "numeric", + "tier": "mod", + "min": 7 + }, + { + "kw": "off", + "tier": "mod", + "min": 3 + }, + { + "kw": "offset", + "tier": "mod", + "min": 3, + "parents": [ + "hidden3d" + ] + }, + { + "kw": "on", + "tier": "mod", + "min": 2 + }, + { + "kw": "parallel", + "tier": "mod", + "min": 8 + }, + { + "kw": "path", + "tier": "mod", + "min": 4 + }, + { + "kw": "pdf", + "tier": "mod", + "min": 3 + }, + { + "kw": "pdftricks2", + "tier": "mod", + "min": 10 + }, + { + "kw": "perl", + "tier": "mod", + "min": 4 + }, + { + "kw": "perltkx", + "tier": "mod", + "min": 7 + }, + { + "kw": "pixels", + "tier": "mod", + "min": 6 + }, + { + "kw": "png", + "tier": "mod", + "min": 3 + }, + { + "kw": "podo", + "tier": "mod", + "min": 4 + }, + { + "kw": "polygon", + "tier": "mod", + "min": 4, + "parents": [ + "object" + ] + }, + { + "kw": "portrait", + "tier": "mod", + "min": 8, + "parents": [ + "t_opts" + ] + }, + { + "kw": "ps_allcF", + "tier": "mod", + "min": 8 + }, + { + "kw": "pstricks", + "tier": "mod", + "min": 8 + }, + { + "kw": "python", + "tier": "mod", + "min": 6 + }, + { + "kw": "rectangle", + "tier": "mod", + "min": 3, + "parents": [ + "object", + "style" + ] + }, + { + "kw": "reset", + "tier": "mod", + "min": 5, + "parents": [ + "t_opts" + ] + }, + { + "kw": "results", + "tier": "mod", + "min": 7 + }, + { + "kw": "rexx", + "tier": "mod", + "min": 4 + }, + { + "kw": "rounded", + "tier": "mod", + "min": -2, + "parents": [ + "line_drawing_method" + ] + }, + { + "kw": "rowsfirst", + "tier": "mod", + "min": 9 + }, + { + "kw": "ruby", + "tier": "mod", + "min": 4 + }, + { + "kw": "sbezier", + "tier": "mod", + "min": 7 + }, + { + "kw": "script", + "tier": "mod", + "min": 6 + }, + { + "kw": "seconds", + "tier": "mod", + "min": 3, + "parents": [ + "mxtics" + ] + }, + { + "kw": "session", + "tier": "mod", + "min": 7 + }, + { + "kw": "set", + "tier": "mod", + "min": 3, + "parents": [ + "_set_multiplot", + "cmd_set" + ] + }, + { + "kw": "simplex", + "tier": "mod", + "min": 7, + "parents": [ + "t_opts" + ] + }, + { + "kw": "sjis", + "tier": "mod", + "min": 2 + }, + { + "kw": "small", + "tier": "mod", + "min": 5 + }, + { + "kw": "smallpoints", + "tier": "mod", + "min": 11, + "parents": [ + "t_opts" + ] + }, + { + "kw": "solid", + "tier": "mod", + "min": 5, + "parents": [ + "fill_style", + "t_opts" + ] + }, + { + "kw": "spherical", + "tier": "mod", + "min": 9 + }, + { + "kw": "splines", + "tier": "mod", + "min": 7 + }, + { + "kw": "square", + "tier": "mod", + "min": 6, + "parents": [ + "size" + ] + }, + { + "kw": "sum", + "tier": "mod", + "min": 3 + }, + { + "kw": "surface", + "tier": "mod", + "min": 1, + "parents": [ + "_argument_set_show", + "contour" + ] + }, + { + "kw": "swarm", + "tier": "mod", + "min": 5 + }, + { + "kw": "tcl", + "tier": "mod", + "min": 3 + }, + { + "kw": "terminal", + "tier": "mod", + "min": 3, + "parents": [ + "cmd_save", + "terminal" + ] + }, + { + "kw": "tex", + "tier": "mod", + "min": 3, + "parents": [ + "t_opts" + ] + }, + { + "kw": "texarrows", + "tier": "mod", + "min": 9 + }, + { + "kw": "texpoints", + "tier": "mod", + "min": 9, + "parents": [ + "t_opts" + ] + }, + { + "kw": "texthidden", + "tier": "mod", + "min": 10 + }, + { + "kw": "textnormal", + "tier": "mod", + "min": 10, + "parents": [ + "t_opts" + ] + }, + { + "kw": "textrigid", + "tier": "mod", + "min": 9 + }, + { + "kw": "textspecial", + "tier": "mod", + "min": 11 + }, + { + "kw": "time", + "tier": "mod", + "min": 4, + "parents": [ + "xdata" + ] + }, + { + "kw": "timedate", + "tier": "mod", + "min": 8 + }, + { + "kw": "tiny", + "tier": "mod", + "min": 4 + }, + { + "kw": "tinypoints", + "tier": "mod", + "min": 10, + "parents": [ + "t_opts" + ] + }, + { + "kw": "transparent", + "tier": "mod", + "min": 5, + "parents": [ + "background", + "fill_style" + ] + }, + { + "kw": "trip", + "tier": "mod", + "min": 4 + }, + { + "kw": "undefined", + "tier": "mod", + "min": 9, + "parents": [ + "hidden3d" + ] + }, + { + "kw": "unique", + "tier": "mod", + "min": 6 + }, + { + "kw": "unit", + "tier": "mod", + "min": 4, + "no": true + }, + { + "kw": "unwrap", + "tier": "mod", + "min": 6 + }, + { + "kw": "upwards", + "tier": "mod", + "min": 7 + }, + { + "kw": "utf8", + "tier": "mod", + "min": 3 + }, + { + "kw": "v4", + "tier": "mod", + "min": 2 + }, + { + "kw": "v5", + "tier": "mod", + "min": 2 + }, + { + "kw": "weeks", + "tier": "mod", + "min": 4, + "parents": [ + "mxtics" + ] + }, + { + "kw": "x0", + "tier": "mod", + "min": 2 + }, + { + "kw": "x1", + "tier": "mod", + "min": 2 + }, + { + "kw": "xx", + "tier": "mod", + "min": 2 + }, + { + "kw": "xy", + "tier": "mod", + "min": 2 + }, + { + "kw": "xyz", + "tier": "mod", + "min": 3 + }, + { + "kw": "xz", + "tier": "mod", + "min": 2 + }, + { + "kw": "y0", + "tier": "mod", + "min": 2 + }, + { + "kw": "y1", + "tier": "mod", + "min": 2 + }, + { + "kw": "years", + "tier": "mod", + "min": 4, + "parents": [ + "mxtics" + ] + }, + { + "kw": "yy", + "tier": "mod", + "min": 2 + }, + { + "kw": "yz", + "tier": "mod", + "min": 2 + }, + { + "kw": "z0", + "tier": "mod", + "min": 2 + }, + { + "kw": "cairolatex", + "tier": "name", + "min": 3 + }, + { + "kw": "canvas", + "tier": "name", + "min": 3 + }, + { + "kw": "cgm", + "tier": "name", + "min": 2 + }, + { + "kw": "context", + "tier": "name", + "min": 2, + "parents": [ + "t_opts" + ] + }, + { + "kw": "domterm", + "tier": "name", + "min": 2 + }, + { + "kw": "dumb", + "tier": "name", + "min": 2 + }, + { + "kw": "dxf", + "tier": "name", + "min": 2 + }, + { + "kw": "emf", + "tier": "name", + "min": 2 + }, + { + "kw": "epscairo", + "tier": "name", + "min": 1 + }, + { + "kw": "epslatex", + "tier": "name", + "min": 4 + }, + { + "kw": "fig", + "tier": "name", + "min": 1 + }, + { + "kw": "gif", + "tier": "name", + "min": 1 + }, + { + "kw": "hpgl", + "tier": "name", + "min": 1 + }, + { + "kw": "jpeg", + "tier": "name", + "min": 1 + }, + { + "kw": "kittycairo", + "tier": "name", + "min": 3 + }, + { + "kw": "kittygd", + "tier": "name", + "min": -1 + }, + { + "kw": "lua", + "tier": "name", + "min": 1 + }, + { + "kw": "pcl5", + "tier": "name", + "min": 2 + }, + { + "kw": "pdfcairo", + "tier": "name", + "min": 2 + }, + { + "kw": "pict2e", + "tier": "name", + "min": 2 + }, + { + "kw": "png", + "tier": "name", + "min": 3 + }, + { + "kw": "pngcairo", + "tier": "name", + "min": 4 + }, + { + "kw": "postscript", + "tier": "name", + "min": 2 + }, + { + "kw": "pslatex", + "tier": "name", + "min": 3 + }, + { + "kw": "pstex", + "tier": "name", + "min": -1 + }, + { + "kw": "pstricks", + "tier": "name", + "min": 4 + }, + { + "kw": "qt", + "tier": "name", + "min": 1 + }, + { + "kw": "sixelgd", + "tier": "name", + "min": 1 + }, + { + "kw": "svg", + "tier": "name", + "min": 2 + }, + { + "kw": "tek40xx", + "tier": "name", + "min": 5 + }, + { + "kw": "tek410x", + "tier": "name", + "min": 5 + }, + { + "kw": "texdraw", + "tier": "name", + "min": 3 + }, + { + "kw": "tikz", + "tier": "name", + "min": 2 + }, + { + "kw": "tkcanvas", + "tier": "name", + "min": 2 + }, + { + "kw": "unknown", + "tier": "name", + "min": 1 + }, + { + "kw": "vttek", + "tier": "name", + "min": 1 + }, + { + "kw": "webp", + "tier": "name", + "min": 1 + }, + { + "kw": "wxt", + "tier": "name", + "min": 2 + }, + { + "kw": "x11", + "tier": "name", + "min": 1 + }, + { + "kw": "xterm", + "tier": "name", + "min": 2 + }, + { + "kw": "angles", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "angles" + ] + }, + { + "kw": "arrow", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "arrow", + "style" + ] + }, + { + "kw": "autoscale", + "tier": "opt", + "min": 4, + "head": true, + "parents": [ + "autoscale" + ] + }, + { + "kw": "bars", + "tier": "opt", + "min": 1, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "bmargin", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "border", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_pm3d", + "border", + "colorbox", + "fill_style", + "style" + ] + }, + { + "kw": "boxdepth", + "tier": "opt", + "min": 8, + "head": true + }, + { + "kw": "boxwidth", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "boxwidth" + ] + }, + { + "kw": "cbdata", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "cbdtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "cblabel", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "cbmtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "cbrange", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "cbtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "clip", + "tier": "opt", + "min": 4, + "head": true, + "parents": [ + "ellipse", + "style", + "t_opts" + ] + }, + { + "kw": "cntrlabel", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "cntrlabel" + ] + }, + { + "kw": "cntrparam", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "cntrparam" + ] + }, + { + "kw": "color", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "mono_color" + ] + }, + { + "kw": "colorbox", + "tier": "opt", + "min": 6, + "head": true, + "parents": [ + "colorbox" + ] + }, + { + "kw": "colormap", + "tier": "opt", + "min": 8, + "head": true, + "parents": [ + "palette" + ] + }, + { + "kw": "colornames", + "tier": "opt", + "min": 6, + "head": true, + "parents": [ + "cmd_show" + ] + }, + { + "kw": "colorsequence", + "tier": "opt", + "min": 13, + "head": true + }, + { + "kw": "contourfill", + "tier": "opt", + "min": 11, + "head": true + }, + { + "kw": "contours", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "contour" + ] + }, + { + "kw": "cornerpoles", + "tier": "opt", + "min": 7, + "head": true, + "parents": [ + "cornerpoles" + ] + }, + { + "kw": "datafile", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "datafile" + ] + }, + { + "kw": "decimalsign", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "decimalsign" + ] + }, + { + "kw": "dgrid3d", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "dgrid3d" + ] + }, + { + "kw": "dummy", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "dummy" + ] + }, + { + "kw": "encoding", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "errorbars", + "tier": "opt", + "min": 9, + "head": true, + "parents": [ + "style" + ] + }, + { + "kw": "fit", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "format", + "tier": "opt", + "min": 4, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "functions", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "cmd_save", + "cmd_show", + "palette" + ] + }, + { + "kw": "grid", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "grid" + ] + }, + { + "kw": "hidden3d", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_argument_set_show", + "_pm3d" + ] + }, + { + "kw": "history", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_argument_set_show", + "cmd_history" + ] + }, + { + "kw": "isosamples", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "isosurface", + "tier": "opt", + "min": 7, + "head": true, + "parents": [ + "_argument_set_show", + "plot_style" + ] + }, + { + "kw": "isotropic", + "tier": "opt", + "min": 9, + "head": true + }, + { + "kw": "jitter", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "key", + "tier": "opt", + "min": 1, + "head": true, + "parents": [ + "key" + ] + }, + { + "kw": "label", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_paxis_label", + "label", + "xlabel" + ] + }, + { + "kw": "link", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "lmargin", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "loadpath", + "tier": "opt", + "min": 4, + "head": true, + "parents": [ + "loadpath", + "locale" + ] + }, + { + "kw": "locale", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "logscale", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "logscale", + "tics_opts" + ] + }, + { + "kw": "mapping", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "mapping" + ] + }, + { + "kw": "margins", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "margin" + ] + }, + { + "kw": "mcbtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "micro", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "minussign", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "monochrome", + "tier": "opt", + "min": 4, + "head": true, + "parents": [ + "mono_color", + "monochrome" + ] + }, + { + "kw": "mouse", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "mrtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "mttics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "multiplot", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "multiplot" + ] + }, + { + "kw": "mutics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "mvtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "mvxtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "mvytics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "mvztics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "mx2tics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "mxtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "mxytics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "my2tics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "mytics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "mztics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "nonlinear", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "nonlinear" + ] + }, + { + "kw": "object", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "object" + ] + }, + { + "kw": "offsets", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "origin", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show", + "colorbox" + ] + }, + { + "kw": "output", + "tier": "opt", + "min": 1, + "head": true, + "parents": [ + "_argument_set_show", + "cmd_stats" + ] + }, + { + "kw": "overflow", + "tier": "opt", + "min": 8, + "head": true + }, + { + "kw": "palette", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "colorspec", + "contourfill", + "line_style", + "palette", + "style_opts" + ] + }, + { + "kw": "parametric", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "paxis", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "pixmap", + "tier": "opt", + "min": 4, + "head": true, + "parents": [ + "pixmap" + ] + }, + { + "kw": "plot", + "tier": "opt", + "min": 1, + "head": true, + "parents": [ + "cmd_show" + ] + }, + { + "kw": "pm3d", + "tier": "opt", + "min": 4, + "head": true, + "parents": [ + "plot_style" + ] + }, + { + "kw": "pointintervalbox", + "tier": "opt", + "min": 8, + "head": true, + "parents": [ + "pointintervalbox" + ] + }, + { + "kw": "pointsize", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "pointsize" + ] + }, + { + "kw": "polar", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_argument_set_show", + "grid" + ] + }, + { + "kw": "print", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "psdir", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "raxis", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "rdata", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "rdtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "rgbmax", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "rlabel", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "rmargin", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "rmtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "rrange", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "rtics", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "samples", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "size", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show", + "canvas_size", + "colorbox" + ] + }, + { + "kw": "spiderplot", + "tier": "opt", + "min": 6, + "head": true, + "parents": [ + "_argument_set_show", + "grid", + "style" + ] + }, + { + "kw": "style", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "style" + ] + }, + { + "kw": "surface", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show", + "contour" + ] + }, + { + "kw": "table", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "table" + ] + }, + { + "kw": "tdata", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "tdtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "terminal", + "tier": "opt", + "min": 1, + "head": true, + "parents": [ + "cmd_save", + "terminal" + ] + }, + { + "kw": "termoption", + "tier": "opt", + "min": 10, + "head": true + }, + { + "kw": "theta", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "tics", + "tier": "opt", + "min": -1, + "head": true, + "parents": [ + "_argument_set_show", + "grid", + "mxtics", + "paxis", + "xdtics", + "xmtics", + "xtics" + ] + }, + { + "kw": "timefmt", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "timestamp", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "_argument_set_show", + "t_opts" + ] + }, + { + "kw": "title", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "key", + "multiplot", + "plot_element", + "style", + "t_opts", + "title" + ] + }, + { + "kw": "tlabel", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "tmargin", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "tmtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "trange", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "ttics", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "udata", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "udtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "ulabel", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "umtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "urange", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "utics", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "variables", + "tier": "opt", + "min": 1, + "head": true, + "parents": [ + "cmd_save", + "cmd_show" + ] + }, + { + "kw": "vdata", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "vdtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "version", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "cmd_show" + ] + }, + { + "kw": "vgrid", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "view", + "tier": "opt", + "min": 2, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "vlabel", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "vmtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vrange", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "vtics", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "vxdata", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "vxdtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "vxlabel", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vxmtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "vxrange", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vxtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vydata", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "vydtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "vylabel", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vymtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "vyrange", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vytics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vzdata", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "vzdtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "vzlabel", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vzmtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "vzrange", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "vztics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "walls", + "tier": "opt", + "min": -1, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "x2data", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "x2dtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "x2label", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "x2mtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "x2range", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "x2tics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "x2zeroaxis", + "tier": "opt", + "min": 7, + "head": true + }, + { + "kw": "xdata", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "xdtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "xlabel", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "xmtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "xrange", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "xtics", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "xydata", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "xydtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "xylabel", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "xymtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "xyplane", + "tier": "opt", + "min": 3, + "head": true, + "parents": [ + "xyplane" + ] + }, + { + "kw": "xyrange", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "xytics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "xzeroaxis", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "y2data", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "y2dtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "y2label", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "y2mtics", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "y2range", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "y2tics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "y2zeroaxis", + "tier": "opt", + "min": 7, + "head": true + }, + { + "kw": "ydata", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "ydtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "ylabel", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "ymtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "yrange", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "ytics", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "yzeroaxis", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "zdata", + "tier": "opt", + "min": 3, + "head": true + }, + { + "kw": "zdtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "zero", + "tier": "opt", + "min": 1, + "head": true, + "parents": [ + "_argument_set_show" + ] + }, + { + "kw": "zeroaxis", + "tier": "opt", + "min": 5, + "head": true, + "parents": [ + "zeroaxis" + ] + }, + { + "kw": "zlabel", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "zmtics", + "tier": "opt", + "min": 5, + "head": true + }, + { + "kw": "zrange", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "ztics", + "tier": "opt", + "min": 4, + "head": true + }, + { + "kw": "zzeroaxis", + "tier": "opt", + "min": 6, + "head": true + }, + { + "kw": "arrows", + "tier": "plt_st", + "min": 3 + }, + { + "kw": "boxerrorbars", + "tier": "plt_st", + "min": 12 + }, + { + "kw": "boxes", + "tier": "plt_st", + "min": 5 + }, + { + "kw": "boxplot", + "tier": "plt_st", + "min": 7 + }, + { + "kw": "boxxyerror", + "tier": "plt_st", + "min": 10 + }, + { + "kw": "candlesticks", + "tier": "plt_st", + "min": 12, + "parents": [ + "plot_style" + ] + }, + { + "kw": "circles", + "tier": "plt_st", + "min": 7 + }, + { + "kw": "contourfill", + "tier": "plt_st", + "min": 11 + }, + { + "kw": "dots", + "tier": "plt_st", + "min": 1 + }, + { + "kw": "ellipses", + "tier": "plt_st", + "min": 8, + "parents": [ + "plot_style" + ] + }, + { + "kw": "errorbars", + "tier": "plt_st", + "min": 1, + "parents": [ + "style" + ] + }, + { + "kw": "errorlines", + "tier": "plt_st", + "min": 6 + }, + { + "kw": "filledcurves", + "tier": "plt_st", + "min": 7, + "parents": [ + "plot_style" + ] + }, + { + "kw": "fillsteps", + "tier": "plt_st", + "min": 9, + "parents": [ + "plot_style" + ] + }, + { + "kw": "financebars", + "tier": "plt_st", + "min": 3 + }, + { + "kw": "fsteps", + "tier": "plt_st", + "min": 6 + }, + { + "kw": "histeps", + "tier": "plt_st", + "min": 7 + }, + { + "kw": "histograms", + "tier": "plt_st", + "min": 4 + }, + { + "kw": "hsteps", + "tier": "plt_st", + "min": 2 + }, + { + "kw": "image", + "tier": "plt_st", + "min": 3, + "parents": [ + "plot_style" + ] + }, + { + "kw": "impulses", + "tier": "plt_st", + "min": 1 + }, + { + "kw": "isosurface", + "tier": "plt_st", + "min": 10, + "parents": [ + "_argument_set_show", + "plot_style" + ] + }, + { + "kw": "labels", + "tier": "plt_st", + "min": 3, + "parents": [ + "mouse", + "plot_style", + "style" + ] + }, + { + "kw": "lines", + "tier": "plt_st", + "min": 1 + }, + { + "kw": "linespoints", + "tier": "plt_st", + "min": 6, + "alt": "lp" + }, + { + "kw": "mask", + "tier": "plt_st", + "min": 4 + }, + { + "kw": "parallelaxes", + "tier": "plt_st", + "min": 12 + }, + { + "kw": "pm3d", + "tier": "plt_st", + "min": 4, + "parents": [ + "plot_style" + ] + }, + { + "kw": "points", + "tier": "plt_st", + "min": 1, + "parents": [ + "clip", + "cntrparam" + ] + }, + { + "kw": "polygons", + "tier": "plt_st", + "min": 8 + }, + { + "kw": "rgbalpha", + "tier": "plt_st", + "min": 8 + }, + { + "kw": "rgbimage", + "tier": "plt_st", + "min": 8 + }, + { + "kw": "sectors", + "tier": "plt_st", + "min": 3 + }, + { + "kw": "spiderplot", + "tier": "plt_st", + "min": 6, + "parents": [ + "_argument_set_show", + "grid", + "style" + ] + }, + { + "kw": "steps", + "tier": "plt_st", + "min": 2 + }, + { + "kw": "surface", + "tier": "plt_st", + "min": 3, + "parents": [ + "_argument_set_show", + "contour" + ] + }, + { + "kw": "table", + "tier": "plt_st", + "min": 5, + "parents": [ + "table" + ] + }, + { + "kw": "vectors", + "tier": "plt_st", + "min": 3, + "parents": [ + "plot_style" + ] + }, + { + "kw": "xerrorbars", + "tier": "plt_st", + "min": 9 + }, + { + "kw": "xerrorlines", + "tier": "plt_st", + "min": 11 + }, + { + "kw": "xyerrorbars", + "tier": "plt_st", + "min": 10 + }, + { + "kw": "xyerrorlines", + "tier": "plt_st", + "min": 12 + }, + { + "kw": "yerrorbars", + "tier": "plt_st", + "min": 9 + }, + { + "kw": "yerrorlines", + "tier": "plt_st", + "min": 11 + }, + { + "kw": "zerrorfill", + "tier": "plt_st", + "min": 6 + }, + { + "kw": "pointsize", + "tier": "ps", + "min": 6, + "alt": "ps", + "parents": [ + "pointsize" + ] + }, + { + "kw": "pointtype", + "tier": "pt", + "min": 6, + "alt": "pt" + }, + { + "kw": "arrowstyle", + "tier": "sa", + "min": 10, + "alt": "as" + }, + { + "kw": "dashlength", + "tier": "sa", + "min": 5, + "alt": "dl" + }, + { + "kw": "linestyle", + "tier": "sa", + "min": 5, + "alt": "ls" + }, + { + "kw": "linewidth", + "tier": "sa", + "min": 5, + "alt": "lw", + "parents": [ + "style" + ] + }, + { + "kw": "pointinterval", + "tier": "sa", + "min": 6, + "alt": "pi" + }, + { + "kw": "pointnumber", + "tier": "sa", + "min": 6, + "alt": "pn" + }, + { + "kw": "arrow", + "tier": "st_opt", + "min": 3, + "parents": [ + "arrow", + "style" + ] + }, + { + "kw": "boxplot", + "tier": "st_opt", + "min": 7 + }, + { + "kw": "circle", + "tier": "st_opt", + "min": -2, + "parents": [ + "object", + "style" + ] + }, + { + "kw": "data", + "tier": "st_opt", + "min": 1, + "parents": [ + "style", + "xdata" + ] + }, + { + "kw": "ellipse", + "tier": "st_opt", + "min": 3, + "parents": [ + "object", + "style" + ] + }, + { + "kw": "function", + "tier": "st_opt", + "min": 1, + "parents": [ + "style" + ] + }, + { + "kw": "histogram", + "tier": "st_opt", + "min": 4, + "parents": [ + "style" + ] + }, + { + "kw": "line", + "tier": "st_opt", + "min": 1, + "parents": [ + "style" + ] + }, + { + "kw": "parallelaxis", + "tier": "st_opt", + "min": -4, + "parents": [ + "style" + ] + }, + { + "kw": "rectangle", + "tier": "st_opt", + "min": 4, + "parents": [ + "object", + "style" + ] + }, + { + "kw": "spiderplot", + "tier": "st_opt", + "min": 6, + "parents": [ + "_argument_set_show", + "grid", + "style" + ] + }, + { + "kw": "textbox", + "tier": "st_opt", + "min": 7 + }, + { + "kw": "watchpoint", + "tier": "st_opt", + "min": 5, + "parents": [ + "style" + ] + }, + { + "kw": "textcolor", + "tier": "tc", + "min": 5, + "alt": "tc" + } + ] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c8d3e22 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "gnuplot.vim", + "private": true, + "description": "Tooling for the gnuplot.vim syntax plugin", + "type": "module", + "scripts": { + "gen:syntax": "node scripts/gen-syntax.mjs", + "check:syntax": "node scripts/gen-syntax.mjs --check", + "test": "nvim --headless -u NONE -S tests/run.vim" + }, + "license": "MIT" +} diff --git a/scripts/gen-syntax.mjs b/scripts/gen-syntax.mjs new file mode 100644 index 0000000..80b7d02 --- /dev/null +++ b/scripts/gen-syntax.mjs @@ -0,0 +1,167 @@ +#!/usr/bin/env node +// Regenerate the keyword block in syntax/gnuplot.vim from keywords.json. +// +// keywords.json is a pinned copy of the dictionary emitted by the +// tree-sitter-gnuplot grammar (scripts/gen-keywords.mjs there). Every entry +// carries the keyword, its highlight tier, and the shortest abbreviation +// gnuplot accepts. Vim's `syn keyword` understands `xr[ange]` natively, which +// is exactly that abbreviation rule — so the whole table becomes plain keyword +// lists with no regex at all. +// +// Usage: node scripts/gen-syntax.mjs [--check] + +import { readFileSync, writeFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname, join } from "node:path"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const SYNTAX = join(root, "syntax", "gnuplot.vim"); +const BEGIN = '" >>> generated by scripts/gen-syntax.mjs — do not edit by hand'; +const END = '" <<< end generated block'; + +// Tier -> syntax group. Mirrors the capture taxonomy documented in the grammar +// repo: the same word in two clause families gets two aliases there, but Vim +// keywords are context-free, so tiers that read the same way share a group. +const GROUP = { + cmd: "gnuplotCommand", + opt: "gnuplotOption", + arg: "gnuplotOption", + name: "gnuplotOption", + axis: "gnuplotOption", + sa: "gnuplotOption", + lt: "gnuplotOption", + lc: "gnuplotOption", + dt: "gnuplotOption", + pt: "gnuplotOption", + ps: "gnuplotOption", + fs: "gnuplotOption", + fc: "gnuplotOption", + tc: "gnuplotOption", + flag: "gnuplotFlag", + coord: "gnuplotFlag", + mod: "gnuplotValue", + attr: "gnuplotAttribute", + plt_st: "gnuplotStyle", + st_opt: "gnuplotStyle", +}; + +// A word may legitimately belong to several tiers (`border` is an option head, +// a body flag and a suboption). Vim cannot tell those apart without the +// context matching this file deliberately avoids, so the first tier listed +// here wins and the choice is recorded in the generated output. +const PRIORITY = [ + "cmd", + "opt", + "plt_st", + "st_opt", + "attr", + "coord", + "mod", + "flag", + "arg", + "name", + "axis", + "sa", + "lt", + "lc", + "dt", + "pt", + "ps", + "fs", + "fc", + "tc", +]; + +// The table stores `min <= 0` as "full word minus |min|". +const effMin = (e) => (e.min <= 0 ? e.kw.length + e.min : e.min); + +// "xrange" with a minimum of 2 becomes `xr[ange]`; a keyword that takes no +// abbreviation is emitted bare. +function form(word, min) { + const m = Math.max(1, Math.min(min, word.length)); + return m >= word.length ? word : `${word.slice(0, m)}[${word.slice(m)}]`; +} + +function build() { + const { keywords } = JSON.parse(readFileSync(join(root, "keywords.json"), "utf8")); + + // resolve each word to a single tier + const chosen = new Map(); + for (const e of keywords) { + const prev = chosen.get(e.kw); + if (!prev || PRIORITY.indexOf(e.tier) < PRIORITY.indexOf(prev.tier)) chosen.set(e.kw, e); + } + + const buckets = new Map(); + const add = (group, text) => { + if (!buckets.has(group)) buckets.set(group, new Set()); + buckets.get(group).add(text); + }; + + for (const e of chosen.values()) { + const group = GROUP[e.tier]; + if (!group) throw new Error(`no group for tier ${e.tier} (${e.kw})`); + add(group, form(e.kw, effMin(e))); + // `lw`, `ls`, `tc` … — fixed two-letter spellings, never abbreviated + if (e.alt) add(group, e.alt); + // toggles also exist in their `no` spelling + if (e.no) add(group, `no${form(e.kw, effMin(e))}`); + } + + // Vim resolves a keyword defined twice to the LAST definition, so emit the + // groups in reverse priority: whichever tier should win a collision is + // written last. `p` is both `p[lot]` and `p[oints]`, and a command verb at + // the start of a statement is the more valuable of the two to get right. + const ORDER = [ + "gnuplotValue", + "gnuplotFlag", + "gnuplotOption", + "gnuplotStyle", + "gnuplotAttribute", + "gnuplotCommand", + ]; + const groups = [...buckets.keys()].sort( + (x, y) => ORDER.indexOf(x) - ORDER.indexOf(y) + ); + + const lines = [BEGIN]; + lines.push( + `" ${chosen.size} keywords across ${buckets.size} groups. Regenerate with`, + '" `npm run gen:syntax` after updating keywords.json.', + '" Groups are emitted in reverse-priority order: Vim resolves a keyword', + '" defined twice to the last definition.' + ); + for (const group of groups) { + const words = [...buckets.get(group)].sort(); + lines.push(""); + let line = `syn keyword ${group}`; + for (const w of words) { + if (line.length + w.length + 1 > 78) { + lines.push(line); + line = `syn keyword ${group}`; + } + line += ` ${w}`; + } + if (line.trim()) lines.push(line); + } + lines.push(END); + return lines.join("\n"); +} + +const block = build(); +const current = readFileSync(SYNTAX, "utf8"); +const start = current.indexOf(BEGIN); +const stop = current.indexOf(END); +if (start < 0 || stop < 0) throw new Error(`markers missing in ${SYNTAX}`); +const next = current.slice(0, start) + block + current.slice(stop + END.length); + +if (process.argv.includes("--check")) { + if (next !== current) { + console.error("syntax/gnuplot.vim is stale — run `npm run gen:syntax`"); + process.exit(1); + } + console.log("syntax/gnuplot.vim is up to date"); +} else { + writeFileSync(SYNTAX, next); + console.log(`wrote ${SYNTAX}`); +} diff --git a/syntax/gnuplot.vim b/syntax/gnuplot.vim index a5a15ec..7a62c5f 100644 --- a/syntax/gnuplot.vim +++ b/syntax/gnuplot.vim @@ -1,546 +1,310 @@ " Vim syntax file -" Language: Gnuplot 5.5 -" Creator: Dai López Jacinto -" Last Change: Mar 28, 2022 -" Filenames: *.plt *.plot *.gp *.gnuplot *.gnu -" URL: http://www.github/dpezto/gnuplot.vim/ +" Language: gnuplot 6 +" Maintainer: Dai López Jacinto +" URL: https://github.com/dpezto/gnuplot.vim +" License: MIT +" +" The keyword lists at the bottom of this file are generated from +" keywords.json, a pinned copy of the dictionary emitted by the +" tree-sitter-gnuplot grammar. Every gnuplot keyword may be abbreviated down to +" some minimum length, and Vim's `syn keyword` spells that natively as +" `xr[ange]` — so the abbreviation rules are carried over exactly without a +" single regex. Edit keywords.json and run `npm run gen:syntax`; do not edit +" between the generated markers. -" Use :syn w/in a buffer to see language element breakdown - -if version < 600 - syntax clear -elseif exists("b:current_syntax") +if exists('b:current_syntax') finish endif -" Number -------------------------------------------------------------------{{{ -syn keyword gnuNumber pi NaN I -syn match gnuNumber "\v<\d*((\.\d+)?((e|E)(-|\+)?\d+)?)?" -syn match gnuNumber "\v(<\d*((\.\d+)?((e|E)(-|\+)?\d+)?)?)@<=(cm|in|pt)" -hi def link gnuNumber Number -" }}} +let s:cpo_save = &cpo +set cpo&vim + +" gnuplot identifiers are [A-Za-z_][A-Za-z0-9_]*, and several built-in +" variables (GPVAL_TERM, STATS_mean_y) rely on '_' being a keyword character. +syn iskeyword @,48-57,_ + +" Comments ------------------------------------------------------------------ +" A trailing backslash continues a comment onto the next line. +syn match gnuplotComment "#.*\%(\\\n.*\)*$" contains=gnuplotTodo,@Spell +syn keyword gnuplotTodo contained TODO FIXME XXX BUG NOTE HACK + +" Strings ------------------------------------------------------------------- +" Double quotes interpret backslash escapes; single quotes do not. +syn match gnuplotEscape contained "\\\%([\\abfnrtv"']\|[0-7]\{1,3}\|x\x\{1,2}\|u\x\{4}\|U\x\{8}\)" +syn match gnuplotFormat contained "%[-+ #0]*\d*\%(\.\d\+\)\?[hlLqjzt]*[diouxXeEfgGcsSpP%]" +syn region gnuplotString start=+"+ skip=+\\.+ end=+"+ contains=gnuplotEscape,gnuplotFormat,@Spell +syn region gnuplotString start=+'+ end=+'+ contains=gnuplotFormat,@Spell + +" Datablocks ---------------------------------------------------------------- +" `$data << EOD ... EOD` — the terminator is user-chosen, so match the whole +" block generically rather than pinning it to EOD. +syn region gnuplotDatablock matchgroup=gnuplotDatablockName + \ start="^\s*\$\h\w*\s*<<\s*\z(\h\w*\)" end="^\s*\z1\s*$" +syn match gnuplotDatablockName "\$\h\w*" -" User-defined -------------------------------------------------------------{{{ -syn match gnuDef "\v\w+(\(\p*)@=" " function -syn match gnuDef "\v\w+(\[[^:]+)@=" " array -hi def link gnuDef Define -" }}} +" Macros -------------------------------------------------------------------- +syn match gnuplotMacro "@\h\w*" -" Commands ------------------------------------------------------------------{{{ -syn keyword gnuCmd array break cd call clear continue do -syn keyword gnuCmd exit fit help history if else for import -syn keyword gnuCmd load lower pause print pwd quit raise refresh reread -syn keyword gnuCmd reset save set shell show stats sum system -syn keyword gnuCmd test toggle undefine unset update vclear vfill while -syn match gnuCmd "\v(||)" -hi def link gnuCmd Statement -" }}} +" Numbers ------------------------------------------------------------------- +" gnuplot folds a unit suffix into the number itself (10cm, 3.0in, 0.5pt). +syn match gnuplotNumber "\<\d\+\%(\.\d*\)\?\%([eE][-+]\?\d\+\)\?\%(cm\|in\|pt\)\?\>" +syn match gnuplotNumber "\<\.\d\+\%([eE][-+]\?\d\+\)\?\%(cm\|in\|pt\)\?\>" +syn match gnuplotNumber "\<0[xX]\x\+\>" -" Gnuplot-defined variables ------------------------------------------------{{{ -syn match gnuVar "\v(GPVAL_)(\1)@<=(\w+>)" -" Stats -syn match gnuVar "\v\w+(_records|_headers|_outofrange|_invalid|_blank|_blocks)@=(\1)" -syn match gnuVar "\v\w+(_columns|_column_header|_index(_min|_max)(_x|_y)?)@=(\1)" -syn match gnuVar "\v\w+(_min(_x|_y)?|_max(_x|_y)?|_mean(_err)?(_x|_y)?|_stddev(_err)?(_x|_y)?)@=(\1)" -syn match gnuVar "\v\w+(_ssd(_x|_y)?|_(lo|up)_quartile(_x|_y)?|_median(_x|_y)?|_sum(sq)?(_x|_y)?)@=(\1)" -syn match gnuVar "\v\w+(_skewness(_err)?(_x|_y)?|_kurtosis(_err)?(_x|_y)?|_adev(_x|_y)?)@=(\1)" -syn match gnuVar "\v\w+(_correlation|_slope(_err)?|_intercept(_err)?)@=(\1)" -syn match gnuVar "\v\w+(_sumxy|_pos(_min|_max)_y)@=(\1)" -syn match gnuVar "\v\w+(_size(_x|_y))@=(\1)" -" Mouse -syn match gnuVar "\v(MOUSE_)(\1)@<=(\w+>)" -hi def link gnuVar Constant -" }}} +" Built-in variables -------------------------------------------------------- +" GPVAL_*, MOUSE_*, FIT_*, ARG*, and the `stats`/`fit` output variables, whose +" prefix the user chooses (`stats … prefix "FOO"`). +syn match gnuplotBuiltinVar "\<\%(GPVAL\|MOUSE\|FIT\)_\w\+\>" +syn match gnuplotBuiltinVar "\" +syn match gnuplotBuiltinVar "\<\w\+_\%(mean\|stddev\|skewness\|kurtosis\)\%(_err\)\?\%(_x\|_y\)\?\>" +syn match gnuplotBuiltinVar "\<\w\+_\%(min\|max\|sdd\|adev\|median\|sum\%(sq\)\?\|\%(lo\|up\)_quartile\)\%(_x\|_y\)\?\>" +syn match gnuplotBuiltinVar "\<\w\+_\%(slope\|intercept\)\%(_err\)\?\>" +syn match gnuplotBuiltinVar "\<\w\+_\%(records\|headers\|outofrange\|invalid\|blank\|blocks\|correlation\|sumxy\|columns\|column_header\|size_x\|size_y\)\>" +syn keyword gnuplotBuiltinVar GNUTERM VoxelDistance GridDistance -" Fit ----------------------------------------------------------------------{{{ -syn match fitOpt "\v(fit .*)@<=(|every|skip)" -syn match fitOpt "\v(fit .*)@<=(|(x|y|xy|x)error)" -syn match fitOpt "\v(fit .*)@<=(errors|via)" -hi def link fitOpt Keyword -" }}} +" Functions ----------------------------------------------------------------- +" Any identifier immediately followed by '(' reads as a call; the built-in list +" is defined afterwards so it wins on the same match position. +syn match gnuplotFunction "\<\h\w*\ze(" +syn match gnuplotBuiltinFunction "\<\%(abs\|acosh\|acos\|airy\|arg\|asinh\|asin\|atan2\|atanh\|atan\|cbrt\|ceil\|conj\|cosh\|cos\|exp\|floor\|imag\|int\|log10\|log\|norm\|rand\|real\|round\|sgn\|sinh\|sin\|sqrt\|tanh\|tan\)\ze(" +syn match gnuplotBuiltinFunction "\<\%(bes[ijy][01n]\|Ai\|Bi\|Bessel[HIJKY]1\?2\?\|Elliptic[EKP]i\?\|erfc\|erfi\|erf\|expint\|gamma\|ibeta\|igamma\|inverf\|invibeta\|invigamma\|invnorm\|LambertW\|lgamma\|lnGamma\|SynchrotronF\|uigamma\|voigt\|zeta\)\ze(" +syn match gnuplotBuiltinFunction "\<\%(cdawson\|cerf\|faddeeva\|Fresnel[CS]\|VP\%(_fwhm\)\?\)\ze(" +syn match gnuplotBuiltinFunction "\<\%(gprintf\|sprintf\|strlen\|strstrt\|substr\|split\|join\|trim\|word\|words\|system\)\ze(" +syn match gnuplotBuiltinFunction "\<\%(column\|columnhead\%(er\)\?\|stringcolumn\|strcol\|exists\|valid\|value\|hsv2rgb\|palette\|rgbcolor\|voxel\|index\)\ze(" +syn match gnuplotBuiltinFunction "\<\%(time\%(column\)\?\|strftime\|strptime\|tm_\w\+\|weekdate_\%(iso\|cdc\)\)\ze(" -" Pause --------------------------------------------------------------------{{{ -syn match pauseOpt "\v(pause .*)@<=(mouse)" -hi def link pauseOpt Structure -" Mouse -syn match pa_mouseOpt "\v(pause mouse .*)@<=(keypress|button1|button2|button3|close|any)" -hi def link pa_mouseOpt Identifier -" }}} +" Operators ----------------------------------------------------------------- +syn match gnuplotOperator "[-+*/%^!~?:.]" +syn match gnuplotOperator "\*\*" +syn match gnuplotOperator "[=!<>]=" +syn match gnuplotOperator "[<>]" +syn match gnuplotOperator "<<\|>>" +syn match gnuplotOperator "&&\|||\|[&|]" +syn match gnuplotOperator "=" +syn keyword gnuplotOperator eq ne -" Plot/Splot ---------------------------------------------------------------{{{ -syn match pltOpt "\v(.*\s|(\\\s*\n)+.*\s)@<=(keyentry|binary|nonuniform|sparse|matrix|)" -syn match pltOpt "\v(.*\s|(\\\s*\n)+.*\s)@<=(every|skip|)" -syn match pltOpt "\v(.*\s|(\\\s*\n)+.*\s)@<=(|smooth|bins|mask|convexhull|zsort)" -syn match pltOpt "\v(.*\s|(\\\s*\n)+.*\s)@<=(<(no)?t(it)?(le)?>)" -hi def link pltOpt Keyword -" Smooth -syn match plt_smtOpt "\v(smooth )@<=(unique|frequency|fnormal|cumulative|cnormal)" -syn match plt_smtOpt "\v(smooth )@<=(csplines|acsplines|mcsplines|path|bezier)" -syn match plt_smtOpt "\v(smooth )@<=(sbezier|kdensity|convexhull|unwrap)" -hi def link plt_smtOpt Identifier -" With -syn match plt_withOpt "\v( )@<=(||linespoints|)" -syn match plt_withOpt "\v( )@<=(financebars||impulses|labels)" -syn match plt_withOpt "\v( )@<=(surface|(f|hi)?steps|arrows|v(ec)?(tors)?)" -syn match plt_withOpt "\v( )@<=((x|y)error(bar|lines)|xyerror(bars|lines))" -syn match plt_withOpt "\v( )@<=(parallelaxes|spiderplot)" -syn match plt_withOpt "\v(p(l(ot?)?)?.*\s|(\\\s*\n)+.*\s)@<=(newspiderplot)" -syn match plt_withOpt "\v( )@<=(boxes|boxerrorbars|boxxyerror|isosurface)" -syn match plt_withOpt "\v( )@<=(boxplot|candlesticks|circles|zerrorfill)" -syn match plt_withOpt "\v( )@<=(ellipses|filledcurves?|fillsteps|histograms)" -syn match plt_withOpt "\v( )@<=(image|pm3d|rgbalpha|rgbimage|polygons)" -hi def link plt_withOpt Identifier -" filledcurves -syn match plt_fillcOpt "\v(filledcurves? .*)@<=(closed|above|below|between)" -hi def link plt_fillcOpt Constant -" subattributes -syn match plts_withOpt "\v((p(l(ot?)?)?.*\s|(\\\s*\n)+.*\s))@<=(|||||)" -hi def link plts_withOpt Constant -" Title -syn match plt_titOps "\v(<(no)?t(it)?(le)? )@<=(|<(no)?enhanced)" -hi def link plt_titOps Identifier -" subattributes -syn match plts_titOps "\v(<(no)?t(it)?(le)? .*at .*)@<=(beginning|end)" -hi def link plts_titOps Constant -" }}} +" Shell escape -------------------------------------------------------------- +syn match gnuplotShell "^\s*!.*$" -" Reset --------------------------------------------------------------------{{{ -syn match resOpt "\v(reset )@<=(bind|errors|session)" -hi def link resOpt Structure -" }}} +" Keywords ------------------------------------------------------------------ +" >>> generated by scripts/gen-syntax.mjs — do not edit by hand +" 724 keywords across 6 groups. Regenerate with +" `npm run gen:syntax` after updating keywords.json. +" Groups are emitted in reverse-priority order: Vim resolves a keyword +" defined twice to the last definition. -" Set/show -----------------------------------------------------------------{{{ -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|)" -syn match setOpt "\v(((un)?set|show) .*)@<=()" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=()" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|)" -syn match setOpt "\v(((un)?set|show) .*)@<=(<(b|l|r|t)?m(ar)?(gin)?>)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=()" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(|||)" -syn match setOpt "\v(((un)?set|show) .*)@<=(