mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-15 10:10:57 +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 document_cache: RefCell<DocumentCache>,
|
||||||
pub server_notifier: crate::ServerNotifier,
|
pub server_notifier: crate::ServerNotifier,
|
||||||
pub init_param: InitializeParams,
|
pub init_param: InitializeParams,
|
||||||
pub preview: Box<dyn PreviewApi>,
|
pub preview: Rc<dyn PreviewApi>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
||||||
|
|
@ -311,6 +311,24 @@ pub fn run_lsp_server() -> Result<IoThreads> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main_loop(connection: Connection, init_param: InitializeParams) -> Result<()> {
|
fn main_loop(connection: Connection, init_param: InitializeParams) -> Result<()> {
|
||||||
|
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 preview = Rc::new(Previewer {
|
||||||
|
server_notifier: server_notifier.clone(),
|
||||||
|
#[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"))]
|
||||||
|
use_external_previewer: RefCell::new(true), // external only
|
||||||
|
#[cfg(all(feature = "preview-builtin", not(feature = "preview-external")))]
|
||||||
|
use_external_previewer: RefCell::new(false), // internal only
|
||||||
|
#[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 =
|
let mut compiler_config =
|
||||||
CompilerConfiguration::new(i_slint_compiler::generator::OutputFormat::Interpreter);
|
CompilerConfiguration::new(i_slint_compiler::generator::OutputFormat::Interpreter);
|
||||||
|
|
||||||
|
|
@ -318,28 +336,23 @@ fn main_loop(connection: Connection, init_param: InitializeParams) -> Result<()>
|
||||||
compiler_config.style =
|
compiler_config.style =
|
||||||
Some(if cli_args.style.is_empty() { "fluent".into() } else { cli_args.style });
|
Some(if cli_args.style.is_empty() { "fluent".into() } else { cli_args.style });
|
||||||
compiler_config.include_paths = cli_args.include_paths;
|
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 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 {
|
let ctx = Rc::new(Context {
|
||||||
document_cache: RefCell::new(DocumentCache::new(compiler_config)),
|
document_cache: RefCell::new(DocumentCache::new(compiler_config)),
|
||||||
server_notifier: server_notifier.clone(),
|
server_notifier: server_notifier,
|
||||||
init_param,
|
init_param,
|
||||||
preview: Box::new(Previewer {
|
preview,
|
||||||
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"))]
|
|
||||||
use_external_previewer: RefCell::new(true), // external only
|
|
||||||
#[cfg(all(feature = "preview-builtin", not(feature = "preview-external")))]
|
|
||||||
use_external_previewer: RefCell::new(false), // internal only
|
|
||||||
#[cfg(all(feature = "preview-builtin", feature = "preview-external"))]
|
|
||||||
use_external_previewer: RefCell::new(false), // prefer internal
|
|
||||||
to_show: RefCell::new(None),
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut futures = Vec::<Pin<Box<dyn Future<Output = Result<()>>>>>::new();
|
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 current = cache.current.clone();
|
||||||
let ui_is_visible = cache.ui_is_visible;
|
let ui_is_visible = cache.ui_is_visible;
|
||||||
drop(cache);
|
drop(cache);
|
||||||
if ui_is_visible {
|
|
||||||
|
if ui_is_visible && !current.path.as_os_str().is_empty() {
|
||||||
load_preview(current);
|
load_preview(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,11 +80,14 @@ fn set_design_mode(enable: bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_style() {
|
fn change_style() {
|
||||||
let component = {
|
let cache = CONTENT_CACHE.get_or_init(Default::default).lock().unwrap();
|
||||||
let cache = CONTENT_CACHE.get_or_init(Default::default).lock().unwrap();
|
let ui_is_visible = cache.ui_is_visible;
|
||||||
cache.current.clone()
|
let current = cache.current.clone();
|
||||||
};
|
drop(cache);
|
||||||
load_preview(component);
|
|
||||||
|
if ui_is_visible && !current.path.as_os_str().is_empty() {
|
||||||
|
load_preview(current);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_parsing() {
|
pub fn start_parsing() {
|
||||||
|
|
@ -119,7 +123,8 @@ pub fn config_changed(
|
||||||
let current = cache.current.clone();
|
let current = cache.current.clone();
|
||||||
let ui_is_visible = cache.ui_is_visible;
|
let ui_is_visible = cache.ui_is_visible;
|
||||||
drop(cache);
|
drop(cache);
|
||||||
if ui_is_visible {
|
|
||||||
|
if ui_is_visible && !current.path.as_os_str().is_empty() {
|
||||||
load_preview(current);
|
load_preview(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,10 @@ impl PreviewApi for Previewer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_preview(&self, component: common::PreviewComponent) {
|
fn load_preview(&self, component: common::PreviewComponent) {
|
||||||
|
if component.path.as_os_str().is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.to_show.replace(Some(component.clone()));
|
self.to_show.replace(Some(component.clone()));
|
||||||
|
|
||||||
#[cfg(feature = "preview-external")]
|
#[cfg(feature = "preview-external")]
|
||||||
|
|
@ -260,29 +264,38 @@ pub fn create(
|
||||||
) -> JsResult<SlintServer> {
|
) -> JsResult<SlintServer> {
|
||||||
console_error_panic_hook::set_once();
|
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 init_param = serde_wasm_bindgen::from_value(init_param)?;
|
||||||
|
|
||||||
let mut compiler_config =
|
let mut compiler_config =
|
||||||
CompilerConfiguration::new(i_slint_compiler::generator::OutputFormat::Interpreter);
|
CompilerConfiguration::new(i_slint_compiler::generator::OutputFormat::Interpreter);
|
||||||
|
|
||||||
|
let preview_notifier = preview.clone();
|
||||||
compiler_config.open_import_fallback = Some(Rc::new(move |path| {
|
compiler_config.open_import_fallback = Some(Rc::new(move |path| {
|
||||||
let load_file = Function::from(load_file.clone());
|
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 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 reentry_guard = Rc::new(RefCell::new(ReentryGuard::default()));
|
||||||
|
|
||||||
let mut rh = RequestHandler::default();
|
let mut rh = RequestHandler::default();
|
||||||
language::register_request_handlers(&mut rh);
|
language::register_request_handlers(&mut rh);
|
||||||
let server_notifier = ServerNotifier { send_notification, send_request };
|
|
||||||
|
|
||||||
Ok(SlintServer {
|
Ok(SlintServer {
|
||||||
ctx: Rc::new(Context {
|
ctx: Rc::new(Context { document_cache, init_param, server_notifier, preview }),
|
||||||
document_cache,
|
|
||||||
init_param,
|
|
||||||
server_notifier: server_notifier.clone(),
|
|
||||||
preview: Box::new(Previewer { server_notifier, to_show: Default::default() }),
|
|
||||||
}),
|
|
||||||
reentry_guard,
|
reentry_guard,
|
||||||
rh: Rc::new(rh),
|
rh: Rc::new(rh),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
// 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";
|
import * as monaco from "monaco-editor";
|
||||||
|
|
||||||
|
|
@ -416,6 +416,10 @@ class EditorPaneWidget extends Widget {
|
||||||
if (monaco.editor.getModels().length === 1) {
|
if (monaco.editor.getModels().length === 1) {
|
||||||
this.#main_uri = uri;
|
this.#main_uri = uri;
|
||||||
this.set_model(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) {
|
async set_demo(location: string) {
|
||||||
let result_uri: monaco.Uri | null = null;
|
|
||||||
if (location) {
|
if (location) {
|
||||||
const default_tag = "XXXX_DEFAULT_TAG_XXXX";
|
const default_tag = "XXXX_DEFAULT_TAG_XXXX";
|
||||||
let tag = default_tag.startsWith("XXXX_DEFAULT_TAG_")
|
let tag = default_tag.startsWith("XXXX_DEFAULT_TAG_")
|
||||||
|
|
@ -813,32 +816,12 @@ export class EditorWidget extends Widget {
|
||||||
tag = "v" + found[1];
|
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}`,
|
`https://raw.githubusercontent.com/slint-ui/slint/${tag}/${location}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.#editor.clear_models();
|
this.#editor.clear_models();
|
||||||
const model = await createModel(
|
await createModel(this.#editor.internal_uuid, hello_world);
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue