Skip to content

Commit 9196cd6

Browse files
committed
feat: add progress notifications
1 parent e7da1a9 commit 9196cd6

File tree

3 files changed

+117
-19
lines changed

3 files changed

+117
-19
lines changed

crates/emmylua_ls/src/context/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub use file_diagnostic::FileDiagnostic;
1212
use lsp_server::{Connection, ErrorCode, Message, RequestId, Response};
1313
pub use snapshot::ServerContextSnapshot;
1414
pub use status_bar::VsCodeStatusBar;
15+
pub use status_bar::Task;
1516
use std::{collections::HashMap, future::Future, sync::Arc};
1617
use tokio::sync::{Mutex, RwLock};
1718
use tokio_util::sync::CancellationToken;

crates/emmylua_ls/src/context/status_bar.rs

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,105 @@
11
use std::sync::Arc;
22

3+
use lsp_types::{
4+
NumberOrString, ProgressParams, ProgressParamsValue, WorkDoneProgress, WorkDoneProgressBegin,
5+
WorkDoneProgressCreateParams, WorkDoneProgressEnd, WorkDoneProgressReport,
6+
};
37
use serde::{Deserialize, Serialize};
48

59
use super::ClientProxy;
610

7-
811
pub struct VsCodeStatusBar {
9-
client: Arc<ClientProxy>
12+
client: Arc<ClientProxy>,
13+
}
14+
15+
#[derive(Clone, Copy)]
16+
pub enum Task {
17+
LoadWorkspace = 0,
18+
DiagnoseWorkspace = 1,
19+
}
20+
21+
fn get_task_name(task: &Task) -> &'static str {
22+
match task {
23+
Task::LoadWorkspace => "Load workspace",
24+
Task::DiagnoseWorkspace => "Diagnose workspace",
25+
}
1026
}
1127

1228
impl VsCodeStatusBar {
1329
pub fn new(client: Arc<ClientProxy>) -> Self {
14-
Self {
15-
client
16-
}
30+
Self { client }
1731
}
1832

1933
pub fn set_server_status(&self, health: &str, loading: bool, message: &str) {
20-
self.client.send_notification("emmy/setServerStatus", EmmyServerStatus {
21-
health: health.to_string(),
22-
loading,
23-
message: message.to_string(),
24-
});
34+
self.client.send_notification(
35+
"emmy/setServerStatus",
36+
EmmyServerStatus {
37+
health: health.to_string(),
38+
loading,
39+
message: message.to_string(),
40+
},
41+
);
42+
}
43+
44+
pub fn start_task(&self, task: Task) {
45+
self.client.send_notification(
46+
"window/workDoneProgress/create",
47+
WorkDoneProgressCreateParams {
48+
token: NumberOrString::Number(task as i32),
49+
},
50+
);
51+
self.client.send_notification(
52+
"$/progress",
53+
ProgressParams {
54+
token: NumberOrString::Number(task as i32),
55+
value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(
56+
WorkDoneProgressBegin {
57+
title: get_task_name(&task).to_string(),
58+
cancellable: Some(false),
59+
message: Some(get_task_name(&task).to_string()),
60+
percentage: None,
61+
},
62+
)),
63+
},
64+
)
65+
}
66+
67+
pub fn update_task(&self, task: Task, percentage: Option<u32>, message: Option<String>) {
68+
self.client.send_notification(
69+
"$/progress",
70+
ProgressParams {
71+
token: NumberOrString::Number(task as i32),
72+
value: ProgressParamsValue::WorkDone(WorkDoneProgress::Report(
73+
WorkDoneProgressReport {
74+
percentage,
75+
cancellable: Some(false),
76+
message,
77+
},
78+
)),
79+
},
80+
)
81+
}
82+
83+
pub fn finish_task(&self, task: Task, message: Option<String>) {
84+
self.client.send_notification(
85+
"$/progress",
86+
ProgressParams {
87+
token: NumberOrString::Number(task as i32),
88+
value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd {
89+
message,
90+
})),
91+
},
92+
)
2593
}
2694

2795
pub fn report_progress(&self, message: &str, percentage: f64) {
28-
self.client.send_notification("emmy/progressReport", EmmyProgress {
29-
text: message.to_string(),
30-
percent: percentage,
31-
});
96+
self.client.send_notification(
97+
"emmy/progressReport",
98+
EmmyProgress {
99+
text: message.to_string(),
100+
percent: percentage,
101+
},
102+
);
32103
}
33104
}
34105

crates/emmylua_ls/src/handlers/initialized/mod.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{path::PathBuf, str::FromStr, sync::Arc};
88

99
use crate::{
1010
cmd_args::CmdArgs,
11-
context::{load_emmy_config, ClientProxy, ServerContextSnapshot, VsCodeStatusBar},
11+
context::{load_emmy_config, ClientProxy, ServerContextSnapshot, Task, VsCodeStatusBar},
1212
logger::init_logger,
1313
};
1414
use client_config::get_client_config;
@@ -103,7 +103,13 @@ pub async fn init_analysis(
103103
info!("current config : {}", emmyrc_json);
104104

105105
status_bar.set_server_status("ok", true, "Load workspace");
106+
status_bar.start_task(Task::LoadWorkspace);
106107
status_bar.report_progress("Load workspace", 0.0);
108+
status_bar.update_task(
109+
Task::LoadWorkspace,
110+
None,
111+
Some("Loading workspace files".to_string()),
112+
);
107113

108114
let mut workspace_folders = workspace_folders;
109115
for workspace_root in &workspace_folders {
@@ -123,14 +129,28 @@ pub async fn init_analysis(
123129
}
124130

125131
status_bar.report_progress("Collect files", 0.1);
132+
status_bar.update_task(
133+
Task::LoadWorkspace,
134+
None,
135+
Some(String::from("Collecting files")),
136+
);
126137
// load files
127138
let files = collect_files(&workspace_folders, &emmyrc);
128139
let files: Vec<(PathBuf, Option<String>)> =
129140
files.into_iter().map(|file| file.into_tuple()).collect();
130141

131142
let file_count = files.len();
132143
status_bar.report_progress(format!("Index {} files", file_count).as_str(), 0.5);
144+
status_bar.update_task(
145+
Task::LoadWorkspace,
146+
None,
147+
Some(format!("Indexing {} files", file_count)),
148+
);
133149
let file_ids = mut_analysis.update_files_by_path(files);
150+
status_bar.finish_task(
151+
Task::LoadWorkspace,
152+
Some(String::from("Finished loading workspace files")),
153+
);
134154

135155
drop(mut_analysis);
136156

@@ -162,16 +182,22 @@ pub async fn init_analysis(
162182
if file_count != 0 {
163183
let text = format!("diagnose {} files", file_count);
164184
let _p = Profile::new(text.as_str());
185+
status_bar.start_task(Task::DiagnoseWorkspace);
165186
while let Some(_) = rx.recv().await {
166187
count += 1;
167188

189+
let message = format!("diagnostic {}/{}", count, file_count);
168190
if client_id.is_vscode() {
169-
status_bar.report_progress(
170-
format!("diagnostic {}/{}", count, file_count).as_str(),
171-
0.75,
172-
);
191+
status_bar.report_progress(message.as_str(), 0.75);
173192
}
193+
let percentage_done = count as u32 / file_count as u32;
194+
status_bar.update_task(
195+
Task::DiagnoseWorkspace,
196+
Some(percentage_done),
197+
Some(message),
198+
);
174199
if count == file_count {
200+
status_bar.finish_task(Task::DiagnoseWorkspace, None);
175201
break;
176202
}
177203
}

0 commit comments

Comments
 (0)