summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/os_input_output.rs
diff options
context:
space:
mode:
authorCosmin Popescu <cosminadrianpopescu@gmail.com>2022-06-06 09:20:07 +0200
committerGitHub <noreply@github.com>2022-06-06 09:20:07 +0200
commite1fcf3a6dbc7a65a341127fab2fca7b4fb2d081b (patch)
treeec1061b57347348f081d64c532f7fc12ff21c4dd /zellij-server/src/os_input_output.rs
parent58cc8fb2e1a091dca72fdbaf9150b200e130fa73 (diff)
feat(scroll): edit scrollback with default editor (#1456)
* initial commit for opening the current buffer in an editor * fix(editor): take hidden panes into consideration when manipulating tiled grid * when closing an edit buffer, take the geometry of the replaced buffer from the closed buffer * if the floating panels are displayed, don't add to hidden panels the current buffer * strategy changing - put the panels inside a suppressed_panels HashMap instead of hidden_panels * Revert "strategy changing - put the panels inside a suppressed_panels HashMap instead of hidden_panels" This reverts commit c52a203a20cf4c87c147be8b9c193ed6458c1038. * remove the floating panes by moving them to the tiled_panes in hidden_panels * feat(edit): open editor to correct line and don't crash when none is set * formatting * feat(edit): use suppressed panes * style(fmt): rustfmt and logs * style(fmt): clean up unused code * test(editor): integration test for suppressing/closing suppressed pane * test(e2e): editor e2e test * style(fmt): rustfmt * feat(edit): update ui and setup * style(fmt): rustfmt * feat(config): allow configuring scrollback_editor explicitly * style(fmt): rustfmt * chore(repo): build after merging Co-authored-by: Aram Drevekenin <aram@poor.dev>
Diffstat (limited to 'zellij-server/src/os_input_output.rs')
-rw-r--r--zellij-server/src/os_input_output.rs69
1 files changed, 54 insertions, 15 deletions
diff --git a/zellij-server/src/os_input_output.rs b/zellij-server/src/os_input_output.rs
index 1e43e47fa..b757ad460 100644
--- a/zellij-server/src/os_input_output.rs
+++ b/zellij-server/src/os_input_output.rs
@@ -145,6 +145,7 @@ fn handle_openpty(
///
fn handle_terminal(
cmd: RunCommand,
+ failover_cmd: Option<RunCommand>,
orig_termios: termios::Termios,
quit_cb: Box<dyn Fn(PaneId) + Send>,
) -> (RawFd, RawFd) {
@@ -152,9 +153,12 @@ fn handle_terminal(
// parent.
match openpty(None, Some(&orig_termios)) {
Ok(open_pty_res) => handle_openpty(open_pty_res, cmd, quit_cb),
- Err(e) => {
- panic!("failed to start pty{:?}", e);
- }
+ Err(e) => match failover_cmd {
+ Some(failover_cmd) => handle_terminal(failover_cmd, None, orig_termios, quit_cb),
+ None => {
+ panic!("failed to start pty{:?}", e);
+ }
+ },
}
}
@@ -174,19 +178,40 @@ pub fn spawn_terminal(
terminal_action: TerminalAction,
orig_termios: termios::Termios,
quit_cb: Box<dyn Fn(PaneId) + Send>,
-) -> (RawFd, RawFd) {
+ default_editor: Option<PathBuf>,
+) -> Result<(RawFd, RawFd), &'static str> {
+ let mut failover_cmd_args = None;
let cmd = match terminal_action {
- TerminalAction::OpenFile(file_to_open) => {
- if env::var("EDITOR").is_err() && env::var("VISUAL").is_err() {
- panic!("Can't edit files if an editor is not defined. To fix: define the EDITOR or VISUAL environment variables with the path to your editor (eg. /usr/bin/vim)");
+ TerminalAction::OpenFile(file_to_open, line_number) => {
+ if default_editor.is_none()
+ && env::var("EDITOR").is_err()
+ && env::var("VISUAL").is_err()
+ {
+ return Err(
+ "No Editor found, consider setting a path to one in $EDITOR or $VISUAL",
+ );
}
- let command =
- PathBuf::from(env::var("EDITOR").unwrap_or_else(|_| env::var("VISUAL").unwrap()));
+ let command = default_editor.unwrap_or_else(|| {
+ PathBuf::from(env::var("EDITOR").unwrap_or_else(|_| env::var("VISUAL").unwrap()))
+ });
- let args = vec![file_to_open
+ let mut args = vec![];
+ let file_to_open = file_to_open
.into_os_string()
.into_string()
- .expect("Not valid Utf8 Encoding")];
+ .expect("Not valid Utf8 Encoding");
+ if let Some(line_number) = line_number {
+ if command.ends_with("vim")
+ || command.ends_with("nvim")
+ || command.ends_with("emacs")
+ || command.ends_with("nano")
+ || command.ends_with("kak")
+ {
+ failover_cmd_args = Some(vec![file_to_open.clone()]);
+ args.push(format!("+{}", line_number));
+ }
+ }
+ args.push(file_to_open);
RunCommand {
command,
args,
@@ -195,8 +220,15 @@ pub fn spawn_terminal(
}
TerminalAction::RunCommand(command) => command,
};
+ let failover_cmd = if let Some(failover_cmd_args) = failover_cmd_args {
+ let mut cmd = cmd.clone();
+ cmd.args = failover_cmd_args;
+ Some(cmd)
+ } else {
+ None
+ };
- handle_terminal(cmd, orig_termios, quit_cb)
+ Ok(handle_terminal(cmd, failover_cmd, orig_termios, quit_cb))
}
#[derive(Clone)]
@@ -245,7 +277,8 @@ pub trait ServerOsApi: Send + Sync {
&self,
terminal_action: TerminalAction,
quit_cb: Box<dyn Fn(PaneId) + Send>,
- ) -> (RawFd, RawFd);
+ default_editor: Option<PathBuf>,
+ ) -> Result<(RawFd, RawFd), &'static str>;
/// Read bytes from the standard output of the virtual terminal referred to by `fd`.
fn read_from_tty_stdout(&self, fd: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>;
/// Creates an `AsyncReader` that can be used to read from `fd` in an async context
@@ -284,9 +317,15 @@ impl ServerOsApi for ServerOsInputOutput {
&self,
terminal_action: TerminalAction,
quit_cb: Box<dyn Fn(PaneId) + Send>,
- ) -> (RawFd, RawFd) {
+ default_editor: Option<PathBuf>,
+ ) -> Result<(RawFd, RawFd), &'static str> {
let orig_termios = self.orig_termios.lock().unwrap();
- spawn_terminal(terminal_action, orig_termios.clone(), quit_cb)
+ spawn_terminal(
+ terminal_action,
+ orig_termios.clone(),
+ quit_cb,
+ default_editor,
+ )
}
fn read_from_tty_stdout(&self, fd: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error> {
unistd::read(fd, buf)