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..7fc064f --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,78 @@ +# 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). Keeping +the two in step is the point of the arrangement; patching the generated block +locally defeats it. + +You do not normally have to copy the dictionary by hand: `sync-keywords.yml` +compares the vendored `keywords.json` against the grammar's default branch every +Monday and opens a PR when they differ, regenerating the syntax file in the same +commit. Run it on demand from the Actions tab. Review those PRs rather than +rubber-stamping them — a keyword whose tier changed moves between highlight +groups, and one whose `min` changed alters which abbreviations are recognised. + +## 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 and releases are cut by +[release-please](https://github.com/googleapis/release-please) from the commit +history, so **PR titles must follow +[Conventional Commits](https://www.conventionalcommits.org)** (`feat: …`, +`fix: …`, `docs: …`). CI checks the title; `feat` and `fix` decide the version +bump and the CHANGELOG entry, and a `!` suffix or a `BREAKING CHANGE:` footer +forces a major. + +Do **not** hand-edit versions. release-please owns `version.txt`, +`CHANGELOG.md` and the `version` and `date-released` fields of `CITATION.cff` — +the latter two through the `# x-release-please-version` and +`# x-release-please-date` markers on those lines. A file that is not listed +under `extra-files` in `.release-please-config.json` is silently never updated, +which is how a CITATION.cff goes stale without anyone noticing. + +## 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..03f3827 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +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.12" + # vint still imports pkg_resources, which setuptools 81 removed and + # Python 3.13+ no longer bundles at all — hence both pins. + - run: pip install vim-vint "setuptools<81" + - 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/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..85bcee6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,38 @@ +name: release + +on: + push: + branches: [main] + +permissions: + contents: write + pull-requests: write + +jobs: + # release-please keeps a release PR open, accumulating the CHANGELOG and the + # version bump (version.txt and CITATION.cff, per .release-please-config.json). + # Merging that PR creates the tag and the GitHub Release in this same run. + # + # There is nothing to publish: plugin managers install straight from the git + # repository, so a tag is the whole release. + release-please: + runs-on: ubuntu-latest + steps: + # Mint a GitHub App token so the release PR is opened by the App rather + # than GITHUB_TOKEN. A PR created by GITHUB_TOKEN cannot trigger CI, so it + # would arrive with no status checks and could not satisfy branch + # protection without an admin merge. + - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 + id: app-token + # Tolerate missing App secrets: the step below falls back to + # GITHUB_TOKEN, and the release still works — the release PR just needs + # an admin merge because it has no checks. + continue-on-error: true + with: + app-id: ${{ secrets.RELEASE_PLEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_PLEASE_APP_KEY }} + - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5 + with: + token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} + config-file: .release-please-config.json + manifest-file: .release-please-manifest.json diff --git a/.github/workflows/sync-keywords.yml b/.github/workflows/sync-keywords.yml new file mode 100644 index 0000000..2cb9b0a --- /dev/null +++ b/.github/workflows/sync-keywords.yml @@ -0,0 +1,97 @@ +name: sync keywords + +# keywords.json is a pinned copy of the dictionary tree-sitter-gnuplot emits. +# Nothing about a vendored file notices when its source moves, so this checks +# weekly and opens a PR when the two differ. The PR runs the normal CI, so a +# sync that would break the syntax file or the assertions cannot merge. +# +# It tracks the grammar's DEFAULT BRANCH, not its latest release. The dictionary +# is generated data about gnuplot rather than an API surface, so newer simply +# means better keyword coverage, and grammar releases lag main by however long +# the next release PR sits — at the time of writing, v3.0.0 carried 772 entries +# against main's 794, so following releases would have rolled the plugin +# backwards. The grammar repo is PR-only with required checks, so its main is +# always green. +on: + schedule: + - cron: "0 5 * * 1" + workflow_dispatch: + +# create-pull-request needs write access when it falls back to GITHUB_TOKEN. +permissions: + contents: write + pull-requests: write + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6 + with: + node-version: lts/* + + - name: Fetch the dictionary from the grammar + id: fetch + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: dpezto/tree-sitter-gnuplot + run: | + rev=$(gh api "repos/$REPO/commits/main" --jq '.sha') + echo "rev=$rev" >> "$GITHUB_OUTPUT" + echo "short=${rev:0:7}" >> "$GITHUB_OUTPUT" + gh api "repos/$REPO/contents/keywords.json?ref=$rev" \ + --jq '.content' | base64 -d > keywords.json.new + # A truncated or error response must not be written over the vendored + # copy: require it to parse and to carry entries. + node -e ' + const k = JSON.parse(require("fs").readFileSync("keywords.json.new", "utf8")); + if (!Array.isArray(k.keywords) || k.keywords.length < 100) { + throw new Error("dictionary looks wrong: " + (k.keywords || []).length + " entries"); + } + console.log("fetched " + k.keywords.length + " keywords"); + ' + if cmp -s keywords.json.new keywords.json; then + echo "changed=false" >> "$GITHUB_OUTPUT" + rm keywords.json.new + else + echo "changed=true" >> "$GITHUB_OUTPUT" + mv keywords.json.new keywords.json + fi + + - name: Regenerate the syntax file + if: steps.fetch.outputs.changed == 'true' + run: node scripts/gen-syntax.mjs + + # A PR opened with GITHUB_TOKEN cannot trigger CI, so it would arrive with + # no checks and could not satisfy branch protection. Fall back to it + # anyway when the App secrets are absent — the PR then needs an admin + # merge, which is better than no PR. + - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 + id: app-token + if: steps.fetch.outputs.changed == 'true' + continue-on-error: true + with: + app-id: ${{ secrets.RELEASE_PLEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_PLEASE_APP_KEY }} + + - uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7 + if: steps.fetch.outputs.changed == 'true' + with: + token: ${{ steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} + branch: chore/sync-keywords + # `fix` so a dictionary change reaches a release on its own; a `chore` + # would sit unreleased until something else happened to land. + title: "fix(keywords): sync the dictionary from tree-sitter-gnuplot" + commit-message: "fix(keywords): sync the dictionary from tree-sitter-gnuplot@${{ steps.fetch.outputs.short }}" + body: | + `keywords.json` differs from the copy on tree-sitter-gnuplot's + default branch at + [${{ steps.fetch.outputs.short }}](https://github.com/dpezto/tree-sitter-gnuplot/commit/${{ steps.fetch.outputs.rev }}). + Updated here and `syntax/gnuplot.vim` regenerated from it. + + Worth a look at the diff before merging: a keyword whose tier + changed moves between highlight groups, and one whose `min` changed + alters which abbreviations are recognised. + labels: dependencies + delete-branch: true 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/.release-please-config.json b/.release-please-config.json new file mode 100644 index 0000000..1adc857 --- /dev/null +++ b/.release-please-config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "simple", + "include-component-in-tag": false, + "changelog-path": "CHANGELOG.md", + "initial-version": "1.0.0", + "packages": { + ".": { + "extra-files": [ + { "type": "generic", "path": "CITATION.cff" } + ] + } + } +} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..e18ee07 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.0.0" +} diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..b60b9d7 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,24 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +title: gnuplot.vim +abstract: >- + Syntax highlighting for gnuplot 6 in Vim and Neovim. The keyword lists are + generated from the tree-sitter-gnuplot dictionary, so both projects recognise + the same words with the same abbreviation rules, and under Neovim the + highlight groups link to the same treesitter captures the grammar uses. +type: software +authors: + - given-names: Dai + family-names: López Jacinto + alias: dpezto + orcid: "https://orcid.org/0009-0009-6780-6977" +repository-code: "https://github.com/dpezto/gnuplot.vim" +license: MIT +keywords: + - gnuplot + - vim + - neovim + - syntax-highlighting + - vim-plugin +version: 0.0.0 # x-release-please-version +date-released: "2026-07-26" # x-release-please-date diff --git a/README.md b/README.md index 95499b2..c5d8849 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,108 @@ -# 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`, `.gpi`, `.plot` and `.plt`, the files `gnuplotrc` and +`.gnuplot`, plus anything 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 -``` +`.gp` is left to PARI/GP, which owns it in the stock Vim and Neovim runtimes. + +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 the generated lists spell that as +`p[lot]` — `:syn-keyword`'s own notation for an optional tail — so an +abbreviation costs no regular expression at all. Which keywords may appear +short is a deliberate choice rather than the full set; see +[Known limits](#known-limits). + +## Colours match the tree-sitter grammar + +Under Neovim the syntax groups link to the same treesitter captures that +[tree-sitter-gnuplot](https://github.com/dpezto/tree-sitter-gnuplot) uses in its +`highlights.scm` — `@keyword` for a command verb, `@variable.member` for an +option or suboption, `@keyword.directive` for a toggle, `@constant` for an +enumerated value, `@property` for a plot-element modifier, `@attribute` for a +plot style. A buffer highlighted by this plugin and one highlighted by the +grammar therefore pick up identical colours from the colorscheme. Measured over +a representative script, the two agree on **92.5%** of the characters they both +highlight; the remainder is listed below. + +Neovim ships default highlights for every standard capture, so this holds even +without a treesitter parser installed. Under Vim, which has no such groups, the +links fall back to the standard ones (`Statement`, `Identifier`, `PreProc`, …). -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. + +Abbreviations are opt-in. Honouring every one of gnuplot's would make most +single letters keywords — fifty-one reduce to one character — so `a = 42` and a +loop counter would light up. Only the forms that are near-universal are +abbreviated: `plot`, `splot`, `replot`, `terminal`, `output`, `using`, `with`, +`title`, `notitle` and the three `with` values. Everything else needs its whole +word, which is why `set xr` is not highlighted. + +Two deliberate differences from the grammar: a datablock body is inert here +(the grammar highlights its contents), and `!` marks only the shell escape +itself, since Vim cannot inject bash into the rest of the line. + +## 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. + +New keywords arrive on their own: a weekly job compares the vendored +`keywords.json` against tree-sitter-gnuplot and opens a PR when it has moved, +regenerating the syntax file with it. + +## Citation + +`CITATION.cff` carries the current version and release date. Both are written +by release-please, so a `Cite this repository` on GitHub always matches the +latest tag. + +## 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..a1f2285 --- /dev/null +++ b/doc/gnuplot.txt @@ -0,0 +1,133 @@ +*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 .gpi .plot .plt + +the files `gnuplotrc` and `.gnuplot`, + +and for any file whose first line is a shebang naming gnuplot: > + + #!/usr/bin/env gnuplot + +`.gp` is not claimed: the stock runtimes assign it to PARI/GP. Detection uses +|:setf| under Vim, which yields to a filetype another runtime file already set, +and `vim.filetype.add()` under Neovim. + +To claim it anyway, add this to your own config rather than to the plugin: > + + " Neovim + vim.filetype.add({ extension = { gp = "gnuplot" } }) + + " Vim + autocmd BufNewFile,BufRead *.gp set filetype=gnuplot + +============================================================================== +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 + + gnuplotConnector at, via, from, to, by + gnuplotColorName viridis, black, bgnd, background + gnuplotStyleVariable the `variable` style slot + gnuplotPseudoElement newhistogram, newspiderplot, keyentry + + gnuplotComment gnuplotTodo gnuplotString gnuplotEscape gnuplotFormat + gnuplotDatablock gnuplotDatablockName gnuplotDatablockRef gnuplotColumnRef + gnuplotMacro gnuplotNumber gnuplotConstant gnuplotBuiltinVar + gnuplotFunction gnuplotBuiltinFunction gnuplotOperator + gnuplotKeywordOperator gnuplotBracket gnuplotWildcard gnuplotShell + +Under Neovim each links to the treesitter capture the grammar's own queries +use, so a buffer highlighted by this plugin and one highlighted by +tree-sitter-gnuplot take the same colours from the colorscheme: `@keyword`, +`@variable.member`, `@keyword.directive`, `@constant`, `@property`, +`@attribute` and so on. Neovim defines every standard capture by default, so +this works with no parser installed. Under Vim the links fall back to the +standard groups. + +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. The generated lists spell that as +`p[lot]`, which is |:syn-keyword|'s own notation for an optional tail, so an +abbreviation costs no regular expression at all. + +Which keywords may appear short is deliberately a small list rather than all of +them: plot, splot, replot, terminal, output, using, with, title, notitle and +the three `with` values lines, points and linespoints. Honouring every gnuplot +abbreviation would make most single letters keywords -- fifty-one of them +shorten to one character -- so `a = 42` and a loop counter would light up. + +============================================================================== +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, plot style, style substyle, element modifier, +coordinate, enumerated value, toggle, suboption. + +`set xr` is not highlighted because xrange is not on the abbreviation list +above; its whole word is required. + +Two differences from the grammar are deliberate: a datablock body is inert +here, where the grammar highlights its contents, and `!` marks only the shell +escape itself because Vim cannot inject bash into the rest of the line. + +============================================================================== +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.lua b/ftdetect/gnuplot.lua new file mode 100644 index 0000000..8d85d78 --- /dev/null +++ b/ftdetect/gnuplot.lua @@ -0,0 +1,21 @@ +-- Filetype detection for gnuplot scripts (Neovim). +-- +-- Registered through vim.filetype.add() rather than an autocmd, which is how +-- Neovim resolves filetypes: vim.filetype.match() consults entries added here +-- before its own tables. +-- +-- The stock runtime already maps `.gpi` and `.gnuplot`; the rest are added +-- here. `.gp` is left alone, since PARI/GP owns it in the stock runtimes. +vim.filetype.add({ + extension = { + gnu = 'gnuplot', + gnuplot = 'gnuplot', + gpi = 'gnuplot', + plot = 'gnuplot', + plt = 'gnuplot', + }, + filename = { + ['gnuplotrc'] = 'gnuplot', + ['.gnuplot'] = 'gnuplot', + }, +}) diff --git a/ftdetect/gnuplot.vim b/ftdetect/gnuplot.vim index 2428fa6..217021d 100644 --- a/ftdetect/gnuplot.vim +++ b/ftdetect/gnuplot.vim @@ -1,2 +1,24 @@ -" Install Filetype detection for Gnuplot files -au BufNewFile,BufRead *.pal, *.plt, *.plot, *.gnuplot, *.gnu, *.gp set filetype=gnuplot +" Filetype detection for gnuplot scripts (Vim). +" +" Neovim is handled by ftdetect/gnuplot.lua, which registers through +" vim.filetype.add() instead. +scriptencoding utf-8 + +if has('nvim') + finish +endif + +" 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. +augroup gnuplotFtdetect + autocmd! + " :setfiletype yields to a filetype another runtime file already set, which + " is what we want: `.gp` belongs to PARI/GP in the stock runtimes and is left + " to it. + autocmd BufNewFile,BufRead *.gnu,*.gnuplot,*.gpi,*.plot,*.plt + \ setfiletype gnuplot + autocmd BufNewFile,BufRead gnuplotrc,.gnuplot setfiletype gnuplot + " Scripts run through `gnuplot` with a shebang. + autocmd BufNewFile,BufRead * + \ if getline(1) =~# '^#!.*\' | setfiletype gnuplot | endif +augroup END diff --git a/ftplugin/gnuplot.vim b/ftplugin/gnuplot.vim new file mode 100644 index 0000000..f1ddfde --- /dev/null +++ b/ftplugin/gnuplot.vim @@ -0,0 +1,31 @@ +" Vim filetype plugin +" Language: gnuplot 6 +" Maintainer: Dai López Jacinto +scriptencoding utf-8 + + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +let s:cpo_save = &cpoptions +set cpoptions&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 &cpoptions = 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..50d4f29 --- /dev/null +++ b/scripts/gen-syntax.mjs @@ -0,0 +1,229 @@ +#!/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); + +// Keywords allowed to appear abbreviated. +// +// gnuplot lets almost every keyword be shortened, but Vim keywords carry no +// context, so honouring all of them means a bare `a`, `h`, `i`, `x` or `w` +// lights up as a keyword wherever it appears — including `a = 42` and a loop +// variable. Fifty-one keywords reduce to a single letter, which is most of the +// alphabet. +// +// So abbreviations are opt-in, and the list is deliberately short: the forms +// that are near-universal in real gnuplot scripts. Everything else is matched +// as a whole word only. `lines`/`points`/`linespoints` are here because `w l` +// and `w lp` are inseparable from `with`. +const ABBREVIATED = new Set([ + "plot", + "splot", + "replot", + "terminal", + "output", + "using", + "with", + "title", + "notitle", + "lines", + "points", + "linespoints", +]); + +// "xrange" with a minimum of 2 becomes `xr[ange]`, but only for a keyword on +// the allowlist; everything else is emitted whole. +function form(word, min) { + if (!ABBREVIATED.has(word)) return word; + 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, but merge `alt` and `no` across every + // entry for that word: `pointsize` is both a set/show option head and a style + // attribute, and only the latter carries the `ps` spelling. Picking one entry + // and reading its fields alone silently drops the short form. + 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, alt: e.alt ?? prev?.alt, no: e.no ?? prev?.no }); + } else { + prev.alt = prev.alt ?? e.alt; + prev.no = prev.no ?? e.no; + } + } + + 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) + ); + + // Vim parses trailing words on a `:syn keyword` line as syntax ARGUMENTS, so + // a keyword that happens to be spelled like one is silently swallowed and + // never registers. gnuplot has three: `extend` (set xrange noextend), + // `transparent` (fillstyle) and `start` (palette cubehelix). They are emitted + // as matches instead, which has no such parsing quirk. + const RESERVED = new Set([ + "cchar", "conceal", "concealends", "contained", "containedin", "contains", + "display", "excludenl", "extend", "fold", "keepend", "matchgroup", + "nextgroup", "oneline", "skip", "skipempty", "skipnl", "skipwhite", + "transparent", "end", "start", + ]); + const matches = []; + for (const [group, set] of buckets) { + for (const w of [...set]) { + if (RESERVED.has(w)) { + set.delete(w); + matches.push(`syn match ${group} "\\<${w}\\>"`); + } + } + } + + 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); + } + if (matches.length) { + lines.push(""); + lines.push('" Spelled like :syn arguments, so these cannot be keywords.'); + lines.push(...matches.sort()); + } + 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..09e55d7 100644 --- a/syntax/gnuplot.vim +++ b/syntax/gnuplot.vim @@ -1,546 +1,452 @@ " 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. +scriptencoding utf-8 -" 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 -" }}} - -" User-defined -------------------------------------------------------------{{{ -syn match gnuDef "\v\w+(\(\p*)@=" " function -syn match gnuDef "\v\w+(\[[^:]+)@=" " array -hi def link gnuDef Define -" }}} - -" 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 -" }}} - -" 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 -" }}} - -" 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 -" }}} - -" 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 -" }}} - -" 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 -" }}} - -" Reset --------------------------------------------------------------------{{{ -syn match resOpt "\v(reset )@<=(bind|errors|session)" -hi def link resOpt Structure -" }}} - -" 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) .*)@<=(