Fix tracking cursor position (#889)

This commit is contained in:
Patrick Förster 2023-05-20 21:02:47 +02:00 committed by GitHub
parent 68bf2b3d96
commit 10890d8869
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 60 deletions

View file

@ -1,14 +1,13 @@
use std::path::PathBuf;
use distro::Language;
use rowan::TextSize;
use syntax::{bibtex, latex, BuildError};
use url::Url;
use crate::{
diagnostics::{self, Diagnostic},
semantics,
util::LineIndex,
util::{LineCol, LineIndex},
Config,
};
@ -26,7 +25,7 @@ pub struct Document {
pub text: String,
pub line_index: LineIndex,
pub owner: Owner,
pub cursor: TextSize,
pub cursor: LineCol,
pub language: Language,
pub data: DocumentData,
pub diagnostics: Vec<Diagnostic>,
@ -38,7 +37,7 @@ impl Document {
text: String,
language: Language,
owner: Owner,
cursor: TextSize,
cursor: LineCol,
config: &Config,
) -> Self {
let dir = uri.join(".").unwrap();

View file

@ -5,11 +5,12 @@ use std::{
use distro::{Distro, Language};
use itertools::Itertools;
use rowan::{TextRange, TextSize};
use rowan::TextRange;
use rustc_hash::FxHashSet;
use text_size::TextLen;
use url::Url;
use crate::{graph, Config, Document, DocumentData, Owner};
use crate::{graph, util::LineCol, Config, Document, DocumentData, Owner};
#[derive(Debug, Default)]
pub struct Workspace {
@ -51,7 +52,7 @@ impl Workspace {
text: String,
language: Language,
owner: Owner,
cursor: TextSize,
cursor: LineCol,
) {
log::debug!("Opening document {uri}...");
self.documents.remove(&uri);
@ -74,19 +75,26 @@ impl Workspace {
Cow::Owned(text) => text,
};
Ok(self.open(uri, text, language, owner, TextSize::default()))
Ok(self.open(uri, text, language, owner, LineCol { line: 0, col: 0 }))
}
pub fn edit(&mut self, uri: &Url, delete: TextRange, insert: &str) -> Option<()> {
let document = self.lookup(uri)?;
let mut text = document.text.clone();
let cursor = if delete.len() == text.text_len() {
let line = document.cursor.line.min(text.lines().count() as u32);
LineCol { line, col: 0 }
} else {
document.line_index.line_col(delete.start())
};
text.replace_range(std::ops::Range::<usize>::from(delete), insert);
self.open(
document.uri.clone(),
text,
document.language,
Owner::Client,
delete.start(),
cursor,
);
Some(())
@ -184,9 +192,10 @@ impl Workspace {
self.folders = folders;
}
pub fn set_cursor(&mut self, uri: &Url, cursor: TextSize) -> Option<()> {
pub fn set_cursor(&mut self, uri: &Url, cursor: LineCol) -> Option<()> {
let mut document = self.lookup(uri)?.clone();
document.cursor = cursor;
self.documents.remove(&document);
self.documents.insert(document);
Some(())
}

View file

@ -32,6 +32,7 @@ pub enum ForwardSearchError {
LaunchViewer(#[from] std::io::Error),
}
#[derive(Debug)]
pub struct ForwardSearch {
program: String,
args: Vec<String>,
@ -79,7 +80,7 @@ impl ForwardSearch {
let tex_path = tex_path.to_string_lossy().into_owned();
let pdf_path = pdf_path.to_string_lossy().into_owned();
let line = line.unwrap_or_else(|| child.line_index.line_col(child.cursor).line);
let line = line.unwrap_or_else(|| child.cursor.line);
let line = (line + 1).to_string();
let program = config.program.clone();

View file

@ -38,9 +38,8 @@ impl<'a> From<&'a Workspace> for ProjectOrdering<'a> {
#[cfg(test)]
mod tests {
use base_db::Owner;
use base_db::{util::LineCol, Owner};
use distro::Language;
use rowan::TextSize;
use super::{ProjectOrdering, Url, Workspace};
@ -57,7 +56,7 @@ mod tests {
String::new(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -65,7 +64,7 @@ mod tests {
String::new(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -73,7 +72,7 @@ mod tests {
r#"\documentclass{article}\include{b}\include{a}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
let ordering = ProjectOrdering::from(&workspace);
@ -95,7 +94,7 @@ mod tests {
String::new(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -103,7 +102,7 @@ mod tests {
r#"\include{a}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -111,7 +110,7 @@ mod tests {
r#"\begin{documnent}\include{b}\end{document}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
let ordering = ProjectOrdering::from(&workspace);
@ -132,7 +131,7 @@ mod tests {
r#"\begin{document}\include{b}\end{document}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -140,7 +139,7 @@ mod tests {
r#"\include{a}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -148,7 +147,7 @@ mod tests {
r#"\include{a}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
let ordering = ProjectOrdering::from(&workspace);
@ -169,7 +168,7 @@ mod tests {
r#"\begin{document}\include{b}\end{document}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -177,7 +176,7 @@ mod tests {
String::new(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -185,7 +184,7 @@ mod tests {
String::new(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
workspace.open(
@ -193,7 +192,7 @@ mod tests {
r#"\begin{document}\include{c}\end{document}"#.to_string(),
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
let ordering = ProjectOrdering::from(&workspace);

View file

@ -1,6 +1,6 @@
use std::path::PathBuf;
use base_db::{Owner, Workspace};
use base_db::{util::LineCol, Owner, Workspace};
use rowan::{TextRange, TextSize};
use url::Url;
@ -35,7 +35,7 @@ impl Fixture {
document.text.clone(),
language,
Owner::Client,
TextSize::from(0),
LineCol { line: 0, col: 0 },
);
}

View file

@ -1,9 +1,8 @@
use base_db::{Owner, Workspace};
use base_db::{util::LineCol, Owner, Workspace};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use distro::Language;
use lsp_types::{ClientCapabilities, Position, Url};
use parser::{parse_latex, SyntaxConfig};
use rowan::TextSize;
const CODE: &str = include_str!("../../../texlab.tex");
@ -22,7 +21,7 @@ fn criterion_benchmark(c: &mut Criterion) {
text,
Language::Tex,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
let client_capabilities = ClientCapabilities::default();

View file

@ -10,15 +10,14 @@ use std::{
};
use anyhow::Result;
use base_db::{Config, Owner, Workspace};
use base_db::{util::LineCol, Config, Owner, Workspace};
use commands::{BuildCommand, CleanCommand, CleanTarget, ForwardSearch};
use crossbeam_channel::{Receiver, Sender};
use distro::{Distro, Language};
use itertools::{FoldWhile, Itertools};
use lsp_server::{Connection, ErrorCode, Message, RequestId};
use lsp_types::{notification::*, request::*, *};
use parking_lot::{Mutex, RwLock};
use rowan::{ast::AstNode, TextSize};
use rowan::ast::AstNode;
use rustc_hash::{FxHashMap, FxHashSet};
use serde::{de::DeserializeOwned, Serialize};
use syntax::bibtex;
@ -362,7 +361,7 @@ impl Server {
params.text_document.text,
language,
Owner::Client,
TextSize::default(),
LineCol { line: 0, col: 0 },
);
self.update_workspace();
@ -389,28 +388,18 @@ impl Server {
workspace.edit(&uri, range, &change.text);
}
None => {
let new_line = document.cursor.line.min(change.text.lines().count() as u32);
let language = document.language;
let line_col = document.line_index.line_col(document.cursor);
let (_, new_cursor) = change
.text
.lines()
.fold_while((0, 0), |(number, index), line| {
if number == line_col.line {
FoldWhile::Done((number, index))
} else {
itertools::FoldWhile::Continue((number + 1, index + line.len()))
}
})
.into_inner();
drop(document);
workspace.open(
uri.clone(),
change.text,
language,
Owner::Client,
TextSize::from(new_cursor as u32),
LineCol {
line: new_line as u32,
col: 0,
},
);
}
};
@ -511,6 +500,9 @@ impl Server {
let position = params.text_document_position.position;
let client_capabilities = Arc::clone(&self.client_capabilities);
let client_info = self.client_info.clone();
self.update_cursor(&uri, position);
self.run_query(id, move |db| {
completion::complete(
db,
@ -523,6 +515,16 @@ impl Server {
Ok(())
}
fn update_cursor(&self, uri: &Url, position: Position) {
self.workspace.write().set_cursor(
uri,
LineCol {
line: position.line,
col: 0,
},
);
}
fn completion_resolve(&self, id: RequestId, mut item: CompletionItem) -> Result<()> {
self.run_query(id, move |workspace| {
match item
@ -584,17 +586,9 @@ impl Server {
let mut uri = params.text_document_position_params.text_document.uri;
normalize_uri(&mut uri);
let workspace = self.workspace.read();
if let Some(document) = workspace.lookup(&uri) {
let position = document
.line_index
.offset_lsp(params.text_document_position_params.position);
drop(workspace);
self.workspace.write().set_cursor(&uri, position);
}
let position = params.text_document_position_params.position;
self.update_cursor(&uri, position);
self.run_query(id, move |db| hover::find(db, &uri, position));
Ok(())
}