Skip to content

Commit dfd40e7

Browse files
feat(completions): insert schema name when selecting non-public tables
1 parent a6972a6 commit dfd40e7

File tree

10 files changed

+74
-12
lines changed

10 files changed

+74
-12
lines changed

crates/pgt_completions/src/builder.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
CompletionItemKind,
2+
CompletionItemKind, CompletionText,
33
context::CompletionContext,
44
item::CompletionItem,
55
relevance::{filtering::CompletionFilter, scoring::CompletionScore},
@@ -11,6 +11,7 @@ pub(crate) struct PossibleCompletionItem<'a> {
1111
pub kind: CompletionItemKind,
1212
pub score: CompletionScore<'a>,
1313
pub filter: CompletionFilter<'a>,
14+
pub completion_text: Option<CompletionText>,
1415
}
1516

1617
pub(crate) struct CompletionBuilder<'a> {
@@ -72,6 +73,7 @@ impl<'a> CompletionBuilder<'a> {
7273

7374
// wonderous Rust syntax ftw
7475
sort_text: format!("{:0>padding$}", idx, padding = max_padding),
76+
completion_text: item.completion_text,
7577
}
7678
})
7779
.collect()

crates/pgt_completions/src/context.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,7 @@ impl<'a> CompletionContext<'a> {
209209

210210
// We have arrived at the leaf node
211211
if current_node.child_count() == 0 {
212-
if matches!(
213-
self.get_ts_node_content(current_node).unwrap(),
214-
NodeText::Replaced
215-
) {
216-
self.node_under_cursor = None;
217-
} else {
218-
self.node_under_cursor = Some(current_node);
219-
}
212+
self.node_under_cursor = Some(current_node);
220213
return;
221214
}
222215

crates/pgt_completions/src/item.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fmt::Display;
22

3+
use pgt_text_size::TextRange;
34
use serde::{Deserialize, Serialize};
45

56
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
@@ -25,6 +26,21 @@ impl Display for CompletionItemKind {
2526
}
2627
}
2728

29+
#[derive(Debug, Serialize, Deserialize)]
30+
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
31+
/// The text that the editor should fill in.
32+
/// If `None`, the `label` should be used.
33+
/// Tables, for example, might have different completion_texts:
34+
///
35+
/// label: "users", description: "Schema: auth", completion_text: "auth.users".
36+
pub struct CompletionText {
37+
pub text: String,
38+
/// A `range` is required because some editors replace the current token,
39+
/// others naively insert the text.
40+
/// Having a range where start == end makes it an insertion.
41+
pub range: TextRange,
42+
}
43+
2844
#[derive(Debug, Serialize, Deserialize)]
2945
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
3046
pub struct CompletionItem {
@@ -34,4 +50,6 @@ pub struct CompletionItem {
3450
pub kind: CompletionItemKind,
3551
/// String used for sorting by LSP clients.
3652
pub sort_text: String,
53+
54+
pub completion_text: Option<CompletionText>,
3755
}

crates/pgt_completions/src/providers/columns.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub fn complete_columns<'a>(ctx: &CompletionContext<'a>, builder: &mut Completio
1717
filter: CompletionFilter::from(relevance),
1818
description: format!("Table: {}.{}", col.schema_name, col.table_name),
1919
kind: CompletionItemKind::Column,
20+
completion_text: None,
2021
};
2122

2223
builder.add_item(item);

crates/pgt_completions/src/providers/functions.rs

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{
55
relevance::{CompletionRelevanceData, filtering::CompletionFilter, scoring::CompletionScore},
66
};
77

8+
use super::helper::get_completion_text_with_schema;
9+
810
pub fn complete_functions<'a>(ctx: &'a CompletionContext, builder: &mut CompletionBuilder<'a>) {
911
let available_functions = &ctx.schema_cache.functions;
1012

@@ -17,6 +19,7 @@ pub fn complete_functions<'a>(ctx: &'a CompletionContext, builder: &mut Completi
1719
filter: CompletionFilter::from(relevance),
1820
description: format!("Schema: {}", func.schema),
1921
kind: CompletionItemKind::Function,
22+
completion_text: get_completion_text_with_schema(ctx, &func.name, &func.schema),
2023
};
2124

2225
builder.add_item(item);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use pgt_text_size::{TextRange, TextSize};
2+
3+
use crate::{CompletionText, context::CompletionContext};
4+
5+
pub(crate) fn get_completion_text_with_schema(
6+
ctx: &CompletionContext,
7+
item_name: &str,
8+
item_schema_name: &str,
9+
) -> Option<CompletionText> {
10+
if item_schema_name == "public" {
11+
None
12+
} else if ctx.schema_name.is_some() {
13+
None
14+
} else {
15+
let node = ctx.node_under_cursor.unwrap();
16+
17+
let range = TextRange::new(
18+
TextSize::try_from(node.start_byte()).unwrap(),
19+
TextSize::try_from(node.end_byte()).unwrap(),
20+
);
21+
22+
Some(CompletionText {
23+
text: format!("{}.{}", item_schema_name, item_name),
24+
range,
25+
})
26+
}
27+
}

crates/pgt_completions/src/providers/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod columns;
22
mod functions;
3+
mod helper;
34
mod schemas;
45
mod tables;
56

crates/pgt_completions/src/providers/schemas.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub fn complete_schemas<'a>(ctx: &'a CompletionContext, builder: &mut Completion
1616
kind: crate::CompletionItemKind::Schema,
1717
score: CompletionScore::from(relevance.clone()),
1818
filter: CompletionFilter::from(relevance),
19+
completion_text: None,
1920
};
2021

2122
builder.add_item(item);

crates/pgt_completions/src/providers/tables.rs

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{
55
relevance::{CompletionRelevanceData, filtering::CompletionFilter, scoring::CompletionScore},
66
};
77

8+
use super::helper::get_completion_text_with_schema;
9+
810
pub fn complete_tables<'a>(ctx: &'a CompletionContext, builder: &mut CompletionBuilder<'a>) {
911
let available_tables = &ctx.schema_cache.tables;
1012

@@ -17,6 +19,7 @@ pub fn complete_tables<'a>(ctx: &'a CompletionContext, builder: &mut CompletionB
1719
filter: CompletionFilter::from(relevance),
1820
description: format!("Schema: {}", table.schema),
1921
kind: CompletionItemKind::Table,
22+
completion_text: get_completion_text_with_schema(ctx, &table.name, &table.schema),
2023
};
2124

2225
builder.add_item(item);

crates/pgt_lsp/src/handlers/completions.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
1-
use crate::{adapters::get_cursor_position, session::Session};
1+
use crate::{
2+
adapters::{self, get_cursor_position},
3+
diagnostics::LspError,
4+
session::Session,
5+
};
26
use anyhow::Result;
37
use pgt_workspace::{WorkspaceError, features::completions::GetCompletionsParams};
4-
use tower_lsp::lsp_types::{self, CompletionItem, CompletionItemLabelDetails};
8+
use tower_lsp::lsp_types::{self, CompletionItem, CompletionItemLabelDetails, TextEdit};
59

610
#[tracing::instrument(level = "debug", skip(session), err)]
711
pub fn get_completions(
812
session: &Session,
913
params: lsp_types::CompletionParams,
10-
) -> Result<lsp_types::CompletionResponse> {
14+
) -> Result<lsp_types::CompletionResponse, LspError> {
1115
let url = params.text_document_position.text_document.uri;
1216
let path = session.file_path(&url)?;
1317

18+
let doc = session.document(&url)?;
19+
let encoding = adapters::negotiated_encoding(session.client_capabilities().unwrap());
20+
1421
let completion_result = match session.workspace.get_completions(GetCompletionsParams {
1522
path,
1623
position: get_cursor_position(session, &url, params.text_document_position.position)?,
@@ -36,6 +43,12 @@ pub fn get_completions(
3643
}),
3744
preselect: Some(i.preselected),
3845
sort_text: Some(i.sort_text),
46+
text_edit: i.completion_text.map(|c| {
47+
lsp_types::CompletionTextEdit::Edit(TextEdit {
48+
new_text: c.text,
49+
range: adapters::to_lsp::range(&doc.line_index, c.range, encoding).unwrap(),
50+
})
51+
}),
3952
kind: Some(to_lsp_types_completion_item_kind(i.kind)),
4053
..CompletionItem::default()
4154
})

0 commit comments

Comments
 (0)