From a6341783ef8b4d6e1da8926d5e1648205746d6a2 Mon Sep 17 00:00:00 2001 From: Joe Date: Sun, 15 Feb 2026 16:19:35 -0600 Subject: [PATCH] Update Luau LSP and project configurations - Upgraded `luau-lsp` dependency to version 1.62.0 for improved features and bug fixes. - Modified sourcemap generator command in VSCode settings for better output handling. - Enabled `fillCallArguments` in project template settings to enhance code completion. - Added new configuration options for fragment autocomplete and quote conversion in project template settings. - Introduced a `sourcemap` flag in `SyncbackCommand` to allow optional sourcemap generation during syncback operations. These changes enhance the development experience and improve the functionality of the Luau language server integration. --- .vscode/settings.json | 2 +- .../place/.vscode/settings.json | 10 ++- rokit.toml | 2 +- src/cli/clone.rs | 1 + src/cli/syncback.rs | 66 +++++++++++-------- tests/rojo_test/serve_util.rs | 2 +- tests/tests/connected_mode.rs | 21 ++++-- 7 files changed, 67 insertions(+), 37 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index b08d6cc6..62d42093 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,7 +25,7 @@ "luau-lsp.completion.imports.requireStyle": "alwaysAbsolute", "luau-lsp.completion.fillCallArguments": false, "luau-lsp.completion.showDeprecatedItems": false, - "luau-lsp.sourcemap.generatorCommand": "atlas", + "luau-lsp.sourcemap.generatorCommand": "atlas sourcemap default.project.json --output sourcemap.json --include-non-scripts --watch", "luau-lsp.fflags.enableNewSolver": false, "luau-lsp.index.maxFiles": 100000, "luau-lsp.plugin.port": 3668, diff --git a/assets/project-templates/place/.vscode/settings.json b/assets/project-templates/place/.vscode/settings.json index c55a1f5d..47e5c350 100644 --- a/assets/project-templates/place/.vscode/settings.json +++ b/assets/project-templates/place/.vscode/settings.json @@ -23,16 +23,20 @@ "luau-lsp.sourcemap.includeNonScripts": true, "luau-lsp.diagnostics.strictDatamodelTypes": true, "luau-lsp.completion.imports.requireStyle": "alwaysAbsolute", - "luau-lsp.completion.fillCallArguments": false, + "luau-lsp.completion.fillCallArguments": true, "luau-lsp.completion.showDeprecatedItems": false, - "luau-lsp.sourcemap.generatorCommand": "atlas", + "luau-lsp.sourcemap.generatorCommand": "atlas sourcemap default.project.json5 --output sourcemap.json --include-non-scripts --watch", "luau-lsp.fflags.enableNewSolver": false, "luau-lsp.index.maxFiles": 100000, + "luau-lsp.completion.enableFragmentAutocomplete": true, + "luau-lsp.format.convertQuotes": true, + "luau-lsp.server.baseLuaurc": ".luaurc", + "luau.trace.server": "off", "stylua.targetReleaseVersion": "latest", "[luau]": { "editor.defaultFormatter": "JohnnyMorganz.stylua" }, - "git.ignoreLimitWarning": true + "git.ignoreLimitWarning": true, } diff --git a/rokit.toml b/rokit.toml index 2e52b104..97af0c92 100644 --- a/rokit.toml +++ b/rokit.toml @@ -2,5 +2,5 @@ selene = "Kampfkarren/selene@0.30.0" stylua = "JohnnyMorganz/stylua@2.3.1" luau = "luau-lang/luau@0.708" -luau-lsp = "JohnnyMorganz/luau-lsp@1.61.0" +luau-lsp = "JohnnyMorganz/luau-lsp@1.62.0" run-in-roblox = "rojo-rbx/run-in-roblox@0.3.0" diff --git a/src/cli/clone.rs b/src/cli/clone.rs index f24a6335..5bcbb3e3 100644 --- a/src/cli/clone.rs +++ b/src/cli/clone.rs @@ -84,6 +84,7 @@ impl CloneCommand { dry_run: false, interactive: false, incremental: false, + sourcemap: false, working_dir: path.clone(), }; diff --git a/src/cli/syncback.rs b/src/cli/syncback.rs index 775c46fb..557e3788 100644 --- a/src/cli/syncback.rs +++ b/src/cli/syncback.rs @@ -71,6 +71,10 @@ pub struct SyncbackCommand { #[clap(long, short = 'n')] pub incremental: bool, + /// Generate a sourcemap.json file after syncback. + #[clap(long)] + pub sourcemap: bool, + /// Base directory for resolving relative paths (project, input). /// Defaults to the current working directory. #[clap(long, hide = true, default_value = ".")] @@ -229,45 +233,53 @@ impl SyncbackCommand { } log::info!("Writing to the file system..."); - let sourcemap_path = base_path.join("sourcemap.json"); - // Run file writes and sourcemap generation in parallel. - // The sourcemap is built entirely from in-memory data (WeakDom + path map), - // so it doesn't need to wait for files to be on disk. - let (write_result, sourcemap_result) = std::thread::scope(|s| { - let write_handle = s.spawn(|| { - result - .fs_snapshot - .write_to_vfs_parallel(base_path, session_old.vfs()) - }); + if self.sourcemap { + let sourcemap_path = base_path.join("sourcemap.json"); - let sourcemap_handle = s.spawn(|| { - write_sourcemap_from_syncback( - &result.new_tree, - &result.instance_paths, - base_path, - &sourcemap_path, + // Run file writes and sourcemap generation in parallel. + // The sourcemap is built entirely from in-memory data (WeakDom + path map), + // so it doesn't need to wait for files to be on disk. + let (write_result, sourcemap_result) = std::thread::scope(|s| { + let write_handle = s.spawn(|| { + result + .fs_snapshot + .write_to_vfs_parallel(base_path, session_old.vfs()) + }); + + let sourcemap_handle = s.spawn(|| { + write_sourcemap_from_syncback( + &result.new_tree, + &result.instance_paths, + base_path, + &sourcemap_path, + ) + }); + + ( + write_handle.join().unwrap(), + sourcemap_handle.join().unwrap(), ) }); - ( - write_handle.join().unwrap(), - sourcemap_handle.join().unwrap(), - ) - }); + write_result?; + + match sourcemap_result { + Ok(()) => log::info!("Generated sourcemap at {}", sourcemap_path.display()), + Err(e) => log::warn!("Could not generate sourcemap: {}", e), + } + } else { + result + .fs_snapshot + .write_to_vfs_parallel(base_path, session_old.vfs())?; + } - write_result?; log::info!( "Finished syncback: wrote {} files/folders, removed {}.", result.fs_snapshot.added_paths().len(), result.fs_snapshot.removed_paths().len() ); - match sourcemap_result { - Ok(()) => log::info!("Generated sourcemap at {}", sourcemap_path.display()), - Err(e) => log::warn!("Could not generate sourcemap: {}", e), - } - // Refresh git index if in a git repository refresh_git_index(base_path); diff --git a/tests/rojo_test/serve_util.rs b/tests/rojo_test/serve_util.rs index 013b6ebc..9577bc0a 100644 --- a/tests/rojo_test/serve_util.rs +++ b/tests/rojo_test/serve_util.rs @@ -568,7 +568,7 @@ pub fn assert_round_trip(session: &TestServeSession, root_id: Ref) { /// (e.g., rename = REMOVE + CREATE on Windows) into a single logical packet /// for snapshot comparison. Takes the highest message cursor and combines /// all added/removed/updated entries into one message. -fn merge_socket_packets(base: &mut SocketPacket<'static>, other: SocketPacket<'static>) { +pub fn merge_socket_packets(base: &mut SocketPacket<'static>, other: SocketPacket<'static>) { match (&mut base.body, other.body) { (SocketPacketBody::Messages(base_msgs), SocketPacketBody::Messages(other_msgs)) => { base_msgs.message_cursor = base_msgs.message_cursor.max(other_msgs.message_cursor); diff --git a/tests/tests/connected_mode.rs b/tests/tests/connected_mode.rs index a9392ba5..8715639f 100644 --- a/tests/tests/connected_mode.rs +++ b/tests/tests/connected_mode.rs @@ -853,9 +853,18 @@ fn api_write_then_filesystem_change() { session.post_api_write(&write_request).unwrap(); std::thread::sleep(std::time::Duration::from_millis(500)); - // Now make a filesystem change to a DIFFERENT file - let socket_packet = session - .recv_socket_packet(SocketPacketType::Messages, 0, || { + // Drain the API write's patch message first. Subscribing at cursor 0 + // gets it immediately, which on macOS would start the settle timer + // before the filesystem event arrives (FSEvents latency > 100ms). + let api_packet = session + .get_api_socket_packet(SocketPacketType::Messages, 0) + .unwrap(); + let api_cursor = crate::rojo_test::serve_util::get_message_cursor(&api_packet); + + // Now subscribe at the post-API cursor and make the filesystem change. + // The settle timer won't start until this new event actually arrives. + let fs_packet = session + .recv_socket_packet(SocketPacketType::Messages, api_cursor, || { fs::write( session.path().join("src/server.server.luau"), "-- fs change\nprint('fs')", @@ -863,9 +872,13 @@ fn api_write_then_filesystem_change() { .unwrap(); }) .unwrap(); + + // Merge both packets for the combined snapshot assertion + let mut combined = api_packet; + crate::rojo_test::serve_util::merge_socket_packets(&mut combined, fs_packet); assert_yaml_snapshot!( "connected_api_then_fs_patch", - socket_packet.intern_and_redact(&mut redactions, ()) + combined.intern_and_redact(&mut redactions, ()) ); assert_round_trip(&session, root_id);