feat(cli): QueryTabNames cli action to list all tab names (#2145)

* extend display char in tab

* Add action to list all tab names

* print tab names and remove logs

* change msg name, and handle Log in normal client

* fix log

* resolve code conflict

* change var name

* add snapshot test

* fix failed test case

* restore snapshot

* Revert "restore snapshot"

This reverts commit b97a9512ab.

* restore snapshot

* revert snapshot

* fix(layout): various parser and ui fixes (#2191)

* fix(layout): error on nodes outside layout node

* fix(layout): move stacked property to pane

* fix(layout): various stack exceptions

* fix(ui): non-flexible stacked pane titles now take up their full length

* fix(ui): stack titles with no-pane-frames take up their proper length

* style(fmt): rustfmt

* docs(changelog): layout fixes

* fix(messaging): cache hold pane messages by their tab_id if the tab is not ready (#2196)

* fix(messaging): cache hold pane messages by their tab_id if the tab is not ready

* style(fmt): rustfmt

* docs(changelog): open panes fix

* fix(layout): tab focus (#2197)

* fix(layout): tab focus

* style(fmt): rustfmt

* docs(changel0g): tab focus fix

* fix(cli): new-tab now also looks in layout_dir for layouts (#2198)

* fix(cli): the new-tab action now also searches for layouts in the layout dir

* style(fmt): rustfmt

* fix(tests): add missing parameter to cli action

* docs(changelog): new-tab cli layout folder fix

* fix(kdl): new-tab keybind looks in layout_dir for layouts (#2200)

* fix(themes): missing tokyo-night-dark theme

* fix(kdl): new-tab keybind also looks in layout_dir for layouts

* docs(changelog): new-tab keybind layout folder fix

* fix(cli): edit cwd (#2201)

* fix(cli): properly set cwd for edit panes

* fix(layouts): properly set cwd for edit panes

* style(fmt): rustfmt

* docs(changelog0

* fix(layouts): do not relayout twice on auto_layout (#2202)

* fix(layouts): do not relayout twice on auto_layout

* style(fmt): rustfmt

* fix(new-tab): get config parameters from config file (#2203)

* fix(cli): take default shell from config if it exists when opening new tab

* fix(cli): take layout dir from config when opening new tab if it exists

* style(fmt): rustfmt

* docs(changelog): new-tab config parameters

* fix(grid): only use background pending styling when deleting characters (#2204)

* docs(changelog): neovim underline fix

* feat(layouts): exact panes constraint (#2206)

* style(fmt): remove warnings

* fix(swap-layouts): introduce exact panes constraint

* fix(swap-layouts): improve floating pane swap layout ux

* style(fmt): rustfmt

* docs(changelog): exact panes constraint

* fix(pty): report no-cwd for empty path returned from sysinfo (#2213)

* fix(sixel): report pixel size in winsize change ioctl (#2212)

* fix(sixel): report pixel size in winsize change ioctl

* style(fmt): rustfmt

* docs(changelog): various fixes

* style(code): naming

* test(log): adjust query tab names test to look at the log message

* style(fmt): rustfmt

---------

Co-authored-by: Aram Drevekenin <aram@poor.dev>
Co-authored-by: Jae-Heon Ji <32578710+jaeheonji@users.noreply.github.com>
This commit is contained in:
哇呜哇呜呀咦耶 2023-03-02 00:28:17 +08:00 committed by GitHub
parent 715ee1109d
commit c2fb275319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 103 additions and 2 deletions

View File

@ -28,6 +28,10 @@ pub fn start_cli_client(os_input: Box<dyn ClientOsApi>, session_name: &str, acti
os_input.send_to_server(ClientToServerMsg::ClientExited);
process::exit(0);
},
Some((ServerToClientMsg::Log(log_lines), _)) => {
log_lines.iter().for_each(|line| println!("{line}"));
process::exit(0);
},
_ => {},
}
}

View File

@ -45,6 +45,7 @@ pub(crate) enum ClientInstruction {
ActiveClients(Vec<ClientId>),
StartedParsingStdinQuery,
DoneParsingStdinQuery,
Log(Vec<String>),
}
impl From<ServerToClientMsg> for ClientInstruction {
@ -58,6 +59,7 @@ impl From<ServerToClientMsg> for ClientInstruction {
},
ServerToClientMsg::Connected => ClientInstruction::Connected,
ServerToClientMsg::ActiveClients(clients) => ClientInstruction::ActiveClients(clients),
ServerToClientMsg::Log(log_lines) => ClientInstruction::Log(log_lines),
}
}
}
@ -72,6 +74,7 @@ impl From<&ClientInstruction> for ClientContext {
ClientInstruction::SwitchToMode(_) => ClientContext::SwitchToMode,
ClientInstruction::Connected => ClientContext::Connected,
ClientInstruction::ActiveClients(_) => ClientContext::ActiveClients,
ClientInstruction::Log(_) => ClientContext::Log,
ClientInstruction::StartedParsingStdinQuery => ClientContext::StartedParsingStdinQuery,
ClientInstruction::DoneParsingStdinQuery => ClientContext::DoneParsingStdinQuery,
}
@ -406,6 +409,11 @@ pub fn start_client(
.send(InputInstruction::SwitchToMode(input_mode))
.unwrap();
},
ClientInstruction::Log(lines_to_log) => {
for line in lines_to_log {
log::info!("{line}");
}
},
_ => {},
}
}

View File

@ -77,6 +77,7 @@ pub enum ServerInstruction {
AttachClient(ClientAttributes, Options, ClientId),
ConnStatus(ClientId),
ActiveClients(ClientId),
Log(Vec<String>, ClientId),
}
impl From<&ServerInstruction> for ServerContext {
@ -93,6 +94,7 @@ impl From<&ServerInstruction> for ServerContext {
ServerInstruction::AttachClient(..) => ServerContext::AttachClient,
ServerInstruction::ConnStatus(..) => ServerContext::ConnStatus,
ServerInstruction::ActiveClients(_) => ServerContext::ActiveClients,
ServerInstruction::Log(..) => ServerContext::Log,
}
}
}
@ -623,6 +625,14 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
session_state
);
},
ServerInstruction::Log(lines_to_log, client_id) => {
send_to_client!(
client_id,
os_input,
ServerToClientMsg::Log(lines_to_log),
session_state
);
},
}
}

View File

@ -659,6 +659,12 @@ pub(crate) fn route_action(
.send_to_screen(ScreenInstruction::NextSwapLayout(client_id))
.with_context(err_context)?;
},
Action::QueryTabNames => {
session
.senders
.send_to_screen(ScreenInstruction::QueryTabNames(client_id))
.with_context(err_context)?;
},
}
Ok(should_break)
}

View File

@ -248,6 +248,7 @@ pub enum ScreenInstruction {
ClearPaneFrameColorOverride(Vec<PaneId>),
PreviousSwapLayout(ClientId),
NextSwapLayout(ClientId),
QueryTabNames(ClientId),
}
impl From<&ScreenInstruction> for ScreenContext {
@ -390,6 +391,7 @@ impl From<&ScreenInstruction> for ScreenContext {
},
ScreenInstruction::PreviousSwapLayout(..) => ScreenContext::PreviousSwapLayout,
ScreenInstruction::NextSwapLayout(..) => ScreenContext::NextSwapLayout,
ScreenInstruction::QueryTabNames(..) => ScreenContext::QueryTabNames,
}
}
}
@ -1171,7 +1173,7 @@ impl Screen {
},
c => {
// It only allows printable unicode
if buf.iter().all(|u| matches!(u, 0x20..=0x7E | 0x80..=0xFF)) {
if buf.iter().all(|u| matches!(u, 0x20..=0x7E | 0xA0..=0xFF)) {
active_tab.name.push_str(c);
}
},
@ -2360,6 +2362,17 @@ pub(crate) fn screen_thread_main(
screen.update_tabs()?;
screen.unblock_input()?;
},
ScreenInstruction::QueryTabNames(client_id) => {
let tab_names = screen
.get_tabs_mut()
.values()
.map(|tab| tab.name.clone())
.collect::<Vec<String>>();
screen
.bus
.senders
.send_to_server(ServerInstruction::Log(tab_names, client_id))?;
},
}
}
Ok(())

View File

@ -3082,7 +3082,7 @@ impl Tab {
// It only allows printable unicode, delete and backspace keys.
let is_updatable = buf
.iter()
.all(|u| matches!(u, 0x20..=0x7E | 0x80..=0xFF | 0x08 | 0x7F));
.all(|u| matches!(u, 0x20..=0x7E | 0xA0..=0xFF | 0x08 | 0x7F));
if is_updatable {
let s = str::from_utf8(&buf).with_context(err_context)?;
active_terminal.update_name(s);

View File

@ -2674,3 +2674,39 @@ pub fn send_cli_undo_rename_tab() {
*received_plugin_instructions.lock().unwrap()
))
}
#[test]
pub fn send_cli_query_tab_names_action() {
let size = Size { cols: 80, rows: 10 };
let client_id = 10; // fake client id should not appear in the screen's state
let mut mock_screen = MockScreen::new(size);
mock_screen.new_tab(TiledPaneLayout::default());
let session_metadata = mock_screen.clone_session_metadata();
let screen_thread = mock_screen.run(Some(TiledPaneLayout::default()));
let received_server_instructions = Arc::new(Mutex::new(vec![]));
let server_receiver = mock_screen.server_receiver.take().unwrap();
let server_thread = log_actions_in_thread!(
received_server_instructions,
ServerInstruction::KillSession,
server_receiver
);
let query_tab_names = CliAction::QueryTabNames;
send_cli_action_to_server(
&session_metadata,
query_tab_names,
&mut mock_screen,
client_id,
);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![server_thread, screen_thread]);
let log_tab_names_instruction = received_server_instructions
.lock()
.unwrap()
.iter()
.find(|instruction| match instruction {
ServerInstruction::Log(..) => true,
_ => false,
})
.cloned();
assert_snapshot!(format!("{:#?}", log_tab_names_instruction));
}

View File

@ -0,0 +1,14 @@
---
source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 2713
expression: "format!(\"{:#?}\", log_tab_names_action)"
---
Some(
Log(
[
"Tab #1",
"Tab #2",
],
10,
),
)

View File

@ -366,4 +366,6 @@ pub enum CliAction {
},
PreviousSwapLayout,
NextSwapLayout,
/// Query all tab names
QueryTabNames,
}

View File

@ -323,6 +323,7 @@ pub enum ScreenContext {
ClearPaneFrameColorOverride,
PreviousSwapLayout,
NextSwapLayout,
QueryTabNames,
}
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
@ -366,6 +367,7 @@ pub enum ClientContext {
SwitchToMode,
Connected,
ActiveClients,
Log,
OwnClientId,
StartedParsingStdinQuery,
DoneParsingStdinQuery,
@ -385,6 +387,7 @@ pub enum ServerContext {
AttachClient,
ConnStatus,
ActiveClients,
Log,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]

View File

@ -223,6 +223,8 @@ pub enum Action {
ToggleMouseMode,
PreviousSwapLayout,
NextSwapLayout,
/// Query all tab names
QueryTabNames,
}
impl Action {
@ -456,6 +458,7 @@ impl Action {
},
CliAction::PreviousSwapLayout => Ok(vec![Action::PreviousSwapLayout]),
CliAction::NextSwapLayout => Ok(vec![Action::NextSwapLayout]),
CliAction::QueryTabNames => Ok(vec![Action::QueryTabNames]),
}
}
}

View File

@ -1943,6 +1943,7 @@ fn cannot_define_stacked_panes_with_grandchildren_in_pane_template() {
assert!(layout.is_err(), "error provided for tab name with space");
}
#[test]
fn run_plugin_location_parsing() {
let kdl_layout = r#"
layout {

View File

@ -109,6 +109,7 @@ pub enum ServerToClientMsg {
SwitchToMode(InputMode),
Connected,
ActiveClients(Vec<ClientId>),
Log(Vec<String>),
}
#[derive(Serialize, Deserialize, Debug, Clone)]