Skip to content

Add support for Diff syntax and queries - #40

Open
dxnnv wants to merge 1 commit into
simonbs:mainfrom
dxnnv:feat/diff-language-support
Open

dxnnv wants to merge 1 commit into
simonbs:mainfrom
dxnnv:feat/diff-language-support

Conversation

@dxnnv

@dxnnv dxnnv commented Oct 30, 2026 •

Copy link
Copy Markdown

Description

Adds the tree-sitter grammar and associated highlight and folding queries for the Diff language.

The source files for the parser were imported from tree-sitter-grammars/tree-sitter-diff, and Query.swift + TreeSitterLanguage+Helpers.swift were modeled after the corresponding Nix/XML files (since those were the most recent language implementations I noticed). highlights.scm was pulled from nvim-treesitter along with folds.scm.

Highlighting validation was integrated into the existing tests, with RequestedLanguageHighlightTests#textColor being updated to include explicit checks for "diff.*" and "punctuation.special" names to display accurate diff coloring.

While looking into other PR's, I noticed "...editor integration, filename/import handling, and actual highlighting assertions are in simonbs/RunestoneEditor...". Since this repo is private, any integration with Runestone has intentionally been omitted. I'm not sure if this would require any changes in simonbs/Runestone since Diff highlighting should have different HighlightName's (at least from what I could tell), but I've avoided making any changes prematurely. If there are any changes that should be made there, I'm fine with doing that as well, just figured that I should inquire about how you would want that implemented; otherwise, I'll leave that to you.

Adaptations

Highlighting was explicitly modified from upstream, as the punctuation marker captures were removed due to Runestone not supporting priority; this is documented in Diff.json's query_adaptations. The @spell capture was also removed, as it is independent from Runestone's spell checking and has no effect. Both of these adaptations have been documented in the relevant section within LANGUAGE_SOURCES.md.

Testing

Passed git diff --check, existing scripts passed.

Testing output
danny@halos $ python3 scripts/import-folding-queries.py --check
Folding queries: verified 45 languages from 48 pinned source files

danny@halos $ python3 scripts/check-language-support.py
Language support: PASS (51 wrappers, 52 factories; dependency/export/consumer parity)

danny@halos $ CC=clang CXX=clang++ \
    python3 Tests/Folding/test.py \
        --runtime ../tree-sitter-0.27.1 \
        --language Diff
Diff: PASS (native parser and folding query)
All 1 folding queries passed.

danny@halos $ CC=clang CXX=clang++ \
    python3 Tests/Compatibility/test.py ../tree-sitter-0.27.1 Diff
Language support: PASS (51 wrappers, 52 factories; dependency/export/consumer parity)
Diff: parsed sample and executed 2 queries
All 1 languages passed.

danny@halos $ CC=clang CXX=clang++\
    python3 Tests/Updates/test.py \
        --runtime ../tree-sitter-0.27.1 \
        --language Diff --verbose
  ('attribute', '@@ -1,3 +1,3 @@')
  ('comment', '# comment')
  ('constant', '1111111')
  ('constant', '1234567')
  ('constant', '2222222')
  ('constant', 'abcdef0')
  ('diff.delta', '!changed')
  ('diff.minus', '--- a/demo.txt')
  ('diff.minus', '---old marker')
  ('diff.minus', '-old value')
  ('diff.minus', 'B11111')
  ('diff.plus', '+++ b/demo.txt')
  ('diff.plus', '+++new marker')
  ('diff.plus', '+new value')
  ('diff.plus', 'A00000')
  ('function', 'diff')
  ('keyword', 'index')
  ('keyword', 'literal')
  ('label', 'GIT')
  ('label', 'binary')
  ('label', 'patch')
  ('number', '1')
  ('number', '100644')
  ('punctuation.special', '..')
  ('punctuation.special', '\\')
  ('string.special', '\\ No newline at end of file')
  ('string.special.path', 'a/demo.txt')
  ('string.special.path', 'a/demo.txt b/demo.txt')
  ('string.special.path', 'a/image.bin b/image.bin')
  ('string.special.path', 'b/demo.txt')
  ('variable.parameter', '--git')
Diff highlights: PASS (parse, query predicates, 15 expected captures, 10 excluded captures)

Also ran Tests/Compatibility/test.py and Tests/Folding/test.py in full without specifying language; both passed, the only error output was from an unrelated Lua runtime error for tree_sitter_lua_external_scanner_create in the compatibility test.

For clarity, all XCode tests including xcodebuild were not performed, as I'm on Linux and do not have access to a MacOS environment. The existing suite was used for all tests that could be performed on my machine, but I'm relying on CI's build job for iOS integration testing (edit: seems CI only triggers on pull_request instead of pull_request_target, so this needs to be approved by a maintainer first for it to run).
The native folding check also proved parsing and query execution, but it does not assert the exact collapsed ranges or any UI behavior; that would still need to be confirmed by a maintainer.

Motivation

I use Runestone regularly on mobile, and have thoroughly enjoyed it; it's by far the best editor out of the many I've tried. One feature that I've been missing though has been Diff syntax highlighting for .diff and .patch files. Looked around and realized the framework was open source, so figured if I wanted something then I should at least put in the effort for it 😄.

While most of this wasn't very difficult as the majority of these files were derived from upstream sources, I will admit that I'm not proficient in Swift or well-versed with the repository. I read through everything I saw to ensure the implementation aligned with the existing ones; if there's anything here that should be done differently, I'll be glad to update this and resolve any issues.

Add the tree-sitter grammar and associated highlight and folding queries for the Diff language to expand language support. Omit the editor-specific `spell` capture and punctuation patterns in highlighting, since `priority` is not recognized by Runestone. Integrate syntax highlighting validation into existing tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant