Swift: don't highlight keywords used as argument labels by adarshsm · Pull Request #3399 · pygments/pygments · GitHub
Skip to content

Swift: don't highlight keywords used as argument labels - #3399

Draft
adarshsm wants to merge 1 commit into
pygments:masterfrom
adarshsm:fix/1079-swift-keyword-argument-labels
Draft

adarshsm wants to merge 1 commit into
pygments:masterfrom
adarshsm:fix/1079-swift-keyword-argument-labels

Conversation

@adarshsm

Copy link
Copy Markdown

Fixes #1079.

Since SE-0001, Swift allows any keyword except inout, var and let as an argument label, and Apple APIs use this a lot (devices(for:), contains(where:), index(of:in:)). SwiftLexer still highlights those labels as keywords:

let d = AVCaptureDevice.devices(for: .audio, noHighlight: 42)
'devices'     Name
'('           Punctuation
'for'         Keyword        <- should look like noHighlight
':'           Punctuation
...
'noHighlight' Name

Fix: a new rule in root, placed before the keyword rules, lexes an identifier that follows ( or , as a Name when it is a label:

  • call site: followed by : (f(for: x))
  • declaration: followed by a parameter name and : (func f(in x: Int))

The lookahead leaves the rest of the parameter to the existing rules. Excluded from the rule:

  • inout, var and let, which SE-0001 doesn't allow as labels. This keeps if let a = x, let b: Int = y and Swift 2 style (inout x: Int) as they are.
  • true, false and nil, so dictionary literals like [true: 1, false: 0] keep both keys as Keyword.Constant.
  • a lone _, so #selector(foo(_:)) and func f(_ x: Int) are unchanged.

I also compared the output before and after for a ternary in an argument list, case a, b:, default:, generic constraints (<T: P, U: Q>, where T: Equatable, U: Hashable) and multi-line calls. Only the keyword labels change.

Tests: I added tests/snippets/swift/test_keyword_argument_labels.txt, covering the call-site and declaration forms. It fails on master and passes with the fix. The tests/examplefiles/swift/test.swift golden output is unchanged, and the full suite passes (pytest tests --ignore=tests/contrast: 5330 passed, 16 skipped). I skipped tests/contrast because wcag_contrast_ratio isn't installed in my environment.

🤖 Generated with Claude Code

Since SE-0001 any keyword except inout, var and let can be an argument
label, e.g. devices(for: .audio) or func f(in x: Int). The lexer
highlighted those labels as keywords. A label after '(' or ',' that is
followed by ':' (call site) or by a parameter name and ':' (declaration)
is now lexed as a Name. true/false/nil are excluded so dictionary keys
such as [true: 1, false: 0] stay constants.

Fixes pygments#1079.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Swift keywords highlighted in argument labels

1 participant