mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-03 05:12:55 +00:00
lsp: Send contents to preview for implicitly loaded slint files
This fixes the no preview in slintpad issue when retrieving the contents of files is slow (e.g. when loaded from the web). Fixes: #3855
This commit is contained in:
parent
aeb512686e
commit
0774d01a59
5 changed files with 73 additions and 59 deletions
|
|
@ -123,7 +123,7 @@ pub struct Context {
|
|||
pub document_cache: RefCell<DocumentCache>,
|
||||
pub server_notifier: crate::ServerNotifier,
|
||||
pub init_param: InitializeParams,
|
||||
pub preview: Box<dyn PreviewApi>,
|
||||
pub preview: Rc<dyn PreviewApi>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
|
|||
|
|
@ -311,25 +311,14 @@ pub fn run_lsp_server() -> Result<IoThreads> {
|
|||
}
|
||||
|
||||
fn main_loop(connection: Connection, init_param: InitializeParams) -> Result<()> {
|
||||
let mut compiler_config =
|
||||
CompilerConfiguration::new(i_slint_compiler::generator::OutputFormat::Interpreter);
|
||||
|
||||
let cli_args = Cli::parse();
|
||||
compiler_config.style =
|
||||
Some(if cli_args.style.is_empty() { "fluent".into() } else { cli_args.style });
|
||||
compiler_config.include_paths = cli_args.include_paths;
|
||||
|
||||
let mut rh = RequestHandler::default();
|
||||
register_request_handlers(&mut rh);
|
||||
|
||||
let request_queue = OutgoingRequestQueue::default();
|
||||
let server_notifier = ServerNotifier(connection.sender.clone(), request_queue.clone());
|
||||
let ctx = Rc::new(Context {
|
||||
document_cache: RefCell::new(DocumentCache::new(compiler_config)),
|
||||
|
||||
let preview = Rc::new(Previewer {
|
||||
server_notifier: server_notifier.clone(),
|
||||
init_param,
|
||||
preview: Box::new(Previewer {
|
||||
server_notifier,
|
||||
#[cfg(all(not(feature = "preview-builtin"), not(feature = "preview-external")))]
|
||||
use_external_previewer: RefCell::new(false), // No preview, pick any.
|
||||
#[cfg(all(not(feature = "preview-builtin"), feature = "preview-external"))]
|
||||
|
|
@ -339,7 +328,31 @@ fn main_loop(connection: Connection, init_param: InitializeParams) -> Result<()>
|
|||
#[cfg(all(feature = "preview-builtin", feature = "preview-external"))]
|
||||
use_external_previewer: RefCell::new(false), // prefer internal
|
||||
to_show: RefCell::new(None),
|
||||
}),
|
||||
});
|
||||
let mut compiler_config =
|
||||
CompilerConfiguration::new(i_slint_compiler::generator::OutputFormat::Interpreter);
|
||||
|
||||
let cli_args = Cli::parse();
|
||||
compiler_config.style =
|
||||
Some(if cli_args.style.is_empty() { "fluent".into() } else { cli_args.style });
|
||||
compiler_config.include_paths = cli_args.include_paths;
|
||||
let preview_notifier = preview.clone();
|
||||
compiler_config.open_import_fallback = Some(Rc::new(move |path| {
|
||||
let preview_notifier = preview_notifier.clone();
|
||||
Box::pin(async move {
|
||||
let contents = std::fs::read_to_string(&path);
|
||||
if let Ok(contents) = &contents {
|
||||
preview_notifier.set_contents(&PathBuf::from(path), contents);
|
||||
}
|
||||
Some(contents)
|
||||
})
|
||||
}));
|
||||
|
||||
let ctx = Rc::new(Context {
|
||||
document_cache: RefCell::new(DocumentCache::new(compiler_config)),
|
||||
server_notifier: server_notifier,
|
||||
init_param,
|
||||
preview,
|
||||
});
|
||||
|
||||
let mut futures = Vec::<Pin<Box<dyn Future<Output = Result<()>>>>>::new();
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ pub fn set_contents(path: &Path, content: String) {
|
|||
let current = cache.current.clone();
|
||||
let ui_is_visible = cache.ui_is_visible;
|
||||
drop(cache);
|
||||
if ui_is_visible {
|
||||
|
||||
if ui_is_visible && !current.path.as_os_str().is_empty() {
|
||||
load_preview(current);
|
||||
}
|
||||
}
|
||||
|
|
@ -79,11 +80,14 @@ fn set_design_mode(enable: bool) {
|
|||
}
|
||||
|
||||
fn change_style() {
|
||||
let component = {
|
||||
let cache = CONTENT_CACHE.get_or_init(Default::default).lock().unwrap();
|
||||
cache.current.clone()
|
||||
};
|
||||
load_preview(component);
|
||||
let ui_is_visible = cache.ui_is_visible;
|
||||
let current = cache.current.clone();
|
||||
drop(cache);
|
||||
|
||||
if ui_is_visible && !current.path.as_os_str().is_empty() {
|
||||
load_preview(current);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_parsing() {
|
||||
|
|
@ -119,7 +123,8 @@ pub fn config_changed(
|
|||
let current = cache.current.clone();
|
||||
let ui_is_visible = cache.ui_is_visible;
|
||||
drop(cache);
|
||||
if ui_is_visible {
|
||||
|
||||
if ui_is_visible && !current.path.as_os_str().is_empty() {
|
||||
load_preview(current);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ impl PreviewApi for Previewer {
|
|||
}
|
||||
|
||||
fn load_preview(&self, component: common::PreviewComponent) {
|
||||
if component.path.as_os_str().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.to_show.replace(Some(component.clone()));
|
||||
|
||||
#[cfg(feature = "preview-external")]
|
||||
|
|
@ -260,29 +264,38 @@ pub fn create(
|
|||
) -> JsResult<SlintServer> {
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let send_request = Function::from(send_request.clone());
|
||||
let server_notifier = ServerNotifier { send_notification, send_request };
|
||||
let preview = Rc::new(Previewer {
|
||||
server_notifier: server_notifier.clone(),
|
||||
to_show: Default::default(),
|
||||
});
|
||||
|
||||
let init_param = serde_wasm_bindgen::from_value(init_param)?;
|
||||
|
||||
let mut compiler_config =
|
||||
CompilerConfiguration::new(i_slint_compiler::generator::OutputFormat::Interpreter);
|
||||
|
||||
let preview_notifier = preview.clone();
|
||||
compiler_config.open_import_fallback = Some(Rc::new(move |path| {
|
||||
let load_file = Function::from(load_file.clone());
|
||||
Box::pin(async move { Some(self::load_file(path, &load_file).await) })
|
||||
let preview_notifier = preview_notifier.clone();
|
||||
Box::pin(async move {
|
||||
let contents = self::load_file(path.clone(), &load_file).await;
|
||||
if let Ok(contents) = &contents {
|
||||
preview_notifier.set_contents(&PathBuf::from(path), contents);
|
||||
}
|
||||
Some(contents)
|
||||
})
|
||||
}));
|
||||
let document_cache = RefCell::new(DocumentCache::new(compiler_config));
|
||||
let send_request = Function::from(send_request.clone());
|
||||
let reentry_guard = Rc::new(RefCell::new(ReentryGuard::default()));
|
||||
|
||||
let mut rh = RequestHandler::default();
|
||||
language::register_request_handlers(&mut rh);
|
||||
let server_notifier = ServerNotifier { send_notification, send_request };
|
||||
|
||||
Ok(SlintServer {
|
||||
ctx: Rc::new(Context {
|
||||
document_cache,
|
||||
init_param,
|
||||
server_notifier: server_notifier.clone(),
|
||||
preview: Box::new(Previewer { server_notifier, to_show: Default::default() }),
|
||||
}),
|
||||
ctx: Rc::new(Context { document_cache, init_param, server_notifier, preview }),
|
||||
reentry_guard,
|
||||
rh: Rc::new(rh),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||
|
||||
// cSpell: ignore edcore lumino mimetypes printerdemo
|
||||
// cSpell: ignore codingame lumino mimetypes printerdemo
|
||||
|
||||
import * as monaco from "monaco-editor";
|
||||
|
||||
|
|
@ -416,6 +416,10 @@ class EditorPaneWidget extends Widget {
|
|||
if (monaco.editor.getModels().length === 1) {
|
||||
this.#main_uri = uri;
|
||||
this.set_model(uri);
|
||||
this.language_client?.sendRequest("workspace/executeCommand", {
|
||||
command: "slint/showPreview",
|
||||
arguments: [this.#main_uri?.toString() ?? "", ""],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -797,7 +801,6 @@ export class EditorWidget extends Widget {
|
|||
}
|
||||
|
||||
async set_demo(location: string) {
|
||||
let result_uri: monaco.Uri | null = null;
|
||||
if (location) {
|
||||
const default_tag = "XXXX_DEFAULT_TAG_XXXX";
|
||||
let tag = default_tag.startsWith("XXXX_DEFAULT_TAG_")
|
||||
|
|
@ -813,32 +816,12 @@ export class EditorWidget extends Widget {
|
|||
tag = "v" + found[1];
|
||||
}
|
||||
}
|
||||
result_uri = await this.project_from_url(
|
||||
await this.project_from_url(
|
||||
`https://raw.githubusercontent.com/slint-ui/slint/${tag}/${location}`,
|
||||
);
|
||||
} else {
|
||||
this.#editor.clear_models();
|
||||
const model = await createModel(
|
||||
this.#editor.internal_uuid,
|
||||
hello_world,
|
||||
);
|
||||
if (model) {
|
||||
result_uri = model.uri;
|
||||
}
|
||||
}
|
||||
|
||||
if (result_uri) {
|
||||
setTimeout(
|
||||
() =>
|
||||
this.language_client?.sendRequest(
|
||||
"workspace/executeCommand",
|
||||
{
|
||||
command: "slint/showPreview",
|
||||
arguments: [result_uri?.toString() ?? "", ""],
|
||||
},
|
||||
),
|
||||
1000,
|
||||
);
|
||||
await createModel(this.#editor.internal_uuid, hello_world);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue