SSH configuration path (#84)

SSH configuration
This commit is contained in:
Christian Visintin
2021-12-11 21:43:23 +01:00
parent 9284f101c8
commit e6ba4d8430
18 changed files with 155 additions and 9 deletions

View File

@@ -391,6 +391,7 @@ impl BookmarkName {
impl Component<Msg, NoUserEvent> for BookmarkName {
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
match ev {
Event::Keyboard(KeyEvent { code: Key::Esc, .. }) => Some(Msg::CloseSaveBookmark),
Event::Keyboard(KeyEvent {
code: Key::Left, ..
}) => {

View File

@@ -368,6 +368,43 @@ impl Component<Msg, NoUserEvent> for RemoteFileFmt {
}
}
#[derive(MockComponent)]
pub struct SshConfig {
component: Input,
}
impl SshConfig {
pub fn new(value: &str) -> Self {
Self {
component: Input::default()
.borders(
Borders::default()
.color(Color::LightBlue)
.modifiers(BorderType::Rounded),
)
.foreground(Color::LightBlue)
.input_type(InputType::Text)
.placeholder(
"~/.ssh/config",
Style::default().fg(Color::Rgb(128, 128, 128)),
)
.title("SSH configuration path", Alignment::Left)
.value(value),
}
}
}
impl Component<Msg, NoUserEvent> for SshConfig {
fn on(&mut self, ev: Event<NoUserEvent>) -> Option<Msg> {
handle_input_ev(
self,
ev,
Msg::Config(ConfigMsg::SshConfigBlurDown),
Msg::Config(ConfigMsg::SshConfigBlurUp),
)
}
}
#[derive(MockComponent)]
pub struct TextEditor {
component: Input,
@@ -448,7 +485,7 @@ fn handle_input_ev(
}
Event::Keyboard(KeyEvent {
code: Key::Char(ch),
modifiers: KeyModifiers::NONE,
modifiers: KeyModifiers::NONE | KeyModifiers::SHIFT,
}) => {
component.perform(Cmd::Type(ch));
Some(Msg::Config(ConfigMsg::ConfigChanged))

View File

@@ -35,7 +35,7 @@ mod theme;
pub(super) use commons::{ErrorPopup, Footer, Header, Keybindings, QuitPopup, SavePopup};
pub(super) use config::{
CheckUpdates, DefaultProtocol, GroupDirs, HiddenFiles, LocalFileFmt, NotificationsEnabled,
NotificationsThreshold, PromptOnFileReplace, RemoteFileFmt, TextEditor,
NotificationsThreshold, PromptOnFileReplace, RemoteFileFmt, SshConfig, TextEditor,
};
pub(super) use ssh::{DelSshKeyPopup, SshHost, SshKeys, SshUsername};
pub(super) use theme::*;

View File

@@ -36,7 +36,10 @@ impl SetupActivity {
pub(super) fn save_config(&mut self) -> Result<(), String> {
match self.config().write_config() {
Ok(_) => Ok(()),
Err(err) => Err(format!("Could not save configuration: {}", err)),
Err(err) => {
error!("Could not save configuration: {}", err);
Err(format!("Could not save configuration: {}", err))
}
}
}

View File

@@ -75,6 +75,7 @@ enum IdConfig {
NotificationsThreshold,
PromptOnFileReplace,
RemoteFileFmt,
SshConfig,
TextEditor,
}
@@ -167,6 +168,8 @@ pub enum ConfigMsg {
PromptOnFileReplaceBlurUp,
RemoteFileFmtBlurDown,
RemoteFileFmtBlurUp,
SshConfigBlurDown,
SshConfigBlurUp,
TextEditorBlurDown,
TextEditorBlurUp,
}

View File

@@ -80,11 +80,13 @@ impl SetupActivity {
CommonMsg::RevertChanges => match self.layout {
ViewLayout::Theme => {
if let Err(err) = self.action_reset_theme() {
error!("Failed to reset theme: {}", err);
self.mount_error(err);
}
}
ViewLayout::SshKeys | ViewLayout::SetupForm => {
if let Err(err) = self.action_reset_config() {
error!("Failed to reset config: {}", err);
self.mount_error(err);
}
}
@@ -92,6 +94,7 @@ impl SetupActivity {
CommonMsg::SaveAndQuit => {
// Save changes
if let Err(err) = self.action_save_all() {
error!("Failed to save config: {}", err);
self.mount_error(err.as_str());
}
// Exit
@@ -99,6 +102,7 @@ impl SetupActivity {
}
CommonMsg::SaveConfig => {
if let Err(err) = self.action_save_all() {
error!("Failed to save config: {}", err);
self.mount_error(err.as_str());
}
self.umount_save_popup();
@@ -173,7 +177,7 @@ impl SetupActivity {
.is_ok());
}
ConfigMsg::NotificationsThresholdBlurDown => {
assert!(self.app.active(&Id::Config(IdConfig::TextEditor)).is_ok());
assert!(self.app.active(&Id::Config(IdConfig::SshConfig)).is_ok());
}
ConfigMsg::NotificationsThresholdBlurUp => {
assert!(self
@@ -203,6 +207,12 @@ impl SetupActivity {
.is_ok());
}
ConfigMsg::TextEditorBlurUp => {
assert!(self.app.active(&Id::Config(IdConfig::SshConfig)).is_ok());
}
ConfigMsg::SshConfigBlurDown => {
assert!(self.app.active(&Id::Config(IdConfig::TextEditor)).is_ok());
}
ConfigMsg::SshConfigBlurUp => {
assert!(self
.app
.active(&Id::Config(IdConfig::NotificationsThreshold))
@@ -230,6 +240,7 @@ impl SetupActivity {
}
SshMsg::EditSshKey(i) => {
if let Err(err) = self.edit_ssh_key(i) {
error!("Failed to edit ssh key: {}", err);
self.mount_error(err.as_str());
}
}

View File

@@ -119,6 +119,7 @@ impl SetupActivity {
Constraint::Length(3), // Remote Format input
Constraint::Length(3), // Notifications enabled
Constraint::Length(3), // Notifications threshold
Constraint::Length(3), // Ssh config
Constraint::Length(1), // Filler
]
.as_ref(),
@@ -144,6 +145,8 @@ impl SetupActivity {
f,
ui_cfg_chunks_col2[3],
);
self.app
.view(&Id::Config(IdConfig::SshConfig), f, ui_cfg_chunks_col2[4]);
// Popups
self.view_popups(f);
});
@@ -261,6 +264,17 @@ impl SetupActivity {
vec![]
)
.is_ok());
// Ssh config
assert!(self
.app
.remount(
Id::Config(IdConfig::SshConfig),
Box::new(components::SshConfig::new(
self.config().get_ssh_config().unwrap_or("")
)),
vec![]
)
.is_ok());
}
/// Collect values from input and put them into the configuration
@@ -332,5 +346,19 @@ impl SetupActivity {
{
self.config_mut().set_notification_threshold(bytes);
}
if let Ok(State::One(StateValue::String(mut path))) =
self.app.state(&Id::Config(IdConfig::SshConfig))
{
if path.is_empty() {
self.config_mut().set_ssh_config(None);
} else {
// Replace '~' with home path
if path.starts_with('~') {
let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from("/root"));
path = path.replacen('~', &home_dir.to_string_lossy(), 1);
}
self.config_mut().set_ssh_config(Some(path));
}
}
}
}