@@ -108,16 +108,6 @@ impl<'a> Context<'a> {
108/// state (usually by creating and applying a transaction).
108/// state (usually by creating and applying a transaction).
109pub type Command = fn(cx: &mut Context);
109pub type Command = fn(cx: &mut Context);
112−fn block_on<T>(future: impl Future<Output = T>) -> T {
113− use tokio::runtime::Runtime;
114− // let rt = Runtime::new().unwrap();
115− let rt = tokio::runtime::Handle::current();
116− // let local = LocalSet::new();
117− // local.block_on(&rt, future)
121pub fn move_char_left(cx: &mut Context) {
111pub fn move_char_left(cx: &mut Context) {
122 let count = cx.count;
112 let count = cx.count;
123 let (view, doc) = cx.current();
113 let (view, doc) = cx.current();
@@ -260,13 +250,13 @@ pub fn move_next_word_end(cx: &mut Context) {
262pub fn move_file_start(cx: &mut Context) {
252pub fn move_file_start(cx: &mut Context) {
263− push_jump(cx);
253+ push_jump(cx.editor);
264 let (view, doc) = cx.current();
254 let (view, doc) = cx.current();
265 doc.set_selection(view.id, Selection::point(0));
255 doc.set_selection(view.id, Selection::point(0));
268pub fn move_file_end(cx: &mut Context) {
258pub fn move_file_end(cx: &mut Context) {
269− push_jump(cx);
259+ push_jump(cx.editor);
270 let (view, doc) = cx.current();
260 let (view, doc) = cx.current();
271 let text = doc.text();
261 let text = doc.text();
272 let last_line = text.line_to_char(text.len_lines().saturating_sub(2));
262 let last_line = text.line_to_char(text.len_lines().saturating_sub(2));
@@ -880,7 +870,7 @@ pub fn command_mode(cx: &mut Context) {
880 // TODO: non-blocking via save() command
870 // TODO: non-blocking via save() command
881 let id = editor.view().doc;
871 let id = editor.view().doc;
882 let doc = &mut editor.documents[id];
872 let doc = &mut editor.documents[id];
883− block_on(doc.save());
873+ tokio::spawn(doc.save());
@@ -1079,8 +1069,8 @@ pub fn normal_mode(cx: &mut Context) {
1081// Store a jump on the jumplist.
1071// Store a jump on the jumplist.
1082−fn push_jump(cx: &mut Context) {
1072+fn push_jump(editor: &mut Editor) {
1083− let (view, doc) = cx.current();
1073+ let (view, doc) = editor.current();
1084 let jump = { (doc.id(), doc.selection(view.id).clone()) };
1074 let jump = { (doc.id(), doc.selection(view.id).clone()) };
1085 view.jumps.push(jump);
1075 view.jumps.push(jump);
@@ -1089,7 +1079,7 @@ pub fn goto_mode(cx: &mut Context) {
1089 let count = cx.count;
1079 let count = cx.count;
1091 if count > 1 {
1081 if count > 1 {
1092− push_jump(cx);
1082+ push_jump(cx.editor);
1094 // TODO: can't go to line 1 since we can't distinguish between g and 1g, g gets converted
1084 // TODO: can't go to line 1 since we can't distinguish between g and 1g, g gets converted
1095 // to 1g
1085 // to 1g
@@ -1127,10 +1117,15 @@ pub fn exit_select_mode(cx: &mut Context) {
1127 cx.doc().mode = Mode::Normal;
1117 cx.doc().mode = Mode::Normal;
1121+ editor: &mut Editor,
1122+ compositor: &mut Compositor,
1123+ locations: Vec<lsp::Location>,
1130−fn _goto(cx: &mut Context, locations: Vec<lsp::Location>, offset_encoding: OffsetEncoding) {
1124+ offset_encoding: OffsetEncoding,
1131 use helix_view::editor::Action;
1126 use helix_view::editor::Action;
1133− push_jump(cx);
1128+ push_jump(editor);
1135 fn jump_to(
1130 fn jump_to(
1136 editor: &mut Editor,
1131 editor: &mut Editor,
@@ -1152,7 +1147,7 @@ fn _goto(cx: &mut Context, locations: Vec<lsp::Location>, offset_encoding: Offse
1153 match locations.as_slice() {
1148 match locations.as_slice() {
1154 [location] => {
1149 [location] => {
1155− jump_to(cx.editor, location, offset_encoding, Action::Replace);
1150+ jump_to(editor, location, offset_encoding, Action::Replace);
1157 [] => (), // maybe show user message that no definition was found?
1152 [] => (), // maybe show user message that no definition was found?
1158 _locations => {
1153 _locations => {
@@ -1167,7 +1162,7 @@ fn _goto(cx: &mut Context, locations: Vec<lsp::Location>, offset_encoding: Offse
1167 jump_to(editor, location, offset_encoding, action)
1162 jump_to(editor, location, offset_encoding, action)
1170− cx.push_layer(Box::new(picker));
1165+ compositor.push(Box::new(picker));
@@ -1184,8 +1179,29 @@ pub fn goto_definition(cx: &mut Context) {
1184 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1179 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1186 // TODO: handle fails
1181 // TODO: handle fails
1187− let res = block_on(language_server.goto_definition(doc.identifier(), pos)).unwrap_or_default();
1182+ let future = language_server.goto_definition(doc.identifier(), pos);
1186+ move |editor: &mut Editor,
1187+ compositor: &mut Compositor,
1188+ response: Option<lsp::GotoDefinitionResponse>| {
1189+ let items = match response {
1190+ Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
1191+ Some(lsp::GotoDefinitionResponse::Array(locations)) => locations,
1192+ Some(lsp::GotoDefinitionResponse::Link(locations)) => locations
1194+ .map(|location_link| lsp::Location {
1195+ uri: location_link.target_uri,
1196+ range: location_link.target_range,
1199+ None => Vec::new(),
1188− _goto(cx, res, offset_encoding);
1202+ _goto(editor, compositor, items, offset_encoding);
1191pub fn goto_type_definition(cx: &mut Context) {
1207pub fn goto_type_definition(cx: &mut Context) {
@@ -1200,9 +1216,29 @@ pub fn goto_type_definition(cx: &mut Context) {
1200 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1216 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1202 // TODO: handle fails
1218 // TODO: handle fails
1204− block_on(language_server.goto_type_definition(doc.identifier(), pos)).unwrap_or_default();
1219+ let future = language_server.goto_type_definition(doc.identifier(), pos);
1223+ move |editor: &mut Editor,
1224+ compositor: &mut Compositor,
1225+ response: Option<lsp::GotoDefinitionResponse>| {
1226+ let items = match response {
1227+ Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
1228+ Some(lsp::GotoDefinitionResponse::Array(locations)) => locations,
1229+ Some(lsp::GotoDefinitionResponse::Link(locations)) => locations
1231+ .map(|location_link| lsp::Location {
1232+ uri: location_link.target_uri,
1233+ range: location_link.target_range,
1236+ None => Vec::new(),
1205− _goto(cx, res, offset_encoding);
1239+ _goto(editor, compositor, items, offset_encoding);
1208pub fn goto_implementation(cx: &mut Context) {
1244pub fn goto_implementation(cx: &mut Context) {
@@ -1217,9 +1253,29 @@ pub fn goto_implementation(cx: &mut Context) {
1217 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1253 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1219 // TODO: handle fails
1255 // TODO: handle fails
1221− block_on(language_server.goto_implementation(doc.identifier(), pos)).unwrap_or_default();
1256+ let future = language_server.goto_implementation(doc.identifier(), pos);
1260+ move |editor: &mut Editor,
1261+ compositor: &mut Compositor,
1262+ response: Option<lsp::GotoDefinitionResponse>| {
1263+ let items = match response {
1264+ Some(lsp::GotoDefinitionResponse::Scalar(location)) => vec![location],
1265+ Some(lsp::GotoDefinitionResponse::Array(locations)) => locations,
1266+ Some(lsp::GotoDefinitionResponse::Link(locations)) => locations
1268+ .map(|location_link| lsp::Location {
1269+ uri: location_link.target_uri,
1270+ range: location_link.target_range,
1273+ None => Vec::new(),
1222− _goto(cx, res, offset_encoding);
1276+ _goto(editor, compositor, items, offset_encoding);
1225pub fn goto_reference(cx: &mut Context) {
1281pub fn goto_reference(cx: &mut Context) {
@@ -1234,8 +1290,21 @@ pub fn goto_reference(cx: &mut Context) {
1234 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1290 let pos = pos_to_lsp_pos(doc.text(), doc.selection(view.id).cursor(), offset_encoding);
1236 // TODO: handle fails
1292 // TODO: handle fails
1237− let res = block_on(language_server.goto_reference(doc.identifier(), pos)).unwrap_or_default();
1293+ let future = language_server.goto_reference(doc.identifier(), pos);
1297+ move |editor: &mut Editor,
1298+ compositor: &mut Compositor,
1299+ items: Option<Vec<lsp::Location>>| {
1303+ items.unwrap_or_default(),
1238− _goto(cx, res, offset_encoding);
1304+ offset_encoding,
1241pub fn signature_help(cx: &mut Context) {
1310pub fn signature_help(cx: &mut Context) {
@@ -1253,23 +1322,28 @@ pub fn signature_help(cx: &mut Context) {
1255 // TODO: handle fails
1324 // TODO: handle fails
1325+ let future = language_server.text_document_signature_help(doc.identifier(), pos);
1257− let res = block_on(language_server.text_document_signature_help(doc.identifier(), pos))
1327+ cx.callback(
1258− .unwrap_or_default();
1328+ future,
1259−
1329+ move |editor: &mut Editor,
1330+ compositor: &mut Compositor,
1331+ response: Option<lsp::SignatureHelp>| {
1260− if let Some(signature_help) = res {
1332+ if let Some(signature_help) = response {
1261− log::info!("{:?}", signature_help);
1333+ log::info!("{:?}", signature_help);
1262− // signatures
1334+ // signatures
1263− // active_signature
1335+ // active_signature
1264− // active_parameter
1336+ // active_parameter
1265− // render as:
1337+ // render as:
1267− // signature
1339+ // signature
1268− // ----------
1340+ // ----------
1271− // with active param highlighted
1343+ // with active param highlighted
1275// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
1349// NOTE: Transactions in this module get appended to history when we switch back to normal mode.
@@ -1643,20 +1717,22 @@ pub fn format_selections(cx: &mut Context) {
1644 // TODO: handle fails
1718 // TODO: handle fails
1645 // TODO: concurrent map
1719 // TODO: concurrent map
1720+ unimplemented!(); // neeed to block to get the formatting
1646− let edits = block_on(language_server.text_document_range_formatting(
1722+ // let edits = block_on(language_server.text_document_range_formatting(
1647− doc.identifier(),
1723+ // doc.identifier(),
1648− range,
1724+ // range,
1649− lsp::FormattingOptions::default(),
1725+ // lsp::FormattingOptions::default(),
1651− .unwrap_or_default();
1727+ // .unwrap_or_default();
1653− let transaction = helix_lsp::util::generate_transaction_from_edits(
1729+ // let transaction = helix_lsp::util::generate_transaction_from_edits(
1654− doc.text(),
1730+ // doc.text(),
1655− edits,
1731+ // edits,
1656− language_server.offset_encoding(),
1732+ // language_server.offset_encoding(),
1659− doc.apply(&transaction, view.id);
1735+ // doc.apply(&transaction, view.id);
1662 doc.append_changes_to_history(view.id);
1738 doc.append_changes_to_history(view.id);
@@ -1734,7 +1810,7 @@ pub fn save(cx: &mut Context) {
1735 // TODO: handle save errors somehow?
1811 // TODO: handle save errors somehow?
1736 // TODO: don't block
1812 // TODO: don't block
1737− block_on(cx.doc().save());
1813+ tokio::spawn(cx.doc().save());
1740pub fn completion(cx: &mut Context) {
1816pub fn completion(cx: &mut Context) {
@@ -1847,30 +1923,34 @@ pub fn hover(cx: &mut Context) {
1849 // TODO: handle fails
1925 // TODO: handle fails
1851− block_on(language_server.text_document_hover(doc.identifier(), pos)).unwrap_or_default();
1926+ let future = language_server.text_document_hover(doc.identifier(), pos);
1853− if let Some(hover) = res {
1854− // hover.contents / .range <- used for visualizing
1855− let contents = match hover.contents {
1856− lsp::HoverContents::Scalar(contents) => {
1857− // markedstring(string/languagestring to be highlighted)
1859− unimplemented!("{:?}", contents)
1861− lsp::HoverContents::Array(contents) => {
1862− unimplemented!("{:?}", contents)
1864− // TODO: render markdown
1865− lsp::HoverContents::Markup(contents) => contents.value,
1868− // skip if contents empty
1928+ cx.callback(
1930+ move |editor: &mut Editor, compositor: &mut Compositor, response: Option<lsp::Hover>| {
1931+ if let Some(hover) = response {
1932+ // hover.contents / .range <- used for visualizing
1933+ let contents = match hover.contents {
1934+ lsp::HoverContents::Scalar(contents) => {
1935+ // markedstring(string/languagestring to be highlighted)
1937+ unimplemented!("{:?}", contents)
1939+ lsp::HoverContents::Array(contents) => {
1940+ unimplemented!("{:?}", contents)
1942+ // TODO: render markdown
1943+ lsp::HoverContents::Markup(contents) => contents.value,
1946+ // skip if contents empty
1870− let contents = ui::Markdown::new(contents);
1948+ let contents = ui::Markdown::new(contents);
1871− let mut popup = Popup::new(contents);
1949+ let mut popup = Popup::new(contents);
1872− cx.push_layer(Box::new(popup));
1950+ compositor.push(Box::new(popup));
1876// view movements
1956// view movements
@@ -1971,7 +2051,7 @@ pub fn space_mode(cx: &mut Context) {
1971 'w' => {
2051 'w' => {
1972 // save current buffer
2052 // save current buffer
1973 let doc = cx.doc();
2053 let doc = cx.doc();
1974− block_on(doc.save());
2054+ tokio::spawn(doc.save());
1976 'c' => {
2056 'c' => {
1977 // close current split
2057 // close current split