Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion crates/squawk_wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use line_index::LineIndex;
use log::info;
use serde::Serialize;
use rowan::TextRange;
use serde::{Deserialize, Serialize};
use squawk_syntax::ast::AstNode;
use wasm_bindgen::prelude::*;
use web_sys::js_sys::Error;

Expand Down Expand Up @@ -456,10 +458,71 @@ pub fn inlay_hints(content: String) -> Result<JsValue, Error> {
serde_wasm_bindgen::to_value(&converted).map_err(into_error)
}

#[derive(Deserialize)]
struct Position {
line: u32,
column: u32,
}

#[wasm_bindgen]
pub fn selection_ranges(content: String, positions: Vec<JsValue>) -> Result<JsValue, Error> {
let parse = squawk_syntax::SourceFile::parse(&content);
let line_index = LineIndex::new(&content);
let tree = parse.tree();
let root = tree.syntax();

let mut results: Vec<Vec<WasmSelectionRange>> = vec![];

for pos in positions {
let pos: Position = serde_wasm_bindgen::from_value(pos).map_err(into_error)?;
let offset = position_to_offset(&line_index, pos.line, pos.column)?;

let mut ranges = vec![];
let mut range = TextRange::new(offset, offset);

for _ in 0..20 {
let next = squawk_ide::expand_selection::extend_selection(root, range);
if next == range {
break;
}

let start = line_index.line_col(next.start());
let end = line_index.line_col(next.end());
let start_wide = line_index
.to_wide(line_index::WideEncoding::Utf16, start)
.unwrap();
let end_wide = line_index
.to_wide(line_index::WideEncoding::Utf16, end)
.unwrap();

ranges.push(WasmSelectionRange {
start_line: start_wide.line,
start_column: start_wide.col,
end_line: end_wide.line,
end_column: end_wide.col,
});

range = next;
}

results.push(ranges);
}

serde_wasm_bindgen::to_value(&results).map_err(into_error)
}

#[derive(Serialize)]
struct WasmInlayHint {
line: u32,
column: u32,
label: String,
kind: String,
}

#[derive(Serialize)]
struct WasmSelectionRange {
start_line: u32,
start_column: u32,
end_line: u32,
end_column: u32,
}
8 changes: 8 additions & 0 deletions playground/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
provideDefinition,
provideReferences,
provideDocumentSymbols,
provideSelectionRanges,
} from "./providers"

const modes = ["Lint", "Syntax Tree", "Tokens"] as const
Expand Down Expand Up @@ -410,6 +411,12 @@ function registerMonacoProviders() {
provideInlayHints,
},
)

const selectionRangeProvider =
monaco.languages.registerSelectionRangeProvider("pgsql", {
provideSelectionRanges,
})

return () => {
languageConfig.dispose()
codeActionProvider.dispose()
Expand All @@ -418,6 +425,7 @@ function registerMonacoProviders() {
referencesProvider.dispose()
documentSymbolProvider.dispose()
inlayHintsProvider.dispose()
selectionRangeProvider.dispose()
tokenProvider.dispose()
}
}
Expand Down
32 changes: 32 additions & 0 deletions playground/src/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
goto_definition,
hover,
inlay_hints,
selection_ranges,
DocumentSymbol,
} from "./squawk"

Expand Down Expand Up @@ -211,3 +212,34 @@ export async function provideReferences(
return []
}
}

export async function provideSelectionRanges(
model: monaco.editor.ITextModel,
positions: monaco.Position[],
): Promise<monaco.languages.SelectionRange[][]> {
const content = model.getValue()
if (!content) return []

try {
const wasmPositions = positions.map((pos) => ({
line: pos.lineNumber - 1,
column: pos.column - 1,
}))

const results = selection_ranges(content, wasmPositions)

return results.map((ranges) =>
ranges.map((range) => ({
range: {
startLineNumber: range.start_line + 1,
startColumn: range.start_column + 1,
endLineNumber: range.end_line + 1,
endColumn: range.end_column + 1,
},
})),
)
} catch (e) {
console.error("Error in provideSelectionRanges:", e)
return []
}
}
15 changes: 15 additions & 0 deletions playground/src/squawk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import initWasm, {
document_symbols as document_symbols_,
code_actions as code_actions_,
inlay_hints as inlay_hints_,
selection_ranges as selection_ranges_,
} from "./pkg/squawk_wasm"

export type TextEdit = {
Expand Down Expand Up @@ -82,6 +83,13 @@ export function find_references(
return find_references_(content, line, column)
}

export function selection_ranges(
content: string,
positions: Array<{ line: number; column: number }>,
): SelectionRange[][] {
return selection_ranges_(content, positions)
}

export function useErrors(text: string) {
const isReady = useWasmStatus()
return isReady ? lint(text) : []
Expand Down Expand Up @@ -164,3 +172,10 @@ interface InlayHint {
label: string
kind: string
}

export interface SelectionRange {
start_line: number
start_column: number
end_line: number
end_column: number
}
Loading