Skip to content

Commit 12e832f

Browse files
fix: bug with : and invalid searches (#42)
Closes #41 thanks for the report! Could you test it on your system @krfl ?
1 parent c6ec30b commit 12e832f

File tree

3 files changed

+44
-62
lines changed

3 files changed

+44
-62
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ ropey = "1.6.1"
1616
select = "0.6.0"
1717
serde = "1.0.197"
1818
serde_json = "1.0.114"
19-
tokio = { version = "1.36.0", features = ["io-util", "io-std", "macros", "rt-multi-thread", "process"] }
19+
tokio = { version = "1.36.0", features = ["io-util", "io-std", "macros", "rt-multi-thread", "process", "time"] }
2020
tower-lsp = "0.20.0"
2121
tracing = "0.1.40"
2222
tracing-subscriber = "0.3.18"

src/backend.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use tower_lsp::{lsp_types::Position, Client};
1313
use crate::gh::wiki::WikiArticle;
1414
use crate::gh::{self, GetDetail, GetEdit, GetLabel};
1515

16+
pub const TRIGGER_CHARACTERS: [char; 5] = ['[', '#', ':', '@', '/'];
17+
1618
#[derive(Debug)]
1719
pub struct Backend {
1820
pub(crate) client: Client,
@@ -174,9 +176,13 @@ impl Backend {
174176
self.client
175177
.log_message(MessageType::INFO, format!("search_owner: {}", needle))
176178
.await;
179+
let needle = needle.replace(':', "");
180+
if needle.is_empty() {
181+
return Ok(vec![]);
182+
}
177183
let users = octocrab::instance()
178184
.search()
179-
.users(needle)
185+
.users(&needle)
180186
// .sort("followers")
181187
// .order("desc")
182188
.send()
@@ -186,7 +192,7 @@ impl Backend {
186192
})?;
187193
let completion_items = users
188194
.into_iter()
189-
.filter(|member| member.login.starts_with(needle)) //TODO: smarter fuzzy match
195+
.filter(|member| member.login.starts_with(&needle))
190196
.map(|member| CompletionItem {
191197
label: member.get_label(),
192198
detail: Some(member.get_detail()),

src/lsp.rs

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,28 @@
11
use serde_json::Value;
2+
use tokio::time::timeout;
23
use tower_lsp::jsonrpc::Result;
34
use tower_lsp::lsp_types::*;
45
use tower_lsp::LanguageServer;
56

67
use crate::backend::Backend;
8+
use crate::backend::TRIGGER_CHARACTERS;
79

810
#[tower_lsp::async_trait]
911
impl LanguageServer for Backend {
1012
async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {
1113
Ok(InitializeResult {
1214
server_info: None,
1315
capabilities: ServerCapabilities {
14-
text_document_sync: Some(TextDocumentSyncCapability::Options(
15-
TextDocumentSyncOptions {
16-
open_close: Some(true),
17-
change: Some(TextDocumentSyncKind::INCREMENTAL),
18-
will_save: None,
19-
will_save_wait_until: None,
20-
save: Some(TextDocumentSyncSaveOptions::SaveOptions(SaveOptions {
21-
include_text: Some(true),
22-
})),
23-
},
16+
text_document_sync: Some(TextDocumentSyncCapability::Kind(
17+
TextDocumentSyncKind::FULL,
2418
)),
2519
completion_provider: Some(CompletionOptions {
2620
resolve_provider: Some(false),
27-
trigger_characters: Some(vec![
28-
"[".to_string(),
29-
"#".to_string(),
30-
":".to_string(),
31-
"@".to_string(),
32-
"/".to_string(),
33-
]),
21+
trigger_characters: Some(TRIGGER_CHARACTERS.map(String::from).to_vec()),
3422
work_done_progress_options: Default::default(),
3523
all_commit_characters: None,
3624
..Default::default()
3725
}),
38-
// execute_command_provider: Some(ExecuteCommandOptions {
39-
// commands: vec!["dummy.do_something".to_string()],
40-
// work_done_progress_options: Default::default(),
41-
// }),
4226
workspace: Some(WorkspaceServerCapabilities {
4327
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
4428
supported: Some(true),
@@ -49,7 +33,6 @@ impl LanguageServer for Backend {
4933
}),
5034
..ServerCapabilities::default()
5135
},
52-
// ..Default::default()
5336
})
5437
}
5538

@@ -106,33 +89,23 @@ impl LanguageServer for Backend {
10689
.await
10790
}
10891

109-
async fn did_change(&self, params: DidChangeTextDocumentParams) {
92+
async fn did_change(&self, mut params: DidChangeTextDocumentParams) {
11093
self.client
11194
.log_message(MessageType::INFO, "file changed!")
11295
.await;
113-
let mut text = self
114-
.document_map
115-
.get_mut(&params.text_document.uri.to_string())
116-
.expect("Did change docs must be opened");
117-
params.content_changes.iter().for_each(|change| {
118-
if let Some(range) = change.range {
119-
let start =
120-
text.line_to_char(range.start.line as usize) + range.start.character as usize;
121-
let end = text.line_to_char(range.end.line as usize) + range.end.character as usize;
122-
if start < end {
123-
text.remove(start..end);
124-
}
125-
text.insert(start, &change.text);
126-
// eprintln!("{}", *text);
127-
}
128-
});
129-
// self.on_change(TextDocumentItem {
130-
// uri: params.text_document.uri,
131-
// text: text,
132-
// version: params.text_document.version,
133-
// language_id: "md".into(), //TODO: is this the way?
134-
// })
135-
// .await
96+
let text = if !params.content_changes[0].text.is_empty() {
97+
std::mem::take(&mut params.content_changes[0].text)
98+
} else {
99+
"\n".into()
100+
};
101+
102+
self.on_change(TextDocumentItem {
103+
uri: params.text_document.uri,
104+
text,
105+
version: params.text_document.version,
106+
language_id: "md".into(),
107+
})
108+
.await;
136109
}
137110

138111
async fn did_save(&self, params: DidSaveTextDocumentParams) {
@@ -167,11 +140,7 @@ impl LanguageServer for Backend {
167140
let line = rope
168141
.get_line(position.line as usize)
169142
.ok_or(tower_lsp::jsonrpc::Error::internal_error())?;
170-
let character_pos = if position.character as usize >= line.len_chars() {
171-
line.len_chars() - 1
172-
} else {
173-
position.character as usize
174-
};
143+
let character_pos = position.character as usize;
175144
let line = line.to_string();
176145
let line = line.split_at(character_pos).0;
177146
let word = line
@@ -187,15 +156,22 @@ impl LanguageServer for Backend {
187156
} else {
188157
word.split_at(1)
189158
};
159+
let fast_ms = tokio::time::Duration::from_millis(200);
160+
let slow_ms = tokio::time::Duration::from_millis(3000);
190161
let completions = match parts.0 {
191-
"#" => self.search_issue_and_pr(position, parts.1).await,
192-
"@" => self.search_user(position, parts.1).await,
193-
"[" => self.search_wiki(position, parts.1).await,
194-
"/" => self.search_repo(position, parts.1).await,
195-
":" => self.search_owner(position, parts.1).await,
196-
_ => Ok(vec![]),
197-
}
198-
.ok();
162+
"#" => timeout(fast_ms, self.search_issue_and_pr(position, parts.1)).await,
163+
"@" => timeout(fast_ms, self.search_user(position, parts.1)).await,
164+
"[" => timeout(fast_ms, self.search_wiki(position, parts.1)).await,
165+
"/" => timeout(fast_ms, self.search_repo(position, parts.1)).await,
166+
":" => timeout(slow_ms, self.search_owner(position, parts.1)).await,
167+
_ => Ok(Ok(vec![])),
168+
};
169+
170+
let completions = if let Ok(completions) = completions {
171+
completions.ok()
172+
} else {
173+
Some(vec![])
174+
};
199175
Ok(completions.map(CompletionResponse::Array))
200176
}
201177
}

0 commit comments

Comments
 (0)