From 5de61738d5f1d2a21427eccd361f414d39e2d166 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 10:08:06 +0100 Subject: [PATCH 01/26] Started adding scope facets to ruby --- .../ruby/class.iteration.document.scope | 18 + data/fixtures/scopes/ruby/class.scope | 10 + .../functionCall/functionCall.chain.scope | 19 + .../functionCall/functionCall.method.scope | 10 + .../ruby/functionCall/functionCall.scope | 10 + data/fixtures/scopes/ruby/ifStatement.scope | 17 + .../ruby/name/name.iteration.document.scope | 12 + .../ruby/namedFunction.iteration.class.scope | 13 + .../scopes/ruby/namedFunction.method.scope | 21 ++ data/fixtures/scopes/ruby/namedFunction.scope | 10 + .../statement.iteration.document.scope | 12 + .../scopes/ruby/string.multiLine.scope | 13 + .../scopes/ruby/string.singleLine.scope | 10 + .../ruby/textFragment.comment.block.scope | 15 + .../ruby/textFragment.comment.line.scope | 10 + .../ruby/textFragment.string.multiLine.scope | 13 + .../ruby/textFragment.string.singleLine.scope | 10 + .../ruby/value/value.iteration.document.scope | 12 + .../common/src/scopeSupportFacets/ruby.ts | 328 +++++++++++++++++- .../delimiterMaps.ts | 1 + queries/ruby.scm | 13 +- 21 files changed, 572 insertions(+), 5 deletions(-) create mode 100644 data/fixtures/scopes/ruby/class.iteration.document.scope create mode 100644 data/fixtures/scopes/ruby/class.scope create mode 100644 data/fixtures/scopes/ruby/functionCall/functionCall.chain.scope create mode 100644 data/fixtures/scopes/ruby/functionCall/functionCall.method.scope create mode 100644 data/fixtures/scopes/ruby/functionCall/functionCall.scope create mode 100644 data/fixtures/scopes/ruby/ifStatement.scope create mode 100644 data/fixtures/scopes/ruby/name/name.iteration.document.scope create mode 100644 data/fixtures/scopes/ruby/namedFunction.iteration.class.scope create mode 100644 data/fixtures/scopes/ruby/namedFunction.method.scope create mode 100644 data/fixtures/scopes/ruby/namedFunction.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.iteration.document.scope create mode 100644 data/fixtures/scopes/ruby/string.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/string.singleLine.scope create mode 100644 data/fixtures/scopes/ruby/textFragment.comment.block.scope create mode 100644 data/fixtures/scopes/ruby/textFragment.comment.line.scope create mode 100644 data/fixtures/scopes/ruby/textFragment.string.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/textFragment.string.singleLine.scope create mode 100644 data/fixtures/scopes/ruby/value/value.iteration.document.scope diff --git a/data/fixtures/scopes/ruby/class.iteration.document.scope b/data/fixtures/scopes/ruby/class.iteration.document.scope new file mode 100644 index 0000000000..b8bd346108 --- /dev/null +++ b/data/fixtures/scopes/ruby/class.iteration.document.scope @@ -0,0 +1,18 @@ + +class Foo end + +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:0 + > +0| +1| class Foo end +2| + < + + +[#2 Content] = +[#2 Domain] = 1:9-1:10 + >-< +1| class Foo end diff --git a/data/fixtures/scopes/ruby/class.scope b/data/fixtures/scopes/ruby/class.scope new file mode 100644 index 0000000000..8efc138326 --- /dev/null +++ b/data/fixtures/scopes/ruby/class.scope @@ -0,0 +1,10 @@ +class Foo end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:13 + >-------------< +0| class Foo end + +[Insertion delimiter] = "\n\n" diff --git a/data/fixtures/scopes/ruby/functionCall/functionCall.chain.scope b/data/fixtures/scopes/ruby/functionCall/functionCall.chain.scope new file mode 100644 index 0000000000..c73434c70d --- /dev/null +++ b/data/fixtures/scopes/ruby/functionCall/functionCall.chain.scope @@ -0,0 +1,19 @@ +foo().bar() +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-0:5 + >-----< +0| foo().bar() + +[#1 Insertion delimiter] = " " + + +[#2 Content] = +[#2 Removal] = +[#2 Domain] = 0:0-0:11 + >-----------< +0| foo().bar() + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/functionCall/functionCall.method.scope b/data/fixtures/scopes/ruby/functionCall/functionCall.method.scope new file mode 100644 index 0000000000..6ab0ba4c3a --- /dev/null +++ b/data/fixtures/scopes/ruby/functionCall/functionCall.method.scope @@ -0,0 +1,10 @@ +foo.bar() +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:9 + >---------< +0| foo.bar() + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/functionCall/functionCall.scope b/data/fixtures/scopes/ruby/functionCall/functionCall.scope new file mode 100644 index 0000000000..00162e317c --- /dev/null +++ b/data/fixtures/scopes/ruby/functionCall/functionCall.scope @@ -0,0 +1,10 @@ +foo() +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:5 + >-----< +0| foo() + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/ifStatement.scope b/data/fixtures/scopes/ruby/ifStatement.scope new file mode 100644 index 0000000000..863d21917d --- /dev/null +++ b/data/fixtures/scopes/ruby/ifStatement.scope @@ -0,0 +1,17 @@ +if true +elsif false +else +end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-3:3 + >------- +0| if true +1| elsif false +2| else +3| end + ---< + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/name/name.iteration.document.scope b/data/fixtures/scopes/ruby/name/name.iteration.document.scope new file mode 100644 index 0000000000..187831aab8 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.iteration.document.scope @@ -0,0 +1,12 @@ + +foo = a + +--- + +[Content] = +[Domain] = 0:0-2:0 + > +0| +1| foo = a +2| + < diff --git a/data/fixtures/scopes/ruby/namedFunction.iteration.class.scope b/data/fixtures/scopes/ruby/namedFunction.iteration.class.scope new file mode 100644 index 0000000000..37cb946c03 --- /dev/null +++ b/data/fixtures/scopes/ruby/namedFunction.iteration.class.scope @@ -0,0 +1,13 @@ +class Foo end +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:13 + >-------------< +0| class Foo end + + +[#2 Content] = +[#2 Domain] = 0:9-0:10 + >-< +0| class Foo end diff --git a/data/fixtures/scopes/ruby/namedFunction.method.scope b/data/fixtures/scopes/ruby/namedFunction.method.scope new file mode 100644 index 0000000000..72e628602a --- /dev/null +++ b/data/fixtures/scopes/ruby/namedFunction.method.scope @@ -0,0 +1,21 @@ +class Foo + def bar() end +end +--- + +[Content] = +[Domain] = 1:4-1:17 + >-------------< +1| def bar() end + +[Removal] = 1:0-2:0 + >----------------- +1| def bar() end +2| end + < + +[Leading delimiter] = 1:0-1:4 + >----< +1| def bar() end + +[Insertion delimiter] = "\n\n" diff --git a/data/fixtures/scopes/ruby/namedFunction.scope b/data/fixtures/scopes/ruby/namedFunction.scope new file mode 100644 index 0000000000..c1eba91b6d --- /dev/null +++ b/data/fixtures/scopes/ruby/namedFunction.scope @@ -0,0 +1,10 @@ +def foo() end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:13 + >-------------< +0| def foo() end + +[Insertion delimiter] = "\n\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.iteration.document.scope b/data/fixtures/scopes/ruby/statement/statement.iteration.document.scope new file mode 100644 index 0000000000..187831aab8 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.iteration.document.scope @@ -0,0 +1,12 @@ + +foo = a + +--- + +[Content] = +[Domain] = 0:0-2:0 + > +0| +1| foo = a +2| + < diff --git a/data/fixtures/scopes/ruby/string.multiLine.scope b/data/fixtures/scopes/ruby/string.multiLine.scope new file mode 100644 index 0000000000..e8f7baaa0a --- /dev/null +++ b/data/fixtures/scopes/ruby/string.multiLine.scope @@ -0,0 +1,13 @@ +"Hello +world" +--- + +[Content] = +[Removal] = +[Domain] = 0:0-1:6 + >------ +0| "Hello +1| world" + ------< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/string.singleLine.scope b/data/fixtures/scopes/ruby/string.singleLine.scope new file mode 100644 index 0000000000..4b26cf31b3 --- /dev/null +++ b/data/fixtures/scopes/ruby/string.singleLine.scope @@ -0,0 +1,10 @@ +"Hello world" +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:13 + >-------------< +0| "Hello world" + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/textFragment.comment.block.scope b/data/fixtures/scopes/ruby/textFragment.comment.block.scope new file mode 100644 index 0000000000..a27dbdcd39 --- /dev/null +++ b/data/fixtures/scopes/ruby/textFragment.comment.block.scope @@ -0,0 +1,15 @@ +=begin +Hello world +=end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-2:4 + >------ +0| =begin +1| Hello world +2| =end + ----< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/textFragment.comment.line.scope b/data/fixtures/scopes/ruby/textFragment.comment.line.scope new file mode 100644 index 0000000000..2c362ef415 --- /dev/null +++ b/data/fixtures/scopes/ruby/textFragment.comment.line.scope @@ -0,0 +1,10 @@ +# Hello world +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:13 + >-------------< +0| # Hello world + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/textFragment.string.multiLine.scope b/data/fixtures/scopes/ruby/textFragment.string.multiLine.scope new file mode 100644 index 0000000000..2780f7ce95 --- /dev/null +++ b/data/fixtures/scopes/ruby/textFragment.string.multiLine.scope @@ -0,0 +1,13 @@ +"Hello +world" +--- + +[Content] = +[Removal] = +[Domain] = 0:1-1:5 + >----- +0| "Hello +1| world" + -----< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/textFragment.string.singleLine.scope b/data/fixtures/scopes/ruby/textFragment.string.singleLine.scope new file mode 100644 index 0000000000..85dcf5fa7f --- /dev/null +++ b/data/fixtures/scopes/ruby/textFragment.string.singleLine.scope @@ -0,0 +1,10 @@ +"Hello world" +--- + +[Content] = +[Removal] = +[Domain] = 0:1-0:12 + >-----------< +0| "Hello world" + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.iteration.document.scope b/data/fixtures/scopes/ruby/value/value.iteration.document.scope new file mode 100644 index 0000000000..187831aab8 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.iteration.document.scope @@ -0,0 +1,12 @@ + +foo = a + +--- + +[Content] = +[Domain] = 0:0-2:0 + > +0| +1| foo = a +2| + < diff --git a/packages/common/src/scopeSupportFacets/ruby.ts b/packages/common/src/scopeSupportFacets/ruby.ts index baaccbb11f..24098ee61b 100644 --- a/packages/common/src/scopeSupportFacets/ruby.ts +++ b/packages/common/src/scopeSupportFacets/ruby.ts @@ -1,25 +1,347 @@ import type { LanguageScopeSupportFacetMap } from "./scopeSupportFacets.types"; import { ScopeSupportFacetLevel } from "./scopeSupportFacets.types"; -// eslint-disable-next-line @typescript-eslint/no-unused-vars const { supported, unsupported, notApplicable } = ScopeSupportFacetLevel; export const rubyScopeSupport: LanguageScopeSupportFacetMap = { - "comment.line": supported, - "comment.block": supported, disqualifyDelimiter: supported, + list: supported, + map: supported, + regularExpression: supported, + ifStatement: supported, + anonymousFunction: supported, + + class: supported, + "class.iteration.document": supported, + "class.iteration.block": supported, + + namedFunction: supported, + "namedFunction.method": supported, + "namedFunction.iteration.document": supported, + "namedFunction.iteration.class": supported, + + functionCall: supported, + "functionCall.method": supported, + "functionCall.chain": supported, + functionCallee: supported, + "functionCallee.method": supported, + "functionCallee.chain": supported, "argument.actual.singleLine": supported, "argument.actual.multiLine": supported, "argument.actual.iteration": supported, + "argument.actual.method.singleLine": supported, + "argument.actual.method.multiLine": supported, + "argument.actual.method.iteration": supported, "argument.formal.singleLine": supported, "argument.formal.multiLine": supported, "argument.formal.iteration": supported, + "argument.formal.method.singleLine": supported, + "argument.formal.method.multiLine": supported, + "argument.formal.method.iteration": supported, + "argument.formal.lambda.singleLine": supported, + "argument.formal.lambda.multiLine": supported, + "argument.formal.lambda.iteration": supported, "argumentList.actual.empty": supported, "argumentList.actual.singleLine": supported, "argumentList.actual.multiLine": supported, + "argumentList.actual.method.empty": supported, + "argumentList.actual.method.singleLine": supported, + "argumentList.actual.method.multiLine": supported, "argumentList.formal.empty": supported, "argumentList.formal.singleLine": supported, "argumentList.formal.multiLine": supported, + "argumentList.formal.lambda.empty": supported, + "argumentList.formal.lambda.singleLine": supported, + "argumentList.formal.lambda.multiLine": supported, + "argumentList.formal.method.empty": supported, + "argumentList.formal.method.singleLine": supported, + "argumentList.formal.method.multiLine": supported, + + "branch.if": supported, + "branch.if.elif.else": supported, + "branch.if.else": supported, + "branch.if.iteration": supported, + "branch.try": supported, + "branch.try.iteration": supported, + "branch.switchCase": supported, + "branch.switchCase.iteration": supported, + "branch.ternary": supported, + "branch.ternary.iteration": supported, + + "comment.block": supported, + "comment.line": supported, + + "condition.if": supported, + "condition.while": supported, + "condition.for": supported, + "condition.switchCase": supported, + "condition.switchCase.iteration": supported, + "condition.ternary": supported, + + "statement.class": supported, + "statement.function": supported, + "statement.method": supported, + "statement.functionCall": supported, + "statement.if": supported, + "statement.try": supported, + "statement.switch": supported, + "statement.for": supported, + "statement.foreach": supported, + "statement.while": supported, + "statement.assignment": supported, + "statement.variable.initialized": supported, + "statement.return": supported, + "statement.yield": supported, + "statement.throw": supported, + "statement.break": supported, + "statement.continue": supported, + "statement.misc": supported, + "statement.iteration.document": supported, + "statement.iteration.class": supported, + "statement.iteration.block": supported, + + "string.singleLine": supported, + "string.multiLine": supported, + + "textFragment.comment.block": supported, + "textFragment.comment.line": supported, + "textFragment.string.singleLine": supported, + "textFragment.string.multiLine": supported, + + "name.argument.actual": supported, + "name.argument.actual.iteration": supported, + "name.argument.formal": supported, + "name.argument.formal.iteration": supported, + "name.argument.formal.method": supported, + "name.argument.formal.method.iteration": supported, + "name.argument.formal.lambda": supported, + "name.argument.formal.lambda.iteration": supported, + "name.assignment": supported, + "name.foreach": supported, + "name.function": supported, + "name.method": supported, + "name.class": supported, + "name.iteration.document": supported, + "name.iteration.class": supported, + "name.iteration.block": supported, + + "key.mapPair": supported, + "key.mapPair.iteration": supported, + + "value.argument.actual": supported, + "value.argument.actual.iteration": supported, + "value.argument.formal": supported, + "value.argument.formal.iteration": supported, + "value.argument.formal.method": supported, + "value.argument.formal.method.iteration": supported, + "value.mapPair": supported, + "value.mapPair.iteration": supported, + "value.assignment": supported, + "value.foreach": supported, + "value.return": supported, + "value.return.lambda": supported, + "value.switch": supported, + "value.variable": supported, + "value.iteration.document": supported, + "value.iteration.class": supported, + "value.iteration.block": supported, + + "interior.class": supported, + "interior.function": supported, + "interior.method": supported, + "interior.lambda": supported, + "interior.if": supported, + "interior.try": supported, + "interior.switch": supported, + "interior.switchCase": supported, + "interior.for": supported, + "interior.foreach": supported, + "interior.while": supported, + + /* UNSUPPORTED */ + fieldAccess: unsupported, + + /* NOT APPLICABLE */ + + // Constructors + "namedFunction.constructor": notApplicable, + "statement.constructor": notApplicable, + "argument.actual.constructor.singleLine": notApplicable, + "argument.actual.constructor.multiLine": notApplicable, + "argument.actual.constructor.iteration": notApplicable, + "argument.formal.constructor.singleLine": notApplicable, + "argument.formal.constructor.multiLine": notApplicable, + "argument.formal.constructor.iteration": notApplicable, + "argumentList.actual.constructor.empty": notApplicable, + "argumentList.actual.constructor.singleLine": notApplicable, + "argumentList.actual.constructor.multiLine": notApplicable, + "argumentList.formal.constructor.empty": notApplicable, + "argumentList.formal.constructor.singleLine": notApplicable, + "argumentList.formal.constructor.multiLine": notApplicable, + "functionCall.constructor": notApplicable, + "functionCallee.constructor": notApplicable, + "name.argument.formal.constructor": notApplicable, + "name.argument.formal.constructor.iteration": notApplicable, + "name.constructor": notApplicable, + "type.argument.formal.constructor": notApplicable, + "type.argument.formal.constructor.iteration": notApplicable, + "value.argument.formal.constructor": notApplicable, + "value.argument.formal.constructor.iteration": notApplicable, + "interior.constructor": notApplicable, + + // Class fields + "statement.field.class": notApplicable, + "name.field.class": notApplicable, + "type.class": notApplicable, + "type.field.class": notApplicable, + "type.iteration.class": notApplicable, + "value.field.class": notApplicable, + + // Interface + "statement.interface": notApplicable, + "statement.field.interface": notApplicable, + "statement.iteration.interface": notApplicable, + "name.interface": notApplicable, + "name.field.interface": notApplicable, + "name.iteration.interface": notApplicable, + "type.interface": notApplicable, + "type.field.interface": notApplicable, + "type.iteration.interface": notApplicable, + "value.field.interface": notApplicable, + "interior.interface": notApplicable, + + // Enum + "statement.enum": notApplicable, + "name.enum": notApplicable, + "name.field.enum": notApplicable, + "name.iteration.enum": notApplicable, + "type.enum": notApplicable, + "value.field.enum": notApplicable, + "value.iteration.enum": notApplicable, + "interior.enum": notApplicable, + "functionCall.enum": notApplicable, + "functionCallee.enum": notApplicable, + + // Type system + "type.argument.formal": notApplicable, + "type.argument.formal.iteration": notApplicable, + "type.argument.formal.method": notApplicable, + "type.argument.formal.method.iteration": notApplicable, + "type.argument.formal.lambda": notApplicable, + "type.argument.formal.lambda.iteration": notApplicable, + "type.return": notApplicable, + "type.return.method": notApplicable, + "type.variable.uninitialized": notApplicable, + "type.variable.initialized": notApplicable, + "type.typeArgument": notApplicable, + "type.typeArgument.iteration": notApplicable, + "type.cast": notApplicable, + "type.foreach": notApplicable, + "type.iteration.block": notApplicable, + "type.iteration.document": notApplicable, + + // Type alias + "type.alias": notApplicable, + "statement.typeAlias": notApplicable, + "name.typeAlias": notApplicable, + "value.typeAlias": notApplicable, + + // Assignment variants not covered + "statement.assignment.destructuring": notApplicable, + "statement.assignment.compound": notApplicable, + "statement.update": notApplicable, + "name.assignment.destructuring": notApplicable, + "name.assignment.compound": notApplicable, + "value.assignment.destructuring": notApplicable, + "value.assignment.compound": notApplicable, + + // Variable declarations + "statement.variable.uninitialized": notApplicable, + "statement.variable.destructuring": notApplicable, + "name.variable.uninitialized": notApplicable, + "name.variable.initialized": notApplicable, + "name.variable.destructuring": notApplicable, + "value.variable.destructuring": notApplicable, + + // Constant declaration scopes + "statement.constant": notApplicable, + "name.constant": notApplicable, + "value.constant": notApplicable, + "type.constant": notApplicable, + + // Catch parameter + "argument.catch": notApplicable, + "name.argument.catch": notApplicable, + "type.argument.catch": notApplicable, + + // Loop branches + "branch.loop": notApplicable, + "branch.loop.iteration": notApplicable, + + // Do while + "statement.doWhile": notApplicable, + "condition.doWhile": notApplicable, + "interior.doWhile": notApplicable, + + // Resources + "statement.resource": notApplicable, + "name.resource": notApplicable, + "value.resource": notApplicable, + "type.resource": notApplicable, + "interior.resource": notApplicable, + + // Namespace + "statement.namespace": notApplicable, + "name.namespace": notApplicable, + "interior.namespace": notApplicable, + + // Generic calls + "functionCall.generic": notApplicable, + "functionCallee.generic": notApplicable, + + // Static + "statement.static": notApplicable, + "interior.static": notApplicable, + + // Command + command: notApplicable, + "statement.command": notApplicable, + "name.command": notApplicable, + "value.command": notApplicable, + "interior.command": notApplicable, + + // Section + section: notApplicable, + "section.iteration.document": notApplicable, + "section.iteration.parent": notApplicable, + + // Elements + element: notApplicable, + tags: notApplicable, + startTag: notApplicable, + endTag: notApplicable, + "interior.element": notApplicable, + "textFragment.element": notApplicable, + attribute: notApplicable, + "key.attribute": notApplicable, + "value.attribute": notApplicable, + + // Notebook cell + notebookCell: notApplicable, + "interior.cell": notApplicable, + + // Unenclosed collection items + "collectionItem.unenclosed.singleLine": notApplicable, + "collectionItem.unenclosed.multiLine": notApplicable, + "collectionItem.unenclosed.iteration": notApplicable, + + // Misc + "statement.package": notApplicable, + "statement.import": notApplicable, + pairDelimiter: notApplicable, + environment: notApplicable, + selector: notApplicable, + unit: notApplicable, }; diff --git a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts index ee6017954b..411d41f816 100644 --- a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts +++ b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/delimiterMaps.ts @@ -71,6 +71,7 @@ const delimiterToTextOverrides: Record> = { }, ruby: { + doubleQuotes: ['"', '"', { isSingleLine: false }], tripleDoubleQuotes: ["%Q(", ")"], }, diff --git a/queries/ruby.scm b/queries/ruby.scm index de99fbf383..2c07b8dc7b 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -103,6 +103,16 @@ ) ) +( + (program) @class.iteration @statement.iteration @namedFunction.iteration + (#document-range! @class.iteration @statement.iteration @namedFunction.iteration) +) + +( + (program) @name.iteration @value.iteration + (#document-range! @name.iteration @value.iteration) +) + (comment) @comment @textFragment (hash) @map (regex) @regularExpression @@ -123,8 +133,6 @@ (singleton_method) ] @namedFunction -(program) @class.iteration @namedFunction.iteration @name.iteration - (class name: (_) @class.iteration.start.endOf @namedFunction.iteration.start.endOf @name.iteration.start.endOf "end" @class.iteration.end.startOf @namedFunction.iteration.end.startOf @name.iteration.end.startOf @@ -134,6 +142,7 @@ name: (_) @name ) @class @_.domain +;;!! "Hello world" (string) @string [ From dabb22119d3f1ae28b0d0ce6688e60b4f4b81636 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 10:26:01 +0100 Subject: [PATCH 02/26] callee --- .../functionCallee/functionCallee.chain.scope | 25 +++++++++++++++++++ .../functionCallee.method.scope | 13 ++++++++++ .../ruby/functionCallee/functionCallee.scope | 13 ++++++++++ queries/ruby.scm | 9 ++++++- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 data/fixtures/scopes/ruby/functionCallee/functionCallee.chain.scope create mode 100644 data/fixtures/scopes/ruby/functionCallee/functionCallee.method.scope create mode 100644 data/fixtures/scopes/ruby/functionCallee/functionCallee.scope diff --git a/data/fixtures/scopes/ruby/functionCallee/functionCallee.chain.scope b/data/fixtures/scopes/ruby/functionCallee/functionCallee.chain.scope new file mode 100644 index 0000000000..b0b9872650 --- /dev/null +++ b/data/fixtures/scopes/ruby/functionCallee/functionCallee.chain.scope @@ -0,0 +1,25 @@ +foo().bar() +--- + +[#1 Content] = +[#1 Removal] = 0:0-0:3 + >---< +0| foo().bar() + +[#1 Domain] = 0:0-0:5 + >-----< +0| foo().bar() + +[#1 Insertion delimiter] = " " + + +[#2 Content] = +[#2 Removal] = 0:0-0:9 + >---------< +0| foo().bar() + +[#2 Domain] = 0:0-0:11 + >-----------< +0| foo().bar() + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/functionCallee/functionCallee.method.scope b/data/fixtures/scopes/ruby/functionCallee/functionCallee.method.scope new file mode 100644 index 0000000000..e77bc361ec --- /dev/null +++ b/data/fixtures/scopes/ruby/functionCallee/functionCallee.method.scope @@ -0,0 +1,13 @@ +foo.bar() +--- + +[Content] = +[Removal] = 0:0-0:7 + >-------< +0| foo.bar() + +[Domain] = 0:0-0:9 + >---------< +0| foo.bar() + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/functionCallee/functionCallee.scope b/data/fixtures/scopes/ruby/functionCallee/functionCallee.scope new file mode 100644 index 0000000000..2b075b5c33 --- /dev/null +++ b/data/fixtures/scopes/ruby/functionCallee/functionCallee.scope @@ -0,0 +1,13 @@ +foo() +--- + +[Content] = +[Removal] = 0:0-0:3 + >---< +0| foo() + +[Domain] = 0:0-0:5 + >-----< +0| foo() + +[Insertion delimiter] = " " diff --git a/queries/ruby.scm b/queries/ruby.scm index 2c07b8dc7b..ef9a60dc2f 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -116,7 +116,14 @@ (comment) @comment @textFragment (hash) @map (regex) @regularExpression -(call) @functionCall + +;;!! foo() +;;! ^^^^^ +;;! ^^^ +(call + receiver: (_)? @functionCallee.start + method: (_) @functionCallee.end +) @functionCall @functionCallee.domain [ (array) From e8d3847409151eb5ff713ae6dd13d1c88ad39399 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 10:32:08 +0100 Subject: [PATCH 03/26] re --- data/fixtures/scopes/ruby/regularExpression.scope | 10 ++++++++++ queries/ruby.scm | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 data/fixtures/scopes/ruby/regularExpression.scope diff --git a/data/fixtures/scopes/ruby/regularExpression.scope b/data/fixtures/scopes/ruby/regularExpression.scope new file mode 100644 index 0000000000..3e65ffe6fd --- /dev/null +++ b/data/fixtures/scopes/ruby/regularExpression.scope @@ -0,0 +1,10 @@ +/^\w+$/g +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:8 + >--------< +0| /^\w+$/g + +[Insertion delimiter] = " " diff --git a/queries/ruby.scm b/queries/ruby.scm index ef9a60dc2f..1cf0eced0c 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -115,6 +115,8 @@ (comment) @comment @textFragment (hash) @map + +;;!! /foo/ (regex) @regularExpression ;;!! foo() From c299c36fc6c440f900b028b5620c73071341a3ad Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 10:40:11 +0100 Subject: [PATCH 04/26] map/list --- data/fixtures/scopes/ruby/list.scope | 10 ++++++++++ data/fixtures/scopes/ruby/list2.scope | 10 ++++++++++ data/fixtures/scopes/ruby/list3.scope | 10 ++++++++++ data/fixtures/scopes/ruby/map.scope | 10 ++++++++++ .../ruby/namedFunction.iteration.document.scope | 12 ++++++++++++ queries/ruby.scm | 7 ++++++- 6 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 data/fixtures/scopes/ruby/list.scope create mode 100644 data/fixtures/scopes/ruby/list2.scope create mode 100644 data/fixtures/scopes/ruby/list3.scope create mode 100644 data/fixtures/scopes/ruby/map.scope create mode 100644 data/fixtures/scopes/ruby/namedFunction.iteration.document.scope diff --git a/data/fixtures/scopes/ruby/list.scope b/data/fixtures/scopes/ruby/list.scope new file mode 100644 index 0000000000..54a5d795c2 --- /dev/null +++ b/data/fixtures/scopes/ruby/list.scope @@ -0,0 +1,10 @@ +[1, 2, 3] +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:9 + >---------< +0| [1, 2, 3] + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/list2.scope b/data/fixtures/scopes/ruby/list2.scope new file mode 100644 index 0000000000..2d3722141d --- /dev/null +++ b/data/fixtures/scopes/ruby/list2.scope @@ -0,0 +1,10 @@ +%w[foo bar baz] +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:15 + >---------------< +0| %w[foo bar baz] + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/list3.scope b/data/fixtures/scopes/ruby/list3.scope new file mode 100644 index 0000000000..a86a6e28d3 --- /dev/null +++ b/data/fixtures/scopes/ruby/list3.scope @@ -0,0 +1,10 @@ +%i[foo bar baz] +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:15 + >---------------< +0| %i[foo bar baz] + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/map.scope b/data/fixtures/scopes/ruby/map.scope new file mode 100644 index 0000000000..7c6e537e73 --- /dev/null +++ b/data/fixtures/scopes/ruby/map.scope @@ -0,0 +1,10 @@ +{aaa: 0, bbb: 1} +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:16 + >----------------< +0| {aaa: 0, bbb: 1} + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/namedFunction.iteration.document.scope b/data/fixtures/scopes/ruby/namedFunction.iteration.document.scope new file mode 100644 index 0000000000..eb3af5c48d --- /dev/null +++ b/data/fixtures/scopes/ruby/namedFunction.iteration.document.scope @@ -0,0 +1,12 @@ + +def foo() end + +--- + +[Content] = +[Domain] = 0:0-2:0 + > +0| +1| def foo() end +2| + < diff --git a/queries/ruby.scm b/queries/ruby.scm index 1cf0eced0c..2e7873bd3a 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -114,7 +114,6 @@ ) (comment) @comment @textFragment -(hash) @map ;;!! /foo/ (regex) @regularExpression @@ -128,11 +127,17 @@ ) @functionCall @functionCallee.domain [ + ;;!! [1, 2, 3] (array) + ;;!! %w[foo bar baz] (string_array) + ;;!! %i[foo bar baz] (symbol_array) ] @list +;;!! {aaa: 0, bbb: 1} +(hash) @map + (_ (if) @ifStatement ) @_.iteration From 6e21df34fc4ded53f418a4c3a49d0b2c22f6db4b Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 11:07:23 +0100 Subject: [PATCH 05/26] statement --- .../scopes/ruby/anonymousFunction.scope | 10 ++++++ .../scopes/ruby/anonymousFunction2.scope | 10 ++++++ .../ruby/statement/statement.assignment.scope | 10 ++++++ .../ruby/statement/statement.break.scope | 33 +++++++++++++++++++ .../ruby/statement/statement.class.scope | 10 ++++++ .../ruby/statement/statement.continue.scope | 33 +++++++++++++++++++ .../ruby/statement/statement.foreach.scope | 10 ++++++ .../ruby/statement/statement.foreach2.scope | 10 ++++++ .../ruby/statement/statement.function.scope | 10 ++++++ .../statement/statement.functionCall.scope | 10 ++++++ .../scopes/ruby/statement/statement.if.scope | 17 ++++++++++ .../ruby/statement/statement.method.scope | 33 +++++++++++++++++++ .../ruby/statement/statement.misc.scope | 10 ++++++ .../ruby/statement/statement.return.scope | 33 +++++++++++++++++++ .../ruby/statement/statement.throw.scope | 10 ++++++ .../statement.variable.initialized.scope | 10 ++++++ .../ruby/statement/statement.while.scope | 10 ++++++ .../ruby/statement/statement.yield.scope | 33 +++++++++++++++++++ .../common/src/scopeSupportFacets/ruby.ts | 2 +- queries/ruby.scm | 22 ++++++------- 20 files changed, 313 insertions(+), 13 deletions(-) create mode 100644 data/fixtures/scopes/ruby/anonymousFunction.scope create mode 100644 data/fixtures/scopes/ruby/anonymousFunction2.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.assignment.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.break.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.class.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.continue.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.foreach.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.foreach2.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.function.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.functionCall.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.if.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.method.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.misc.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.return.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.throw.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.variable.initialized.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.while.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.yield.scope diff --git a/data/fixtures/scopes/ruby/anonymousFunction.scope b/data/fixtures/scopes/ruby/anonymousFunction.scope new file mode 100644 index 0000000000..76eeb47747 --- /dev/null +++ b/data/fixtures/scopes/ruby/anonymousFunction.scope @@ -0,0 +1,10 @@ +->() {} +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:7 + >-------< +0| ->() {} + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/anonymousFunction2.scope b/data/fixtures/scopes/ruby/anonymousFunction2.scope new file mode 100644 index 0000000000..cd73200230 --- /dev/null +++ b/data/fixtures/scopes/ruby/anonymousFunction2.scope @@ -0,0 +1,10 @@ +-> {} +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:5 + >-----< +0| -> {} + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.assignment.scope b/data/fixtures/scopes/ruby/statement/statement.assignment.scope new file mode 100644 index 0000000000..acdb2b1498 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.assignment.scope @@ -0,0 +1,10 @@ +foo = 0 +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:7 + >-------< +0| foo = 0 + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.break.scope b/data/fixtures/scopes/ruby/statement/statement.break.scope new file mode 100644 index 0000000000..c455cf8f65 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.break.scope @@ -0,0 +1,33 @@ +while true + break +end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-2:3 + >---------- +0| while true +1| break +2| end + ---< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 1:4-1:9 + >-----< +1| break + +[#2 Removal] = 1:0-2:0 + >--------- +1| break +2| end + < + +[#2 Leading delimiter] = 1:0-1:4 + >----< +1| break + +[#2 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.class.scope b/data/fixtures/scopes/ruby/statement/statement.class.scope new file mode 100644 index 0000000000..3cb9dbd7a0 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.class.scope @@ -0,0 +1,10 @@ +class Foo end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:13 + >-------------< +0| class Foo end + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.continue.scope b/data/fixtures/scopes/ruby/statement/statement.continue.scope new file mode 100644 index 0000000000..335081f32e --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.continue.scope @@ -0,0 +1,33 @@ +while true + next +end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-2:3 + >---------- +0| while true +1| next +2| end + ---< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 1:4-1:8 + >----< +1| next + +[#2 Removal] = 1:0-2:0 + >-------- +1| next +2| end + < + +[#2 Leading delimiter] = 1:0-1:4 + >----< +1| next + +[#2 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.foreach.scope b/data/fixtures/scopes/ruby/statement/statement.foreach.scope new file mode 100644 index 0000000000..ef28ddb684 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.foreach.scope @@ -0,0 +1,10 @@ +for v in values end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:19 + >-------------------< +0| for v in values end + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.foreach2.scope b/data/fixtures/scopes/ruby/statement/statement.foreach2.scope new file mode 100644 index 0000000000..ad7139921f --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.foreach2.scope @@ -0,0 +1,10 @@ +values.each do |v| end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:22 + >----------------------< +0| values.each do |v| end + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.function.scope b/data/fixtures/scopes/ruby/statement/statement.function.scope new file mode 100644 index 0000000000..08b579a2ea --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.function.scope @@ -0,0 +1,10 @@ +def foo() end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:13 + >-------------< +0| def foo() end + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.functionCall.scope b/data/fixtures/scopes/ruby/statement/statement.functionCall.scope new file mode 100644 index 0000000000..fb55b4580a --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.functionCall.scope @@ -0,0 +1,10 @@ +foo() +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:5 + >-----< +0| foo() + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.if.scope b/data/fixtures/scopes/ruby/statement/statement.if.scope new file mode 100644 index 0000000000..863d21917d --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.if.scope @@ -0,0 +1,17 @@ +if true +elsif false +else +end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-3:3 + >------- +0| if true +1| elsif false +2| else +3| end + ---< + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.method.scope b/data/fixtures/scopes/ruby/statement/statement.method.scope new file mode 100644 index 0000000000..234307c913 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.method.scope @@ -0,0 +1,33 @@ +class Foo + def bar() end +end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| def bar() end +2| end + ---< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 1:4-1:17 + >-------------< +1| def bar() end + +[#2 Removal] = 1:0-2:0 + >----------------- +1| def bar() end +2| end + < + +[#2 Leading delimiter] = 1:0-1:4 + >----< +1| def bar() end + +[#2 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.misc.scope b/data/fixtures/scopes/ruby/statement/statement.misc.scope new file mode 100644 index 0000000000..c09fcfd765 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.misc.scope @@ -0,0 +1,10 @@ +retry if false +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:14 + >--------------< +0| retry if false + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.return.scope b/data/fixtures/scopes/ruby/statement/statement.return.scope new file mode 100644 index 0000000000..e3afb05fdc --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.return.scope @@ -0,0 +1,33 @@ +def foo() + return 0 +end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-2:3 + >--------- +0| def foo() +1| return 0 +2| end + ---< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 1:4-1:12 + >--------< +1| return 0 + +[#2 Removal] = 1:0-2:0 + >------------ +1| return 0 +2| end + < + +[#2 Leading delimiter] = 1:0-1:4 + >----< +1| return 0 + +[#2 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.throw.scope b/data/fixtures/scopes/ruby/statement/statement.throw.scope new file mode 100644 index 0000000000..ae11b90280 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.throw.scope @@ -0,0 +1,10 @@ +raise foo +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:9 + >---------< +0| raise foo + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.variable.initialized.scope b/data/fixtures/scopes/ruby/statement/statement.variable.initialized.scope new file mode 100644 index 0000000000..acdb2b1498 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.variable.initialized.scope @@ -0,0 +1,10 @@ +foo = 0 +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:7 + >-------< +0| foo = 0 + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.while.scope b/data/fixtures/scopes/ruby/statement/statement.while.scope new file mode 100644 index 0000000000..af068e6448 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.while.scope @@ -0,0 +1,10 @@ +while true end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:14 + >--------------< +0| while true end + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.yield.scope b/data/fixtures/scopes/ruby/statement/statement.yield.scope new file mode 100644 index 0000000000..7bcef34e4c --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.yield.scope @@ -0,0 +1,33 @@ +def foo() + yield 0 +end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-2:3 + >--------- +0| def foo() +1| yield 0 +2| end + ---< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 1:4-1:11 + >-------< +1| yield 0 + +[#2 Removal] = 1:0-2:0 + >----------- +1| yield 0 +2| end + < + +[#2 Leading delimiter] = 1:0-1:4 + >----< +1| yield 0 + +[#2 Insertion delimiter] = "\n" diff --git a/packages/common/src/scopeSupportFacets/ruby.ts b/packages/common/src/scopeSupportFacets/ruby.ts index 24098ee61b..995f9afca6 100644 --- a/packages/common/src/scopeSupportFacets/ruby.ts +++ b/packages/common/src/scopeSupportFacets/ruby.ts @@ -87,7 +87,6 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { "statement.if": supported, "statement.try": supported, "statement.switch": supported, - "statement.for": supported, "statement.foreach": supported, "statement.while": supported, "statement.assignment": supported, @@ -340,6 +339,7 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { // Misc "statement.package": notApplicable, "statement.import": notApplicable, + "statement.for": notApplicable, pairDelimiter: notApplicable, environment: notApplicable, selector: notApplicable, diff --git a/queries/ruby.scm b/queries/ruby.scm index 2e7873bd3a..e586e0de8a 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -81,9 +81,10 @@ ) @_dummy (#type? @_dummy + program + block_body begin_block begin - block_body block body_statement do_block @@ -94,9 +95,7 @@ heredoc_beginning interpolation lambda - method parenthesized_statements - program singleton_class singleton_method then @@ -138,24 +137,24 @@ ;;!! {aaa: 0, bbb: 1} (hash) @map -(_ - (if) @ifStatement -) @_.iteration +;;!! if true end +(if) @ifStatement [ (method) (singleton_method) ] @namedFunction +;;!! class Foo end +(class + name: (_) @name +) @class @_.domain + (class name: (_) @class.iteration.start.endOf @namedFunction.iteration.start.endOf @name.iteration.start.endOf "end" @class.iteration.end.startOf @namedFunction.iteration.end.startOf @name.iteration.end.startOf ) @class -(class - name: (_) @name -) @class @_.domain - ;;!! "Hello world" (string) @string @@ -231,8 +230,7 @@ condition: (_) @condition ) @_.domain -;;!! hi = -> { puts "Hi!" } -;;! ^^^^^^^^^^^^^^^^^ +;;!! -> {} (lambda) @anonymousFunction ;;!! [1,2,3].each do |i| end From f17d72124b8641f8a67fdbd3365e9d9e6780ad7c Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 14:41:37 +0100 Subject: [PATCH 06/26] more tests --- .../scopes/ruby/name/name.assignment.scope | 20 ++++ .../scopes/ruby/name/name.class.scope | 24 +++++ .../scopes/ruby/name/name.foreach.scope | 24 +++++ .../scopes/ruby/name/name.function.scope | 17 +++ .../ruby/name/name.iteration.class.scope | 13 +++ .../scopes/ruby/name/name.method.scope | 41 +++++++ .../ruby/statement/statement.foreach2.scope | 10 -- .../statement/statement.iteration.class.scope | 13 +++ .../ruby/statement/statement.switch.scope | 10 ++ .../scopes/ruby/statement/statement.try.scope | 15 +++ .../scopes/ruby/value/value.assignment.scope | 20 ++++ .../scopes/ruby/value/value.foreach.scope | 24 +++++ .../ruby/value/value.iteration.class.scope | 13 +++ .../ruby/value/value.return.lambda.scope | 24 +++++ .../scopes/ruby/value/value.return.scope | 22 ++++ .../scopes/ruby/value/value.switch.scope | 24 +++++ .../scopes/ruby/value/value.variable.scope | 20 ++++ queries/ruby.scm | 102 +++++++++++------- 18 files changed, 390 insertions(+), 46 deletions(-) create mode 100644 data/fixtures/scopes/ruby/name/name.assignment.scope create mode 100644 data/fixtures/scopes/ruby/name/name.class.scope create mode 100644 data/fixtures/scopes/ruby/name/name.foreach.scope create mode 100644 data/fixtures/scopes/ruby/name/name.function.scope create mode 100644 data/fixtures/scopes/ruby/name/name.iteration.class.scope create mode 100644 data/fixtures/scopes/ruby/name/name.method.scope delete mode 100644 data/fixtures/scopes/ruby/statement/statement.foreach2.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.iteration.class.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.switch.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.try.scope create mode 100644 data/fixtures/scopes/ruby/value/value.assignment.scope create mode 100644 data/fixtures/scopes/ruby/value/value.foreach.scope create mode 100644 data/fixtures/scopes/ruby/value/value.iteration.class.scope create mode 100644 data/fixtures/scopes/ruby/value/value.return.lambda.scope create mode 100644 data/fixtures/scopes/ruby/value/value.return.scope create mode 100644 data/fixtures/scopes/ruby/value/value.switch.scope create mode 100644 data/fixtures/scopes/ruby/value/value.variable.scope diff --git a/data/fixtures/scopes/ruby/name/name.assignment.scope b/data/fixtures/scopes/ruby/name/name.assignment.scope new file mode 100644 index 0000000000..7a03d93749 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.assignment.scope @@ -0,0 +1,20 @@ +foo = 0 +--- + +[Content] = 0:0-0:3 + >---< +0| foo = 0 + +[Removal] = 0:0-0:6 + >------< +0| foo = 0 + +[Trailing delimiter] = 0:3-0:6 + >---< +0| foo = 0 + +[Domain] = 0:0-0:7 + >-------< +0| foo = 0 + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.class.scope b/data/fixtures/scopes/ruby/name/name.class.scope new file mode 100644 index 0000000000..8d0c82e2b4 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.class.scope @@ -0,0 +1,24 @@ +class Foo end +--- + +[Content] = 0:6-0:9 + >---< +0| class Foo end + +[Removal] = 0:6-0:10 + >----< +0| class Foo end + +[Leading delimiter] = 0:5-0:6 + >-< +0| class Foo end + +[Trailing delimiter] = 0:9-0:10 + >-< +0| class Foo end + +[Domain] = 0:0-0:13 + >-------------< +0| class Foo end + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.foreach.scope b/data/fixtures/scopes/ruby/name/name.foreach.scope new file mode 100644 index 0000000000..31c9a799c8 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.foreach.scope @@ -0,0 +1,24 @@ +for v in values end +--- + +[Content] = 0:4-0:5 + >-< +0| for v in values end + +[Removal] = 0:4-0:6 + >--< +0| for v in values end + +[Leading delimiter] = 0:3-0:4 + >-< +0| for v in values end + +[Trailing delimiter] = 0:5-0:6 + >-< +0| for v in values end + +[Domain] = 0:0-0:19 + >-------------------< +0| for v in values end + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.function.scope b/data/fixtures/scopes/ruby/name/name.function.scope new file mode 100644 index 0000000000..33caf0dc68 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.function.scope @@ -0,0 +1,17 @@ +def foo() end +--- + +[Content] = +[Removal] = 0:4-0:7 + >---< +0| def foo() end + +[Leading delimiter] = 0:3-0:4 + >-< +0| def foo() end + +[Domain] = 0:0-0:13 + >-------------< +0| def foo() end + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.iteration.class.scope b/data/fixtures/scopes/ruby/name/name.iteration.class.scope new file mode 100644 index 0000000000..37cb946c03 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.iteration.class.scope @@ -0,0 +1,13 @@ +class Foo end +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:13 + >-------------< +0| class Foo end + + +[#2 Content] = +[#2 Domain] = 0:9-0:10 + >-< +0| class Foo end diff --git a/data/fixtures/scopes/ruby/name/name.method.scope b/data/fixtures/scopes/ruby/name/name.method.scope new file mode 100644 index 0000000000..45490c4789 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.method.scope @@ -0,0 +1,41 @@ +class Foo + def bar() end +end +--- + +[#1 Content] = 0:6-0:9 + >---< +0| class Foo + +[#1 Removal] = 0:5-0:9 + >----< +0| class Foo + +[#1 Leading delimiter] = 0:5-0:6 + >-< +0| class Foo + +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| def bar() end +2| end + ---< + +[#1 Insertion delimiter] = " " + + +[#2 Content] = +[#2 Removal] = 1:8-1:11 + >---< +1| def bar() end + +[#2 Leading delimiter] = 1:7-1:8 + >-< +1| def bar() end + +[#2 Domain] = 1:4-1:17 + >-------------< +1| def bar() end + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/statement/statement.foreach2.scope b/data/fixtures/scopes/ruby/statement/statement.foreach2.scope deleted file mode 100644 index ad7139921f..0000000000 --- a/data/fixtures/scopes/ruby/statement/statement.foreach2.scope +++ /dev/null @@ -1,10 +0,0 @@ -values.each do |v| end ---- - -[Content] = -[Removal] = -[Domain] = 0:0-0:22 - >----------------------< -0| values.each do |v| end - -[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.iteration.class.scope b/data/fixtures/scopes/ruby/statement/statement.iteration.class.scope new file mode 100644 index 0000000000..b727c7aaba --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.iteration.class.scope @@ -0,0 +1,13 @@ +class A end +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:11 + >-----------< +0| class A end + + +[#2 Content] = +[#2 Domain] = 0:7-0:8 + >-< +0| class A end diff --git a/data/fixtures/scopes/ruby/statement/statement.switch.scope b/data/fixtures/scopes/ruby/statement/statement.switch.scope new file mode 100644 index 0000000000..c38eb88735 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.switch.scope @@ -0,0 +1,10 @@ +case foo end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:12 + >------------< +0| case foo end + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.try.scope b/data/fixtures/scopes/ruby/statement/statement.try.scope new file mode 100644 index 0000000000..c8ac562300 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.try.scope @@ -0,0 +1,15 @@ +begin +rescue +end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-2:3 + >----- +0| begin +1| rescue +2| end + ---< + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/value/value.assignment.scope b/data/fixtures/scopes/ruby/value/value.assignment.scope new file mode 100644 index 0000000000..6e89de0927 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.assignment.scope @@ -0,0 +1,20 @@ +foo = 0 +--- + +[Content] = 0:6-0:7 + >-< +0| foo = 0 + +[Removal] = 0:3-0:7 + >----< +0| foo = 0 + +[Leading delimiter] = 0:3-0:6 + >---< +0| foo = 0 + +[Domain] = 0:0-0:7 + >-------< +0| foo = 0 + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.foreach.scope b/data/fixtures/scopes/ruby/value/value.foreach.scope new file mode 100644 index 0000000000..41777bf058 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.foreach.scope @@ -0,0 +1,24 @@ +for v in values end +--- + +[Content] = 0:9-0:15 + >------< +0| for v in values end + +[Removal] = 0:9-0:16 + >-------< +0| for v in values end + +[Leading delimiter] = 0:8-0:9 + >-< +0| for v in values end + +[Trailing delimiter] = 0:15-0:16 + >-< +0| for v in values end + +[Domain] = 0:0-0:19 + >-------------------< +0| for v in values end + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.iteration.class.scope b/data/fixtures/scopes/ruby/value/value.iteration.class.scope new file mode 100644 index 0000000000..37cb946c03 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.iteration.class.scope @@ -0,0 +1,13 @@ +class Foo end +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:13 + >-------------< +0| class Foo end + + +[#2 Content] = +[#2 Domain] = 0:9-0:10 + >-< +0| class Foo end diff --git a/data/fixtures/scopes/ruby/value/value.return.lambda.scope b/data/fixtures/scopes/ruby/value/value.return.lambda.scope new file mode 100644 index 0000000000..8ac277ee5a --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.return.lambda.scope @@ -0,0 +1,24 @@ +->() { 0 } +--- + +[Content] = 0:7-0:8 + >-< +0| ->() { 0 } + +[Removal] = 0:7-0:9 + >--< +0| ->() { 0 } + +[Leading delimiter] = 0:6-0:7 + >-< +0| ->() { 0 } + +[Trailing delimiter] = 0:8-0:9 + >-< +0| ->() { 0 } + +[Domain] = 0:0-0:10 + >----------< +0| ->() { 0 } + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.return.scope b/data/fixtures/scopes/ruby/value/value.return.scope new file mode 100644 index 0000000000..acd1a19e45 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.return.scope @@ -0,0 +1,22 @@ +def foo() + return 0 +end +--- + +[Content] = 1:11-1:12 + >-< +1| return 0 + +[Removal] = 1:10-1:12 + >--< +1| return 0 + +[Leading delimiter] = 1:10-1:11 + >-< +1| return 0 + +[Domain] = 1:4-1:12 + >--------< +1| return 0 + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.switch.scope b/data/fixtures/scopes/ruby/value/value.switch.scope new file mode 100644 index 0000000000..bcba518c77 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.switch.scope @@ -0,0 +1,24 @@ +case foo end +--- + +[Content] = 0:5-0:8 + >---< +0| case foo end + +[Removal] = 0:5-0:9 + >----< +0| case foo end + +[Leading delimiter] = 0:4-0:5 + >-< +0| case foo end + +[Trailing delimiter] = 0:8-0:9 + >-< +0| case foo end + +[Domain] = 0:0-0:12 + >------------< +0| case foo end + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.variable.scope b/data/fixtures/scopes/ruby/value/value.variable.scope new file mode 100644 index 0000000000..6e89de0927 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.variable.scope @@ -0,0 +1,20 @@ +foo = 0 +--- + +[Content] = 0:6-0:7 + >-< +0| foo = 0 + +[Removal] = 0:3-0:7 + >----< +0| foo = 0 + +[Leading delimiter] = 0:3-0:6 + >---< +0| foo = 0 + +[Domain] = 0:0-0:7 + >-------< +0| foo = 0 + +[Insertion delimiter] = " " diff --git a/queries/ruby.scm b/queries/ruby.scm index e586e0de8a..66ca7c0075 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -150,9 +150,16 @@ name: (_) @name ) @class @_.domain +;;!! class Foo end +;;! ^ +(class + name: (_) @class.iteration.start.endOf @namedFunction.iteration.start.endOf @statement.iteration.start.endOf + "end" @class.iteration.end.startOf @namedFunction.iteration.end.startOf @statement.iteration.end.startOf +) @class + (class - name: (_) @class.iteration.start.endOf @namedFunction.iteration.start.endOf @name.iteration.start.endOf - "end" @class.iteration.end.startOf @namedFunction.iteration.end.startOf @name.iteration.end.startOf + name: (_) @name.iteration.start.endOf @value.iteration.start.endOf + "end" @name.iteration.end.startOf @value.iteration.end.startOf ) @class ;;!! "Hello world" @@ -163,6 +170,8 @@ (heredoc_content) ] @textFragment +;;!! class foo def bar() end end +;;! ^^^ (method name: (_) @name ) @_.domain @@ -171,32 +180,37 @@ name: (_) @name ) @_.domain +;;!! foo = 0 +;;! ^^^ +;;! ^ (assignment - left: (_) @name + left: (_) @name @value.leading.endOf + right: (_) @value @name.trailing.startOf ) @_.domain +;;!! foo += 0 +;;! ^^^ +;;! ^ (operator_assignment - left: (_) @name + left: (_) @name @value.leading.endOf + right: (_) @value @name.trailing.startOf ) @_.domain -(_ - operator: [ - "<" - ">" - "<=" - ">=" - "<<" - ">>" - "<<=" - ">>=" - ] @disqualifyDelimiter -) -(pair - "=>" @disqualifyDelimiter -) -(match_pattern - "=>" @disqualifyDelimiter -) +;;!! for v in values end +;;! ^ +;;! ^^^^^^ +(for + pattern: (_) @name + value: (in + (_) @value + ) +) @_.domain + +;;!! case foo end +;;! ^^^ +(case + value: (_) @value +) @value.domain ;;!! %w(foo bar) ;;! ^^^ ^^^ @@ -233,6 +247,17 @@ ;;!! -> {} (lambda) @anonymousFunction +;;!! -> { 0 } +(lambda + (block + (block_body + . + (_) @value + . + ) + ) +) @value.domain + ;;!! [1,2,3].each do |i| end ;;! ^^^^^^^^^^ (do_block) @anonymousFunction @@ -283,20 +308,6 @@ (argument_list) @value ) @_.domain -;;!! a = 10 -;;! ^^ -(assignment - left: (_) @_.leading.endOf - right: (_) @value -) @_.domain - -;;!! a += 10 -;;! ^^ -(operator_assignment - left: (_) @_.leading.endOf - right: (_) @value -) @_.domain - ;;!! def foo(aaa, bbb) ;;! ^^^ ^^^ ( @@ -370,3 +381,22 @@ (#child-range! @argumentList 1 -2) ) ) @argumentList.domain @argumentOrParameter.iteration.domain + +(_ + operator: [ + "<" + ">" + "<=" + ">=" + "<<" + ">>" + "<<=" + ">>=" + ] @disqualifyDelimiter +) +(pair + "=>" @disqualifyDelimiter +) +(match_pattern + "=>" @disqualifyDelimiter +) From a14075b9b01be7990d635d1d4d42efb6e610ef7c Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 14:44:48 +0100 Subject: [PATCH 07/26] pair --- .../ruby/key/key.mapPair.iteration.scope | 7 ++++ .../scopes/ruby/key/key.mapPair.scope | 39 +++++++++++++++++++ .../ruby/value/value.mapPair.iteration.scope | 13 +++++++ .../scopes/ruby/value/value.mapPair.scope | 39 +++++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 data/fixtures/scopes/ruby/key/key.mapPair.iteration.scope create mode 100644 data/fixtures/scopes/ruby/key/key.mapPair.scope create mode 100644 data/fixtures/scopes/ruby/value/value.mapPair.iteration.scope create mode 100644 data/fixtures/scopes/ruby/value/value.mapPair.scope diff --git a/data/fixtures/scopes/ruby/key/key.mapPair.iteration.scope b/data/fixtures/scopes/ruby/key/key.mapPair.iteration.scope new file mode 100644 index 0000000000..7708be130f --- /dev/null +++ b/data/fixtures/scopes/ruby/key/key.mapPair.iteration.scope @@ -0,0 +1,7 @@ +{aaa: 0, bbb: 1} +--- + +[Content] = +[Domain] = 0:1-0:15 + >--------------< +0| {aaa: 0, bbb: 1} diff --git a/data/fixtures/scopes/ruby/key/key.mapPair.scope b/data/fixtures/scopes/ruby/key/key.mapPair.scope new file mode 100644 index 0000000000..2a80a5972d --- /dev/null +++ b/data/fixtures/scopes/ruby/key/key.mapPair.scope @@ -0,0 +1,39 @@ +{aaa: 0, bbb: 1} +--- + +[#1 Content] = 0:1-0:4 + >---< +0| {aaa: 0, bbb: 1} + +[#1 Removal] = 0:1-0:6 + >-----< +0| {aaa: 0, bbb: 1} + +[#1 Trailing delimiter] = 0:4-0:6 + >--< +0| {aaa: 0, bbb: 1} + +[#1 Domain] = 0:1-0:7 + >------< +0| {aaa: 0, bbb: 1} + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 0:9-0:12 + >---< +0| {aaa: 0, bbb: 1} + +[#2 Removal] = 0:9-0:14 + >-----< +0| {aaa: 0, bbb: 1} + +[#2 Trailing delimiter] = 0:12-0:14 + >--< +0| {aaa: 0, bbb: 1} + +[#2 Domain] = 0:9-0:15 + >------< +0| {aaa: 0, bbb: 1} + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.mapPair.iteration.scope b/data/fixtures/scopes/ruby/value/value.mapPair.iteration.scope new file mode 100644 index 0000000000..e952029a05 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.mapPair.iteration.scope @@ -0,0 +1,13 @@ +{aaa: 0, bbb: 1} +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:16 + >----------------< +0| {aaa: 0, bbb: 1} + + +[#2 Content] = +[#2 Domain] = 0:1-0:15 + >--------------< +0| {aaa: 0, bbb: 1} diff --git a/data/fixtures/scopes/ruby/value/value.mapPair.scope b/data/fixtures/scopes/ruby/value/value.mapPair.scope new file mode 100644 index 0000000000..c6bd37aa6c --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.mapPair.scope @@ -0,0 +1,39 @@ +{aaa: 0, bbb: 1} +--- + +[#1 Content] = 0:6-0:7 + >-< +0| {aaa: 0, bbb: 1} + +[#1 Removal] = 0:4-0:7 + >---< +0| {aaa: 0, bbb: 1} + +[#1 Leading delimiter] = 0:4-0:6 + >--< +0| {aaa: 0, bbb: 1} + +[#1 Domain] = 0:1-0:7 + >------< +0| {aaa: 0, bbb: 1} + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 0:14-0:15 + >-< +0| {aaa: 0, bbb: 1} + +[#2 Removal] = 0:12-0:15 + >---< +0| {aaa: 0, bbb: 1} + +[#2 Leading delimiter] = 0:12-0:14 + >--< +0| {aaa: 0, bbb: 1} + +[#2 Domain] = 0:9-0:15 + >------< +0| {aaa: 0, bbb: 1} + +[#2 Insertion delimiter] = " " From 82204d620a45aa03acbad68d8e876378cdfec496 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 14:46:55 +0100 Subject: [PATCH 08/26] lambda --- .../scopes/ruby/anonymousFunction3.scope | 17 +++++++++++++++++ queries/ruby.scm | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 data/fixtures/scopes/ruby/anonymousFunction3.scope diff --git a/data/fixtures/scopes/ruby/anonymousFunction3.scope b/data/fixtures/scopes/ruby/anonymousFunction3.scope new file mode 100644 index 0000000000..0a93d706ec --- /dev/null +++ b/data/fixtures/scopes/ruby/anonymousFunction3.scope @@ -0,0 +1,17 @@ +values.each do |v| end +--- + +[Content] = +[Domain] = 0:12-0:22 + >----------< +0| values.each do |v| end + +[Removal] = 0:11-0:22 + >-----------< +0| values.each do |v| end + +[Leading delimiter] = 0:11-0:12 + >-< +0| values.each do |v| end + +[Insertion delimiter] = "\n" diff --git a/queries/ruby.scm b/queries/ruby.scm index 66ca7c0075..8581d7c61a 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -258,8 +258,8 @@ ) ) @value.domain -;;!! [1,2,3].each do |i| end -;;! ^^^^^^^^^^ +;;!! values.each do |v| end +;;! ^^^^^^^^^^ (do_block) @anonymousFunction (call From e14d5afd790fa1125dec36befb86cee1484b75fb Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 14:47:53 +0100 Subject: [PATCH 09/26] update tests --- data/fixtures/recorded/languages/ruby/chuckNameThis.yml | 6 +++--- data/fixtures/recorded/languages/ruby/chuckNameThis2.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/fixtures/recorded/languages/ruby/chuckNameThis.yml b/data/fixtures/recorded/languages/ruby/chuckNameThis.yml index e532532034..76b0b19806 100644 --- a/data/fixtures/recorded/languages/ruby/chuckNameThis.yml +++ b/data/fixtures/recorded/languages/ruby/chuckNameThis.yml @@ -18,7 +18,7 @@ initialState: active: {line: 0, character: 5} marks: {} finalState: - documentContents: += 1 + documentContents: "1" selections: - - anchor: {line: 0, character: 3} - active: {line: 0, character: 3} + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/data/fixtures/recorded/languages/ruby/chuckNameThis2.yml b/data/fixtures/recorded/languages/ruby/chuckNameThis2.yml index 6d0d24adbf..770e6323f1 100644 --- a/data/fixtures/recorded/languages/ruby/chuckNameThis2.yml +++ b/data/fixtures/recorded/languages/ruby/chuckNameThis2.yml @@ -18,7 +18,7 @@ initialState: active: {line: 0, character: 4} marks: {} finalState: - documentContents: "= 1" + documentContents: "1" selections: - - anchor: {line: 0, character: 2} - active: {line: 0, character: 2} + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} From bf204f2931153f47f1abf11daa5da0eda2dcfcba Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 14:58:46 +0100 Subject: [PATCH 10/26] argument list --- .../argumentList.actual.method.empty.scope | 13 +++++++ ...argumentList.actual.method.multiLine.scope | 33 +++++++++++++++++ ...rgumentList.actual.method.singleLine.scope | 13 +++++++ .../argumentList.formal.lambda.empty.scope | 13 +++++++ ...argumentList.formal.lambda.multiLine.scope | 33 +++++++++++++++++ ...rgumentList.formal.lambda.singleLine.scope | 13 +++++++ .../argumentList.formal.method.empty.scope | 15 ++++++++ ...argumentList.formal.method.multiLine.scope | 35 +++++++++++++++++++ ...rgumentList.formal.method.singleLine.scope | 15 ++++++++ queries/ruby.scm | 11 ++++++ 10 files changed, 194 insertions(+) create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.empty.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.singleLine.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.empty.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.singleLine.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.empty.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.singleLine.scope diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.empty.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.empty.scope new file mode 100644 index 0000000000..ed61422204 --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.empty.scope @@ -0,0 +1,13 @@ +foo.bar() +--- + +[Content] = +[Removal] = 0:8-0:8 + >< +0| foo.bar() + +[Domain] = 0:0-0:9 + >---------< +0| foo.bar() + +[Insertion delimiter] = "" diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.multiLine.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.multiLine.scope new file mode 100644 index 0000000000..fbf6ce60c0 --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.multiLine.scope @@ -0,0 +1,33 @@ +foo.bar( + aaa, + bbb +) +--- + +[Content] = 1:4-2:7 + >---- +1| aaa, +2| bbb + -------< + +[Removal] = 0:8-3:0 + > +0| foo.bar( +1| aaa, +2| bbb +3| ) + < + +[Leading delimiter] = 1:0-1:4 + >----< +1| aaa, + +[Domain] = 0:0-3:1 + >-------- +0| foo.bar( +1| aaa, +2| bbb +3| ) + -< + +[Insertion delimiter] = ",\n" diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.singleLine.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.singleLine.scope new file mode 100644 index 0000000000..69cf068256 --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.actual.method.singleLine.scope @@ -0,0 +1,13 @@ +foo.bar(aaa, bbb) +--- + +[Content] = +[Removal] = 0:8-0:16 + >--------< +0| foo.bar(aaa, bbb) + +[Domain] = 0:0-0:17 + >-----------------< +0| foo.bar(aaa, bbb) + +[Insertion delimiter] = ", " diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.empty.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.empty.scope new file mode 100644 index 0000000000..bc2d0589bf --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.empty.scope @@ -0,0 +1,13 @@ +->() {} +--- + +[Content] = +[Removal] = 0:3-0:3 + >< +0| ->() {} + +[Domain] = 0:0-0:7 + >-------< +0| ->() {} + +[Insertion delimiter] = "" diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.multiLine.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.multiLine.scope new file mode 100644 index 0000000000..61d83bb70c --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.multiLine.scope @@ -0,0 +1,33 @@ +->( + aaa, + bbb +) {} +--- + +[Content] = 1:4-2:7 + >---- +1| aaa, +2| bbb + -------< + +[Removal] = 0:3-3:0 + > +0| ->( +1| aaa, +2| bbb +3| ) {} + < + +[Leading delimiter] = 1:0-1:4 + >----< +1| aaa, + +[Domain] = 0:0-3:4 + >--- +0| ->( +1| aaa, +2| bbb +3| ) {} + ----< + +[Insertion delimiter] = ",\n" diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.singleLine.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.singleLine.scope new file mode 100644 index 0000000000..7c8bd53628 --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.lambda.singleLine.scope @@ -0,0 +1,13 @@ +->(aaa, bbb) {} +--- + +[Content] = +[Removal] = 0:3-0:11 + >--------< +0| ->(aaa, bbb) {} + +[Domain] = 0:0-0:15 + >---------------< +0| ->(aaa, bbb) {} + +[Insertion delimiter] = ", " diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.empty.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.empty.scope new file mode 100644 index 0000000000..0a5c2c4d38 --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.empty.scope @@ -0,0 +1,15 @@ +class Foo + def bar() end +end +--- + +[Content] = +[Removal] = 1:12-1:12 + >< +1| def bar() end + +[Domain] = 1:4-1:17 + >-------------< +1| def bar() end + +[Insertion delimiter] = "" diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.multiLine.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.multiLine.scope new file mode 100644 index 0000000000..ce46aa2a82 --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.multiLine.scope @@ -0,0 +1,35 @@ +class Foo + def bar( + aaa, + bbb + ) end +end +--- + +[Content] = 2:8-3:11 + >---- +2| aaa, +3| bbb + -----------< + +[Removal] = 1:12-4:4 + > +1| def bar( +2| aaa, +3| bbb +4| ) end + ----< + +[Leading delimiter] = 2:0-2:8 + >--------< +2| aaa, + +[Domain] = 1:4-4:9 + >-------- +1| def bar( +2| aaa, +3| bbb +4| ) end + ---------< + +[Insertion delimiter] = ",\n" diff --git a/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.singleLine.scope b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.singleLine.scope new file mode 100644 index 0000000000..5c46915a72 --- /dev/null +++ b/data/fixtures/scopes/ruby/argumentList/argumentList.formal.method.singleLine.scope @@ -0,0 +1,15 @@ +class Foo + def bar(aaa, bbb) end +end +--- + +[Content] = +[Removal] = 1:12-1:20 + >--------< +1| def bar(aaa, bbb) end + +[Domain] = 1:4-1:25 + >---------------------< +1| def bar(aaa, bbb) end + +[Insertion delimiter] = ", " diff --git a/queries/ruby.scm b/queries/ruby.scm index 8581d7c61a..c211ddd3fc 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -358,6 +358,17 @@ (#child-range! @argumentList 1 -2) ) @argumentList.domain @argumentOrParameter.iteration.domain +;;!! ->(aaa, bbb) {} +;;! ^^^^^^^^ +(_ + (lambda_parameters + "(" @argumentList.removal.start.endOf @argumentOrParameter.iteration.start.endOf + ")" @argumentList.removal.end.startOf @argumentOrParameter.iteration.end.startOf + ) @argumentList + (#empty-single-multi-delimiter! @argumentList @argumentList "" ", " ",\n") + (#child-range! @argumentList 1 -2) +) @argumentList.domain @argumentOrParameter.iteration.domain + ;;!! foo(aaa, bbb) ;;! ^^^^^^^^ (_ From f5f41c3d2af7e9a674125b55de6b1bdd45e30630 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 15:03:00 +0100 Subject: [PATCH 11/26] argument --- .../argument.actual.method.iteration.scope | 10 ++++ .../argument.actual.method.multiLine.scope | 44 ++++++++++++++++++ .../argument.actual.method.singleLine.scope | 33 +++++++++++++ .../argument.formal.lambda.iteration.scope | 10 ++++ .../argument.formal.lambda.multiLine.scope | 44 ++++++++++++++++++ .../argument.formal.lambda.singleLine.scope | 33 +++++++++++++ .../argument.formal.method.iteration.scope | 12 +++++ .../argument.formal.method.multiLine.scope | 46 +++++++++++++++++++ .../argument.formal.method.singleLine.scope | 35 ++++++++++++++ 9 files changed, 267 insertions(+) create mode 100644 data/fixtures/scopes/ruby/argument/argument.actual.method.iteration.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.actual.method.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.actual.method.singleLine.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.formal.lambda.iteration.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.formal.lambda.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.formal.lambda.singleLine.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.formal.method.iteration.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.formal.method.multiLine.scope create mode 100644 data/fixtures/scopes/ruby/argument/argument.formal.method.singleLine.scope diff --git a/data/fixtures/scopes/ruby/argument/argument.actual.method.iteration.scope b/data/fixtures/scopes/ruby/argument/argument.actual.method.iteration.scope new file mode 100644 index 0000000000..8b3899b4a1 --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.actual.method.iteration.scope @@ -0,0 +1,10 @@ +foo.bar(aaa, bbb) +--- + +[Content] = 0:8-0:16 + >--------< +0| foo.bar(aaa, bbb) + +[Domain] = 0:0-0:17 + >-----------------< +0| foo.bar(aaa, bbb) diff --git a/data/fixtures/scopes/ruby/argument/argument.actual.method.multiLine.scope b/data/fixtures/scopes/ruby/argument/argument.actual.method.multiLine.scope new file mode 100644 index 0000000000..7dace79cea --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.actual.method.multiLine.scope @@ -0,0 +1,44 @@ +foo.bar( + aaa, + bbb +) +--- + +[#1 Content] = +[#1 Domain] = 1:4-1:7 + >---< +1| aaa, + +[#1 Removal] = 1:4-2:4 + >---- +1| aaa, +2| bbb + ----< + +[#1 Trailing delimiter] = 1:7-2:4 + >- +1| aaa, +2| bbb + ----< + +[#1 Insertion delimiter] = ",\n" + + +[#2 Content] = +[#2 Domain] = 2:4-2:7 + >---< +2| bbb + +[#2 Removal] = 1:7-2:7 + >- +1| aaa, +2| bbb + -------< + +[#2 Leading delimiter] = 1:7-2:4 + >- +1| aaa, +2| bbb + ----< + +[#2 Insertion delimiter] = ",\n" diff --git a/data/fixtures/scopes/ruby/argument/argument.actual.method.singleLine.scope b/data/fixtures/scopes/ruby/argument/argument.actual.method.singleLine.scope new file mode 100644 index 0000000000..d22bd33706 --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.actual.method.singleLine.scope @@ -0,0 +1,33 @@ +foo.bar(aaa, bbb) +--- + +[#1 Content] = +[#1 Domain] = 0:8-0:11 + >---< +0| foo.bar(aaa, bbb) + +[#1 Removal] = 0:8-0:13 + >-----< +0| foo.bar(aaa, bbb) + +[#1 Trailing delimiter] = 0:11-0:13 + >--< +0| foo.bar(aaa, bbb) + +[#1 Insertion delimiter] = ", " + + +[#2 Content] = +[#2 Domain] = 0:13-0:16 + >---< +0| foo.bar(aaa, bbb) + +[#2 Removal] = 0:11-0:16 + >-----< +0| foo.bar(aaa, bbb) + +[#2 Leading delimiter] = 0:11-0:13 + >--< +0| foo.bar(aaa, bbb) + +[#2 Insertion delimiter] = ", " diff --git a/data/fixtures/scopes/ruby/argument/argument.formal.lambda.iteration.scope b/data/fixtures/scopes/ruby/argument/argument.formal.lambda.iteration.scope new file mode 100644 index 0000000000..13be50b990 --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.formal.lambda.iteration.scope @@ -0,0 +1,10 @@ +->(aaa, bbb) {} +--- + +[Content] = 0:3-0:11 + >--------< +0| ->(aaa, bbb) {} + +[Domain] = 0:0-0:15 + >---------------< +0| ->(aaa, bbb) {} diff --git a/data/fixtures/scopes/ruby/argument/argument.formal.lambda.multiLine.scope b/data/fixtures/scopes/ruby/argument/argument.formal.lambda.multiLine.scope new file mode 100644 index 0000000000..52913bec80 --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.formal.lambda.multiLine.scope @@ -0,0 +1,44 @@ +->( + aaa, + bbb +) {} +--- + +[#1 Content] = +[#1 Domain] = 1:4-1:7 + >---< +1| aaa, + +[#1 Removal] = 1:4-2:4 + >---- +1| aaa, +2| bbb + ----< + +[#1 Trailing delimiter] = 1:7-2:4 + >- +1| aaa, +2| bbb + ----< + +[#1 Insertion delimiter] = ",\n" + + +[#2 Content] = +[#2 Domain] = 2:4-2:7 + >---< +2| bbb + +[#2 Removal] = 1:7-2:7 + >- +1| aaa, +2| bbb + -------< + +[#2 Leading delimiter] = 1:7-2:4 + >- +1| aaa, +2| bbb + ----< + +[#2 Insertion delimiter] = ",\n" diff --git a/data/fixtures/scopes/ruby/argument/argument.formal.lambda.singleLine.scope b/data/fixtures/scopes/ruby/argument/argument.formal.lambda.singleLine.scope new file mode 100644 index 0000000000..82a6499b63 --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.formal.lambda.singleLine.scope @@ -0,0 +1,33 @@ +->(aaa, bbb) {} +--- + +[#1 Content] = +[#1 Domain] = 0:3-0:6 + >---< +0| ->(aaa, bbb) {} + +[#1 Removal] = 0:3-0:8 + >-----< +0| ->(aaa, bbb) {} + +[#1 Trailing delimiter] = 0:6-0:8 + >--< +0| ->(aaa, bbb) {} + +[#1 Insertion delimiter] = ", " + + +[#2 Content] = +[#2 Domain] = 0:8-0:11 + >---< +0| ->(aaa, bbb) {} + +[#2 Removal] = 0:6-0:11 + >-----< +0| ->(aaa, bbb) {} + +[#2 Leading delimiter] = 0:6-0:8 + >--< +0| ->(aaa, bbb) {} + +[#2 Insertion delimiter] = ", " diff --git a/data/fixtures/scopes/ruby/argument/argument.formal.method.iteration.scope b/data/fixtures/scopes/ruby/argument/argument.formal.method.iteration.scope new file mode 100644 index 0000000000..410d3e722f --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.formal.method.iteration.scope @@ -0,0 +1,12 @@ +class Foo + def bar(aaa, bbb) end +end +--- + +[Content] = 1:12-1:20 + >--------< +1| def bar(aaa, bbb) end + +[Domain] = 1:4-1:25 + >---------------------< +1| def bar(aaa, bbb) end diff --git a/data/fixtures/scopes/ruby/argument/argument.formal.method.multiLine.scope b/data/fixtures/scopes/ruby/argument/argument.formal.method.multiLine.scope new file mode 100644 index 0000000000..d0f4f95e37 --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.formal.method.multiLine.scope @@ -0,0 +1,46 @@ +class Foo + def bar( + aaa, + bbb + ) end +end +--- + +[#1 Content] = +[#1 Domain] = 2:8-2:11 + >---< +2| aaa, + +[#1 Removal] = 2:8-3:8 + >---- +2| aaa, +3| bbb + --------< + +[#1 Trailing delimiter] = 2:11-3:8 + >- +2| aaa, +3| bbb + --------< + +[#1 Insertion delimiter] = ",\n" + + +[#2 Content] = +[#2 Domain] = 3:8-3:11 + >---< +3| bbb + +[#2 Removal] = 2:11-3:11 + >- +2| aaa, +3| bbb + -----------< + +[#2 Leading delimiter] = 2:11-3:8 + >- +2| aaa, +3| bbb + --------< + +[#2 Insertion delimiter] = ",\n" diff --git a/data/fixtures/scopes/ruby/argument/argument.formal.method.singleLine.scope b/data/fixtures/scopes/ruby/argument/argument.formal.method.singleLine.scope new file mode 100644 index 0000000000..ff31abfdf1 --- /dev/null +++ b/data/fixtures/scopes/ruby/argument/argument.formal.method.singleLine.scope @@ -0,0 +1,35 @@ +class Foo + def bar(aaa, bbb) end +end +--- + +[#1 Content] = +[#1 Domain] = 1:12-1:15 + >---< +1| def bar(aaa, bbb) end + +[#1 Removal] = 1:12-1:17 + >-----< +1| def bar(aaa, bbb) end + +[#1 Trailing delimiter] = 1:15-1:17 + >--< +1| def bar(aaa, bbb) end + +[#1 Insertion delimiter] = ", " + + +[#2 Content] = +[#2 Domain] = 1:17-1:20 + >---< +1| def bar(aaa, bbb) end + +[#2 Removal] = 1:15-1:20 + >-----< +1| def bar(aaa, bbb) end + +[#2 Leading delimiter] = 1:15-1:17 + >--< +1| def bar(aaa, bbb) end + +[#2 Insertion delimiter] = ", " From 2019595dc4e0007df83873106cbaaee45b583ade Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 15:03:14 +0100 Subject: [PATCH 12/26] argument fixes --- queries/ruby.scm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/queries/ruby.scm b/queries/ruby.scm index c211ddd3fc..7ed7b4a2a5 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -321,6 +321,19 @@ (#single-or-multi-line-delimiter! @argumentOrParameter @_dummy ", " ",\n") ) +;;!! ->(aaa, bbb) {} +;;! ^^^ ^^^ +( + (lambda_parameters + (_)? @_.leading.endOf + . + (_) @argumentOrParameter + . + (_)? @_.trailing.startOf + ) @_dummy + (#single-or-multi-line-delimiter! @argumentOrParameter @_dummy ", " ",\n") +) + ;;!! foo(aaa, bbb) ;;! ^^^ ^^^ ( From 30780e630f9d00220e4c9137314924cefd59f9f6 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 15:12:18 +0100 Subject: [PATCH 13/26] argument actual --- .../name/name.argument.actual.iteration.scope | 13 +++++++ .../ruby/name/name.argument.actual.scope | 39 +++++++++++++++++++ .../value.argument.actual.iteration.scope | 13 +++++++ .../ruby/value/value.argument.actual.scope | 39 +++++++++++++++++++ queries/ruby.scm | 20 ++++++++-- 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 data/fixtures/scopes/ruby/name/name.argument.actual.iteration.scope create mode 100644 data/fixtures/scopes/ruby/name/name.argument.actual.scope create mode 100644 data/fixtures/scopes/ruby/value/value.argument.actual.iteration.scope create mode 100644 data/fixtures/scopes/ruby/value/value.argument.actual.scope diff --git a/data/fixtures/scopes/ruby/name/name.argument.actual.iteration.scope b/data/fixtures/scopes/ruby/name/name.argument.actual.iteration.scope new file mode 100644 index 0000000000..c25ba7b1bd --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.actual.iteration.scope @@ -0,0 +1,13 @@ +foo(aaa: 0, bbb: 1) +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:19 + >-------------------< +0| foo(aaa: 0, bbb: 1) + + +[#2 Content] = +[#2 Domain] = 0:4-0:18 + >--------------< +0| foo(aaa: 0, bbb: 1) diff --git a/data/fixtures/scopes/ruby/name/name.argument.actual.scope b/data/fixtures/scopes/ruby/name/name.argument.actual.scope new file mode 100644 index 0000000000..8f76744ee7 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.actual.scope @@ -0,0 +1,39 @@ +foo(aaa: 0, bbb: 1) +--- + +[#1 Content] = 0:4-0:7 + >---< +0| foo(aaa: 0, bbb: 1) + +[#1 Removal] = 0:4-0:9 + >-----< +0| foo(aaa: 0, bbb: 1) + +[#1 Trailing delimiter] = 0:7-0:9 + >--< +0| foo(aaa: 0, bbb: 1) + +[#1 Domain] = 0:4-0:10 + >------< +0| foo(aaa: 0, bbb: 1) + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 0:12-0:15 + >---< +0| foo(aaa: 0, bbb: 1) + +[#2 Removal] = 0:12-0:17 + >-----< +0| foo(aaa: 0, bbb: 1) + +[#2 Trailing delimiter] = 0:15-0:17 + >--< +0| foo(aaa: 0, bbb: 1) + +[#2 Domain] = 0:12-0:18 + >------< +0| foo(aaa: 0, bbb: 1) + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.argument.actual.iteration.scope b/data/fixtures/scopes/ruby/value/value.argument.actual.iteration.scope new file mode 100644 index 0000000000..c25ba7b1bd --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.argument.actual.iteration.scope @@ -0,0 +1,13 @@ +foo(aaa: 0, bbb: 1) +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:19 + >-------------------< +0| foo(aaa: 0, bbb: 1) + + +[#2 Content] = +[#2 Domain] = 0:4-0:18 + >--------------< +0| foo(aaa: 0, bbb: 1) diff --git a/data/fixtures/scopes/ruby/value/value.argument.actual.scope b/data/fixtures/scopes/ruby/value/value.argument.actual.scope new file mode 100644 index 0000000000..569017e7ed --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.argument.actual.scope @@ -0,0 +1,39 @@ +foo(aaa: 0, bbb: 1) +--- + +[#1 Content] = 0:9-0:10 + >-< +0| foo(aaa: 0, bbb: 1) + +[#1 Removal] = 0:7-0:10 + >---< +0| foo(aaa: 0, bbb: 1) + +[#1 Leading delimiter] = 0:7-0:9 + >--< +0| foo(aaa: 0, bbb: 1) + +[#1 Domain] = 0:4-0:10 + >------< +0| foo(aaa: 0, bbb: 1) + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 0:17-0:18 + >-< +0| foo(aaa: 0, bbb: 1) + +[#2 Removal] = 0:15-0:18 + >---< +0| foo(aaa: 0, bbb: 1) + +[#2 Leading delimiter] = 0:15-0:17 + >--< +0| foo(aaa: 0, bbb: 1) + +[#2 Domain] = 0:12-0:18 + >------< +0| foo(aaa: 0, bbb: 1) + +[#2 Insertion delimiter] = " " diff --git a/queries/ruby.scm b/queries/ruby.scm index 7ed7b4a2a5..ed6aeb0a01 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -123,6 +123,10 @@ (call receiver: (_)? @functionCallee.start method: (_) @functionCallee.end + arguments: (_ + "(" @name.iteration.start.endOf @value.iteration.start.endOf + ")" @name.iteration.end.startOf @value.iteration.end.startOf + ) ) @functionCall @functionCallee.domain [ @@ -295,6 +299,16 @@ value: (_) @value @collectionKey.trailing.startOf ) @_.domain +;;!! foo(aaa: 0, bbb: 1) +;;! ^^^ +;;! ^^^ +(argument_list + (pair + key: (_) @name + value: (_) @name.trailing.startOf + ) @name.domain +) + ;;!! {"1" => "one", "2" => "two"} ;;! ^^^^^^^^^^^^^^^^^^^^^^^^^^ (hash @@ -302,11 +316,11 @@ "}" @collectionKey.iteration.end.startOf @value.iteration.end.startOf ) -;;!! return 10 -;;! ^^ +;;!! return 0 +;;! ^ (return (argument_list) @value -) @_.domain +) @value.domain ;;!! def foo(aaa, bbb) ;;! ^^^ ^^^ From c3efb78468caf083865016d03a4493a4e2fc395a Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 15:29:39 +0100 Subject: [PATCH 14/26] argument formal --- .../name/name.argument.formal.iteration.scope | 13 ++++ ...ame.argument.formal.lambda.iteration.scope | 13 ++++ .../name/name.argument.formal.lambda.scope | 33 +++++++++ ...ame.argument.formal.method.iteration.scope | 27 +++++++ .../name/name.argument.formal.method.scope | 73 +++++++++++++++++++ .../ruby/name/name.argument.formal.scope | 49 +++++++++++++ .../value.argument.formal.iteration.scope | 13 ++++ ...lue.argument.formal.method.iteration.scope | 27 +++++++ .../value/value.argument.formal.method.scope | 41 +++++++++++ .../ruby/value/value.argument.formal.scope | 39 ++++++++++ queries/ruby.scm | 36 +++++++++ 11 files changed, 364 insertions(+) create mode 100644 data/fixtures/scopes/ruby/name/name.argument.formal.iteration.scope create mode 100644 data/fixtures/scopes/ruby/name/name.argument.formal.lambda.iteration.scope create mode 100644 data/fixtures/scopes/ruby/name/name.argument.formal.lambda.scope create mode 100644 data/fixtures/scopes/ruby/name/name.argument.formal.method.iteration.scope create mode 100644 data/fixtures/scopes/ruby/name/name.argument.formal.method.scope create mode 100644 data/fixtures/scopes/ruby/name/name.argument.formal.scope create mode 100644 data/fixtures/scopes/ruby/value/value.argument.formal.iteration.scope create mode 100644 data/fixtures/scopes/ruby/value/value.argument.formal.method.iteration.scope create mode 100644 data/fixtures/scopes/ruby/value/value.argument.formal.method.scope create mode 100644 data/fixtures/scopes/ruby/value/value.argument.formal.scope diff --git a/data/fixtures/scopes/ruby/name/name.argument.formal.iteration.scope b/data/fixtures/scopes/ruby/name/name.argument.formal.iteration.scope new file mode 100644 index 0000000000..a9ad68b58c --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.formal.iteration.scope @@ -0,0 +1,13 @@ +def foo(aaa, bbb = 0) end +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:25 + >-------------------------< +0| def foo(aaa, bbb = 0) end + + +[#2 Content] = +[#2 Domain] = 0:8-0:20 + >------------< +0| def foo(aaa, bbb = 0) end diff --git a/data/fixtures/scopes/ruby/name/name.argument.formal.lambda.iteration.scope b/data/fixtures/scopes/ruby/name/name.argument.formal.lambda.iteration.scope new file mode 100644 index 0000000000..0897500cc0 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.formal.lambda.iteration.scope @@ -0,0 +1,13 @@ +->(aaa, bbb = 0) {} +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:19 + >-------------------< +0| ->(aaa, bbb = 0) {} + + +[#2 Content] = +[#2 Domain] = 0:3-0:15 + >------------< +0| ->(aaa, bbb = 0) {} diff --git a/data/fixtures/scopes/ruby/name/name.argument.formal.lambda.scope b/data/fixtures/scopes/ruby/name/name.argument.formal.lambda.scope new file mode 100644 index 0000000000..561b69ea05 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.formal.lambda.scope @@ -0,0 +1,33 @@ +->(aaa, bbb = 0) {} +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:3-0:6 + >---< +0| ->(aaa, bbb = 0) {} + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 0:8-0:11 + >---< +0| ->(aaa, bbb = 0) {} + +[#2 Removal] = 0:8-0:12 + >----< +0| ->(aaa, bbb = 0) {} + +[#2 Leading delimiter] = 0:7-0:8 + >-< +0| ->(aaa, bbb = 0) {} + +[#2 Trailing delimiter] = 0:11-0:12 + >-< +0| ->(aaa, bbb = 0) {} + +[#2 Domain] = 0:8-0:15 + >-------< +0| ->(aaa, bbb = 0) {} + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.argument.formal.method.iteration.scope b/data/fixtures/scopes/ruby/name/name.argument.formal.method.iteration.scope new file mode 100644 index 0000000000..390c047431 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.formal.method.iteration.scope @@ -0,0 +1,27 @@ +class Foo + def bar(aaa, bbb = 0) end +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| def bar(aaa, bbb = 0) end +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-2:0 + > +0| class Foo +1| def bar(aaa, bbb = 0) end +2| end + < + + +[#3 Content] = +[#3 Domain] = 1:12-1:24 + >------------< +1| def bar(aaa, bbb = 0) end diff --git a/data/fixtures/scopes/ruby/name/name.argument.formal.method.scope b/data/fixtures/scopes/ruby/name/name.argument.formal.method.scope new file mode 100644 index 0000000000..0f69dd8a3e --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.formal.method.scope @@ -0,0 +1,73 @@ +class Foo + def bar(aaa, bbb = 0) end +end +--- + +[#1 Content] = 0:6-0:9 + >---< +0| class Foo + +[#1 Removal] = 0:5-0:9 + >----< +0| class Foo + +[#1 Leading delimiter] = 0:5-0:6 + >-< +0| class Foo + +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| def bar(aaa, bbb = 0) end +2| end + ---< + +[#1 Insertion delimiter] = " " + + +[#2 Content] = +[#2 Removal] = 1:8-1:11 + >---< +1| def bar(aaa, bbb = 0) end + +[#2 Leading delimiter] = 1:7-1:8 + >-< +1| def bar(aaa, bbb = 0) end + +[#2 Domain] = 1:4-1:29 + >-------------------------< +1| def bar(aaa, bbb = 0) end + +[#2 Insertion delimiter] = " " + + +[#3 Content] = +[#3 Removal] = +[#3 Domain] = 1:12-1:15 + >---< +1| def bar(aaa, bbb = 0) end + +[#3 Insertion delimiter] = " " + + +[#4 Content] = 1:17-1:20 + >---< +1| def bar(aaa, bbb = 0) end + +[#4 Removal] = 1:17-1:21 + >----< +1| def bar(aaa, bbb = 0) end + +[#4 Leading delimiter] = 1:16-1:17 + >-< +1| def bar(aaa, bbb = 0) end + +[#4 Trailing delimiter] = 1:20-1:21 + >-< +1| def bar(aaa, bbb = 0) end + +[#4 Domain] = 1:17-1:24 + >-------< +1| def bar(aaa, bbb = 0) end + +[#4 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.argument.formal.scope b/data/fixtures/scopes/ruby/name/name.argument.formal.scope new file mode 100644 index 0000000000..0717782c22 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.argument.formal.scope @@ -0,0 +1,49 @@ +def foo(aaa, bbb = 0) end +--- + +[#1 Content] = +[#1 Removal] = 0:4-0:7 + >---< +0| def foo(aaa, bbb = 0) end + +[#1 Leading delimiter] = 0:3-0:4 + >-< +0| def foo(aaa, bbb = 0) end + +[#1 Domain] = 0:0-0:25 + >-------------------------< +0| def foo(aaa, bbb = 0) end + +[#1 Insertion delimiter] = " " + + +[#2 Content] = +[#2 Removal] = +[#2 Domain] = 0:8-0:11 + >---< +0| def foo(aaa, bbb = 0) end + +[#2 Insertion delimiter] = " " + + +[#3 Content] = 0:13-0:16 + >---< +0| def foo(aaa, bbb = 0) end + +[#3 Removal] = 0:13-0:17 + >----< +0| def foo(aaa, bbb = 0) end + +[#3 Leading delimiter] = 0:12-0:13 + >-< +0| def foo(aaa, bbb = 0) end + +[#3 Trailing delimiter] = 0:16-0:17 + >-< +0| def foo(aaa, bbb = 0) end + +[#3 Domain] = 0:13-0:20 + >-------< +0| def foo(aaa, bbb = 0) end + +[#3 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.argument.formal.iteration.scope b/data/fixtures/scopes/ruby/value/value.argument.formal.iteration.scope new file mode 100644 index 0000000000..79a492fc2f --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.argument.formal.iteration.scope @@ -0,0 +1,13 @@ +def foo(aaa = 0, bbb = 1) end +--- + +[#1 Content] = +[#1 Domain] = 0:0-0:29 + >-----------------------------< +0| def foo(aaa = 0, bbb = 1) end + + +[#2 Content] = +[#2 Domain] = 0:8-0:24 + >----------------< +0| def foo(aaa = 0, bbb = 1) end diff --git a/data/fixtures/scopes/ruby/value/value.argument.formal.method.iteration.scope b/data/fixtures/scopes/ruby/value/value.argument.formal.method.iteration.scope new file mode 100644 index 0000000000..7919efc4c1 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.argument.formal.method.iteration.scope @@ -0,0 +1,27 @@ +class Foo + def bar(aaa = 0, bbb = 1) end +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| def bar(aaa = 0, bbb = 1) end +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-2:0 + > +0| class Foo +1| def bar(aaa = 0, bbb = 1) end +2| end + < + + +[#3 Content] = +[#3 Domain] = 1:12-1:28 + >----------------< +1| def bar(aaa = 0, bbb = 1) end diff --git a/data/fixtures/scopes/ruby/value/value.argument.formal.method.scope b/data/fixtures/scopes/ruby/value/value.argument.formal.method.scope new file mode 100644 index 0000000000..1d25a5c698 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.argument.formal.method.scope @@ -0,0 +1,41 @@ +class Foo + def bar(aaa = 0, bbb = 1) end +end +--- + +[#1 Content] = 1:18-1:19 + >-< +1| def bar(aaa = 0, bbb = 1) end + +[#1 Removal] = 1:15-1:19 + >----< +1| def bar(aaa = 0, bbb = 1) end + +[#1 Leading delimiter] = 1:15-1:18 + >---< +1| def bar(aaa = 0, bbb = 1) end + +[#1 Domain] = 1:12-1:19 + >-------< +1| def bar(aaa = 0, bbb = 1) end + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 1:27-1:28 + >-< +1| def bar(aaa = 0, bbb = 1) end + +[#2 Removal] = 1:24-1:28 + >----< +1| def bar(aaa = 0, bbb = 1) end + +[#2 Leading delimiter] = 1:24-1:27 + >---< +1| def bar(aaa = 0, bbb = 1) end + +[#2 Domain] = 1:21-1:28 + >-------< +1| def bar(aaa = 0, bbb = 1) end + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.argument.formal.scope b/data/fixtures/scopes/ruby/value/value.argument.formal.scope new file mode 100644 index 0000000000..3fb1d118ff --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.argument.formal.scope @@ -0,0 +1,39 @@ +def foo(aaa = 0, bbb = 1) end +--- + +[#1 Content] = 0:14-0:15 + >-< +0| def foo(aaa = 0, bbb = 1) end + +[#1 Removal] = 0:11-0:15 + >----< +0| def foo(aaa = 0, bbb = 1) end + +[#1 Leading delimiter] = 0:11-0:14 + >---< +0| def foo(aaa = 0, bbb = 1) end + +[#1 Domain] = 0:8-0:15 + >-------< +0| def foo(aaa = 0, bbb = 1) end + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 0:23-0:24 + >-< +0| def foo(aaa = 0, bbb = 1) end + +[#2 Removal] = 0:20-0:24 + >----< +0| def foo(aaa = 0, bbb = 1) end + +[#2 Leading delimiter] = 0:20-0:23 + >---< +0| def foo(aaa = 0, bbb = 1) end + +[#2 Domain] = 0:17-0:24 + >-------< +0| def foo(aaa = 0, bbb = 1) end + +[#2 Insertion delimiter] = " " diff --git a/queries/ruby.scm b/queries/ruby.scm index ed6aeb0a01..2338bbb69e 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -385,6 +385,24 @@ (#child-range! @argumentList 1 -2) ) @argumentList.domain @argumentOrParameter.iteration.domain +(method_parameters + "(" @name.iteration.start.endOf @value.iteration.start.endOf + ")" @name.iteration.end.startOf @value.iteration.end.startOf +) + +;;!! def foo(aaa, bbb = 0) +;;! ^^^ ^^^ +;;! ^ +(method_parameters + [ + (identifier) @name + (optional_parameter + name: (_) @name @value.leading.endOf + value: (_) @value + ) @_.domain + ] +) + ;;!! ->(aaa, bbb) {} ;;! ^^^^^^^^ (_ @@ -396,6 +414,24 @@ (#child-range! @argumentList 1 -2) ) @argumentList.domain @argumentOrParameter.iteration.domain +(lambda_parameters + "(" @name.iteration.start.endOf @value.iteration.start.endOf + ")" @name.iteration.end.startOf @value.iteration.end.startOf +) + +;;!! ->(aaa, bbb = 0) +;;! ^^^ ^^^ +;;! ^ +(lambda_parameters + [ + (identifier) @name + (optional_parameter + name: (_) @name @value.leading.endOf + value: (_) @value + ) @_.domain + ] +) + ;;!! foo(aaa, bbb) ;;! ^^^^^^^^ (_ From 603dd7066e52380c437c0fba22546ec33692f550 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 19 Feb 2026 15:58:34 +0100 Subject: [PATCH 15/26] condition --- .../scopes/ruby/condition/condition.if.scope | 54 +++++++++++++++++++ .../condition.switchCase.iteration.scope | 7 +++ .../ruby/condition/condition.switchCase.scope | 25 +++++++++ .../condition/condition.switchCase2.scope | 25 +++++++++ .../ruby/condition/condition.ternary.scope | 20 +++++++ .../ruby/condition/condition.while.scope | 24 +++++++++ .../common/src/scopeSupportFacets/ruby.ts | 8 +-- queries/ruby.scm | 44 ++++++++++++--- 8 files changed, 196 insertions(+), 11 deletions(-) create mode 100644 data/fixtures/scopes/ruby/condition/condition.if.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.switchCase.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.switchCase2.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.ternary.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.while.scope diff --git a/data/fixtures/scopes/ruby/condition/condition.if.scope b/data/fixtures/scopes/ruby/condition/condition.if.scope new file mode 100644 index 0000000000..584b90be95 --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.if.scope @@ -0,0 +1,54 @@ +if true + a +elsif false + a +else + a +end +--- + +[#1 Content] = 0:3-0:7 + >----< +0| if true + +[#1 Removal] = 0:2-0:7 + >-----< +0| if true + +[#1 Leading delimiter] = 0:2-0:3 + >-< +0| if true + +[#1 Domain] = 0:0-6:3 + >------- +0| if true +1| a +2| elsif false +3| a +4| else +5| a +6| end + ---< + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 2:6-2:11 + >-----< +2| elsif false + +[#2 Removal] = 2:5-2:11 + >------< +2| elsif false + +[#2 Leading delimiter] = 2:5-2:6 + >-< +2| elsif false + +[#2 Domain] = 2:0-3:5 + >----------- +2| elsif false +3| a + -----< + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope new file mode 100644 index 0000000000..af1890349e --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope @@ -0,0 +1,7 @@ +case foo end +--- + +[Content] = +[Domain] = 0:8-0:9 + >-< +0| case foo end diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase.scope new file mode 100644 index 0000000000..5104caa5a4 --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase.scope @@ -0,0 +1,25 @@ +case foo +in 0 + puts 0 +end +--- + +[Content] = 1:3-1:4 + >-< +1| in 0 + +[Removal] = 1:2-1:4 + >--< +1| in 0 + +[Leading delimiter] = 1:2-1:3 + >-< +1| in 0 + +[Domain] = 1:0-2:10 + >---- +1| in 0 +2| puts 0 + ----------< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase2.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase2.scope new file mode 100644 index 0000000000..59378e2430 --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase2.scope @@ -0,0 +1,25 @@ +case foo +in 0 | 1 + puts 0 +end +--- + +[Content] = 1:3-1:8 + >-----< +1| in 0 | 1 + +[Removal] = 1:2-1:8 + >------< +1| in 0 | 1 + +[Leading delimiter] = 1:2-1:3 + >-< +1| in 0 | 1 + +[Domain] = 1:0-2:10 + >-------- +1| in 0 | 1 +2| puts 0 + ----------< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/condition/condition.ternary.scope b/data/fixtures/scopes/ruby/condition/condition.ternary.scope new file mode 100644 index 0000000000..2b6cdb301a --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.ternary.scope @@ -0,0 +1,20 @@ +true ? 0 : 1 +--- + +[Content] = 0:0-0:4 + >----< +0| true ? 0 : 1 + +[Removal] = 0:0-0:5 + >-----< +0| true ? 0 : 1 + +[Trailing delimiter] = 0:4-0:5 + >-< +0| true ? 0 : 1 + +[Domain] = 0:0-0:12 + >------------< +0| true ? 0 : 1 + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/condition/condition.while.scope b/data/fixtures/scopes/ruby/condition/condition.while.scope new file mode 100644 index 0000000000..b77e624b24 --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.while.scope @@ -0,0 +1,24 @@ +while true end +--- + +[Content] = 0:6-0:10 + >----< +0| while true end + +[Removal] = 0:6-0:11 + >-----< +0| while true end + +[Leading delimiter] = 0:5-0:6 + >-< +0| while true end + +[Trailing delimiter] = 0:10-0:11 + >-< +0| while true end + +[Domain] = 0:0-0:14 + >--------------< +0| while true end + +[Insertion delimiter] = " " diff --git a/packages/common/src/scopeSupportFacets/ruby.ts b/packages/common/src/scopeSupportFacets/ruby.ts index 995f9afca6..395798e459 100644 --- a/packages/common/src/scopeSupportFacets/ruby.ts +++ b/packages/common/src/scopeSupportFacets/ruby.ts @@ -75,7 +75,6 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { "condition.if": supported, "condition.while": supported, - "condition.for": supported, "condition.switchCase": supported, "condition.switchCase.iteration": supported, "condition.ternary": supported, @@ -155,7 +154,6 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { "interior.try": supported, "interior.switch": supported, "interior.switchCase": supported, - "interior.for": supported, "interior.foreach": supported, "interior.while": supported, @@ -336,10 +334,14 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { "collectionItem.unenclosed.multiLine": notApplicable, "collectionItem.unenclosed.iteration": notApplicable, + // For loop + "statement.for": notApplicable, + "condition.for": notApplicable, + "interior.for": notApplicable, + // Misc "statement.package": notApplicable, "statement.import": notApplicable, - "statement.for": notApplicable, pairDelimiter: notApplicable, environment: notApplicable, selector: notApplicable, diff --git a/queries/ruby.scm b/queries/ruby.scm index 2338bbb69e..0af44f1c48 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -142,7 +142,30 @@ (hash) @map ;;!! if true end -(if) @ifStatement +;;! ^^^^^^^^^^^ +;;! ^^^^ +(if + condition: (_) @condition +) @ifStatement @condition.domain + +;;!! elsif true end +;;! ^^^^ +(elsif + condition: (_) @condition + consequence: (_) @condition.domain.end.endOf +) @condition.domain.start.startOf + +;;!! while true end +;;! ^^^^ +(while + condition: (_) @condition +) @condition.domain + +;;!! true ? 0 : 1 +;;! ^^^^ +(conditional + condition: (_) @condition +) @condition.domain [ (method) @@ -150,6 +173,7 @@ ] @namedFunction ;;!! class Foo end +;;! ^^^ (class name: (_) @name ) @class @_.domain @@ -212,10 +236,20 @@ ;;!! case foo end ;;! ^^^ +;;! ^ (case - value: (_) @value + value: (_) @value @condition.iteration.start.endOf @branch.iteration.start.endOf + "end" @condition.iteration.end.startOf @branch.iteration.end.startOf ) @value.domain +;;!! in 0 +;;! ^ +(case_match + (in_clause + pattern: (_) @condition + ) @condition.domain +) + ;;!! %w(foo bar) ;;! ^^^ ^^^ ( @@ -242,12 +276,6 @@ (#insertion-delimiter! @collectionItem " ") ) -;;!! if true -;;! ^^^^ -(_ - condition: (_) @condition -) @_.domain - ;;!! -> {} (lambda) @anonymousFunction From c804b932bc0fe04a4f62a2b5bfbaa86447be83ae Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 03:26:59 +0100 Subject: [PATCH 16/26] Added change pair test --- .../parseTree/ruby/changePair.yml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 data/fixtures/recorded/surroundingPair/parseTree/ruby/changePair.yml diff --git a/data/fixtures/recorded/surroundingPair/parseTree/ruby/changePair.yml b/data/fixtures/recorded/surroundingPair/parseTree/ruby/changePair.yml new file mode 100644 index 0000000000..b14057e75b --- /dev/null +++ b/data/fixtures/recorded/surroundingPair/parseTree/ruby/changePair.yml @@ -0,0 +1,25 @@ +languageId: ruby +command: + version: 7 + spokenForm: change pair + action: + name: clearAndSetSelection + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: surroundingPair, delimiter: any} + usePrePhraseSnapshot: false +initialState: + documentContents: |- + "Hello + world" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} From 2dcb78ac2a0bb155b5f3ea76b29a6afe25fae9d4 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 04:38:18 +0100 Subject: [PATCH 17/26] branch --- .../ruby/branch/branch.if.elif.else.scope | 58 +++++++++++++ .../scopes/ruby/branch/branch.if.else.scope | 39 +++++++++ .../ruby/branch/branch.if.iteration.scope | 20 +++++ .../scopes/ruby/branch/branch.if.scope | 20 +++++ .../branch/branch.switchCase.iteration.scope | 12 +++ .../branch/branch.switchCase.iteration2.scope | 12 +++ .../ruby/branch/branch.switchCase.scope | 21 +++++ .../ruby/branch/branch.switchCase2.scope | 21 +++++ .../ruby/branch/branch.switchCase3.scope | 21 +++++ .../branch/branch.ternary.iteration.scope | 7 ++ .../scopes/ruby/branch/branch.ternary.scope | 37 ++++++++ .../ruby/branch/branch.try.iteration.scope | 16 ++++ .../scopes/ruby/branch/branch.try.scope | 33 +++++++ .../condition.switchCase.iteration.scope | 13 ++- .../condition.switchCase.iteration2.scope | 12 +++ .../ruby/condition/condition.switchCase.scope | 24 +++--- .../condition/condition.switchCase2.scope | 24 +++--- .../condition/condition.switchCase3.scope | 25 ++++++ .../condition/condition.switchCase4.scope | 25 ++++++ .../ruby/statement/statement.switch.scope | 13 ++- .../ruby/statement/statement.switch2.scope | 15 ++++ .../scopes/ruby/value/value.switch.scope | 27 +++--- .../scopes/ruby/value/value.switch2.scope | 25 ++++++ queries/ruby.scm | 86 ++++++++++++++++--- 24 files changed, 550 insertions(+), 56 deletions(-) create mode 100644 data/fixtures/scopes/ruby/branch/branch.if.elif.else.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.if.else.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.if.iteration.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.if.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.switchCase.iteration.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.switchCase.iteration2.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.switchCase.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.switchCase2.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.switchCase3.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.ternary.iteration.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.ternary.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.try.iteration.scope create mode 100644 data/fixtures/scopes/ruby/branch/branch.try.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.switchCase.iteration2.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.switchCase3.scope create mode 100644 data/fixtures/scopes/ruby/condition/condition.switchCase4.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.switch2.scope create mode 100644 data/fixtures/scopes/ruby/value/value.switch2.scope diff --git a/data/fixtures/scopes/ruby/branch/branch.if.elif.else.scope b/data/fixtures/scopes/ruby/branch/branch.if.elif.else.scope new file mode 100644 index 0000000000..564d68bd0d --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.if.elif.else.scope @@ -0,0 +1,58 @@ +if true + a +elsif false + a +else + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-1:5 + >------- +0| if true +1| a + -----< + +[#1 Removal] = 0:0-2:3 + >------- +0| if true +1| a +2| elsif false + ---< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 2:0-3:5 + >----------- +2| elsif false +3| a + -----< + +[#2 Removal] = 2:0-4:0 + >----------- +2| elsif false +3| a +4| else + < + +[#2 Insertion delimiter] = "\n" + + +[#3 Content] = +[#3 Domain] = 4:0-5:5 + >---- +4| else +5| a + -----< + +[#3 Removal] = 4:0-6:0 + >---- +4| else +5| a +6| end + < + +[#3 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/branch/branch.if.else.scope b/data/fixtures/scopes/ruby/branch/branch.if.else.scope new file mode 100644 index 0000000000..5dcea81eb5 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.if.else.scope @@ -0,0 +1,39 @@ +if true + a +else + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-1:5 + >------- +0| if true +1| a + -----< + +[#1 Removal] = 0:0-2:0 + >------- +0| if true +1| a +2| else + < + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 2:0-3:5 + >---- +2| else +3| a + -----< + +[#2 Removal] = 2:0-4:0 + >---- +2| else +3| a +4| end + < + +[#2 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/branch/branch.if.iteration.scope b/data/fixtures/scopes/ruby/branch/branch.if.iteration.scope new file mode 100644 index 0000000000..b67c7b8290 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.if.iteration.scope @@ -0,0 +1,20 @@ +if true + a +elsif false + a +else + a +end +--- + +[Content] = +[Domain] = 0:0-6:3 + >------- +0| if true +1| a +2| elsif false +3| a +4| else +5| a +6| end + ---< diff --git a/data/fixtures/scopes/ruby/branch/branch.if.scope b/data/fixtures/scopes/ruby/branch/branch.if.scope new file mode 100644 index 0000000000..aabc7de0e3 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.if.scope @@ -0,0 +1,20 @@ +if true + a +end +--- + +[Content] = +[Domain] = 0:0-1:5 + >------- +0| if true +1| a + -----< + +[Removal] = 0:0-2:3 + >------- +0| if true +1| a +2| end + ---< + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/branch/branch.switchCase.iteration.scope b/data/fixtures/scopes/ruby/branch/branch.switchCase.iteration.scope new file mode 100644 index 0000000000..ceffaee63e --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.switchCase.iteration.scope @@ -0,0 +1,12 @@ +case foo +when 0 +end +--- + +[Content] = +[Domain] = 0:8-2:0 + > +0| case foo +1| when 0 +2| end + < diff --git a/data/fixtures/scopes/ruby/branch/branch.switchCase.iteration2.scope b/data/fixtures/scopes/ruby/branch/branch.switchCase.iteration2.scope new file mode 100644 index 0000000000..c9bc6a18ec --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.switchCase.iteration2.scope @@ -0,0 +1,12 @@ +case foo +in 0 +end +--- + +[Content] = +[Domain] = 0:8-2:0 + > +0| case foo +1| in 0 +2| end + < diff --git a/data/fixtures/scopes/ruby/branch/branch.switchCase.scope b/data/fixtures/scopes/ruby/branch/branch.switchCase.scope new file mode 100644 index 0000000000..5a9b2136c6 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.switchCase.scope @@ -0,0 +1,21 @@ +case foo +when 0 + puts 0 +end +--- + +[Content] = +[Domain] = 1:0-2:10 + >------ +1| when 0 +2| puts 0 + ----------< + +[Removal] = 1:0-3:0 + >------ +1| when 0 +2| puts 0 +3| end + < + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/branch/branch.switchCase2.scope b/data/fixtures/scopes/ruby/branch/branch.switchCase2.scope new file mode 100644 index 0000000000..48c6e530c4 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.switchCase2.scope @@ -0,0 +1,21 @@ +case foo +in 0 + puts 0 +end +--- + +[Content] = +[Domain] = 1:0-2:10 + >---- +1| in 0 +2| puts 0 + ----------< + +[Removal] = 1:0-3:0 + >---- +1| in 0 +2| puts 0 +3| end + < + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/branch/branch.switchCase3.scope b/data/fixtures/scopes/ruby/branch/branch.switchCase3.scope new file mode 100644 index 0000000000..1802143c42 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.switchCase3.scope @@ -0,0 +1,21 @@ +case foo +else + puts 0 +end +--- + +[Content] = +[Domain] = 1:0-2:10 + >---- +1| else +2| puts 0 + ----------< + +[Removal] = 1:0-3:0 + >---- +1| else +2| puts 0 +3| end + < + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/branch/branch.ternary.iteration.scope b/data/fixtures/scopes/ruby/branch/branch.ternary.iteration.scope new file mode 100644 index 0000000000..924f6a3ea3 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.ternary.iteration.scope @@ -0,0 +1,7 @@ +true ? 0 : 1 +--- + +[Content] = +[Domain] = 0:0-0:12 + >------------< +0| true ? 0 : 1 diff --git a/data/fixtures/scopes/ruby/branch/branch.ternary.scope b/data/fixtures/scopes/ruby/branch/branch.ternary.scope new file mode 100644 index 0000000000..d52a64d3ee --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.ternary.scope @@ -0,0 +1,37 @@ +true ? 0 : 1 +--- + +[#1 Content] = +[#1 Domain] = 0:7-0:8 + >-< +0| true ? 0 : 1 + +[#1 Removal] = 0:7-0:9 + >--< +0| true ? 0 : 1 + +[#1 Leading delimiter] = 0:6-0:7 + >-< +0| true ? 0 : 1 + +[#1 Trailing delimiter] = 0:8-0:9 + >-< +0| true ? 0 : 1 + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 0:11-0:12 + >-< +0| true ? 0 : 1 + +[#2 Removal] = 0:10-0:12 + >--< +0| true ? 0 : 1 + +[#2 Leading delimiter] = 0:10-0:11 + >-< +0| true ? 0 : 1 + +[#2 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/branch/branch.try.iteration.scope b/data/fixtures/scopes/ruby/branch/branch.try.iteration.scope new file mode 100644 index 0000000000..2bbbdd588d --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.try.iteration.scope @@ -0,0 +1,16 @@ +begin + a +rescue + a +end +--- + +[Content] = +[Domain] = 0:0-4:3 + >----- +0| begin +1| a +2| rescue +3| a +4| end + ---< diff --git a/data/fixtures/scopes/ruby/branch/branch.try.scope b/data/fixtures/scopes/ruby/branch/branch.try.scope new file mode 100644 index 0000000000..3ff5a3eea5 --- /dev/null +++ b/data/fixtures/scopes/ruby/branch/branch.try.scope @@ -0,0 +1,33 @@ +begin + a +rescue + a +end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-1:5 + >----- +0| begin +1| a + -----< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Domain] = 2:0-3:5 + >------ +2| rescue +3| a + -----< + +[#2 Removal] = 2:0-4:0 + >------ +2| rescue +3| a +4| end + < + +[#2 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope index af1890349e..ceffaee63e 100644 --- a/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration.scope @@ -1,7 +1,12 @@ -case foo end +case foo +when 0 +end --- [Content] = -[Domain] = 0:8-0:9 - >-< -0| case foo end +[Domain] = 0:8-2:0 + > +0| case foo +1| when 0 +2| end + < diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration2.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration2.scope new file mode 100644 index 0000000000..c9bc6a18ec --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase.iteration2.scope @@ -0,0 +1,12 @@ +case foo +in 0 +end +--- + +[Content] = +[Domain] = 0:8-2:0 + > +0| case foo +1| in 0 +2| end + < diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase.scope index 5104caa5a4..ff5df76d86 100644 --- a/data/fixtures/scopes/ruby/condition/condition.switchCase.scope +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase.scope @@ -1,24 +1,24 @@ case foo -in 0 +when 0 puts 0 end --- -[Content] = 1:3-1:4 - >-< -1| in 0 +[Content] = 1:5-1:6 + >-< +1| when 0 -[Removal] = 1:2-1:4 - >--< -1| in 0 +[Removal] = 1:4-1:6 + >--< +1| when 0 -[Leading delimiter] = 1:2-1:3 - >-< -1| in 0 +[Leading delimiter] = 1:4-1:5 + >-< +1| when 0 [Domain] = 1:0-2:10 - >---- -1| in 0 + >------ +1| when 0 2| puts 0 ----------< diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase2.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase2.scope index 59378e2430..2b628cf667 100644 --- a/data/fixtures/scopes/ruby/condition/condition.switchCase2.scope +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase2.scope @@ -1,24 +1,24 @@ case foo -in 0 | 1 +when 0..5 puts 0 end --- -[Content] = 1:3-1:8 - >-----< -1| in 0 | 1 +[Content] = 1:5-1:9 + >----< +1| when 0..5 -[Removal] = 1:2-1:8 - >------< -1| in 0 | 1 +[Removal] = 1:4-1:9 + >-----< +1| when 0..5 -[Leading delimiter] = 1:2-1:3 - >-< -1| in 0 | 1 +[Leading delimiter] = 1:4-1:5 + >-< +1| when 0..5 [Domain] = 1:0-2:10 - >-------- -1| in 0 | 1 + >--------- +1| when 0..5 2| puts 0 ----------< diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase3.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase3.scope new file mode 100644 index 0000000000..5104caa5a4 --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase3.scope @@ -0,0 +1,25 @@ +case foo +in 0 + puts 0 +end +--- + +[Content] = 1:3-1:4 + >-< +1| in 0 + +[Removal] = 1:2-1:4 + >--< +1| in 0 + +[Leading delimiter] = 1:2-1:3 + >-< +1| in 0 + +[Domain] = 1:0-2:10 + >---- +1| in 0 +2| puts 0 + ----------< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/condition/condition.switchCase4.scope b/data/fixtures/scopes/ruby/condition/condition.switchCase4.scope new file mode 100644 index 0000000000..59378e2430 --- /dev/null +++ b/data/fixtures/scopes/ruby/condition/condition.switchCase4.scope @@ -0,0 +1,25 @@ +case foo +in 0 | 1 + puts 0 +end +--- + +[Content] = 1:3-1:8 + >-----< +1| in 0 | 1 + +[Removal] = 1:2-1:8 + >------< +1| in 0 | 1 + +[Leading delimiter] = 1:2-1:3 + >-< +1| in 0 | 1 + +[Domain] = 1:0-2:10 + >-------- +1| in 0 | 1 +2| puts 0 + ----------< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/statement/statement.switch.scope b/data/fixtures/scopes/ruby/statement/statement.switch.scope index c38eb88735..2909eb76e4 100644 --- a/data/fixtures/scopes/ruby/statement/statement.switch.scope +++ b/data/fixtures/scopes/ruby/statement/statement.switch.scope @@ -1,10 +1,15 @@ -case foo end +case foo +when 0 +end --- [Content] = [Removal] = -[Domain] = 0:0-0:12 - >------------< -0| case foo end +[Domain] = 0:0-2:3 + >-------- +0| case foo +1| when 0 +2| end + ---< [Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.switch2.scope b/data/fixtures/scopes/ruby/statement/statement.switch2.scope new file mode 100644 index 0000000000..41190a4f24 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.switch2.scope @@ -0,0 +1,15 @@ +case foo +in 0 +end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-2:3 + >-------- +0| case foo +1| in 0 +2| end + ---< + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/value/value.switch.scope b/data/fixtures/scopes/ruby/value/value.switch.scope index bcba518c77..9d5cc8e0f8 100644 --- a/data/fixtures/scopes/ruby/value/value.switch.scope +++ b/data/fixtures/scopes/ruby/value/value.switch.scope @@ -1,24 +1,25 @@ -case foo end +case foo +when 0 +end --- [Content] = 0:5-0:8 >---< -0| case foo end +0| case foo -[Removal] = 0:5-0:9 - >----< -0| case foo end +[Removal] = 0:4-0:8 + >----< +0| case foo [Leading delimiter] = 0:4-0:5 >-< -0| case foo end +0| case foo -[Trailing delimiter] = 0:8-0:9 - >-< -0| case foo end - -[Domain] = 0:0-0:12 - >------------< -0| case foo end +[Domain] = 0:0-2:3 + >-------- +0| case foo +1| when 0 +2| end + ---< [Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.switch2.scope b/data/fixtures/scopes/ruby/value/value.switch2.scope new file mode 100644 index 0000000000..c3ff03c097 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.switch2.scope @@ -0,0 +1,25 @@ +case foo +in 0 +end +--- + +[Content] = 0:5-0:8 + >---< +0| case foo + +[Removal] = 0:4-0:8 + >----< +0| case foo + +[Leading delimiter] = 0:4-0:5 + >-< +0| case foo + +[Domain] = 0:0-2:3 + >-------- +0| case foo +1| in 0 +2| end + ---< + +[Insertion delimiter] = " " diff --git a/queries/ruby.scm b/queries/ruby.scm index 0af44f1c48..8ed175799a 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -146,15 +146,61 @@ ;;! ^^^^ (if condition: (_) @condition -) @ifStatement @condition.domain +) @ifStatement @condition.domain @branch.iteration + +;;!! if true elsif false end +(if + "if" @branch.start @branch.removal.start.startOf + consequence: (_) @branch.end + (elsif) @branch.removal.end.startOf + (#character-range! @branch.removal.end.startOf 3) +) + +;;!! if true end +;;!! if true else end +(if + "if" @branch.start @branch.removal.start.startOf + consequence: (_) @branch.end + [ + (else) @branch.removal.end.startOf + "end" @branch.removal.end.endOf + ] +) ;;!! elsif true end ;;! ^^^^ (elsif + "elsif" @branch.start condition: (_) @condition - consequence: (_) @condition.domain.end.endOf + consequence: (_) @branch.end @condition.domain.end.endOf ) @condition.domain.start.startOf +;;!! else end +(else) @branch + +;;!! begin rescue end +(begin) @branch.iteration + +;;!! begin rescue end +(begin + "begin" @branch.start @branch.removal.start + (_) @branch.end @branch.removal.end + . + (rescue) +) + +;;!! begin end +(begin + "begin" @branch.start + (_) @branch.end + . + "end" + (#not-type? @branch.end rescue) +) @branch.removal + +;;!! rescue end +(rescue) @branch + ;;!! while true end ;;! ^^^^ (while @@ -163,9 +209,15 @@ ;;!! true ? 0 : 1 ;;! ^^^^ +;;! ^ ^ (conditional condition: (_) @condition -) @condition.domain + consequence: (_) @branch +) @condition.domain @branch.iteration + +(conditional + alternative: (_) @branch +) [ (method) @@ -234,21 +286,33 @@ ) ) @_.domain -;;!! case foo end +;;!! case foo when 0 end ;;! ^^^ -;;! ^ +;;! ^^^^^^^^ (case value: (_) @value @condition.iteration.start.endOf @branch.iteration.start.endOf "end" @condition.iteration.end.startOf @branch.iteration.end.startOf ) @value.domain -;;!! in 0 -;;! ^ +;;!! case foo in 0 end +;;! ^^^ +;;! ^^^^^^ (case_match - (in_clause - pattern: (_) @condition - ) @condition.domain -) + value: (_) @value @condition.iteration.start.endOf @branch.iteration.start.endOf + "end" @condition.iteration.end.startOf @branch.iteration.end.startOf +) @value.domain + +;;!! when 0 +;;! ^ +(when + pattern: (_) @condition +) @branch @condition.domain + +;;!! in foo +;;! ^^^ +(in_clause + pattern: (_) @condition +) @branch @condition.domain ;;!! %w(foo bar) ;;! ^^^ ^^^ From e712bc84bf77e22b67d44a1b0ff364e811e43224 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 05:36:19 +0100 Subject: [PATCH 18/26] interior --- .../scopes/ruby/interior/interior.class.scope | 18 +++++ .../ruby/interior/interior.foreach.scope | 18 +++++ .../ruby/interior/interior.function.scope | 18 +++++ .../ruby/interior/interior.function2.scope | 18 +++++ .../ruby/interior/interior.function3.scope | 18 +++++ .../ruby/interior/interior.function4.scope | 18 +++++ .../ruby/interior/interior.method.scope | 40 ++++++++++++ .../scopes/ruby/interior/interior.while.scope | 18 +++++ .../scopes/ruby/name/name.function2.scope | 23 +++++++ .../scopes/ruby/name/name.function3.scope | 13 ++++ .../scopes/ruby/name/name.function4.scope | 16 +++++ .../fixtures/scopes/ruby/namedFunction2.scope | 13 ++++ .../fixtures/scopes/ruby/namedFunction3.scope | 10 +++ .../fixtures/scopes/ruby/namedFunction4.scope | 13 ++++ .../ruby/statement/statement.function2.scope | 13 ++++ .../ruby/statement/statement.function3.scope | 32 +++++++++ .../ruby/statement/statement.function4.scope | 35 ++++++++++ queries/ruby.scm | 65 ++++++++++++++----- 18 files changed, 381 insertions(+), 18 deletions(-) create mode 100644 data/fixtures/scopes/ruby/interior/interior.class.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.foreach.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.function.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.function2.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.function3.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.function4.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.method.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.while.scope create mode 100644 data/fixtures/scopes/ruby/name/name.function2.scope create mode 100644 data/fixtures/scopes/ruby/name/name.function3.scope create mode 100644 data/fixtures/scopes/ruby/name/name.function4.scope create mode 100644 data/fixtures/scopes/ruby/namedFunction2.scope create mode 100644 data/fixtures/scopes/ruby/namedFunction3.scope create mode 100644 data/fixtures/scopes/ruby/namedFunction4.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.function2.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.function3.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.function4.scope diff --git a/data/fixtures/scopes/ruby/interior/interior.class.scope b/data/fixtures/scopes/ruby/interior/interior.class.scope new file mode 100644 index 0000000000..00cfd9c781 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.class.scope @@ -0,0 +1,18 @@ +class Foo + # +end +--- + +[Content] = 1:4-1:5 + >-< +1| # + +[Removal] = +[Domain] = 0:9-2:0 + > +0| class Foo +1| # +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.foreach.scope b/data/fixtures/scopes/ruby/interior/interior.foreach.scope new file mode 100644 index 0000000000..40aa7237b7 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.foreach.scope @@ -0,0 +1,18 @@ +for v in values + # +end +--- + +[Content] = 1:4-1:5 + >-< +1| # + +[Removal] = +[Domain] = 0:15-2:0 + > +0| for v in values +1| # +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.function.scope b/data/fixtures/scopes/ruby/interior/interior.function.scope new file mode 100644 index 0000000000..f6f1fb9c9f --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.function.scope @@ -0,0 +1,18 @@ +def foo() + # +end +--- + +[Content] = 1:4-1:5 + >-< +1| # + +[Removal] = +[Domain] = 0:9-2:0 + > +0| def foo() +1| # +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.function2.scope b/data/fixtures/scopes/ruby/interior/interior.function2.scope new file mode 100644 index 0000000000..fac2344f11 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.function2.scope @@ -0,0 +1,18 @@ +def foo + # +end +--- + +[Content] = 1:4-1:5 + >-< +1| # + +[Removal] = +[Domain] = 0:7-2:0 + > +0| def foo +1| # +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.function3.scope b/data/fixtures/scopes/ruby/interior/interior.function3.scope new file mode 100644 index 0000000000..a47916ae4a --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.function3.scope @@ -0,0 +1,18 @@ +def foo.bar() + # +end +--- + +[Content] = 1:4-1:5 + >-< +1| # + +[Removal] = +[Domain] = 0:13-2:0 + > +0| def foo.bar() +1| # +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.function4.scope b/data/fixtures/scopes/ruby/interior/interior.function4.scope new file mode 100644 index 0000000000..970f46b917 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.function4.scope @@ -0,0 +1,18 @@ +def foo.bar + # +end +--- + +[Content] = 1:4-1:5 + >-< +1| # + +[Removal] = +[Domain] = 0:11-2:0 + > +0| def foo.bar +1| # +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.method.scope b/data/fixtures/scopes/ruby/interior/interior.method.scope new file mode 100644 index 0000000000..485b3570f8 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.method.scope @@ -0,0 +1,40 @@ +class Foo + def bar() + # + end +end +--- + +[#1 Content] = 1:4-3:7 + >--------- +1| def bar() +2| # +3| end + -------< + +[#1 Removal] = +[#1 Domain] = 0:9-4:0 + > +0| class Foo +1| def bar() +2| # +3| end +4| end + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 2:8-2:9 + >-< +2| # + +[#2 Removal] = +[#2 Domain] = 1:13-3:4 + > +1| def bar() +2| # +3| end + ----< + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.while.scope b/data/fixtures/scopes/ruby/interior/interior.while.scope new file mode 100644 index 0000000000..c8841571a1 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.while.scope @@ -0,0 +1,18 @@ +while true + # +end +--- + +[Content] = 1:4-1:5 + >-< +1| # + +[Removal] = +[Domain] = 0:10-2:0 + > +0| while true +1| # +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.function2.scope b/data/fixtures/scopes/ruby/name/name.function2.scope new file mode 100644 index 0000000000..2a7b873c4b --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.function2.scope @@ -0,0 +1,23 @@ +def foo +end +--- + +[Content] = 0:4-0:7 + >---< +0| def foo + +[Removal] = 0:3-0:7 + >----< +0| def foo + +[Leading delimiter] = 0:3-0:4 + >-< +0| def foo + +[Domain] = 0:0-1:3 + >------- +0| def foo +1| end + ---< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.function3.scope b/data/fixtures/scopes/ruby/name/name.function3.scope new file mode 100644 index 0000000000..13984be493 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.function3.scope @@ -0,0 +1,13 @@ +def foo.bar() end +--- + +[Content] = +[Removal] = 0:8-0:11 + >---< +0| def foo.bar() end + +[Domain] = 0:0-0:17 + >-----------------< +0| def foo.bar() end + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/name/name.function4.scope b/data/fixtures/scopes/ruby/name/name.function4.scope new file mode 100644 index 0000000000..bada2e9b72 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.function4.scope @@ -0,0 +1,16 @@ +def foo.bar +end +--- + +[Content] = +[Removal] = 0:8-0:11 + >---< +0| def foo.bar + +[Domain] = 0:0-1:3 + >----------- +0| def foo.bar +1| end + ---< + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/namedFunction2.scope b/data/fixtures/scopes/ruby/namedFunction2.scope new file mode 100644 index 0000000000..7232ae0e4c --- /dev/null +++ b/data/fixtures/scopes/ruby/namedFunction2.scope @@ -0,0 +1,13 @@ +def foo +end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-1:3 + >------- +0| def foo +1| end + ---< + +[Insertion delimiter] = "\n\n" diff --git a/data/fixtures/scopes/ruby/namedFunction3.scope b/data/fixtures/scopes/ruby/namedFunction3.scope new file mode 100644 index 0000000000..151e333f05 --- /dev/null +++ b/data/fixtures/scopes/ruby/namedFunction3.scope @@ -0,0 +1,10 @@ +def foo.bar() end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-0:17 + >-----------------< +0| def foo.bar() end + +[Insertion delimiter] = "\n\n" diff --git a/data/fixtures/scopes/ruby/namedFunction4.scope b/data/fixtures/scopes/ruby/namedFunction4.scope new file mode 100644 index 0000000000..8debb5359e --- /dev/null +++ b/data/fixtures/scopes/ruby/namedFunction4.scope @@ -0,0 +1,13 @@ +def foo.bar +end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-1:3 + >----------- +0| def foo.bar +1| end + ---< + +[Insertion delimiter] = "\n\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.function2.scope b/data/fixtures/scopes/ruby/statement/statement.function2.scope new file mode 100644 index 0000000000..7e44df458e --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.function2.scope @@ -0,0 +1,13 @@ +def foo +end +--- + +[Content] = +[Removal] = +[Domain] = 0:0-1:3 + >------- +0| def foo +1| end + ---< + +[Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.function3.scope b/data/fixtures/scopes/ruby/statement/statement.function3.scope new file mode 100644 index 0000000000..a32511cdda --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.function3.scope @@ -0,0 +1,32 @@ +def foo.bar() end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-0:17 + >-----------------< +0| def foo.bar() end + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Removal] = +[#2 Domain] = 0:4-0:7 + >---< +0| def foo.bar() end + +[#2 Leading delimiter] = 0:3-0:4 + >-< +0| def foo.bar() end + +[#2 Insertion delimiter] = "\n" + + +[#3 Content] = +[#3 Removal] = +[#3 Domain] = 0:8-0:11 + >---< +0| def foo.bar() end + +[#3 Insertion delimiter] = "\n" diff --git a/data/fixtures/scopes/ruby/statement/statement.function4.scope b/data/fixtures/scopes/ruby/statement/statement.function4.scope new file mode 100644 index 0000000000..e16e974e81 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.function4.scope @@ -0,0 +1,35 @@ +def foo.bar +end +--- + +[#1 Content] = +[#1 Removal] = +[#1 Domain] = 0:0-1:3 + >----------- +0| def foo.bar +1| end + ---< + +[#1 Insertion delimiter] = "\n" + + +[#2 Content] = +[#2 Removal] = +[#2 Domain] = 0:4-0:7 + >---< +0| def foo.bar + +[#2 Leading delimiter] = 0:3-0:4 + >-< +0| def foo.bar + +[#2 Insertion delimiter] = "\n" + + +[#3 Content] = +[#3 Removal] = +[#3 Domain] = 0:8-0:11 + >---< +0| def foo.bar + +[#3 Insertion delimiter] = "\n" diff --git a/queries/ruby.scm b/queries/ruby.scm index 8ed175799a..6abeb54a12 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -179,32 +179,41 @@ (else) @branch ;;!! begin rescue end +;;!! begin end (begin) @branch.iteration ;;!! begin rescue end (begin - "begin" @branch.start @branch.removal.start + "begin" @branch.start @branch.removal.start @interior.start.endOf (_) @branch.end @branch.removal.end . - (rescue) + (rescue) @interior.end.startOf ) ;;!! begin end (begin - "begin" @branch.start + "begin" @branch.start @interior.start.endOf (_) @branch.end . - "end" + "end" @interior.end.startOf (#not-type? @branch.end rescue) ) @branch.removal ;;!! rescue end -(rescue) @branch +(begin + (rescue + "rescue" @interior.start.endOf + ) @branch + "end" @interior.end.startOf +) ;;!! while true end ;;! ^^^^ (while - condition: (_) @condition + condition: (_) @condition @interior.start.endOf + (do + "end" @interior.end.startOf + ) ) @condition.domain ;;!! true ? 0 : 1 @@ -219,11 +228,6 @@ alternative: (_) @branch ) -[ - (method) - (singleton_method) -] @namedFunction - ;;!! class Foo end ;;! ^^^ (class @@ -238,8 +242,8 @@ ) @class (class - name: (_) @name.iteration.start.endOf @value.iteration.start.endOf - "end" @name.iteration.end.startOf @value.iteration.end.startOf + name: (_) @name.iteration.start.endOf @value.iteration.start.endOf @interior.start.endOf + "end" @name.iteration.end.startOf @value.iteration.end.startOf @interior.end.startOf ) @class ;;!! "Hello world" @@ -250,15 +254,37 @@ (heredoc_content) ] @textFragment -;;!! class foo def bar() end end -;;! ^^^ +;;!! def foo() end +;;! ^^^ (method name: (_) @name -) @_.domain + parameters: (_) @interior.start.endOf + "end" @interior.end.startOf +) @namedFunction @name.domain +;;!! def foo end +;;! ^^^ +(method + name: (_) @name @interior.start.endOf + !parameters + "end" @interior.end.startOf +) @namedFunction @name.domain + +;;!! def foo.bar() end +;;! ^^^ (singleton_method name: (_) @name -) @_.domain + parameters: (_) @interior.start.endOf + "end" @interior.end.startOf +) @namedFunction @name.domain + +;;!! def foo.bar end +;;! ^^^ +(singleton_method + name: (_) @name @interior.start.endOf + !parameters + "end" @interior.end.startOf +) @namedFunction @name.domain ;;!! foo = 0 ;;! ^^^ @@ -283,8 +309,11 @@ pattern: (_) @name value: (in (_) @value + ) @interior.start.endOf + (do + "end" @interior.end.startOf ) -) @_.domain +) @name.domain @value.domain ;;!! case foo when 0 end ;;! ^^^ From d4616ae81b7e8db3845d82ff100f61bc3132777b Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 06:07:09 +0100 Subject: [PATCH 19/26] more interior --- .../scopes/ruby/interior/interior.class.scope | 6 +-- .../ruby/interior/interior.foreach.scope | 6 +-- .../ruby/interior/interior.function.scope | 6 +-- .../ruby/interior/interior.function2.scope | 6 +-- .../ruby/interior/interior.function3.scope | 6 +-- .../ruby/interior/interior.function4.scope | 6 +-- .../scopes/ruby/interior/interior.if.scope | 51 +++++++++++++++++++ .../scopes/ruby/interior/interior.if2.scope | 34 +++++++++++++ .../scopes/ruby/interior/interior.if3.scope | 18 +++++++ .../ruby/interior/interior.method.scope | 10 ++-- .../scopes/ruby/interior/interior.try.scope | 35 +++++++++++++ .../scopes/ruby/interior/interior.while.scope | 6 +-- queries/ruby.scm | 35 ++++++++++++- 13 files changed, 197 insertions(+), 28 deletions(-) create mode 100644 data/fixtures/scopes/ruby/interior/interior.if.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.if2.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.if3.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.try.scope diff --git a/data/fixtures/scopes/ruby/interior/interior.class.scope b/data/fixtures/scopes/ruby/interior/interior.class.scope index 00cfd9c781..a56437de13 100644 --- a/data/fixtures/scopes/ruby/interior/interior.class.scope +++ b/data/fixtures/scopes/ruby/interior/interior.class.scope @@ -1,17 +1,17 @@ class Foo - # + a end --- [Content] = 1:4-1:5 >-< -1| # +1| a [Removal] = [Domain] = 0:9-2:0 > 0| class Foo -1| # +1| a 2| end < diff --git a/data/fixtures/scopes/ruby/interior/interior.foreach.scope b/data/fixtures/scopes/ruby/interior/interior.foreach.scope index 40aa7237b7..62215a187c 100644 --- a/data/fixtures/scopes/ruby/interior/interior.foreach.scope +++ b/data/fixtures/scopes/ruby/interior/interior.foreach.scope @@ -1,17 +1,17 @@ for v in values - # + a end --- [Content] = 1:4-1:5 >-< -1| # +1| a [Removal] = [Domain] = 0:15-2:0 > 0| for v in values -1| # +1| a 2| end < diff --git a/data/fixtures/scopes/ruby/interior/interior.function.scope b/data/fixtures/scopes/ruby/interior/interior.function.scope index f6f1fb9c9f..d1a59040d8 100644 --- a/data/fixtures/scopes/ruby/interior/interior.function.scope +++ b/data/fixtures/scopes/ruby/interior/interior.function.scope @@ -1,17 +1,17 @@ def foo() - # + a end --- [Content] = 1:4-1:5 >-< -1| # +1| a [Removal] = [Domain] = 0:9-2:0 > 0| def foo() -1| # +1| a 2| end < diff --git a/data/fixtures/scopes/ruby/interior/interior.function2.scope b/data/fixtures/scopes/ruby/interior/interior.function2.scope index fac2344f11..f5ed20d75f 100644 --- a/data/fixtures/scopes/ruby/interior/interior.function2.scope +++ b/data/fixtures/scopes/ruby/interior/interior.function2.scope @@ -1,17 +1,17 @@ def foo - # + a end --- [Content] = 1:4-1:5 >-< -1| # +1| a [Removal] = [Domain] = 0:7-2:0 > 0| def foo -1| # +1| a 2| end < diff --git a/data/fixtures/scopes/ruby/interior/interior.function3.scope b/data/fixtures/scopes/ruby/interior/interior.function3.scope index a47916ae4a..befbe07393 100644 --- a/data/fixtures/scopes/ruby/interior/interior.function3.scope +++ b/data/fixtures/scopes/ruby/interior/interior.function3.scope @@ -1,17 +1,17 @@ def foo.bar() - # + a end --- [Content] = 1:4-1:5 >-< -1| # +1| a [Removal] = [Domain] = 0:13-2:0 > 0| def foo.bar() -1| # +1| a 2| end < diff --git a/data/fixtures/scopes/ruby/interior/interior.function4.scope b/data/fixtures/scopes/ruby/interior/interior.function4.scope index 970f46b917..0745baba4b 100644 --- a/data/fixtures/scopes/ruby/interior/interior.function4.scope +++ b/data/fixtures/scopes/ruby/interior/interior.function4.scope @@ -1,17 +1,17 @@ def foo.bar - # + a end --- [Content] = 1:4-1:5 >-< -1| # +1| a [Removal] = [Domain] = 0:11-2:0 > 0| def foo.bar -1| # +1| a 2| end < diff --git a/data/fixtures/scopes/ruby/interior/interior.if.scope b/data/fixtures/scopes/ruby/interior/interior.if.scope new file mode 100644 index 0000000000..f43e1c77ff --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.if.scope @@ -0,0 +1,51 @@ +if true + a +elsif false + a +else + a +end +--- + +[#1 Content] = 1:4-1:5 + >-< +1| a + +[#1 Removal] = +[#1 Domain] = 0:7-2:0 + > +0| if true +1| a +2| elsif false + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 3:4-3:5 + >-< +3| a + +[#2 Removal] = +[#2 Domain] = 2:11-4:0 + > +2| elsif false +3| a +4| else + < + +[#2 Insertion delimiter] = " " + + +[#3 Content] = 5:4-5:5 + >-< +5| a + +[#3 Removal] = +[#3 Domain] = 4:4-5:5 + > +4| else +5| a + -----< + +[#3 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.if2.scope b/data/fixtures/scopes/ruby/interior/interior.if2.scope new file mode 100644 index 0000000000..e51e3098f3 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.if2.scope @@ -0,0 +1,34 @@ +if true + a +else + a +end +--- + +[#1 Content] = 1:4-1:5 + >-< +1| a + +[#1 Removal] = +[#1 Domain] = 0:7-2:0 + > +0| if true +1| a +2| else + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 3:4-3:5 + >-< +3| a + +[#2 Removal] = +[#2 Domain] = 2:4-3:5 + > +2| else +3| a + -----< + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.if3.scope b/data/fixtures/scopes/ruby/interior/interior.if3.scope new file mode 100644 index 0000000000..6025a615e8 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.if3.scope @@ -0,0 +1,18 @@ +if true + a +end +--- + +[Content] = 1:4-1:5 + >-< +1| a + +[Removal] = +[Domain] = 0:7-2:0 + > +0| if true +1| a +2| end + < + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.method.scope b/data/fixtures/scopes/ruby/interior/interior.method.scope index 485b3570f8..5bfb8c71ce 100644 --- a/data/fixtures/scopes/ruby/interior/interior.method.scope +++ b/data/fixtures/scopes/ruby/interior/interior.method.scope @@ -1,6 +1,6 @@ class Foo def bar() - # + a end end --- @@ -8,7 +8,7 @@ end [#1 Content] = 1:4-3:7 >--------- 1| def bar() -2| # +2| a 3| end -------< @@ -17,7 +17,7 @@ end > 0| class Foo 1| def bar() -2| # +2| a 3| end 4| end < @@ -27,13 +27,13 @@ end [#2 Content] = 2:8-2:9 >-< -2| # +2| a [#2 Removal] = [#2 Domain] = 1:13-3:4 > 1| def bar() -2| # +2| a 3| end ----< diff --git a/data/fixtures/scopes/ruby/interior/interior.try.scope b/data/fixtures/scopes/ruby/interior/interior.try.scope new file mode 100644 index 0000000000..daabb82494 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.try.scope @@ -0,0 +1,35 @@ +begin + a +rescue + a +end +--- + +[#1 Content] = 1:4-1:5 + >-< +1| a + +[#1 Removal] = +[#1 Domain] = 0:5-2:0 + > +0| begin +1| a +2| rescue + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 3:4-3:5 + >-< +3| a + +[#2 Removal] = +[#2 Domain] = 2:6-4:0 + > +2| rescue +3| a +4| end + < + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.while.scope b/data/fixtures/scopes/ruby/interior/interior.while.scope index c8841571a1..938cbecce1 100644 --- a/data/fixtures/scopes/ruby/interior/interior.while.scope +++ b/data/fixtures/scopes/ruby/interior/interior.while.scope @@ -1,17 +1,17 @@ while true - # + a end --- [Content] = 1:4-1:5 >-< -1| # +1| a [Removal] = [Domain] = 0:10-2:0 > 0| while true -1| # +1| a 2| end < diff --git a/queries/ruby.scm b/queries/ruby.scm index 6abeb54a12..0315e100fa 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -112,6 +112,13 @@ (#document-range! @name.iteration @value.iteration) ) +;;!! { } +;;! ^ +(block + "{" @interior.start.endOf + "}" @interior.end.startOf +) + (comment) @comment @textFragment ;;!! /foo/ @@ -142,12 +149,20 @@ (hash) @map ;;!! if true end -;;! ^^^^^^^^^^^ ;;! ^^^^ (if condition: (_) @condition ) @ifStatement @condition.domain @branch.iteration +;;!! if true end +;;! ^ +(if + condition: (_) @interior.start.endOf + consequence: (_) + . + _ @interior.end.startOf +) + ;;!! if true elsif false end (if "if" @branch.start @branch.removal.start.startOf @@ -175,8 +190,24 @@ consequence: (_) @branch.end @condition.domain.end.endOf ) @condition.domain.start.startOf +;;!! elsif true else end +;;! ^ +(elsif + condition: (_) @interior.start.endOf + alternative: (_) @interior.end.startOf +) + +;;!! elsif true end +;;! ^ +(elsif + condition: (_) @interior.start.endOf + !alternative +) @interior.end.endOf + ;;!! else end -(else) @branch +(else + "else" @interior.start.endOf +) @branch @interior.end.endOf ;;!! begin rescue end ;;!! begin end From cfb3f814c88e683fec7a77f9b2580d2c819f722a Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 06:14:40 +0100 Subject: [PATCH 20/26] switch --- .../ruby/interior/interior.lambda.scope | 10 ++++ .../ruby/interior/interior.switch.scope | 36 ++++++++++++ .../ruby/interior/interior.switch2.scope | 36 ++++++++++++ .../ruby/interior/interior.switchCase.scope | 56 +++++++++++++++++++ .../ruby/interior/interior.switchCase2.scope | 56 +++++++++++++++++++ queries/ruby.scm | 44 ++++++++++----- 6 files changed, 224 insertions(+), 14 deletions(-) create mode 100644 data/fixtures/scopes/ruby/interior/interior.lambda.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.switch.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.switch2.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.switchCase.scope create mode 100644 data/fixtures/scopes/ruby/interior/interior.switchCase2.scope diff --git a/data/fixtures/scopes/ruby/interior/interior.lambda.scope b/data/fixtures/scopes/ruby/interior/interior.lambda.scope new file mode 100644 index 0000000000..f2846ca708 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.lambda.scope @@ -0,0 +1,10 @@ +->() { } +--- + +[Content] = +[Removal] = +[Domain] = 0:6-0:7 + >-< +0| ->() { } + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.switch.scope b/data/fixtures/scopes/ruby/interior/interior.switch.scope new file mode 100644 index 0000000000..be53ba631b --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.switch.scope @@ -0,0 +1,36 @@ +case foo +when 0 + a +end +--- + +[#1 Content] = 1:0-2:5 + >------ +1| when 0 +2| a + -----< + +[#1 Removal] = +[#1 Domain] = 0:8-3:0 + > +0| case foo +1| when 0 +2| a +3| end + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 2:4-2:5 + >-< +2| a + +[#2 Removal] = +[#2 Domain] = 1:6-2:5 + > +1| when 0 +2| a + -----< + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.switch2.scope b/data/fixtures/scopes/ruby/interior/interior.switch2.scope new file mode 100644 index 0000000000..c5e9959938 --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.switch2.scope @@ -0,0 +1,36 @@ +case foo +in 0 + a +end +--- + +[#1 Content] = 1:0-2:5 + >---- +1| in 0 +2| a + -----< + +[#1 Removal] = +[#1 Domain] = 0:8-3:0 + > +0| case foo +1| in 0 +2| a +3| end + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 2:4-2:5 + >-< +2| a + +[#2 Removal] = +[#2 Domain] = 1:4-2:5 + > +1| in 0 +2| a + -----< + +[#2 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.switchCase.scope b/data/fixtures/scopes/ruby/interior/interior.switchCase.scope new file mode 100644 index 0000000000..f01376b8ec --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.switchCase.scope @@ -0,0 +1,56 @@ +case foo +when 0 + a +else + a +end +--- + +[#1 Content] = 1:0-4:5 + >------ +1| when 0 +2| a +3| else +4| a + -----< + +[#1 Removal] = +[#1 Domain] = 0:8-5:0 + > +0| case foo +1| when 0 +2| a +3| else +4| a +5| end + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 2:4-2:5 + >-< +2| a + +[#2 Removal] = +[#2 Domain] = 1:6-2:5 + > +1| when 0 +2| a + -----< + +[#2 Insertion delimiter] = " " + + +[#3 Content] = 4:4-4:5 + >-< +4| a + +[#3 Removal] = +[#3 Domain] = 3:4-4:5 + > +3| else +4| a + -----< + +[#3 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/interior/interior.switchCase2.scope b/data/fixtures/scopes/ruby/interior/interior.switchCase2.scope new file mode 100644 index 0000000000..fb28184e0a --- /dev/null +++ b/data/fixtures/scopes/ruby/interior/interior.switchCase2.scope @@ -0,0 +1,56 @@ +case foo +in 0 + a +else + a +end +--- + +[#1 Content] = 1:0-4:5 + >---- +1| in 0 +2| a +3| else +4| a + -----< + +[#1 Removal] = +[#1 Domain] = 0:8-5:0 + > +0| case foo +1| in 0 +2| a +3| else +4| a +5| end + < + +[#1 Insertion delimiter] = " " + + +[#2 Content] = 2:4-2:5 + >-< +2| a + +[#2 Removal] = +[#2 Domain] = 1:4-2:5 + > +1| in 0 +2| a + -----< + +[#2 Insertion delimiter] = " " + + +[#3 Content] = 4:4-4:5 + >-< +4| a + +[#3 Removal] = +[#3 Domain] = 3:4-4:5 + > +3| else +4| a + -----< + +[#3 Insertion delimiter] = " " diff --git a/queries/ruby.scm b/queries/ruby.scm index 0315e100fa..7ffad56f40 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -119,8 +119,20 @@ "}" @interior.end.startOf ) +;;!! # Hello world (comment) @comment @textFragment +;;!! "Hello world" +;;!! ^^^^^^^^^^^^^ +;;!! ^^^^^^^^^^^ +(string + (string_content)? @textFragment +) @string + +[ + (heredoc_content) +] @textFragment + ;;!! /foo/ (regex) @regularExpression @@ -277,14 +289,6 @@ "end" @name.iteration.end.startOf @value.iteration.end.startOf @interior.end.startOf ) @class -;;!! "Hello world" -(string) @string - -[ - (string_content) - (heredoc_content) -] @textFragment - ;;!! def foo() end ;;! ^^^ (method @@ -348,30 +352,42 @@ ;;!! case foo when 0 end ;;! ^^^ -;;! ^^^^^^^^ (case - value: (_) @value @condition.iteration.start.endOf @branch.iteration.start.endOf - "end" @condition.iteration.end.startOf @branch.iteration.end.startOf + value: (_) @value ) @value.domain +;;!! case foo when 0 end +;;! ^^^^^^^^ +(case + value: (_) @interior.start.endOf @condition.iteration.start.endOf @branch.iteration.start.endOf + "end" @interior.end.startOf @condition.iteration.end.startOf @branch.iteration.end.startOf +) + ;;!! case foo in 0 end ;;! ^^^ -;;! ^^^^^^ (case_match - value: (_) @value @condition.iteration.start.endOf @branch.iteration.start.endOf - "end" @condition.iteration.end.startOf @branch.iteration.end.startOf + value: (_) @value ) @value.domain +;;!! case foo in 0 end +;;! ^^^^^^ +(case_match + value: (_) @interior.start.endOf @condition.iteration.start.endOf @branch.iteration.start.endOf + "end" @interior.end.startOf @condition.iteration.end.startOf @branch.iteration.end.startOf +) + ;;!! when 0 ;;! ^ (when pattern: (_) @condition + body: (_) @interior ) @branch @condition.domain ;;!! in foo ;;! ^^^ (in_clause pattern: (_) @condition + body: (_) @interior ) @branch @condition.domain ;;!! %w(foo bar) From 2606f488223017f9635f1477bcbf97c67dfed193 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 06:40:11 +0100 Subject: [PATCH 21/26] iteration --- .../ruby/name/name.iteration.block.scope | 36 +++++++++++++++ .../ruby/name/name.iteration.block2.scope | 21 +++++++++ .../ruby/name/name.iteration.block4.scope | 21 +++++++++ .../statement/statement.iteration.block.scope | 36 +++++++++++++++ .../statement.iteration.block2.scope | 21 +++++++++ .../statement.iteration.block4.scope | 21 +++++++++ .../ruby/value/value.iteration.block.scope | 36 +++++++++++++++ .../ruby/value/value.iteration.block2.scope | 21 +++++++++ .../ruby/value/value.iteration.block4.scope | 21 +++++++++ queries/ruby.scm | 46 +++++++++++++++++++ 10 files changed, 280 insertions(+) create mode 100644 data/fixtures/scopes/ruby/name/name.iteration.block.scope create mode 100644 data/fixtures/scopes/ruby/name/name.iteration.block2.scope create mode 100644 data/fixtures/scopes/ruby/name/name.iteration.block4.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.iteration.block.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.iteration.block2.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.iteration.block4.scope create mode 100644 data/fixtures/scopes/ruby/value/value.iteration.block.scope create mode 100644 data/fixtures/scopes/ruby/value/value.iteration.block2.scope create mode 100644 data/fixtures/scopes/ruby/value/value.iteration.block4.scope diff --git a/data/fixtures/scopes/ruby/name/name.iteration.block.scope b/data/fixtures/scopes/ruby/name/name.iteration.block.scope new file mode 100644 index 0000000000..a20def6086 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.iteration.block.scope @@ -0,0 +1,36 @@ +class Foo + def bar() + a + end +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-4:3 + >--------- +0| class Foo +1| def bar() +2| a +3| end +4| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-4:0 + > +0| class Foo +1| def bar() +2| a +3| end +4| end + < + + +[#3 Content] = +[#3 Domain] = 1:13-3:4 + > +1| def bar() +2| a +3| end + ----< diff --git a/data/fixtures/scopes/ruby/name/name.iteration.block2.scope b/data/fixtures/scopes/ruby/name/name.iteration.block2.scope new file mode 100644 index 0000000000..d4944bdf12 --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.iteration.block2.scope @@ -0,0 +1,21 @@ +def foo() + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >--------- +0| def foo() +1| a +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-2:0 + > +0| def foo() +1| a +2| end + < diff --git a/data/fixtures/scopes/ruby/name/name.iteration.block4.scope b/data/fixtures/scopes/ruby/name/name.iteration.block4.scope new file mode 100644 index 0000000000..686026650b --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.iteration.block4.scope @@ -0,0 +1,21 @@ +while true + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >---------- +0| while true +1| a +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:10-2:0 + > +0| while true +1| a +2| end + < diff --git a/data/fixtures/scopes/ruby/statement/statement.iteration.block.scope b/data/fixtures/scopes/ruby/statement/statement.iteration.block.scope new file mode 100644 index 0000000000..a20def6086 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.iteration.block.scope @@ -0,0 +1,36 @@ +class Foo + def bar() + a + end +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-4:3 + >--------- +0| class Foo +1| def bar() +2| a +3| end +4| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-4:0 + > +0| class Foo +1| def bar() +2| a +3| end +4| end + < + + +[#3 Content] = +[#3 Domain] = 1:13-3:4 + > +1| def bar() +2| a +3| end + ----< diff --git a/data/fixtures/scopes/ruby/statement/statement.iteration.block2.scope b/data/fixtures/scopes/ruby/statement/statement.iteration.block2.scope new file mode 100644 index 0000000000..d4944bdf12 --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.iteration.block2.scope @@ -0,0 +1,21 @@ +def foo() + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >--------- +0| def foo() +1| a +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-2:0 + > +0| def foo() +1| a +2| end + < diff --git a/data/fixtures/scopes/ruby/statement/statement.iteration.block4.scope b/data/fixtures/scopes/ruby/statement/statement.iteration.block4.scope new file mode 100644 index 0000000000..686026650b --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.iteration.block4.scope @@ -0,0 +1,21 @@ +while true + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >---------- +0| while true +1| a +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:10-2:0 + > +0| while true +1| a +2| end + < diff --git a/data/fixtures/scopes/ruby/value/value.iteration.block.scope b/data/fixtures/scopes/ruby/value/value.iteration.block.scope new file mode 100644 index 0000000000..a20def6086 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.iteration.block.scope @@ -0,0 +1,36 @@ +class Foo + def bar() + a + end +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-4:3 + >--------- +0| class Foo +1| def bar() +2| a +3| end +4| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-4:0 + > +0| class Foo +1| def bar() +2| a +3| end +4| end + < + + +[#3 Content] = +[#3 Domain] = 1:13-3:4 + > +1| def bar() +2| a +3| end + ----< diff --git a/data/fixtures/scopes/ruby/value/value.iteration.block2.scope b/data/fixtures/scopes/ruby/value/value.iteration.block2.scope new file mode 100644 index 0000000000..d4944bdf12 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.iteration.block2.scope @@ -0,0 +1,21 @@ +def foo() + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >--------- +0| def foo() +1| a +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:9-2:0 + > +0| def foo() +1| a +2| end + < diff --git a/data/fixtures/scopes/ruby/value/value.iteration.block4.scope b/data/fixtures/scopes/ruby/value/value.iteration.block4.scope new file mode 100644 index 0000000000..686026650b --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.iteration.block4.scope @@ -0,0 +1,21 @@ +while true + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-2:3 + >---------- +0| while true +1| a +2| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:10-2:0 + > +0| while true +1| a +2| end + < diff --git a/queries/ruby.scm b/queries/ruby.scm index 7ffad56f40..870be0a08d 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -119,6 +119,52 @@ "}" @interior.end.startOf ) +(_ + _ @statement.iteration.start.endOf @name.iteration.start.endOf @value.iteration.start.endOf + . + body: (_) + . + "end" @statement.iteration.end.startOf @name.iteration.end.startOf @value.iteration.end.startOf +) + +(_ + _ @statement.iteration.start.endOf @name.iteration.start.endOf @value.iteration.start.endOf + . + body: (_ + "end" @statement.iteration.end.startOf @name.iteration.end.startOf @value.iteration.end.startOf + ) +) + +;; (method +;; "def" +;; name: (identifier) +;; parameters: (method_parameters +;; "(" +;; ")" +;; ) +;; body: (body_statement +;; (identifier) +;; ) +;; "end" +;; ) + +;; (class +;; "class" +;; name: (constant) +;; body: (body_statement +;; ) +;; "end" +;; ) + +;; (while +;; "while" +;; condition: (true) +;; body: (do +;; (identifier) +;; "end" +;; ) +;; ) + ;;!! # Hello world (comment) @comment @textFragment From fc352b3b27674184a47d1720841c0ba4711163d3 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 07:16:35 +0100 Subject: [PATCH 22/26] iteration --- .../ruby/name/name.iteration.block3.scope | 46 +++++++ .../ruby/name/name.iteration.class.scope | 22 ++-- .../statement.iteration.block3.scope | 46 +++++++ .../statement/statement.iteration.class.scope | 22 ++-- .../ruby/value/value.iteration.block3.scope | 46 +++++++ .../ruby/value/value.iteration.class.scope | 22 ++-- queries/ruby.scm | 113 +++++++----------- 7 files changed, 223 insertions(+), 94 deletions(-) create mode 100644 data/fixtures/scopes/ruby/name/name.iteration.block3.scope create mode 100644 data/fixtures/scopes/ruby/statement/statement.iteration.block3.scope create mode 100644 data/fixtures/scopes/ruby/value/value.iteration.block3.scope diff --git a/data/fixtures/scopes/ruby/name/name.iteration.block3.scope b/data/fixtures/scopes/ruby/name/name.iteration.block3.scope new file mode 100644 index 0000000000..150ac8082d --- /dev/null +++ b/data/fixtures/scopes/ruby/name/name.iteration.block3.scope @@ -0,0 +1,46 @@ +if true + a +elsif false + a +else + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-6:3 + >------- +0| if true +1| a +2| elsif false +3| a +4| else +5| a +6| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:7-2:0 + > +0| if true +1| a +2| elsif false + < + + +[#3 Content] = +[#3 Domain] = 2:11-4:0 + > +2| elsif false +3| a +4| else + < + + +[#4 Content] = +[#4 Domain] = 4:4-5:5 + > +4| else +5| a + -----< diff --git a/data/fixtures/scopes/ruby/name/name.iteration.class.scope b/data/fixtures/scopes/ruby/name/name.iteration.class.scope index 37cb946c03..e4f15ca612 100644 --- a/data/fixtures/scopes/ruby/name/name.iteration.class.scope +++ b/data/fixtures/scopes/ruby/name/name.iteration.class.scope @@ -1,13 +1,21 @@ -class Foo end +class Foo + a +end --- [#1 Content] = -[#1 Domain] = 0:0-0:13 - >-------------< -0| class Foo end +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| a +2| end + ---< [#2 Content] = -[#2 Domain] = 0:9-0:10 - >-< -0| class Foo end +[#2 Domain] = 0:9-2:0 + > +0| class Foo +1| a +2| end + < diff --git a/data/fixtures/scopes/ruby/statement/statement.iteration.block3.scope b/data/fixtures/scopes/ruby/statement/statement.iteration.block3.scope new file mode 100644 index 0000000000..150ac8082d --- /dev/null +++ b/data/fixtures/scopes/ruby/statement/statement.iteration.block3.scope @@ -0,0 +1,46 @@ +if true + a +elsif false + a +else + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-6:3 + >------- +0| if true +1| a +2| elsif false +3| a +4| else +5| a +6| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:7-2:0 + > +0| if true +1| a +2| elsif false + < + + +[#3 Content] = +[#3 Domain] = 2:11-4:0 + > +2| elsif false +3| a +4| else + < + + +[#4 Content] = +[#4 Domain] = 4:4-5:5 + > +4| else +5| a + -----< diff --git a/data/fixtures/scopes/ruby/statement/statement.iteration.class.scope b/data/fixtures/scopes/ruby/statement/statement.iteration.class.scope index b727c7aaba..e4f15ca612 100644 --- a/data/fixtures/scopes/ruby/statement/statement.iteration.class.scope +++ b/data/fixtures/scopes/ruby/statement/statement.iteration.class.scope @@ -1,13 +1,21 @@ -class A end +class Foo + a +end --- [#1 Content] = -[#1 Domain] = 0:0-0:11 - >-----------< -0| class A end +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| a +2| end + ---< [#2 Content] = -[#2 Domain] = 0:7-0:8 - >-< -0| class A end +[#2 Domain] = 0:9-2:0 + > +0| class Foo +1| a +2| end + < diff --git a/data/fixtures/scopes/ruby/value/value.iteration.block3.scope b/data/fixtures/scopes/ruby/value/value.iteration.block3.scope new file mode 100644 index 0000000000..150ac8082d --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.iteration.block3.scope @@ -0,0 +1,46 @@ +if true + a +elsif false + a +else + a +end +--- + +[#1 Content] = +[#1 Domain] = 0:0-6:3 + >------- +0| if true +1| a +2| elsif false +3| a +4| else +5| a +6| end + ---< + + +[#2 Content] = +[#2 Domain] = 0:7-2:0 + > +0| if true +1| a +2| elsif false + < + + +[#3 Content] = +[#3 Domain] = 2:11-4:0 + > +2| elsif false +3| a +4| else + < + + +[#4 Content] = +[#4 Domain] = 4:4-5:5 + > +4| else +5| a + -----< diff --git a/data/fixtures/scopes/ruby/value/value.iteration.class.scope b/data/fixtures/scopes/ruby/value/value.iteration.class.scope index 37cb946c03..e4f15ca612 100644 --- a/data/fixtures/scopes/ruby/value/value.iteration.class.scope +++ b/data/fixtures/scopes/ruby/value/value.iteration.class.scope @@ -1,13 +1,21 @@ -class Foo end +class Foo + a +end --- [#1 Content] = -[#1 Domain] = 0:0-0:13 - >-------------< -0| class Foo end +[#1 Domain] = 0:0-2:3 + >--------- +0| class Foo +1| a +2| end + ---< [#2 Content] = -[#2 Domain] = 0:9-0:10 - >-< -0| class Foo end +[#2 Domain] = 0:9-2:0 + > +0| class Foo +1| a +2| end + < diff --git a/queries/ruby.scm b/queries/ruby.scm index 870be0a08d..17d23077bd 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -127,6 +127,14 @@ "end" @statement.iteration.end.startOf @name.iteration.end.startOf @value.iteration.end.startOf ) +(_ + _ @interior.start.endOf + . + body: (_) + . + "end" @interior.end.startOf +) + (_ _ @statement.iteration.start.endOf @name.iteration.start.endOf @value.iteration.start.endOf . @@ -135,35 +143,13 @@ ) ) -;; (method -;; "def" -;; name: (identifier) -;; parameters: (method_parameters -;; "(" -;; ")" -;; ) -;; body: (body_statement -;; (identifier) -;; ) -;; "end" -;; ) - -;; (class -;; "class" -;; name: (constant) -;; body: (body_statement -;; ) -;; "end" -;; ) - -;; (while -;; "while" -;; condition: (true) -;; body: (do -;; (identifier) -;; "end" -;; ) -;; ) +(_ + _ @interior.start.endOf + . + body: (_ + "end" @interior.end.startOf + ) +) ;;!! # Hello world (comment) @comment @textFragment @@ -175,9 +161,9 @@ (string_content)? @textFragment ) @string -[ - (heredoc_content) -] @textFragment +;;!! < Date: Fri, 20 Feb 2026 07:20:00 +0100 Subject: [PATCH 23/26] Cleanup --- packages/common/src/scopeSupportFacets/ruby.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/scopeSupportFacets/ruby.ts b/packages/common/src/scopeSupportFacets/ruby.ts index 395798e459..a0fddaa891 100644 --- a/packages/common/src/scopeSupportFacets/ruby.ts +++ b/packages/common/src/scopeSupportFacets/ruby.ts @@ -13,7 +13,6 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { class: supported, "class.iteration.document": supported, - "class.iteration.block": supported, namedFunction: supported, "namedFunction.method": supported, @@ -342,6 +341,7 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { // Misc "statement.package": notApplicable, "statement.import": notApplicable, + "class.iteration.block": notApplicable, pairDelimiter: notApplicable, environment: notApplicable, selector: notApplicable, From 1c66c410fb1e716552605a72caa3101f897dd173 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 07:43:22 +0100 Subject: [PATCH 24/26] More tests --- .../scopes/ruby/value/value.throw.scope | 20 +++++++++++++++++ .../scopes/ruby/value/value.yield.scope | 22 +++++++++++++++++++ .../common/src/scopeSupportFacets/ruby.ts | 2 ++ queries/ruby.scm | 16 +++++++++++++- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 data/fixtures/scopes/ruby/value/value.throw.scope create mode 100644 data/fixtures/scopes/ruby/value/value.yield.scope diff --git a/data/fixtures/scopes/ruby/value/value.throw.scope b/data/fixtures/scopes/ruby/value/value.throw.scope new file mode 100644 index 0000000000..1d685f052f --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.throw.scope @@ -0,0 +1,20 @@ +raise foo +--- + +[Content] = 0:6-0:9 + >---< +0| raise foo + +[Removal] = 0:5-0:9 + >----< +0| raise foo + +[Leading delimiter] = 0:5-0:6 + >-< +0| raise foo + +[Domain] = 0:0-0:9 + >---------< +0| raise foo + +[Insertion delimiter] = " " diff --git a/data/fixtures/scopes/ruby/value/value.yield.scope b/data/fixtures/scopes/ruby/value/value.yield.scope new file mode 100644 index 0000000000..0b9b489f88 --- /dev/null +++ b/data/fixtures/scopes/ruby/value/value.yield.scope @@ -0,0 +1,22 @@ +def foo() + yield 0 +end +--- + +[Content] = 1:10-1:11 + >-< +1| yield 0 + +[Removal] = 1:9-1:11 + >--< +1| yield 0 + +[Leading delimiter] = 1:9-1:10 + >-< +1| yield 0 + +[Domain] = 1:4-1:11 + >-------< +1| yield 0 + +[Insertion delimiter] = " " diff --git a/packages/common/src/scopeSupportFacets/ruby.ts b/packages/common/src/scopeSupportFacets/ruby.ts index a0fddaa891..3ed0c21c05 100644 --- a/packages/common/src/scopeSupportFacets/ruby.ts +++ b/packages/common/src/scopeSupportFacets/ruby.ts @@ -139,6 +139,8 @@ export const rubyScopeSupport: LanguageScopeSupportFacetMap = { "value.foreach": supported, "value.return": supported, "value.return.lambda": supported, + "value.yield": supported, + "value.throw": supported, "value.switch": supported, "value.variable": supported, "value.iteration.document": supported, diff --git a/queries/ruby.scm b/queries/ruby.scm index 17d23077bd..7e8069e509 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -177,7 +177,7 @@ arguments: (_ "(" @name.iteration.start.endOf @value.iteration.start.endOf ")" @name.iteration.end.startOf @value.iteration.end.startOf - ) + )? ) @functionCall @functionCallee.domain [ @@ -503,6 +503,20 @@ (argument_list) @value ) @value.domain +;;!! yield 0 +;;! ^ +(yield + (argument_list) @value +) @value.domain + +;;!! raise 0 +;;! ^ +(call + method: (_) @_dummy + (argument_list) @value + (#eq? @_dummy raise) +) @value.domain + ;;!! def foo(aaa, bbb) ;;! ^^^ ^^^ ( From 1232a9487df39f104c796f2072923e576c4f0e29 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 07:55:40 +0100 Subject: [PATCH 25/26] Update tests --- data/fixtures/recorded/relativeScopes/clearNextCall2.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/fixtures/recorded/relativeScopes/clearNextCall2.yml b/data/fixtures/recorded/relativeScopes/clearNextCall2.yml index 653bcba309..e52750aff9 100644 --- a/data/fixtures/recorded/relativeScopes/clearNextCall2.yml +++ b/data/fixtures/recorded/relativeScopes/clearNextCall2.yml @@ -20,7 +20,7 @@ initialState: active: {line: 0, character: 0} marks: {} finalState: - documentContents: aaa(, ccc()) + ddd() + documentContents: "aaa(bbb(), ccc()) + " selections: - - anchor: {line: 0, character: 4} - active: {line: 0, character: 4} + - anchor: {line: 0, character: 20} + active: {line: 0, character: 20} From e0db703a64fb71c828efff5a10758af6543273ce Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Fri, 20 Feb 2026 08:06:29 +0100 Subject: [PATCH 26/26] Update tests --- data/fixtures/recorded/relativeScopes/clearNextCall4.yml | 6 +++--- .../recorded/relativeScopes/clearSecondNextCall.yml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data/fixtures/recorded/relativeScopes/clearNextCall4.yml b/data/fixtures/recorded/relativeScopes/clearNextCall4.yml index 4a51441206..48a0244920 100644 --- a/data/fixtures/recorded/relativeScopes/clearNextCall4.yml +++ b/data/fixtures/recorded/relativeScopes/clearNextCall4.yml @@ -20,7 +20,7 @@ initialState: active: {line: 0, character: 1} marks: {} finalState: - documentContents: aaa(, ccc()) + ddd() + documentContents: "aaa(bbb(), ccc()) + " selections: - - anchor: {line: 0, character: 4} - active: {line: 0, character: 4} + - anchor: {line: 0, character: 20} + active: {line: 0, character: 20} diff --git a/data/fixtures/recorded/relativeScopes/clearSecondNextCall.yml b/data/fixtures/recorded/relativeScopes/clearSecondNextCall.yml index ff925fefa3..13a336a5e8 100644 --- a/data/fixtures/recorded/relativeScopes/clearSecondNextCall.yml +++ b/data/fixtures/recorded/relativeScopes/clearSecondNextCall.yml @@ -14,13 +14,13 @@ command: direction: forward usePrePhraseSnapshot: true initialState: - documentContents: aaa(bbb(), ccc()) + ddd() + documentContents: aaa(bbb(), ccc()) + ddd() + eee() selections: - anchor: {line: 0, character: 10} active: {line: 0, character: 10} marks: {} finalState: - documentContents: "aaa(bbb(), ccc()) + " + documentContents: "aaa(bbb(), ccc()) + ddd() + " selections: - - anchor: {line: 0, character: 20} - active: {line: 0, character: 20} + - anchor: {line: 0, character: 28} + active: {line: 0, character: 28}