diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcf5b85 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +src/scanner.c -linguist-detectable +queries/highlights.scm -linguist-detectable diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..b35cffc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,56 @@ +name: Bug Report +description: File a bug or issue +title: "bug: " +labels: [bug] +body: + - type: markdown + attributes: + value: | + **Before** reporting an issue, make sure to search [existing issues](https://github.com/tree-sitter-grammars/tree-sitter-PARSER_NAME/issues). + If your issue is related to a bug in your editor-experience because your editor *leverages* tree-sitter and this parser, then it is likely your issue does *NOT* belong here and belongs in the relevant editor's repository. + - type: checkboxes + attributes: + label: Did you check existing issues? + description: Make sure you've checked all of the below before submitting an issue + options: + - label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser + required: false + - label: I have searched the existing issues of tree-sitter-PARSER_NAME + required: true + - type: input + attributes: + label: "Tree-Sitter CLI Version, if relevant (output of `tree-sitter --version`)" + placeholder: "tree-sitter 0.20.8 (6bbb50bef8249e6460e7d69e42cc8146622fa4fd)" + validations: + required: false + - type: textarea + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. Please include any related errors you see such as parsing errors or tree-sitter cli errors. + validations: + required: true + - type: textarea + attributes: + label: Steps To Reproduce/Bad Parse Tree + description: Steps to reproduce the behavior. If you have a bad parse tree, please include it here. You can get this by running `tree-sitter parse ` and copying the output. + placeholder: | + 1. + 2. + 3. + validations: + required: true + - type: textarea + attributes: + label: Expected Behavior/Parse Tree + description: A concise description of what you expected to happen, or in the case of a bad parse tree, the expected parse tree. + validations: + required: true + - type: textarea + attributes: + label: Repro + description: Minimal code to reproduce this issue. Ideally this should be reproducible with the C library or the tree-sitter cli, do not suggest an editor or external tool. + placeholder: | + Example code that causes the issue + render: PARSER_NAME + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..cb9d51b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Matrix room + url: https://matrix.to/#/#tree-sitter-chat:matrix.org + about: Chat or ask questions diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..fc069a0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,36 @@ +name: Feature Request +description: Suggest a new feature +title: "feature: " +labels: [enhancement] +body: + - type: checkboxes + attributes: + label: Did you check the tree-sitter docs? + description: Make sure you read all the docs before submitting a feature request + options: + - label: I have read all the [tree-sitter docs](https://tree-sitter.github.io/tree-sitter/using-parsers) if it relates to using the parser + required: false + - type: textarea + validations: + required: true + attributes: + label: Is your feature request related to a problem? Please describe. + description: A clear and concise description of what the problem is. Ex. I think the grammar models this rule incorrectly and can be improved, or the scanner can be improved by doing [...], or PARSER_NAME has officially added a new feature that should be added to the grammar. + - type: textarea + validations: + required: true + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + - type: textarea + validations: + required: true + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + - type: textarea + validations: + required: false + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. If your feature request is related to a new PARSER_NAME feature, please include a link to the relevant **official** PARSER_NAME documentation. diff --git a/.github/not-dependabot.yml b/.github/not-dependabot.yml new file mode 100644 index 0000000..c19b8f1 --- /dev/null +++ b/.github/not-dependabot.yml @@ -0,0 +1,43 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: sunday + commit-message: + prefix: ci + labels: + - dependencies + groups: + actions: + patterns: ["*"] + + - package-ecosystem: npm + versioning-strategy: increase + directory: / + schedule: + interval: weekly + day: sunday + commit-message: + prefix: build(deps) + labels: + - dependencies + groups: + npm: + patterns: ["*"] + + # NOTE: uncomment to also keep cargo up-to-date + + # - package-ecosystem: cargo + # directory: / + # schedule: + # interval: weekly + # day: sunday + # commit-message: + # prefix: build(deps) + # labels: + # - dependencies + # groups: + # cargo: + # patterns: ["*"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4fef1d9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +name: CI + +on: + push: + branches: + - master + - main + paths: + - grammar.js + - src/** + - test/** + - bindings/** + - binding.gyp + pull_request: + paths: + - grammar.js + - src/** + - test/** + - bindings/** + - binding.gyp + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: true + +jobs: + test: + name: Test parser + runs-on: ${{matrix.os}} + if: >- + !github.event.repository.is_template && + github.event.head_commit.message != 'Initial commit' + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-14] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up tree-sitter + uses: tree-sitter/setup-action/cli@v1 + - name: Check for scanner changes + id: scanner-check + shell: sh + run: |- + { + test -f src/scanner.c && ! git diff --quiet HEAD^ -- "$_" && + printf 'changed=true\n' || printf 'changed=false\n' + } >> "$GITHUB_OUTPUT" + - name: Fuzz scanner + uses: tree-sitter/fuzz-action@v4 + if: steps.scanner-check.outputs.changed == 'true' + - name: Run tests + uses: tree-sitter/parser-test-action@v2 + with: + test-rust: ${{runner.os == 'Linux'}} + fuzz: + name: Fuzz scanner + runs-on: ubuntu-latest + if: >- + !github.event.repository.is_template && + github.event.head_commit.message != 'Initial commit' + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Check for scanner changes + id: scanner-check + shell: sh + run: |- + { + test -f src/scanner.c && ! git diff --quiet HEAD^ -- "$_" && + printf 'changed=true\n' || printf 'changed=false\n' + } >> "$GITHUB_OUTPUT" + - name: Run fuzzer + uses: tree-sitter/fuzz-action@v4 + if: steps.scanner-check.outputs.changed == 'true' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..022d6af --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,24 @@ +# NOTE: remove this workflow if you don't want to publish packages +name: Publish package + +on: + push: + tags: ["*"] + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: true + +jobs: + npm: + uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main + secrets: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + crates: + uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main + secrets: + CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_TOKEN}} + pypi: + uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main + secrets: + PYPI_API_TOKEN: ${{secrets.PYPI_TOKEN}} diff --git a/.github/workflows/regenerate.yml b/.github/workflows/regenerate.yml new file mode 100644 index 0000000..51139df --- /dev/null +++ b/.github/workflows/regenerate.yml @@ -0,0 +1,15 @@ +name: Regenerate parser + +on: + pull_request: + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: true + +jobs: + regenerate: + uses: tree-sitter/workflows/.github/workflows/regenerate.yml@main + if: >- + !github.event.repository.is_template && + github.actor == 'dependabot[bot]' diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml new file mode 100644 index 0000000..ad06a78 --- /dev/null +++ b/.github/workflows/setup.yml @@ -0,0 +1,98 @@ +name: Initial setup + +on: + push: + +permissions: write-all + +jobs: + setup: + runs-on: ubuntu-latest + if: "!github.event.repository.is_template" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install tree-sitter CLI + uses: tree-sitter/setup-action/cli@v1 + with: + tree-sitter-ref: latest + - name: Remove template files + run: rm .gitattributes .github/workflows/setup.yml + - name: Generate bindings + run: tree-sitter generate + - name: Set environment variables + run: |- + printf 'PARSER_NAME=%s\n' $(jq -r '.keywords[3]' package.json) >> "$GITHUB_ENV" + if [[ -n $AUTHOR_EMAIL && ${AUTHOR_EMAIL#*@} != users.noreply.github.com ]]; then + AUTHOR_NAME_EMAIL="$AUTHOR_NAME <$AUTHOR_EMAIL>" + fi + printf >> "$GITHUB_ENV" '%s\n' \ + "AUTHOR_NAME=$AUTHOR_NAME" \ + "AUTHOR_EMAIL=$AUTHOR_EMAIL" \ + "AUTHOR_NAME_EMAIL=${AUTHOR_NAME_EMAIL:-$AUTHOR_NAME}" + env: + AUTHOR_NAME: ${{github.event.head_commit.author.name}} + AUTHOR_EMAIL: ${{github.event.head_commit.author.email}} + - name: Update files + run: |- + sed -i README.md -e 's/PARSER_NAME/${{env.PARSER_NAME}}/' + sed -i LICENSE -e 's/AUTHOR_NAME/${{env.AUTHOR_NAME}}/' + sed -i grammar.js \ + -e 's/TODO:/NOTE:/' \ + -e 's/source_file.*/changeme: $ => "",/' + sed -i package.json \ + -e '/"scope"/a \ "highlights": "queries/highlights.scm",' \ + -e '/"repository"/a \ "author": "${{env.AUTHOR_NAME_EMAIL}}",' \ + -e '/"repository"/s|github:.*"|github:${{github.repository}}"|' + sed -i Cargo.toml \ + -e '/^repository/a authors = ["${{env.AUTHOR_NAME_EMAIL}}"]' \ + -e '/^repository/s|/tree-sitter/.*|/${{github.repository}}"|' + sed -i pyproject.toml \ + -e '/^classifiers/i authors = [' \ + -e '/^classifiers/i ]' \ + -e '/^Homepage/s|/tree-sitter/.*|/${{github.repository}}"|' + if [[ $AUTHOR_NAME_EMAIL == $AUTHOR_NAME ]]; then + sed -i pyproject.toml \ + -e '/^authors/a \ {name = "${{env.AUTHOR_NAME}}"}' + else + sed -i pyproject.toml \ + -e '/^authors/a \ {name = "${{env.AUTHOR_NAME}}", email = "${{env.AUTHOR_EMAIL}}"}' + fi + sed -i Makefile \ + -e '/^PARSER_REPO_URL/i PARSER_URL := https://github.com/${{github.repository}}' + sed -i bindings/rust/lib.rs \ + -e '/Uncomment these/s/Uncomment.*/NOTE: \l&:/' + sed -i bindings/go/binding_test.go \ + -e 's|/tree-sitter/.*|/${{github.repository}}"|' + mv .github/not-dependabot.yml .github/dependabot.yml + env: + REPO_OWNER: ${{github.repository_owner}} + REPO_NAME: ${{github.event.repository.name}} + - name: Update commit + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_user_name: ${{github.event.head_commit.author.username}} + commit_user_email: ${{github.event.head_commit.author.email}} + commit_message: "feat: initial commit" + commit_options: --amend + push_options: --force + skip_fetch: true + - name: Add next steps to summary + run: |- + printf >> "$GITHUB_STEP_SUMMARY" '%s\n' \ + 'The repository has been set up successfully.' \ + 'You can now clone and configure it like so:' \ + '' \ + '~~~bash' \ + 'git clone ${{github.server_url}}/${{github.repository}}' \ + 'cd ${{github.event.repository.name}}' \ + 'gh repo edit \' \ + ' --enable-merge-commit=false \' \ + ' --enable-discussions=false \' \ + ' --enable-projects=false \' \ + ' --enable-wiki=false \' \ + ' --add-topic=tree-sitter \' \ + ' --add-topic=parser \' \ + ' --add-topic=${{env.PARSER_NAME}} \' \ + " -d '$(jq -r .description package.json)'" \ + '~~~' diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1c47e09 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2024 AUTHOR_NAME + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..051d0fb --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# tree-sitter-PARSER_NAME + +[![CI][ci]](https://github.com/tree-sitter-grammars/tree-sitter-PARSER_NAME/actions/workflows/ci.yml) +[![discord][discord]](https://discord.gg/w7nTvsVJhm) +[![matrix][matrix]](https://matrix.to/#/#tree-sitter-chat:matrix.org) + + + + + +A tree-sitter parser for PARSER_NAME files. + +## References + + + +[ci]: https://img.shields.io/github/actions/workflow/status/tree-sitter-grammars/tree-sitter-PARSER_NAME/ci.yml?logo=github&label=CI +[discord]: https://img.shields.io/discord/1063097320771698699?logo=discord&label=discord +[matrix]: https://img.shields.io/matrix/tree-sitter-chat%3Amatrix.org?logo=matrix&label=matrix +[npm]: https://img.shields.io/npm/v/tree-sitter-PARSER_NAME?logo=npm +[crates]: https://img.shields.io/crates/v/tree-sitter-PARSER_NAME?logo=rust +[pypi]: https://img.shields.io/pypi/v/tree-sitter-PARSER_NAME?logo=pypi&logoColor=ffd242 diff --git a/queries/highlights.scm b/queries/highlights.scm new file mode 100644 index 0000000..398cf32 --- /dev/null +++ b/queries/highlights.scm @@ -0,0 +1 @@ +; NOTE: add highlight queries here diff --git a/src/scanner.c b/src/scanner.c new file mode 100644 index 0000000..eefb24c --- /dev/null +++ b/src/scanner.c @@ -0,0 +1,22 @@ +// NOTE: remove this file if you don't need an external scanner +#include "tree_sitter/parser.h" + +void *tree_sitter_PARSER_NAME_external_scanner_create() { + return NULL; +} + +bool tree_sitter_xml_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) { + return false; +} + +void tree_sitter_PARSER_NAME_external_scanner_destroy(void *payload) { + /* NOOP */ +} + +unsigned tree_sitter_PARSER_NAME_external_scanner_serialize(void *payload, char *buffer) { + return 0; +} + +void tree_sitter_PARSER_NAME_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) { + /* NOOP */ +}