дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
feat(java): Separate the jdtls JDK and add Settings for New Projects (#21)
- Languages & Frameworks › Java › Language Server › JDK (languages.java.jdtlsJdk) runs jdtls on its own JDK, like IDEA's JDK for importer; the project keeps compiling and running with the Project JDK. - Toolchain pages get the Global / This project switch (default This project); Global shows and edits the global layer. - File › New Projects Setup › Settings for New Projects… edits only the global layer, which new projects inherit. - Configuration errors (launch_error) show as "Not started" instead of "Crashed". Fixes #18 Fixes #19 Claude-Session: https://claude.ai/code/session_01SaPPsVPuk6ZTNsoUCNCbMv
Цей коміт міститься в:
1 джерело
a765959d48
коміт
059f25f13e
38 files changed
+486
-93
No files matched your search
@@ -109,6 +109,14 @@ pub fn settings_get(window: Window, state: State<'_, AppState>) -> Settings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Defaults plus the global layer, without any project's values: what new
|
||||
/// projects (and projects without their own value) get.
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn settings_get_global(state: State<'_, AppState>) -> Settings {
|
||||
state.global_settings.effective()
|
||||
}
|
||||
|
||||
/// `value` is JSON text, e.g. `14` or `"dark"`. Every window (for a project
|
||||
/// value: that project's windows) is told (`IdeEvent::SettingsChanged`) so it
|
||||
/// re-reads its effective settings.
|
||||
|
||||
@@ -48,6 +48,7 @@ pub fn builder() -> tauri_specta::Builder<tauri::Wry> {
|
||||
app::close_project,
|
||||
app::languages,
|
||||
app::settings_get,
|
||||
app::settings_get_global,
|
||||
app::settings_set,
|
||||
app::project_roots,
|
||||
app::cancel_request,
|
||||
|
||||
@@ -24,7 +24,8 @@ pub async fn window_new(app: AppHandle) -> IdeResult<String> {
|
||||
windows::create_window(&app, None).map(|w| w.label().to_owned())
|
||||
}
|
||||
|
||||
/// Opens this window's Settings window on `page` (or focuses it and navigates).
|
||||
/// Opens this window's Settings window on `page` (or focuses it and navigates);
|
||||
/// `new_projects` edits the global layer only ("Settings for New Projects").
|
||||
/// `background` (`#rrggbb`) paints a new window until its page has loaded.
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
@@ -32,9 +33,10 @@ pub async fn window_open_settings(
|
||||
app: AppHandle,
|
||||
window: WebviewWindow,
|
||||
page: Option<String>,
|
||||
new_projects: bool,
|
||||
background: Option<String>,
|
||||
) -> IdeResult<()> {
|
||||
windows::open_settings_window(&app, &window, page, background)
|
||||
windows::open_settings_window(&app, &window, page, new_projects, background)
|
||||
}
|
||||
|
||||
/// Focuses the next / previous window (⌘` / ⇧⌘`).
|
||||
|
||||
@@ -79,7 +79,7 @@ pub fn run() {
|
||||
if let Ok(cwd) = std::env::current_dir()
|
||||
&& let Some(path) = windows::cli_path(&std::env::args().collect::<Vec<_>>(), &cwd)
|
||||
{
|
||||
windows.set_launch("main", windows::Launch { project: Some(path.into()), settings_page: None });
|
||||
windows.set_launch("main", windows::Launch { project: Some(path.into()), ..Default::default() });
|
||||
}
|
||||
let menu_state = menu::MenuState::default();
|
||||
menu::install(app.handle(), &menu_state, &state.recent.list());
|
||||
@@ -135,7 +135,11 @@ fn on_menu_event(app: &tauri::AppHandle, event: tauri::menu::MenuEvent) {
|
||||
Some(w) => {
|
||||
// Settings is modal for its project window: only app-level items get through, to the parent.
|
||||
let label = match windows::settings_parent(w.label()) {
|
||||
Some(parent) if matches!(route.action.as_str(), "app.quit" | "file.settings") => parent,
|
||||
Some(parent)
|
||||
if matches!(route.action.as_str(), "app.quit" | "file.settings" | "file.newProjectsSettings") =>
|
||||
{
|
||||
parent
|
||||
}
|
||||
Some(_) => return,
|
||||
None => w.label(),
|
||||
};
|
||||
|
||||
@@ -208,6 +208,11 @@ pub fn spec(os: Os) -> Vec<Entry> {
|
||||
act("file.save", "Save All"),
|
||||
sub("fileProperties", "File Properties", vec![act("file.toggleReadOnly", "Make File Read-only / Writable")]),
|
||||
SEP,
|
||||
sub(
|
||||
"newProjectsSetup",
|
||||
"New Projects Setup",
|
||||
vec![act("file.newProjectsSettings", "Settings for New Projects…")],
|
||||
),
|
||||
act("file.invalidateCaches", "Invalidate Caches…"),
|
||||
];
|
||||
if !mac {
|
||||
@@ -972,6 +977,7 @@ mod tests {
|
||||
"file.closeProject",
|
||||
"file.save",
|
||||
"file.settings",
|
||||
"file.newProjectsSettings",
|
||||
"window.new",
|
||||
"window.next",
|
||||
"window.previous",
|
||||
|
||||
@@ -259,12 +259,17 @@ impl AppState {
|
||||
if let Some(problem) = lombok.problem() {
|
||||
tracing::warn!("{problem}");
|
||||
}
|
||||
let server_jdk = ide_sdk::apply::jdtls_jdk(&root, &effective).unwrap_or_else(|e| {
|
||||
cfg.launch_error = Some(e);
|
||||
None
|
||||
});
|
||||
ide_sdk::java::configure_jdtls(
|
||||
cfg,
|
||||
server_root,
|
||||
&data_dir,
|
||||
&jdks,
|
||||
ide_sdk::apply::project_jdk(&root, &effective).as_ref(),
|
||||
server_jdk.as_ref(),
|
||||
min_java,
|
||||
&bundles,
|
||||
lombok.jar(),
|
||||
|
||||
@@ -39,6 +39,8 @@ pub struct Launch {
|
||||
pub project: Option<ide_core::IpcPath>,
|
||||
/// Settings windows: the page to show.
|
||||
pub settings_page: Option<String>,
|
||||
/// Settings windows: edit the global layer only ("Settings for New Projects").
|
||||
pub new_projects: bool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -271,7 +273,7 @@ pub fn create_window(app: &AppHandle, project: Option<PathBuf>) -> IdeResult<Web
|
||||
config.y = Some(pos.y + CASCADE);
|
||||
config.center = false;
|
||||
}
|
||||
app.state::<WindowsState>().set_launch(&label, Launch { project: project.map(Into::into), settings_page: None });
|
||||
app.state::<WindowsState>().set_launch(&label, Launch { project: project.map(Into::into), ..Default::default() });
|
||||
let window = build_project_window(app, config)?;
|
||||
focus(&window);
|
||||
Ok(window)
|
||||
@@ -338,7 +340,7 @@ pub fn open_path(app: &AppHandle, path: &Path) {
|
||||
match free {
|
||||
Some(w) => {
|
||||
app.state::<WindowsState>()
|
||||
.set_launch(w.label(), Launch { project: Some(root.into()), settings_page: None });
|
||||
.set_launch(w.label(), Launch { project: Some(root.into()), ..Default::default() });
|
||||
let _ = app.emit_to(w.label(), LAUNCH_EVENT, ());
|
||||
focus(&w);
|
||||
}
|
||||
@@ -375,6 +377,7 @@ pub fn open_settings_window(
|
||||
app: &AppHandle,
|
||||
parent: &WebviewWindow,
|
||||
page: Option<String>,
|
||||
new_projects: bool,
|
||||
background: Option<String>,
|
||||
) -> IdeResult<()> {
|
||||
// Asked from a settings window itself: navigate it.
|
||||
@@ -382,8 +385,8 @@ pub fn open_settings_window(
|
||||
let label = settings_label(&parent_label);
|
||||
let windows = app.state::<WindowsState>();
|
||||
if let Some(existing) = app.get_webview_window(&label) {
|
||||
if page.is_some() {
|
||||
windows.set_launch(&label, Launch { project: None, settings_page: page });
|
||||
if page.is_some() || new_projects {
|
||||
windows.set_launch(&label, Launch { project: None, settings_page: page, new_projects });
|
||||
let _ = app.emit_to(label.as_str(), LAUNCH_EVENT, ());
|
||||
}
|
||||
focus(&existing);
|
||||
@@ -406,7 +409,7 @@ pub fn open_settings_window(
|
||||
if let Some(color) = background.and_then(|c| serde_json::from_value(serde_json::Value::String(c)).ok()) {
|
||||
config.background_color = Some(color);
|
||||
}
|
||||
windows.set_launch(&label, Launch { project: None, settings_page: page });
|
||||
windows.set_launch(&label, Launch { project: None, settings_page: page, new_projects });
|
||||
let window = WebviewWindowBuilder::from_config(app, &config)
|
||||
.and_then(|b| b.parent(&parent))
|
||||
.and_then(|b| b.build())
|
||||
@@ -485,7 +488,7 @@ mod tests {
|
||||
#[test]
|
||||
fn launches_are_taken_once() {
|
||||
let st = WindowsState::default();
|
||||
st.set_launch("project-1", Launch { project: Some("/p".into()), settings_page: None });
|
||||
st.set_launch("project-1", Launch { project: Some("/p".into()), ..Default::default() });
|
||||
assert_eq!(st.take_launch("project-1").and_then(|l| l.project), Some("/p".into()));
|
||||
assert_eq!(st.take_launch("project-1"), None);
|
||||
}
|
||||
|
||||
Reference in new issue
Заблокувати користувача