Skip to content

Commit 8483fc3

Browse files
author
Junfeng Li
committed
Add support using quickfix as LanguageClient_selectionUI.
Close #402.
1 parent 566ad51 commit 8483fc3

File tree

4 files changed

+87
-51
lines changed

4 files changed

+87
-51
lines changed

doc/LanguageClient.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ Default: 1.
128128
Selection UI used when there are multiple entries.
129129

130130
Default: If fzf is loaded, use "fzf", otherwise use "location-list".
131-
Valid options: "fzf" | "location-list"
131+
Valid options: "fzf" | "quickfix" | "location-list"
132132

133133
2.7 g:LanguageClient_trace *g:LanguageClient_trace*
134134

src/languageclient.rs

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,21 @@ impl State {
353353
Ok(())
354354
}
355355

356+
fn location_to_quickfix_entry(&mut self, loc: &Location) -> Result<QuickfixEntry> {
357+
let filename = loc.uri.filepath()?;
358+
let start = loc.range.start;
359+
let text = self.get_line(&filename, start.line).unwrap_or_default();
360+
361+
Ok(QuickfixEntry {
362+
filename: filename.to_string_lossy().into_owned(),
363+
lnum: start.line + 1,
364+
col: Some(start.character + 1),
365+
text: Some(text),
366+
nr: None,
367+
typee: None,
368+
})
369+
}
370+
356371
fn display_locations(&mut self, locations: &[Location], _languageId: &str) -> Result<()> {
357372
match self.get(|state| Ok(state.selectionUI.clone()))? {
358373
SelectionUI::FZF => {
@@ -381,24 +396,22 @@ impl State {
381396
json!([source, format!("s:{}", NOTIFICATION__FZFSinkLocation)]),
382397
)?;
383398
}
399+
SelectionUI::Quickfix => {
400+
let list: Result<Vec<_>> = locations
401+
.iter()
402+
.map(|loc| self.location_to_quickfix_entry(loc))
403+
.collect();
404+
let list = list?;
405+
self.setqflist(&list)?;
406+
self.echo("Quickfix list updated.")?;
407+
}
384408
SelectionUI::LocationList => {
385-
let loclist: Result<Vec<_>> = locations
409+
let list: Result<Vec<_>> = locations
386410
.iter()
387-
.map(|loc| {
388-
let filename = loc.uri.filepath()?;
389-
let start = loc.range.start;
390-
let text = self.get_line(&filename, start.line).unwrap_or_default();
391-
Ok(json!({
392-
"filename": filename,
393-
"lnum": start.line + 1,
394-
"col": start.character + 1,
395-
"text": text,
396-
}))
397-
})
411+
.map(|loc| self.location_to_quickfix_entry(loc))
398412
.collect();
399-
let loclist = loclist?;
400-
401-
self.call::<_, u8>(None, "setloclist", json!([0, loclist]))?;
413+
let list = list?;
414+
self.setloclist(&list)?;
402415
self.echo("Location list updated.")?;
403416
}
404417
}
@@ -906,21 +919,16 @@ impl State {
906919
json!([source, format!("s:{}", NOTIFICATION__FZFSinkLocation)]),
907920
)?;
908921
}
922+
SelectionUI::Quickfix => {
923+
let list: Result<Vec<_>> = symbols.iter().map(QuickfixEntry::from_lsp).collect();
924+
let list = list?;
925+
self.setqflist(&list)?;
926+
self.echo("Document symbols populated to quickfix list.")?;
927+
}
909928
SelectionUI::LocationList => {
910-
let loclist: Vec<_> = symbols
911-
.iter()
912-
.map(|sym| {
913-
let start = sym.location.range.start;
914-
json!({
915-
"filename": filename,
916-
"lnum": start.line + 1,
917-
"col": start.character + 1,
918-
"text": sym.name,
919-
})
920-
})
921-
.collect();
922-
923-
self.call::<_, u8>(None, "setloclist", json!([0, loclist]))?;
929+
let list: Result<Vec<_>> = symbols.iter().map(QuickfixEntry::from_lsp).collect();
930+
let list = list?;
931+
self.setloclist(&list)?;
924932
self.echo("Document symbols populated to location list.")?;
925933
}
926934
}
@@ -1390,22 +1398,16 @@ impl State {
13901398
json!([source, format!("s:{}", NOTIFICATION__FZFSinkLocation)]),
13911399
)?;
13921400
}
1401+
SelectionUI::Quickfix => {
1402+
let list: Result<Vec<_>> = symbols.iter().map(QuickfixEntry::from_lsp).collect();
1403+
let list = list?;
1404+
self.setqflist(&list)?;
1405+
self.echo("Workspace symbols populated to quickfix list.")?;
1406+
}
13931407
SelectionUI::LocationList => {
1394-
let loclist: Result<Vec<_>> = symbols
1395-
.iter()
1396-
.map(|sym| {
1397-
let start = sym.location.range.start;
1398-
Ok(json!({
1399-
"filename": sym.location.uri.filepath()?,
1400-
"lnum": start.line + 1,
1401-
"col": start.character + 1,
1402-
"text": sym.name,
1403-
}))
1404-
})
1405-
.collect();
1406-
let loclist = loclist?;
1407-
1408-
self.call::<_, u8>(None, "setloclist", json!([0, loclist]))?;
1408+
let list: Result<Vec<_>> = symbols.iter().map(QuickfixEntry::from_lsp).collect();
1409+
let list = list?;
1410+
self.setloclist(&list)?;
14091411
self.echo("Workspace symbols populated to location list.")?;
14101412
}
14111413
}
@@ -1646,14 +1648,10 @@ impl State {
16461648

16471649
match self.get(|state| Ok(state.diagnosticsList.clone()))? {
16481650
DiagnosticsList::Quickfix => {
1649-
if self.call::<_, u8>(None, "setqflist", json!([qflist, "r"]))? != 0 {
1650-
bail!("Failed to set quickfix list!");
1651-
}
1651+
self.setqflist(&qflist)?;
16521652
}
16531653
DiagnosticsList::Location => {
1654-
if self.call::<_, u8>(None, "setloclist", json!([0, qflist, "r"]))? != 0 {
1655-
bail!("Failed to set location list!");
1656-
}
1654+
self.setloclist(&qflist)?;
16571655
}
16581656
DiagnosticsList::Disabled => {}
16591657
}

src/types.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ impl State {
192192
#[derive(Debug, Clone, Serialize, Deserialize)]
193193
pub enum SelectionUI {
194194
FZF,
195+
Quickfix,
195196
LocationList,
196197
}
197198

@@ -207,6 +208,7 @@ impl FromStr for SelectionUI {
207208
fn from_str(s: &str) -> Result<Self> {
208209
match s.to_ascii_uppercase().as_str() {
209210
"FZF" => Ok(SelectionUI::FZF),
211+
"QUICKFIX" => Ok(SelectionUI::Quickfix),
210212
"LOCATIONLIST" | "LOCATION-LIST" => Ok(SelectionUI::LocationList),
211213
_ => bail!("Invalid option for LanguageClient_selectionUI: {}", s),
212214
}
@@ -898,3 +900,25 @@ where
898900
serde_json::to_value(self)?.to_lsp()
899901
}
900902
}
903+
904+
pub trait FromLSP<F>
905+
where
906+
Self: Sized,
907+
{
908+
fn from_lsp(f: &F) -> Result<Self>;
909+
}
910+
911+
impl FromLSP<SymbolInformation> for QuickfixEntry {
912+
fn from_lsp(sym: &SymbolInformation) -> Result<Self> {
913+
let start = sym.location.range.start;
914+
915+
Ok(QuickfixEntry {
916+
filename: sym.location.uri.filepath()?.to_string_lossy().into_owned(),
917+
lnum: start.line + 1,
918+
col: Some(start.character + 1),
919+
text: Some(sym.name.clone()),
920+
nr: None,
921+
typee: None,
922+
})
923+
}
924+
}

src/vim.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,20 @@ impl State {
269269
self.command(cmd)
270270
}
271271

272+
pub fn setqflist(&mut self, list: &[QuickfixEntry]) -> Result<()> {
273+
if self.call::<_, u8>(None, "setqflist", json!([list, "r"]))? != 0 {
274+
bail!("Failed to set quickfix list!");
275+
}
276+
Ok(())
277+
}
278+
279+
pub fn setloclist(&mut self, list: &[QuickfixEntry]) -> Result<()> {
280+
if self.call::<_, u8>(None, "setloclist", json!([0, list, "r"]))? != 0 {
281+
bail!("Failed to set location list!");
282+
}
283+
Ok(())
284+
}
285+
272286
pub fn get<F, T>(&self, f: F) -> Result<T>
273287
where
274288
F: FnOnce(&State) -> Result<T>,

0 commit comments

Comments
 (0)