Finished terminal refactoring
This commit is contained in:
parent
119207a9e5
commit
a41e54f3dc
2 changed files with 75 additions and 39 deletions
|
@ -60,10 +60,9 @@ pub struct TerminalError {
|
||||||
pub source: std::io::Error,
|
pub source: std::io::Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for TerminalError {
|
impl TerminalError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
pub fn fmt_directory(&self) -> String {
|
||||||
let dir_string: String = self
|
self.directory
|
||||||
.directory
|
|
||||||
.clone()
|
.clone()
|
||||||
.map(|path| {
|
.map(|path| {
|
||||||
match path
|
match path
|
||||||
|
@ -79,13 +78,22 @@ impl Display for TerminalError {
|
||||||
let default_dir =
|
let default_dir =
|
||||||
dirs::home_dir().map(|buf| buf.into_os_string().to_string_lossy().to_string());
|
dirs::home_dir().map(|buf| buf.into_os_string().to_string_lossy().to_string());
|
||||||
match default_dir {
|
match default_dir {
|
||||||
Some(dir) => format!("<none specified, using home> {}", dir),
|
Some(dir) => format!("<none specified, using home directory> {}", dir),
|
||||||
None => "<none specified, could not find home>".to_string(),
|
None => "<none specified, could not find home directory>".to_string(),
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
let shell = self
|
pub fn shell_to_string(&self) -> Option<String> {
|
||||||
.shell
|
self.shell.as_ref().map(|shell| match shell {
|
||||||
|
Shell::System => "<system shell>".to_string(),
|
||||||
|
Shell::Program(p) => p.to_string(),
|
||||||
|
Shell::WithArguments { program, args } => format!("{} {}", program, args.join(" ")),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fmt_shell(&self) -> String {
|
||||||
|
self.shell
|
||||||
.clone()
|
.clone()
|
||||||
.map(|shell| match shell {
|
.map(|shell| match shell {
|
||||||
Shell::System => {
|
Shell::System => {
|
||||||
|
@ -94,7 +102,7 @@ impl Display for TerminalError {
|
||||||
|
|
||||||
match pw {
|
match pw {
|
||||||
Some(pw) => format!("<system defined shell> {}", pw.shell),
|
Some(pw) => format!("<system defined shell> {}", pw.shell),
|
||||||
None => "<could not access system defined shell>".to_string(),
|
None => "<could not access the password file>".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Shell::Program(s) => s,
|
Shell::Program(s) => s,
|
||||||
|
@ -107,11 +115,17 @@ impl Display for TerminalError {
|
||||||
Some(pw) => {
|
Some(pw) => {
|
||||||
format!("<none specified, using system defined shell> {}", pw.shell)
|
format!("<none specified, using system defined shell> {}", pw.shell)
|
||||||
}
|
}
|
||||||
None => {
|
None => "<none specified, could not access the password file> {}".to_string(),
|
||||||
"<none specified, could not access system defined shell> {}".to_string()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for TerminalError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let dir_string: String = self.fmt_directory();
|
||||||
|
|
||||||
|
let shell = self.fmt_shell();
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
@ -210,7 +224,6 @@ impl TerminalBuilder {
|
||||||
pty_tx: Notifier(pty_tx),
|
pty_tx: Notifier(pty_tx),
|
||||||
term,
|
term,
|
||||||
title: shell_txt.to_string(),
|
title: shell_txt.to_string(),
|
||||||
associated_directory: working_directory,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(TerminalBuilder {
|
Ok(TerminalBuilder {
|
||||||
|
@ -245,7 +258,6 @@ pub struct Terminal {
|
||||||
pty_tx: Notifier,
|
pty_tx: Notifier,
|
||||||
term: Arc<FairMutex<Term<ZedListener>>>,
|
term: Arc<FairMutex<Term<ZedListener>>>,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub associated_directory: Option<PathBuf>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Terminal {
|
impl Terminal {
|
||||||
|
|
|
@ -58,6 +58,7 @@ impl TerminalContent {
|
||||||
pub struct TerminalView {
|
pub struct TerminalView {
|
||||||
modal: bool,
|
modal: bool,
|
||||||
content: TerminalContent,
|
content: TerminalContent,
|
||||||
|
associated_directory: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ErrorView {
|
pub struct ErrorView {
|
||||||
|
@ -98,7 +99,8 @@ impl TerminalView {
|
||||||
let shell = settings.terminal_overrides.shell.clone();
|
let shell = settings.terminal_overrides.shell.clone();
|
||||||
let envs = settings.terminal_overrides.env.clone(); //Should be short and cheap.
|
let envs = settings.terminal_overrides.env.clone(); //Should be short and cheap.
|
||||||
|
|
||||||
let content = match TerminalBuilder::new(working_directory, shell, envs, size_info) {
|
let content = match TerminalBuilder::new(working_directory.clone(), shell, envs, size_info)
|
||||||
|
{
|
||||||
Ok(terminal) => {
|
Ok(terminal) => {
|
||||||
let terminal = cx.add_model(|cx| terminal.subscribe(cx));
|
let terminal = cx.add_model(|cx| terminal.subscribe(cx));
|
||||||
let view = cx.add_view(|cx| ConnectedView::from_terminal(terminal, modal, cx));
|
let view = cx.add_view(|cx| ConnectedView::from_terminal(terminal, modal, cx));
|
||||||
|
@ -115,7 +117,11 @@ impl TerminalView {
|
||||||
};
|
};
|
||||||
cx.focus(content.handle());
|
cx.focus(content.handle());
|
||||||
|
|
||||||
TerminalView { modal, content }
|
TerminalView {
|
||||||
|
modal,
|
||||||
|
content,
|
||||||
|
associated_directory: working_directory,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_terminal(
|
fn from_terminal(
|
||||||
|
@ -127,6 +133,7 @@ impl TerminalView {
|
||||||
TerminalView {
|
TerminalView {
|
||||||
modal,
|
modal,
|
||||||
content: TerminalContent::Connected(connected_view),
|
content: TerminalContent::Connected(connected_view),
|
||||||
|
associated_directory: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,16 +183,39 @@ impl View for ErrorView {
|
||||||
let settings = cx.global::<Settings>();
|
let settings = cx.global::<Settings>();
|
||||||
let style = TerminalEl::make_text_style(cx.font_cache(), settings);
|
let style = TerminalEl::make_text_style(cx.font_cache(), settings);
|
||||||
|
|
||||||
Label::new(
|
//TODO:
|
||||||
format!(
|
//We want markdown style highlighting so we can format the program and working directory with ``
|
||||||
"Failed to open the terminal. Info: \n{}",
|
//We want a max-width of 75% with word-wrap
|
||||||
self.error.to_string()
|
//We want to be able to select the text
|
||||||
),
|
//Want to be able to scroll if the error message is massive somehow (resiliency)
|
||||||
style,
|
|
||||||
)
|
let program_text = {
|
||||||
.aligned()
|
match self.error.shell_to_string() {
|
||||||
.contained()
|
Some(shell_txt) => format!("Shell Program: `{}`", shell_txt),
|
||||||
.boxed()
|
None => "No program specified".to_string(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let directory_text = {
|
||||||
|
match self.error.directory.as_ref() {
|
||||||
|
Some(path) => format!("Working directory: `{}`", path.to_string_lossy()),
|
||||||
|
None => "No working directory specified".to_string(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let error_text = self.error.source.to_string();
|
||||||
|
|
||||||
|
Flex::column()
|
||||||
|
.with_child(
|
||||||
|
Text::new("Failed to open the terminal.".to_string(), style.clone())
|
||||||
|
.contained()
|
||||||
|
.boxed(),
|
||||||
|
)
|
||||||
|
.with_child(Text::new(program_text, style.clone()).contained().boxed())
|
||||||
|
.with_child(Text::new(directory_text, style.clone()).contained().boxed())
|
||||||
|
.with_child(Text::new(error_text, style.clone()).contained().boxed())
|
||||||
|
.aligned()
|
||||||
|
.boxed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,17 +247,11 @@ impl Item for TerminalView {
|
||||||
//From what I can tell, there's no way to tell the current working
|
//From what I can tell, there's no way to tell the current working
|
||||||
//Directory of the terminal from outside the shell. There might be
|
//Directory of the terminal from outside the shell. There might be
|
||||||
//solutions to this, but they are non-trivial and require more IPC
|
//solutions to this, but they are non-trivial and require more IPC
|
||||||
if let TerminalContent::Connected(connected) = &self.content {
|
Some(TerminalView::new(
|
||||||
let associated_directory = connected
|
self.associated_directory.clone(),
|
||||||
.read(cx)
|
false,
|
||||||
.handle()
|
cx,
|
||||||
.read(cx)
|
))
|
||||||
.associated_directory
|
|
||||||
.clone();
|
|
||||||
Some(TerminalView::new(associated_directory, false, cx))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn project_path(&self, _cx: &gpui::AppContext) -> Option<ProjectPath> {
|
fn project_path(&self, _cx: &gpui::AppContext) -> Option<ProjectPath> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue