diff --git a/crates/squawk_ide/src/goto_definition.rs b/crates/squawk_ide/src/goto_definition.rs index 6f2af077..79daad0f 100644 --- a/crates/squawk_ide/src/goto_definition.rs +++ b/crates/squawk_ide/src/goto_definition.rs @@ -245,7 +245,7 @@ drop table t$0; } #[test] - fn goto_definition_on_dot_prefers_previous_token() { + fn goto_definition_prefers_previous_token() { assert_snapshot!(goto(" create table t(a int); select t.$0a from t; @@ -256,6 +256,50 @@ select t.$0a from t; 3 │ select t.a from t; ╰╴ ─ 1. source "); + + assert_snapshot!(goto(" +create type ty as (a int, b int); +with t as (select '(1,2)'::ty c) +select (c)$0.a from t; +"), @r" + ╭▸ + 3 │ with t as (select '(1,2)'::ty c) + │ ─ 2. destination + 4 │ select (c).a from t; + ╰╴ ─ 1. source + "); + assert_snapshot!(goto(" +create function f() returns int as 'select 1' language sql; +select f($0); +"), @r" + ╭▸ + 2 │ create function f() returns int as 'select 1' language sql; + │ ─ 2. destination + 3 │ select f(); + ╰╴ ─ 1. source + "); + + assert_snapshot!(goto(" +with t as (select array[1,2,3]::int[] c) +select c[$01] from t; +"), @r" + ╭▸ + 2 │ with t as (select array[1,2,3]::int[] c) + │ ─ 2. destination + 3 │ select c[1] from t; + ╰╴ ─ 1. source + "); + + assert_snapshot!(goto(" +with t as (select array[1,2,3]::int[] c, 1 b) +select c[b]$0 from t; +"), @r" + ╭▸ + 2 │ with t as (select array[1,2,3]::int[] c, 1 b) + │ ─ 2. destination + 3 │ select c[b] from t; + ╰╴ ─ 1. source + "); } #[test] diff --git a/crates/squawk_ide/src/offsets.rs b/crates/squawk_ide/src/offsets.rs index 2d6b18de..129c7ba2 100644 --- a/crates/squawk_ide/src/offsets.rs +++ b/crates/squawk_ide/src/offsets.rs @@ -10,9 +10,19 @@ pub(crate) fn token_from_offset(file: &ast::SourceFile, offset: TextSize) -> Opt // - the trailing `;` of a line // - the `,` in a target list, like `select a, b, c` // - the `.` following a table/schema/column, like `select t.a from t` + // - the `)` following a composite type, like `select (c).f from t` + // - the `[` in `select c[1] from t` + // - the `]` in `select c[a] from t` + // - the `(` in `select foo()` if matches!( token.kind(), - SyntaxKind::SEMICOLON | SyntaxKind::COMMA | SyntaxKind::DOT + SyntaxKind::SEMICOLON + | SyntaxKind::COMMA + | SyntaxKind::DOT + | SyntaxKind::R_PAREN + | SyntaxKind::L_BRACK + | SyntaxKind::R_BRACK + | SyntaxKind::L_PAREN ) { token = token.prev_token()?; }