fix: set entry state on changing entry (#180)

This commit is contained in:
Myriad-Dreamin 2024-04-09 16:36:30 +08:00 committed by GitHub
parent 59ca5bdabc
commit e7acb31a54
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 57 deletions

View file

@ -286,7 +286,7 @@ impl CompileDriver {
pub struct CompileClientActor {
pub diag_group: String,
pub config: CompileConfig,
entry: Arc<Mutex<EntryState>>,
entry: EntryState,
inner: Deferred<CompileClient>,
render_tx: broadcast::Sender<RenderActorRequest>,
}
@ -302,7 +302,7 @@ impl CompileClientActor {
Self {
diag_group,
config,
entry: Arc::new(Mutex::new(entry)),
entry,
inner,
render_tx,
}
@ -328,7 +328,7 @@ impl CompileClientActor {
self.inner().steal_async(f).await
}
pub fn settle(&self) {
pub fn settle(&mut self) {
let _ = self.change_entry(None);
info!("TypstActor({}): settle requested", self.diag_group);
let res = self.inner().settle();
@ -347,7 +347,7 @@ impl CompileClientActor {
self.config = config;
}
pub fn change_entry(&self, path: Option<ImmutPath>) -> Result<(), Error> {
pub fn change_entry(&mut self, path: Option<ImmutPath>) -> Result<(), Error> {
if path
.as_deref()
.is_some_and(|p| !p.is_absolute() && !p.starts_with("/untitled"))
@ -357,15 +357,7 @@ impl CompileClientActor {
let next_entry = self.config.determine_entry(path);
// todo: more robust rollback logic
let entry = self.entry.clone();
let should_change = {
let prev_entry = entry.lock();
let should_change = next_entry != *prev_entry;
should_change.then(|| prev_entry.clone())
};
if let Some(prev) = should_change {
if next_entry != self.entry {
let next = next_entry.clone();
info!(
@ -403,22 +395,18 @@ impl CompileClientActor {
if res.is_err() {
self.render_tx
.send(RenderActorRequest::ChangeExportPath(PathVars {
entry: prev.clone(),
entry: self.entry.clone(),
}))
.unwrap();
let mut entry = entry.lock();
// todo: the rollback is actually not atomic
if *entry == next_entry {
*entry = prev;
}
return res;
}
// todo: trigger recompile
// todo: better way to trigger recompile
let files = FileChangeSet::new_inserts(vec![]);
self.inner().add_memory_changes(MemoryEvent::Update(files));
self.entry = next_entry;
}
Ok(())
@ -428,14 +416,12 @@ impl CompileClientActor {
self.inner.wait().add_memory_changes(event);
}
pub(crate) fn change_export_pdf(&self, config: ExportConfig) {
let entry = self.entry.lock().clone();
pub(crate) fn change_export_pdf(&mut self, config: ExportConfig) {
let _ = self
.render_tx
.send(RenderActorRequest::ChangeConfig(ExportConfig {
substitute_pattern: config.substitute_pattern,
// root: self.root.get().cloned().flatten(),
entry,
entry: self.entry.clone(),
mode: config.mode,
}))
.unwrap();

View file

@ -371,7 +371,7 @@ impl CompileServer {
};
self.compiler
.as_ref()
.as_mut()
.unwrap()
.change_export_pdf(config.clone());
}
@ -457,7 +457,7 @@ impl CompileServer {
}
/// Focus main file to some path.
pub fn change_entry(&self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
pub fn change_entry(&mut self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
let new_entry = parse_path_or_null(arguments.first())?;
let update_result = self.do_change_entry(new_entry.clone());

View file

@ -658,25 +658,25 @@ impl TypstLanguageServer {
}
/// Export the current document as a PDF file.
pub fn export_pdf(&self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
pub fn export_pdf(&mut self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
self.export(ExportKind::Pdf, arguments)
}
/// Export the current document as a Svg file.
pub fn export_svg(&self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
pub fn export_svg(&mut self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
let opts = parse_opts(arguments.get(1))?;
self.export(ExportKind::Svg { page: opts.page }, arguments)
}
/// Export the current document as a Png file.
pub fn export_png(&self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
pub fn export_png(&mut self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
let opts = parse_opts(arguments.get(1))?;
self.export(ExportKind::Png { page: opts.page }, arguments)
}
/// Export the current document as some format. The client is responsible
/// for passing the correct absolute path of typst document.
pub fn export(&self, kind: ExportKind, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
pub fn export(&mut self, kind: ExportKind, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
let path = parse_path(arguments.first())?.as_ref().to_owned();
let res = run_query!(self.OnExport(path, kind))?;
@ -687,7 +687,7 @@ impl TypstLanguageServer {
/// Get the trace data of the document.
pub fn get_document_trace(
&self,
&mut self,
req_id: RequestId,
arguments: Vec<JsonValue>,
) -> LspResult<Option<()>> {
@ -744,7 +744,7 @@ impl TypstLanguageServer {
}
/// Get the metrics of the document.
pub fn get_document_metrics(&self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
pub fn get_document_metrics(&mut self, arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
let path = parse_path(arguments.first())?.as_ref().to_owned();
let res = run_query!(self.DocumentMetrics(path))?;
@ -755,7 +755,7 @@ impl TypstLanguageServer {
}
/// Get the server info.
pub fn get_server_info(&self, _arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
pub fn get_server_info(&mut self, _arguments: Vec<JsonValue>) -> LspResult<JsonValue> {
let res = run_query!(self.ServerInfo())?;
let res = serde_json::to_value(res)
@ -968,7 +968,7 @@ impl TypstLanguageServer {
Ok(())
}
fn did_save(&self, params: DidSaveTextDocumentParams) -> LspResult<()> {
fn did_save(&mut self, params: DidSaveTextDocumentParams) -> LspResult<()> {
let path = as_path(params.text_document);
let _ = run_query!(self.OnSaveExport(path));
@ -1056,7 +1056,7 @@ impl TypstLanguageServer {
/// Standard Language Features
impl TypstLanguageServer {
fn goto_definition(
&self,
&mut self,
params: GotoDefinitionParams,
) -> LspResult<Option<GotoDefinitionResponse>> {
let (path, position) = as_path_pos(params.text_document_position_params);
@ -1064,31 +1064,34 @@ impl TypstLanguageServer {
}
fn goto_declaration(
&self,
&mut self,
params: GotoDeclarationParams,
) -> LspResult<Option<GotoDeclarationResponse>> {
let (path, position) = as_path_pos(params.text_document_position_params);
run_query!(self.GotoDeclaration(path, position))
}
fn references(&self, params: ReferenceParams) -> LspResult<Option<Vec<Location>>> {
fn references(&mut self, params: ReferenceParams) -> LspResult<Option<Vec<Location>>> {
let (path, position) = as_path_pos(params.text_document_position);
run_query!(self.References(path, position))
}
fn hover(&self, params: HoverParams) -> LspResult<Option<Hover>> {
fn hover(&mut self, params: HoverParams) -> LspResult<Option<Hover>> {
let (path, position) = as_path_pos(params.text_document_position_params);
run_query!(self.Hover(path, position))
}
fn folding_range(&self, params: FoldingRangeParams) -> LspResult<Option<Vec<FoldingRange>>> {
fn folding_range(
&mut self,
params: FoldingRangeParams,
) -> LspResult<Option<Vec<FoldingRange>>> {
let path = as_path(params.text_document);
let line_folding_only = self.const_config().doc_line_folding_only;
run_query!(self.FoldingRange(path, line_folding_only))
}
fn selection_range(
&self,
&mut self,
params: SelectionRangeParams,
) -> LspResult<Option<Vec<SelectionRange>>> {
let path = as_path(params.text_document);
@ -1097,7 +1100,7 @@ impl TypstLanguageServer {
}
fn document_symbol(
&self,
&mut self,
params: DocumentSymbolParams,
) -> LspResult<Option<DocumentSymbolResponse>> {
let path = as_path(params.text_document);
@ -1105,7 +1108,7 @@ impl TypstLanguageServer {
}
fn semantic_tokens_full(
&self,
&mut self,
params: SemanticTokensParams,
) -> LspResult<Option<SemanticTokensResult>> {
let path = as_path(params.text_document);
@ -1113,7 +1116,7 @@ impl TypstLanguageServer {
}
fn semantic_tokens_full_delta(
&self,
&mut self,
params: SemanticTokensDeltaParams,
) -> LspResult<Option<SemanticTokensFullDeltaResult>> {
let path = as_path(params.text_document);
@ -1143,14 +1146,14 @@ impl TypstLanguageServer {
.map_err(|e| internal_error(format!("could not format document: {e}")))
}
fn inlay_hint(&self, params: InlayHintParams) -> LspResult<Option<Vec<InlayHint>>> {
fn inlay_hint(&mut self, params: InlayHintParams) -> LspResult<Option<Vec<InlayHint>>> {
let path = as_path(params.text_document);
let range = params.range;
run_query!(self.InlayHint(path, range))
}
fn document_color(
&self,
&mut self,
params: DocumentColorParams,
) -> LspResult<Option<Vec<ColorInformation>>> {
let path = as_path(params.text_document);
@ -1158,7 +1161,7 @@ impl TypstLanguageServer {
}
fn color_presentation(
&self,
&mut self,
params: ColorPresentationParams,
) -> LspResult<Option<Vec<ColorPresentation>>> {
let path = as_path(params.text_document);
@ -1167,12 +1170,12 @@ impl TypstLanguageServer {
run_query!(self.ColorPresentation(path, color, range))
}
fn code_lens(&self, params: CodeLensParams) -> LspResult<Option<Vec<CodeLens>>> {
fn code_lens(&mut self, params: CodeLensParams) -> LspResult<Option<Vec<CodeLens>>> {
let path = as_path(params.text_document);
run_query!(self.CodeLens(path))
}
fn completion(&self, params: CompletionParams) -> LspResult<Option<CompletionResponse>> {
fn completion(&mut self, params: CompletionParams) -> LspResult<Option<CompletionResponse>> {
let (path, position) = as_path_pos(params.text_document_position);
let explicit = params
.context
@ -1182,26 +1185,29 @@ impl TypstLanguageServer {
run_query!(self.Completion(path, position, explicit))
}
fn signature_help(&self, params: SignatureHelpParams) -> LspResult<Option<SignatureHelp>> {
fn signature_help(&mut self, params: SignatureHelpParams) -> LspResult<Option<SignatureHelp>> {
let (path, position) = as_path_pos(params.text_document_position_params);
run_query!(self.SignatureHelp(path, position))
}
fn rename(&self, params: RenameParams) -> LspResult<Option<WorkspaceEdit>> {
fn rename(&mut self, params: RenameParams) -> LspResult<Option<WorkspaceEdit>> {
let (path, position) = as_path_pos(params.text_document_position);
let new_name = params.new_name;
run_query!(self.Rename(path, position, new_name))
}
fn prepare_rename(
&self,
&mut self,
params: TextDocumentPositionParams,
) -> LspResult<Option<PrepareRenameResponse>> {
let (path, position) = as_path_pos(params);
run_query!(self.PrepareRename(path, position))
}
fn symbol(&self, params: WorkspaceSymbolParams) -> LspResult<Option<Vec<SymbolInformation>>> {
fn symbol(
&mut self,
params: WorkspaceSymbolParams,
) -> LspResult<Option<Vec<SymbolInformation>>> {
let pattern = (!params.query.is_empty()).then_some(params.query);
run_query!(self.Symbol(pattern))
}

View file

@ -19,9 +19,9 @@ use crate::{actor::typ_client::CompileClientActor, compiler::CompileServer, Typs
impl CompileServer {
/// Focus main file to some path.
pub fn do_change_entry(&self, new_entry: Option<ImmutPath>) -> Result<(), Error> {
pub fn do_change_entry(&mut self, new_entry: Option<ImmutPath>) -> Result<(), Error> {
self.compiler
.as_ref()
.as_mut()
.unwrap()
.change_entry(new_entry.clone())?;
@ -218,7 +218,7 @@ impl TypstLanguageServer {
f(source)
}
pub fn query(&self, query: CompilerQueryRequest) -> anyhow::Result<CompilerQueryResponse> {
pub fn query(&mut self, query: CompilerQueryRequest) -> anyhow::Result<CompilerQueryResponse> {
use CompilerQueryRequest::*;
match query {
@ -229,7 +229,7 @@ impl TypstLanguageServer {
DocumentSymbol(req) => query_source!(self, DocumentSymbol, req),
ColorPresentation(req) => Ok(CompilerQueryResponse::ColorPresentation(req.request())),
_ => {
let client = &self.primary;
let client = &mut self.primary;
if !self.pinning && !self.config.compile.has_default_entry_path {
// todo: race condition, we need atomic primary query
if let Some(path) = query.associated_path() {