@@ -289,15 +289,18 @@ struct DefaultState {
scrollbar: ScrollbarState,
add_new_server: NavigableEntry,
servers: Vec<RemoteEntry>,
- handle: ScrollHandle,
}
impl DefaultState {
- fn new(cx: &mut App) -> Self {
+ fn new(ssh_config_servers: &BTreeSet<SharedString>, cx: &mut App) -> Self {
let handle = ScrollHandle::new();
let scrollbar = ScrollbarState::new(handle.clone());
let add_new_server = NavigableEntry::new(&handle, cx);
- let servers = SshSettings::get_global(cx)
+
+ let ssh_settings = SshSettings::get_global(cx);
+ let read_ssh_config = ssh_settings.read_ssh_config;
+
+ let mut servers: Vec<RemoteEntry> = ssh_settings
.ssh_connections()
.map(|connection| {
let open_folder = NavigableEntry::new(&handle, cx);
@@ -316,11 +319,25 @@ impl DefaultState {
})
.collect();
+ if read_ssh_config {
+ let mut extra_servers_from_config = ssh_config_servers.clone();
+ for server in &servers {
+ if let RemoteEntry::Project { connection, .. } = server {
+ extra_servers_from_config.remove(&connection.host);
+ }
+ }
+ servers.extend(extra_servers_from_config.into_iter().map(|host| {
+ RemoteEntry::SshConfig {
+ open_folder: NavigableEntry::new(&handle, cx),
+ host,
+ }
+ }));
+ }
+
Self {
scrollbar,
add_new_server,
servers,
- handle,
}
}
}
@@ -340,8 +357,8 @@ enum Mode {
}
impl Mode {
- fn default_mode(cx: &mut App) -> Self {
- Self::Default(DefaultState::new(cx))
+ fn default_mode(ssh_config_servers: &BTreeSet<SharedString>, cx: &mut App) -> Self {
+ Self::Default(DefaultState::new(ssh_config_servers, cx))
}
}
impl RemoteServerProjects {
@@ -404,7 +421,7 @@ impl RemoteServerProjects {
});
Self {
- mode: Mode::default_mode(cx),
+ mode: Mode::default_mode(&BTreeSet::new(), cx),
focus_handle,
workspace,
retained_connections: Vec::new(),
@@ -481,7 +498,7 @@ impl RemoteServerProjects {
telemetry::event!("SSH Server Created");
this.retained_connections.push(client);
this.add_ssh_server(connection_options, cx);
- this.mode = Mode::default_mode(cx);
+ this.mode = Mode::default_mode(&this.ssh_config_servers, cx);
this.focus_handle(cx).focus(window);
cx.notify()
})
@@ -648,7 +665,7 @@ impl RemoteServerProjects {
}
}
});
- self.mode = Mode::default_mode(cx);
+ self.mode = Mode::default_mode(&self.ssh_config_servers, cx);
self.focus_handle.focus(window);
}
}
@@ -668,7 +685,7 @@ impl RemoteServerProjects {
cx.notify();
}
_ => {
- self.mode = Mode::default_mode(cx);
+ self.mode = Mode::default_mode(&self.ssh_config_servers, cx);
self.focus_handle(cx).focus(window);
cx.notify();
}
@@ -1229,7 +1246,10 @@ impl RemoteServerProjects {
.ok();
remote_servers
.update(cx, |this, cx| {
- this.mode = Mode::default_mode(cx);
+ this.mode = Mode::default_mode(
+ &this.ssh_config_servers,
+ cx,
+ );
cx.notify();
})
.ok();
@@ -1281,7 +1301,7 @@ impl RemoteServerProjects {
.id("ssh-options-copy-server-address")
.track_focus(&entries[3].focus_handle)
.on_action(cx.listener(|this, _: &menu::Confirm, window, cx| {
- this.mode = Mode::default_mode(cx);
+ this.mode = Mode::default_mode(&this.ssh_config_servers, cx);
cx.focus_self(window);
cx.notify();
}))
@@ -1297,7 +1317,8 @@ impl RemoteServerProjects {
)
.child(Label::new("Go Back"))
.on_click(cx.listener(|this, _, window, cx| {
- this.mode = Mode::default_mode(cx);
+ this.mode =
+ Mode::default_mode(&this.ssh_config_servers, cx);
cx.focus_self(window);
cx.notify()
})),
@@ -1358,7 +1379,8 @@ impl RemoteServerProjects {
cx: &mut Context<Self>,
) -> impl IntoElement {
let ssh_settings = SshSettings::get_global(cx);
- let read_ssh_config = ssh_settings.read_ssh_config;
+ let mut should_rebuild = false;
+
if ssh_settings
.ssh_connections
.as_ref()
@@ -1373,31 +1395,33 @@ impl RemoteServerProjects {
.ne(connections.iter())
})
{
- self.mode = Mode::default_mode(cx);
- if let Mode::Default(new_state) = &self.mode {
- state = new_state.clone();
+ should_rebuild = true;
+ };
+
+ if !should_rebuild && ssh_settings.read_ssh_config {
+ let current_ssh_hosts: BTreeSet<SharedString> = state
+ .servers
+ .iter()
+ .filter_map(|server| match server {
+ RemoteEntry::SshConfig { host, .. } => Some(host.clone()),
+ _ => None,
+ })
+ .collect();
+ let mut expected_ssh_hosts = self.ssh_config_servers.clone();
+ for server in &state.servers {
+ if let RemoteEntry::Project { connection, .. } = server {
+ expected_ssh_hosts.remove(&connection.host);
+ }
}
+ should_rebuild = current_ssh_hosts != expected_ssh_hosts;
}
- let mut extra_servers_from_config = if read_ssh_config {
- self.ssh_config_servers.clone()
- } else {
- BTreeSet::new()
- };
- let mut servers = state.servers.clone();
- for server in &servers {
- if let RemoteEntry::Project { connection, .. } = server {
- extra_servers_from_config.remove(&connection.host);
+ if should_rebuild {
+ self.mode = Mode::default_mode(&self.ssh_config_servers, cx);
+ if let Mode::Default(new_state) = &self.mode {
+ state = new_state.clone();
}
}
- servers.extend(
- extra_servers_from_config
- .into_iter()
- .map(|host| RemoteEntry::SshConfig {
- open_folder: NavigableEntry::new(&state.handle, cx),
- host,
- }),
- );
let scroll_state = state.scrollbar.parent_entity(&cx.entity());
let connect_button = div()
@@ -1455,7 +1479,7 @@ impl RemoteServerProjects {
)
.into_any_element(),
)
- .children(servers.iter().enumerate().map(|(ix, connection)| {
+ .children(state.servers.iter().enumerate().map(|(ix, connection)| {
self.render_ssh_connection(ix, connection.clone(), window, cx)
.into_any_element()
})),
@@ -1464,7 +1488,7 @@ impl RemoteServerProjects {
)
.entry(state.add_new_server.clone());
- for server in &servers {
+ for server in &state.servers {
match server {
RemoteEntry::Project {
open_folder,
@@ -1556,7 +1580,7 @@ impl RemoteServerProjects {
},
cx,
);
- self.mode = Mode::default_mode(cx);
+ self.mode = Mode::default_mode(&self.ssh_config_servers, cx);
new_ix.load(atomic::Ordering::Acquire)
}
}