feat(ui): configuration screen + configure non-colliding keys at runtime (#3502)
* rebind => reconfigure * persist keybinds and mode info to new tabs * add configuration plugin * make tests pass * remove warnings * style(fmt): rustfmt
This commit is contained in:
parent
f6ec1a1385
commit
84ff29dd02
46 changed files with 3066 additions and 95 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
|
@ -749,6 +749,15 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "configuration"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"chrono",
|
||||
"zellij-tile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.15.0"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ members = [
|
|||
"default-plugins/tab-bar",
|
||||
"default-plugins/fixture-plugin-for-tests",
|
||||
"default-plugins/session-manager",
|
||||
"default-plugins/configuration",
|
||||
"zellij-client",
|
||||
"zellij-server",
|
||||
"zellij-utils",
|
||||
|
|
|
|||
2
default-plugins/configuration/.cargo/config.toml
Normal file
2
default-plugins/configuration/.cargo/config.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[build]
|
||||
target = "wasm32-wasi"
|
||||
1
default-plugins/configuration/.gitignore
vendored
Normal file
1
default-plugins/configuration/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
11
default-plugins/configuration/Cargo.toml
Normal file
11
default-plugins/configuration/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "configuration"
|
||||
version = "0.1.0"
|
||||
authors = ["Aram Drevekenin <aram@poor.dev>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
ansi_term = "0.12.1"
|
||||
zellij-tile = { path = "../../zellij-tile" }
|
||||
chrono = "0.4.0"
|
||||
1
default-plugins/configuration/LICENSE.md
Symbolic link
1
default-plugins/configuration/LICENSE.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../LICENSE.md
|
||||
1987
default-plugins/configuration/src/main.rs
Normal file
1987
default-plugins/configuration/src/main.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -56,7 +56,7 @@ impl ZellijPlugin for State {
|
|||
PermissionType::WebAccess,
|
||||
PermissionType::ReadCliPipes,
|
||||
PermissionType::MessageAndLaunchOtherPlugins,
|
||||
PermissionType::RebindKeys,
|
||||
PermissionType::Reconfigure,
|
||||
]);
|
||||
self.configuration = configuration;
|
||||
subscribe(&[
|
||||
|
|
@ -320,7 +320,7 @@ impl ZellijPlugin for State {
|
|||
);
|
||||
},
|
||||
BareKey::Char('0') if key.has_modifiers(&[KeyModifier::Ctrl]) => {
|
||||
rebind_keys(
|
||||
reconfigure(
|
||||
"
|
||||
keybinds {
|
||||
locked {
|
||||
|
|
|
|||
|
|
@ -1265,6 +1265,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<KeyWithModifier
|
|||
]} else if mi.mode == IM::Session { vec![
|
||||
(s("Detach"), s("Detach"), action_key(&km, &[Action::Detach])),
|
||||
(s("Session Manager"), s("Manager"), session_manager_key(&km)),
|
||||
(s("Configure"), s("Config"), configuration_key(&km)),
|
||||
(s("Select pane"), s("Select"), to_basemode_key),
|
||||
]} else if mi.mode == IM::Tmux { vec![
|
||||
(s("Move focus"), s("Move"), action_key_group(&km, &[
|
||||
|
|
@ -1355,6 +1356,25 @@ fn session_manager_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWith
|
|||
}
|
||||
}
|
||||
|
||||
fn configuration_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithModifier> {
|
||||
let mut matching = keymap.iter().find_map(|(key, acvec)| {
|
||||
let has_match = acvec
|
||||
.iter()
|
||||
.find(|a| a.launches_plugin("configuration"))
|
||||
.is_some();
|
||||
if has_match {
|
||||
Some(key.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
if let Some(matching) = matching.take() {
|
||||
vec![matching]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<usize>) -> LinePart {
|
||||
if keyvec.is_empty() {
|
||||
return LinePart::default();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: src/tests/e2e/cases.rs
|
||||
assertion_line: 1050
|
||||
assertion_line: 1064
|
||||
expression: last_snapshot
|
||||
---
|
||||
Zellij (e2e-test) Tab #1
|
||||
|
|
@ -26,4 +26,4 @@ expression: last_snapshot
|
|||
│ ││ │
|
||||
│ ││ │
|
||||
└────────────────────────────────────────────────┘└────────────────────────────────────────────────┘
|
||||
Ctrl + g p t n h s o q Alt + <n> New Pane <←↓↑→> Change Focus
|
||||
Ctrl + g p t n h s o q Alt + <n> New <←↓↑→> Focus <f> Floating
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: src/tests/e2e/cases.rs
|
||||
assertion_line: 2349
|
||||
assertion_line: 2372
|
||||
expression: last_snapshot
|
||||
---
|
||||
Zellij (e2e-test) Tab #1 Alt <[]> VERTICAL
|
||||
|
|
@ -26,4 +26,4 @@ expression: last_snapshot
|
|||
│ ││ │
|
||||
│ ││ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘└ [ EXIT CODE: 0 ] <ENTER> re-run, <ESC> drop to shell, <Ctrl-c> exit ────┘
|
||||
Ctrl + <g> LOCK <p> PANE <t> TAB <n> RESIZE <h> MOVE <s> SEARCH <o> SESSION <q> QUIT Alt + <n> New <←↓↑→> Focus
|
||||
Ctrl + <g> LOCK <p> PANE <t> TAB <n> RESIZE <h> MOVE <s> SEARCH <o> SESSION <q> QUIT
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ lazy_static::lazy_static! {
|
|||
WorkspaceMember{crate_name: "default-plugins/tab-bar", build: true},
|
||||
WorkspaceMember{crate_name: "default-plugins/fixture-plugin-for-tests", build: true},
|
||||
WorkspaceMember{crate_name: "default-plugins/session-manager", build: true},
|
||||
WorkspaceMember{crate_name: "default-plugins/configuration", build: true},
|
||||
WorkspaceMember{crate_name: "zellij-utils", build: false},
|
||||
WorkspaceMember{crate_name: "zellij-tile-utils", build: false},
|
||||
WorkspaceMember{crate_name: "zellij-tile", build: false},
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ pub enum ServerInstruction {
|
|||
DisconnectAllClientsExcept(ClientId),
|
||||
ChangeMode(ClientId, InputMode),
|
||||
ChangeModeForAllClients(InputMode),
|
||||
RebindKeys(ClientId, String), // String -> stringified keybindings
|
||||
Reconfigure(ClientId, String), // String -> stringified configuration
|
||||
}
|
||||
|
||||
impl From<&ServerInstruction> for ServerContext {
|
||||
|
|
@ -129,7 +129,7 @@ impl From<&ServerInstruction> for ServerContext {
|
|||
ServerInstruction::ChangeModeForAllClients(..) => {
|
||||
ServerContext::ChangeModeForAllClients
|
||||
},
|
||||
ServerInstruction::RebindKeys(..) => ServerContext::RebindKeys,
|
||||
ServerInstruction::Reconfigure(..) => ServerContext::Reconfigure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ pub(crate) struct SessionMetaData {
|
|||
pub config_options: Box<Options>,
|
||||
pub client_keybinds: HashMap<ClientId, Keybinds>,
|
||||
pub client_input_modes: HashMap<ClientId, InputMode>,
|
||||
pub default_mode: InputMode,
|
||||
pub default_mode: HashMap<ClientId, InputMode>,
|
||||
screen_thread: Option<thread::JoinHandle<()>>,
|
||||
pty_thread: Option<thread::JoinHandle<()>>,
|
||||
plugin_thread: Option<thread::JoinHandle<()>>,
|
||||
|
|
@ -570,6 +570,10 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
|
|||
default_mode,
|
||||
&attrs,
|
||||
session_data.capabilities,
|
||||
session_data
|
||||
.client_keybinds
|
||||
.get(&client_id)
|
||||
.unwrap_or(&session_data.client_attributes.keybinds),
|
||||
Some(default_mode),
|
||||
);
|
||||
session_data
|
||||
|
|
@ -911,24 +915,57 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
|
|||
.unwrap()
|
||||
.change_mode_for_all_clients(input_mode);
|
||||
},
|
||||
ServerInstruction::RebindKeys(client_id, new_keybinds) => {
|
||||
ServerInstruction::Reconfigure(client_id, new_config) => {
|
||||
let mut new_default_mode = None;
|
||||
match Options::from_string(&new_config) {
|
||||
Ok(mut new_config_options) => {
|
||||
if let Some(default_mode) = new_config_options.default_mode.take() {
|
||||
new_default_mode = Some(default_mode);
|
||||
session_data
|
||||
.write()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.default_mode
|
||||
.insert(client_id, default_mode);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to parse config: {}", e);
|
||||
},
|
||||
}
|
||||
|
||||
let new_keybinds = session_data
|
||||
.write()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.rebind_keys(client_id, new_keybinds)
|
||||
.rebind_keys(client_id, new_config)
|
||||
.clone();
|
||||
if let Some(new_keybinds) = new_keybinds {
|
||||
session_data
|
||||
.write()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::RebindKeys(new_keybinds, client_id))
|
||||
.send_to_screen(ScreenInstruction::Reconfigure {
|
||||
client_id,
|
||||
keybinds: new_keybinds.clone(),
|
||||
default_mode: new_default_mode,
|
||||
})
|
||||
.unwrap();
|
||||
session_data
|
||||
.write()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.senders
|
||||
.send_to_plugin(PluginInstruction::Reconfigure {
|
||||
client_id,
|
||||
keybinds: new_keybinds,
|
||||
default_mode: new_default_mode,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -1167,7 +1204,7 @@ fn init_session(
|
|||
plugin_thread: Some(plugin_thread),
|
||||
pty_writer_thread: Some(pty_writer_thread),
|
||||
background_jobs_thread: Some(background_jobs_thread),
|
||||
default_mode,
|
||||
default_mode: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use zellij_utils::{
|
|||
errors::{prelude::*, ContextType, PluginContext},
|
||||
input::{
|
||||
command::TerminalAction,
|
||||
keybinds::Keybinds,
|
||||
layout::{FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginOrAlias, TiledPaneLayout},
|
||||
plugins::PluginAliases,
|
||||
},
|
||||
|
|
@ -142,6 +143,11 @@ pub enum PluginInstruction {
|
|||
message: MessageToPlugin,
|
||||
},
|
||||
UnblockCliPipes(Vec<PluginRenderAsset>),
|
||||
Reconfigure {
|
||||
client_id: ClientId,
|
||||
keybinds: Option<Keybinds>,
|
||||
default_mode: Option<InputMode>,
|
||||
},
|
||||
WatchFilesystem,
|
||||
Exit,
|
||||
}
|
||||
|
|
@ -182,6 +188,7 @@ impl From<&PluginInstruction> for PluginContext {
|
|||
PluginInstruction::WatchFilesystem => PluginContext::WatchFilesystem,
|
||||
PluginInstruction::KeybindPipe { .. } => PluginContext::KeybindPipe,
|
||||
PluginInstruction::DumpLayoutToPlugin(..) => PluginContext::DumpLayoutToPlugin,
|
||||
PluginInstruction::Reconfigure { .. } => PluginContext::Reconfigure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -734,6 +741,15 @@ pub(crate) fn plugin_thread_main(
|
|||
.context("failed to unblock input pipe");
|
||||
}
|
||||
},
|
||||
PluginInstruction::Reconfigure {
|
||||
client_id,
|
||||
keybinds,
|
||||
default_mode,
|
||||
} => {
|
||||
wasm_bridge
|
||||
.reconfigure(client_id, keybinds, default_mode)
|
||||
.non_fatal();
|
||||
},
|
||||
PluginInstruction::WatchFilesystem => {
|
||||
wasm_bridge.start_fs_watcher_if_not_started();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use zellij_utils::{
|
|||
data::{InputMode, PluginCapabilities},
|
||||
errors::prelude::*,
|
||||
input::command::TerminalAction,
|
||||
input::keybinds::Keybinds,
|
||||
input::layout::Layout,
|
||||
input::plugins::PluginConfig,
|
||||
ipc::ClientAttributes,
|
||||
|
|
@ -69,6 +70,7 @@ pub struct PluginLoader<'a> {
|
|||
default_layout: Box<Layout>,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: Option<Keybinds>,
|
||||
}
|
||||
|
||||
impl<'a> PluginLoader<'a> {
|
||||
|
|
@ -89,6 +91,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout: Box<Layout>,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: &HashMap<ClientId, Keybinds>,
|
||||
) -> Result<()> {
|
||||
let err_context = || format!("failed to reload plugin {plugin_id} from memory");
|
||||
let mut connected_clients: Vec<ClientId> =
|
||||
|
|
@ -97,6 +100,7 @@ impl<'a> PluginLoader<'a> {
|
|||
return Err(anyhow!("No connected clients, cannot reload plugin"));
|
||||
}
|
||||
let first_client_id = connected_clients.remove(0);
|
||||
let keybinds = keybinds.get(&first_client_id).cloned();
|
||||
|
||||
let mut plugin_loader = PluginLoader::new_from_existing_plugin_attributes(
|
||||
&plugin_cache,
|
||||
|
|
@ -115,6 +119,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout,
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds,
|
||||
)?;
|
||||
plugin_loader
|
||||
.load_module_from_memory()
|
||||
|
|
@ -152,6 +157,7 @@ impl<'a> PluginLoader<'a> {
|
|||
skip_cache: bool,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: Option<Keybinds>,
|
||||
) -> Result<()> {
|
||||
let err_context = || format!("failed to start plugin {plugin_id} for client {client_id}");
|
||||
let mut plugin_loader = PluginLoader::new(
|
||||
|
|
@ -173,6 +179,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout,
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds,
|
||||
)?;
|
||||
if skip_cache {
|
||||
plugin_loader
|
||||
|
|
@ -226,6 +233,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout: Box<Layout>,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: Option<Keybinds>,
|
||||
) -> Result<()> {
|
||||
let mut new_plugins = HashSet::new();
|
||||
for plugin_id in plugin_map.lock().unwrap().plugin_ids() {
|
||||
|
|
@ -249,6 +257,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout.clone(),
|
||||
layout_dir.clone(),
|
||||
default_mode,
|
||||
keybinds.clone(),
|
||||
)?;
|
||||
plugin_loader
|
||||
.load_module_from_memory()
|
||||
|
|
@ -278,6 +287,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout: Box<Layout>,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: &HashMap<ClientId, Keybinds>,
|
||||
) -> Result<()> {
|
||||
let err_context = || format!("failed to reload plugin id {plugin_id}");
|
||||
|
||||
|
|
@ -287,6 +297,7 @@ impl<'a> PluginLoader<'a> {
|
|||
return Err(anyhow!("No connected clients, cannot reload plugin"));
|
||||
}
|
||||
let first_client_id = connected_clients.remove(0);
|
||||
let keybinds = keybinds.get(&first_client_id).cloned();
|
||||
|
||||
let mut plugin_loader = PluginLoader::new_from_existing_plugin_attributes(
|
||||
&plugin_cache,
|
||||
|
|
@ -305,6 +316,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout,
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds,
|
||||
)?;
|
||||
plugin_loader
|
||||
.compile_module()
|
||||
|
|
@ -338,6 +350,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout: Box<Layout>,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: Option<Keybinds>,
|
||||
) -> Result<Self> {
|
||||
let plugin_own_data_dir = ZELLIJ_SESSION_CACHE_DIR
|
||||
.join(Url::from(&plugin.location).to_string())
|
||||
|
|
@ -366,6 +379,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout,
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds,
|
||||
})
|
||||
}
|
||||
pub fn new_from_existing_plugin_attributes(
|
||||
|
|
@ -385,6 +399,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout: Box<Layout>,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: Option<Keybinds>,
|
||||
) -> Result<Self> {
|
||||
let err_context = || "Failed to find existing plugin";
|
||||
let (running_plugin, _subscriptions, _workers) = {
|
||||
|
|
@ -420,6 +435,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout,
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds,
|
||||
)
|
||||
}
|
||||
pub fn new_from_different_client_id(
|
||||
|
|
@ -439,6 +455,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout: Box<Layout>,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: Option<Keybinds>,
|
||||
) -> Result<Self> {
|
||||
let err_context = || "Failed to find existing plugin";
|
||||
let running_plugin = {
|
||||
|
|
@ -475,6 +492,7 @@ impl<'a> PluginLoader<'a> {
|
|||
default_layout,
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds,
|
||||
)
|
||||
}
|
||||
pub fn load_module_from_memory(&mut self) -> Result<Module> {
|
||||
|
|
@ -731,6 +749,7 @@ impl<'a> PluginLoader<'a> {
|
|||
self.default_layout.clone(),
|
||||
self.layout_dir.clone(),
|
||||
self.default_mode,
|
||||
self.keybinds.clone(),
|
||||
)?;
|
||||
plugin_loader_for_client
|
||||
.load_module_from_memory()
|
||||
|
|
@ -832,6 +851,11 @@ impl<'a> PluginLoader<'a> {
|
|||
layout_dir: self.layout_dir.clone(),
|
||||
default_mode: self.default_mode.clone(),
|
||||
subscriptions: Arc::new(Mutex::new(HashSet::new())),
|
||||
keybinds: self
|
||||
.keybinds
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| &self.client_attributes.keybinds)
|
||||
.clone(),
|
||||
stdin_pipe,
|
||||
stdout_pipe,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ use zellij_utils::{
|
|||
data::InputMode,
|
||||
data::PluginCapabilities,
|
||||
input::command::TerminalAction,
|
||||
input::keybinds::Keybinds,
|
||||
input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginLocation},
|
||||
input::plugins::PluginConfig,
|
||||
ipc::ClientAttributes,
|
||||
|
|
@ -289,6 +290,7 @@ pub struct PluginEnv {
|
|||
pub subscriptions: Arc<Mutex<Subscriptions>>,
|
||||
pub stdin_pipe: Arc<Mutex<VecDeque<u8>>>,
|
||||
pub stdout_pipe: Arc<Mutex<VecDeque<u8>>>,
|
||||
pub keybinds: Keybinds,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -424,4 +426,10 @@ impl RunningPlugin {
|
|||
false
|
||||
}
|
||||
}
|
||||
pub fn update_keybinds(&mut self, keybinds: Keybinds) {
|
||||
self.store.data_mut().keybinds = keybinds;
|
||||
}
|
||||
pub fn update_default_mode(&mut self, default_mode: InputMode) {
|
||||
self.store.data_mut().default_mode = default_mode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6492,7 +6492,7 @@ pub fn disconnect_other_clients_plugins_command() {
|
|||
|
||||
#[test]
|
||||
#[ignore]
|
||||
pub fn rebind_keys_plugin_command() {
|
||||
pub fn reconfigure_plugin_command() {
|
||||
let temp_folder = tempdir().unwrap(); // placed explicitly in the test scope because its
|
||||
// destructor removes the directory
|
||||
let plugin_host_folder = PathBuf::from(temp_folder.path());
|
||||
|
|
@ -6527,7 +6527,7 @@ pub fn rebind_keys_plugin_command() {
|
|||
let received_server_instruction = Arc::new(Mutex::new(vec![]));
|
||||
let server_thread = log_actions_in_thread!(
|
||||
received_server_instruction,
|
||||
ServerInstruction::RebindKeys,
|
||||
ServerInstruction::Reconfigure,
|
||||
server_receiver,
|
||||
1
|
||||
);
|
||||
|
|
@ -6555,20 +6555,20 @@ pub fn rebind_keys_plugin_command() {
|
|||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
teardown();
|
||||
server_thread.join().unwrap(); // this might take a while if the cache is cold
|
||||
let rebind_keys_event = received_server_instruction
|
||||
let reconfigure_event = received_server_instruction
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.rev()
|
||||
.find_map(|i| {
|
||||
if let ServerInstruction::RebindKeys(..) = i {
|
||||
if let ServerInstruction::Reconfigure(..) = i {
|
||||
Some(i.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.clone();
|
||||
assert_snapshot!(format!("{:#?}", rebind_keys_event));
|
||||
assert_snapshot!(format!("{:#?}", reconfigure_event));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 5500
|
||||
assertion_line: 5505
|
||||
expression: "format!(\"{:#?}\", permissions)"
|
||||
---
|
||||
Some(
|
||||
|
|
@ -14,6 +14,6 @@ Some(
|
|||
WebAccess,
|
||||
ReadCliPipes,
|
||||
MessageAndLaunchOtherPlugins,
|
||||
RebindKeys,
|
||||
Reconfigure,
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 6571
|
||||
expression: "format!(\"{:#?}\", reconfigure_event)"
|
||||
---
|
||||
Some(
|
||||
Reconfigure(
|
||||
1,
|
||||
"\n keybinds {\n locked {\n bind \"a\" { NewTab; }\n }\n }\n ",
|
||||
),
|
||||
)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 5409
|
||||
assertion_line: 5414
|
||||
expression: "format!(\"{:#?}\", new_tab_event)"
|
||||
---
|
||||
Some(
|
||||
|
|
@ -16,6 +16,6 @@ Some(
|
|||
WebAccess,
|
||||
ReadCliPipes,
|
||||
MessageAndLaunchOtherPlugins,
|
||||
RebindKeys,
|
||||
Reconfigure,
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use zellij_utils::async_std::task::{self, JoinHandle};
|
|||
use zellij_utils::consts::ZELLIJ_CACHE_DIR;
|
||||
use zellij_utils::data::{InputMode, PermissionStatus, PermissionType, PipeMessage, PipeSource};
|
||||
use zellij_utils::downloader::Downloader;
|
||||
use zellij_utils::input::keybinds::Keybinds;
|
||||
use zellij_utils::input::permission::PermissionCache;
|
||||
use zellij_utils::notify_debouncer_full::{notify::RecommendedWatcher, Debouncer, FileIdMap};
|
||||
use zellij_utils::plugin_api::event::ProtobufEvent;
|
||||
|
|
@ -103,6 +104,7 @@ pub struct WasmBridge {
|
|||
pending_pipes: PendingPipes,
|
||||
layout_dir: Option<PathBuf>,
|
||||
default_mode: InputMode,
|
||||
keybinds: HashMap<ClientId, Keybinds>,
|
||||
}
|
||||
|
||||
impl WasmBridge {
|
||||
|
|
@ -149,6 +151,7 @@ impl WasmBridge {
|
|||
pending_pipes: Default::default(),
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds: HashMap::new(),
|
||||
}
|
||||
}
|
||||
pub fn load_plugin(
|
||||
|
|
@ -206,6 +209,7 @@ impl WasmBridge {
|
|||
let default_layout = self.default_layout.clone();
|
||||
let layout_dir = self.layout_dir.clone();
|
||||
let default_mode = self.default_mode;
|
||||
let keybinds = self.keybinds.get(&client_id).cloned();
|
||||
async move {
|
||||
let _ = senders.send_to_background_jobs(
|
||||
BackgroundJob::AnimatePluginLoading(plugin_id),
|
||||
|
|
@ -254,6 +258,7 @@ impl WasmBridge {
|
|||
skip_cache,
|
||||
layout_dir,
|
||||
default_mode,
|
||||
keybinds,
|
||||
) {
|
||||
Ok(_) => handle_plugin_successful_loading(&senders, plugin_id),
|
||||
Err(e) => handle_plugin_loading_failure(
|
||||
|
|
@ -346,6 +351,7 @@ impl WasmBridge {
|
|||
let default_layout = self.default_layout.clone();
|
||||
let layout_dir = self.layout_dir.clone();
|
||||
let default_mode = self.default_mode;
|
||||
let keybinds = self.keybinds.clone();
|
||||
async move {
|
||||
match PluginLoader::reload_plugin(
|
||||
first_plugin_id,
|
||||
|
|
@ -364,6 +370,7 @@ impl WasmBridge {
|
|||
default_layout.clone(),
|
||||
layout_dir.clone(),
|
||||
default_mode,
|
||||
&keybinds,
|
||||
) {
|
||||
Ok(_) => {
|
||||
handle_plugin_successful_loading(&senders, first_plugin_id);
|
||||
|
|
@ -390,6 +397,7 @@ impl WasmBridge {
|
|||
default_layout.clone(),
|
||||
layout_dir.clone(),
|
||||
default_mode,
|
||||
&keybinds,
|
||||
) {
|
||||
Ok(_) => handle_plugin_successful_loading(&senders, *plugin_id),
|
||||
Err(e) => handle_plugin_loading_failure(
|
||||
|
|
@ -443,6 +451,7 @@ impl WasmBridge {
|
|||
self.default_layout.clone(),
|
||||
self.layout_dir.clone(),
|
||||
self.default_mode,
|
||||
self.keybinds.get(&client_id).cloned(),
|
||||
) {
|
||||
Ok(_) => {
|
||||
let _ = self
|
||||
|
|
@ -795,6 +804,51 @@ impl WasmBridge {
|
|||
.unwrap()
|
||||
.run_plugin_of_plugin_id(plugin_id)
|
||||
}
|
||||
|
||||
pub fn reconfigure(
|
||||
&mut self,
|
||||
client_id: ClientId,
|
||||
keybinds: Option<Keybinds>,
|
||||
default_mode: Option<InputMode>,
|
||||
) -> Result<()> {
|
||||
let plugins_to_reconfigure: Vec<Arc<Mutex<RunningPlugin>>> = self
|
||||
.plugin_map
|
||||
.lock()
|
||||
.unwrap()
|
||||
.running_plugins()
|
||||
.iter()
|
||||
.cloned()
|
||||
.filter_map(|(_plugin_id, c_id, running_plugin)| {
|
||||
if c_id == client_id {
|
||||
Some(running_plugin.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
if let Some(default_mode) = default_mode.as_ref() {
|
||||
self.default_mode = *default_mode;
|
||||
}
|
||||
if let Some(keybinds) = keybinds.as_ref() {
|
||||
self.keybinds.insert(client_id, keybinds.clone());
|
||||
}
|
||||
for running_plugin in plugins_to_reconfigure {
|
||||
task::spawn({
|
||||
let running_plugin = running_plugin.clone();
|
||||
let keybinds = keybinds.clone();
|
||||
async move {
|
||||
let mut running_plugin = running_plugin.lock().unwrap();
|
||||
if let Some(keybinds) = keybinds {
|
||||
running_plugin.update_keybinds(keybinds);
|
||||
}
|
||||
if let Some(default_mode) = default_mode {
|
||||
running_plugin.update_default_mode(default_mode);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn apply_cached_events_and_resizes_for_plugin(
|
||||
&mut self,
|
||||
plugin_id: PluginId,
|
||||
|
|
@ -1288,6 +1342,18 @@ pub fn apply_event_to_plugin(
|
|||
let err_context = || format!("Failed to apply event to plugin {plugin_id}");
|
||||
match check_event_permission(running_plugin.store.data(), event) {
|
||||
(PermissionStatus::Granted, _) => {
|
||||
let mut event = event.clone();
|
||||
if let Event::ModeUpdate(mode_info) = &mut event {
|
||||
// we do this because there can be some cases where this event arrives here with
|
||||
// the wrong keybindings or default mode (for example: when triggered from the CLI,
|
||||
// where we do not know the target client_id and thus don't know if their keybindings are the
|
||||
// default or if they have changed at runtime), the keybindings in running_plugin
|
||||
// should always be up-to-date. Ideally, we would have changed the keybindings in
|
||||
// ModeInfo to an Option, but alas - this is already part of our contract and that
|
||||
// would be a breaking change.
|
||||
mode_info.keybinds = running_plugin.store.data().keybinds.to_keybinds_vec();
|
||||
mode_info.base_mode = Some(running_plugin.store.data().default_mode);
|
||||
}
|
||||
let protobuf_event: ProtobufEvent = event
|
||||
.clone()
|
||||
.try_into()
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ macro_rules! apply_action {
|
|||
$env.default_shell.clone(),
|
||||
$env.default_layout.clone(),
|
||||
None,
|
||||
$env.keybinds.clone(),
|
||||
$env.default_mode.clone(),
|
||||
) {
|
||||
log::error!("{}: {:?}", $error_message(), e);
|
||||
|
|
@ -244,7 +245,7 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
|
|||
PluginCommand::WatchFilesystem => watch_filesystem(env),
|
||||
PluginCommand::DumpSessionLayout => dump_session_layout(env),
|
||||
PluginCommand::CloseSelf => close_self(env),
|
||||
PluginCommand::RebindKeys(new_keybinds) => rebind_keys(env, new_keybinds)?,
|
||||
PluginCommand::Reconfigure(new_config) => reconfigure(env, new_config)?,
|
||||
},
|
||||
(PermissionStatus::Denied, permission) => {
|
||||
log::error!(
|
||||
|
|
@ -781,11 +782,11 @@ fn close_self(env: &PluginEnv) {
|
|||
.non_fatal();
|
||||
}
|
||||
|
||||
fn rebind_keys(env: &PluginEnv, new_keybinds: String) -> Result<()> {
|
||||
let err_context = || "Failed to rebind keys";
|
||||
fn reconfigure(env: &PluginEnv, new_config: String) -> Result<()> {
|
||||
let err_context = || "Failed to reconfigure";
|
||||
let client_id = env.client_id;
|
||||
env.senders
|
||||
.send_to_server(ServerInstruction::RebindKeys(client_id, new_keybinds))
|
||||
.send_to_server(ServerInstruction::Reconfigure(client_id, new_config))
|
||||
.with_context(err_context)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1446,7 +1447,7 @@ fn check_command_permission(
|
|||
| PluginCommand::CliPipeOutput(..) => PermissionType::ReadCliPipes,
|
||||
PluginCommand::MessageToPlugin(..) => PermissionType::MessageAndLaunchOtherPlugins,
|
||||
PluginCommand::DumpSessionLayout => PermissionType::ReadApplicationState,
|
||||
PluginCommand::RebindKeys(..) => PermissionType::RebindKeys,
|
||||
PluginCommand::Reconfigure(..) => PermissionType::Reconfigure,
|
||||
_ => return (PermissionStatus::Granted, None),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use zellij_utils::{
|
|||
actions::{Action, SearchDirection, SearchOption},
|
||||
command::TerminalAction,
|
||||
get_mode_info,
|
||||
keybinds::Keybinds,
|
||||
layout::Layout,
|
||||
},
|
||||
ipc::{
|
||||
|
|
@ -38,6 +39,7 @@ pub(crate) fn route_action(
|
|||
default_shell: Option<TerminalAction>,
|
||||
default_layout: Box<Layout>,
|
||||
mut seen_cli_pipes: Option<&mut HashSet<String>>,
|
||||
client_keybinds: Keybinds,
|
||||
default_mode: InputMode,
|
||||
) -> Result<bool> {
|
||||
let mut should_break = false;
|
||||
|
|
@ -99,7 +101,13 @@ pub(crate) fn route_action(
|
|||
.send_to_plugin(PluginInstruction::Update(vec![(
|
||||
None,
|
||||
Some(client_id),
|
||||
Event::ModeUpdate(get_mode_info(mode, attrs, capabilities, Some(default_mode))),
|
||||
Event::ModeUpdate(get_mode_info(
|
||||
mode,
|
||||
attrs,
|
||||
capabilities,
|
||||
&client_keybinds,
|
||||
Some(default_mode),
|
||||
)),
|
||||
)]))
|
||||
.with_context(err_context)?;
|
||||
senders
|
||||
|
|
@ -107,7 +115,13 @@ pub(crate) fn route_action(
|
|||
.with_context(err_context)?;
|
||||
senders
|
||||
.send_to_screen(ScreenInstruction::ChangeMode(
|
||||
get_mode_info(mode, attrs, capabilities, Some(default_mode)),
|
||||
get_mode_info(
|
||||
mode,
|
||||
attrs,
|
||||
capabilities,
|
||||
&client_keybinds,
|
||||
Some(default_mode),
|
||||
),
|
||||
client_id,
|
||||
))
|
||||
.with_context(err_context)?;
|
||||
|
|
@ -349,6 +363,7 @@ pub(crate) fn route_action(
|
|||
input_mode,
|
||||
attrs,
|
||||
capabilities,
|
||||
&client_keybinds,
|
||||
Some(default_mode),
|
||||
)),
|
||||
)]))
|
||||
|
|
@ -363,6 +378,7 @@ pub(crate) fn route_action(
|
|||
input_mode,
|
||||
attrs,
|
||||
capabilities,
|
||||
&client_keybinds,
|
||||
Some(default_mode),
|
||||
)))
|
||||
.with_context(err_context)?;
|
||||
|
|
@ -1025,7 +1041,20 @@ pub(crate) fn route_thread_main(
|
|||
rlocked_sessions.default_shell.clone(),
|
||||
rlocked_sessions.layout.clone(),
|
||||
Some(&mut seen_cli_pipes),
|
||||
rlocked_sessions.default_mode,
|
||||
rlocked_sessions
|
||||
.client_keybinds
|
||||
.get(&client_id)
|
||||
.unwrap_or(
|
||||
&rlocked_sessions
|
||||
.client_attributes
|
||||
.keybinds,
|
||||
)
|
||||
.clone(),
|
||||
rlocked_sessions
|
||||
.default_mode
|
||||
.get(&client_id)
|
||||
.unwrap_or(&InputMode::Normal)
|
||||
.clone(),
|
||||
)? {
|
||||
should_break = true;
|
||||
}
|
||||
|
|
@ -1050,7 +1079,16 @@ pub(crate) fn route_thread_main(
|
|||
rlocked_sessions.default_shell.clone(),
|
||||
rlocked_sessions.layout.clone(),
|
||||
Some(&mut seen_cli_pipes),
|
||||
rlocked_sessions.default_mode,
|
||||
rlocked_sessions
|
||||
.client_keybinds
|
||||
.get(&client_id)
|
||||
.unwrap_or(&rlocked_sessions.client_attributes.keybinds)
|
||||
.clone(),
|
||||
rlocked_sessions
|
||||
.default_mode
|
||||
.get(&client_id)
|
||||
.unwrap_or(&InputMode::Normal)
|
||||
.clone(),
|
||||
)? {
|
||||
should_break = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -361,7 +361,11 @@ pub enum ScreenInstruction {
|
|||
DumpLayoutToHd,
|
||||
RenameSession(String, ClientId), // String -> new name
|
||||
ListClientsMetadata(Option<PathBuf>, ClientId), // Option<PathBuf> - default shell
|
||||
RebindKeys(Keybinds, ClientId),
|
||||
Reconfigure {
|
||||
client_id: ClientId,
|
||||
keybinds: Option<Keybinds>,
|
||||
default_mode: Option<InputMode>,
|
||||
},
|
||||
}
|
||||
|
||||
impl From<&ScreenInstruction> for ScreenContext {
|
||||
|
|
@ -546,7 +550,7 @@ impl From<&ScreenInstruction> for ScreenContext {
|
|||
ScreenInstruction::DumpLayoutToHd => ScreenContext::DumpLayoutToHd,
|
||||
ScreenInstruction::RenameSession(..) => ScreenContext::RenameSession,
|
||||
ScreenInstruction::ListClientsMetadata(..) => ScreenContext::ListClientsMetadata,
|
||||
ScreenInstruction::RebindKeys(..) => ScreenContext::RebindKeys,
|
||||
ScreenInstruction::Reconfigure { .. } => ScreenContext::Reconfigure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1214,7 +1218,7 @@ impl Screen {
|
|||
let tab_name = tab_name.unwrap_or_else(|| String::new());
|
||||
|
||||
let position = self.tabs.len();
|
||||
let tab = Tab::new(
|
||||
let mut tab = Tab::new(
|
||||
tab_index,
|
||||
position,
|
||||
tab_name,
|
||||
|
|
@ -1245,6 +1249,9 @@ impl Screen {
|
|||
self.styled_underlines,
|
||||
self.explicitly_disable_kitty_keyboard_protocol,
|
||||
);
|
||||
for (client_id, mode_info) in &self.mode_info {
|
||||
tab.change_mode_info(mode_info.clone(), *client_id);
|
||||
}
|
||||
self.tabs.insert(tab_index, tab);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -2151,18 +2158,31 @@ impl Screen {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn rebind_keys(&mut self, new_keybinds: Keybinds, client_id: ClientId) -> Result<()> {
|
||||
pub fn reconfigure_mode_info(
|
||||
&mut self,
|
||||
new_keybinds: Option<Keybinds>,
|
||||
new_default_mode: Option<InputMode>,
|
||||
client_id: ClientId,
|
||||
) -> Result<()> {
|
||||
if self.connected_clients_contains(&client_id) {
|
||||
let should_update_mode_info = new_keybinds.is_some() || new_default_mode.is_some();
|
||||
let mode_info = self
|
||||
.mode_info
|
||||
.entry(client_id)
|
||||
.or_insert_with(|| self.default_mode_info.clone());
|
||||
if let Some(new_keybinds) = new_keybinds {
|
||||
mode_info.update_keybinds(new_keybinds);
|
||||
}
|
||||
if let Some(new_default_mode) = new_default_mode {
|
||||
mode_info.update_default_mode(new_default_mode);
|
||||
}
|
||||
if should_update_mode_info {
|
||||
for tab in self.tabs.values_mut() {
|
||||
tab.change_mode_info(mode_info.clone(), client_id);
|
||||
tab.mark_active_pane_for_rerender(client_id);
|
||||
tab.update_input_modes()?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::error!("Could not find client_id {client_id} to rebind keys");
|
||||
}
|
||||
|
|
@ -2363,6 +2383,7 @@ pub(crate) fn screen_thread_main(
|
|||
// ¯\_(ツ)_/¯
|
||||
arrow_fonts: !arrow_fonts,
|
||||
},
|
||||
&client_attributes.keybinds,
|
||||
config_options.default_mode,
|
||||
),
|
||||
draw_pane_frames,
|
||||
|
|
@ -4028,8 +4049,14 @@ pub(crate) fn screen_thread_main(
|
|||
}
|
||||
screen.unblock_input()?;
|
||||
},
|
||||
ScreenInstruction::RebindKeys(new_keybinds, client_id) => {
|
||||
screen.rebind_keys(new_keybinds, client_id).non_fatal();
|
||||
ScreenInstruction::Reconfigure {
|
||||
client_id,
|
||||
keybinds,
|
||||
default_mode,
|
||||
} => {
|
||||
screen
|
||||
.reconfigure_mode_info(keybinds, default_mode, client_id)
|
||||
.non_fatal();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ fn send_cli_action_to_server(
|
|||
let get_current_dir = || PathBuf::from(".");
|
||||
let actions = Action::actions_from_cli(cli_action, Box::new(get_current_dir), None).unwrap();
|
||||
let senders = session_metadata.senders.clone();
|
||||
let client_keybinds = session_metadata.client_keybinds.clone();
|
||||
let default_mode = session_metadata.default_mode.clone();
|
||||
let capabilities = PluginCapabilities::default();
|
||||
let client_attributes = ClientAttributes::default();
|
||||
|
|
@ -130,7 +131,14 @@ fn send_cli_action_to_server(
|
|||
default_shell.clone(),
|
||||
default_layout.clone(),
|
||||
None,
|
||||
default_mode,
|
||||
client_keybinds
|
||||
.get(&client_id)
|
||||
.unwrap_or(&session_metadata.client_attributes.keybinds)
|
||||
.clone(),
|
||||
default_mode
|
||||
.get(&client_id)
|
||||
.unwrap_or(&InputMode::Normal)
|
||||
.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
@ -578,7 +586,7 @@ impl MockScreen {
|
|||
layout,
|
||||
client_input_modes: HashMap::new(),
|
||||
client_keybinds: HashMap::new(),
|
||||
default_mode: InputMode::Normal,
|
||||
default_mode: HashMap::new(),
|
||||
};
|
||||
|
||||
let os_input = FakeInputOutput::default();
|
||||
|
|
|
|||
|
|
@ -809,8 +809,8 @@ pub fn dump_session_layout() {
|
|||
}
|
||||
|
||||
/// Rebind keys for the current user
|
||||
pub fn rebind_keys(keys: String) {
|
||||
let plugin_command = PluginCommand::RebindKeys(keys);
|
||||
pub fn reconfigure(new_config: String) {
|
||||
let plugin_command = PluginCommand::Reconfigure(new_config);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
|
|
|
|||
|
|
@ -120,6 +120,13 @@ keybinds {
|
|||
};
|
||||
SwitchToMode "Normal"
|
||||
}
|
||||
bind "c" {
|
||||
LaunchOrFocusPlugin "configuration" {
|
||||
floating true
|
||||
move_to_focused_tab true
|
||||
};
|
||||
SwitchToMode "Normal"
|
||||
}
|
||||
}
|
||||
tmux {
|
||||
bind "[" { SwitchToMode "Scroll"; }
|
||||
|
|
@ -147,6 +154,7 @@ keybinds {
|
|||
shared_except "locked" {
|
||||
bind "Ctrl g" { SwitchToMode "Locked"; }
|
||||
bind "Ctrl q" { Quit; }
|
||||
bind "Alt f" { ToggleFloatingPanes; }
|
||||
bind "Alt n" { NewPane; }
|
||||
bind "Alt i" { MoveTab "Left"; }
|
||||
bind "Alt o" { MoveTab "Right"; }
|
||||
|
|
@ -197,6 +205,7 @@ plugins {
|
|||
filepicker location="zellij:strider" {
|
||||
cwd "/"
|
||||
}
|
||||
configuration location="zellij:configuration"
|
||||
}
|
||||
|
||||
// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP
|
||||
|
|
|
|||
BIN
zellij-utils/assets/plugins/configuration.wasm
Executable file
BIN
zellij-utils/assets/plugins/configuration.wasm
Executable file
Binary file not shown.
|
|
@ -119,7 +119,7 @@ pub mod plugin_command {
|
|||
#[prost(message, tag = "62")]
|
||||
NewTabsWithLayoutInfoPayload(super::NewTabsWithLayoutInfoPayload),
|
||||
#[prost(string, tag = "63")]
|
||||
RebindKeysPayload(::prost::alloc::string::String),
|
||||
ReconfigurePayload(::prost::alloc::string::String),
|
||||
}
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
|
|
@ -433,7 +433,7 @@ pub enum CommandName {
|
|||
DumpSessionLayout = 84,
|
||||
CloseSelf = 85,
|
||||
NewTabsWithLayoutInfo = 86,
|
||||
RebindKeys = 87,
|
||||
Reconfigure = 87,
|
||||
}
|
||||
impl CommandName {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
|
|
@ -529,7 +529,7 @@ impl CommandName {
|
|||
CommandName::DumpSessionLayout => "DumpSessionLayout",
|
||||
CommandName::CloseSelf => "CloseSelf",
|
||||
CommandName::NewTabsWithLayoutInfo => "NewTabsWithLayoutInfo",
|
||||
CommandName::RebindKeys => "RebindKeys",
|
||||
CommandName::Reconfigure => "Reconfigure",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
|
|
@ -622,7 +622,7 @@ impl CommandName {
|
|||
"DumpSessionLayout" => Some(Self::DumpSessionLayout),
|
||||
"CloseSelf" => Some(Self::CloseSelf),
|
||||
"NewTabsWithLayoutInfo" => Some(Self::NewTabsWithLayoutInfo),
|
||||
"RebindKeys" => Some(Self::RebindKeys),
|
||||
"Reconfigure" => Some(Self::Reconfigure),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub enum PermissionType {
|
|||
WebAccess = 6,
|
||||
ReadCliPipes = 7,
|
||||
MessageAndLaunchOtherPlugins = 8,
|
||||
RebindKeys = 9,
|
||||
Reconfigure = 9,
|
||||
}
|
||||
impl PermissionType {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
|
|
@ -30,7 +30,7 @@ impl PermissionType {
|
|||
PermissionType::MessageAndLaunchOtherPlugins => {
|
||||
"MessageAndLaunchOtherPlugins"
|
||||
}
|
||||
PermissionType::RebindKeys => "RebindKeys",
|
||||
PermissionType::Reconfigure => "Reconfigure",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
|
|
@ -45,7 +45,7 @@ impl PermissionType {
|
|||
"WebAccess" => Some(Self::WebAccess),
|
||||
"ReadCliPipes" => Some(Self::ReadCliPipes),
|
||||
"MessageAndLaunchOtherPlugins" => Some(Self::MessageAndLaunchOtherPlugins),
|
||||
"RebindKeys" => Some(Self::RebindKeys),
|
||||
"Reconfigure" => Some(Self::Reconfigure),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ mod not_wasm {
|
|||
add_plugin!(assets, "tab-bar.wasm");
|
||||
add_plugin!(assets, "strider.wasm");
|
||||
add_plugin!(assets, "session-manager.wasm");
|
||||
add_plugin!(assets, "configuration.wasm");
|
||||
assets
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -942,7 +942,7 @@ pub enum Permission {
|
|||
WebAccess,
|
||||
ReadCliPipes,
|
||||
MessageAndLaunchOtherPlugins,
|
||||
RebindKeys,
|
||||
Reconfigure,
|
||||
}
|
||||
|
||||
impl PermissionType {
|
||||
|
|
@ -963,7 +963,7 @@ impl PermissionType {
|
|||
PermissionType::MessageAndLaunchOtherPlugins => {
|
||||
"Send messages to and launch other plugins".to_owned()
|
||||
},
|
||||
PermissionType::RebindKeys => "Rebind keys".to_owned(),
|
||||
PermissionType::Reconfigure => "Change Zellij runtime configuration".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1164,6 +1164,9 @@ impl ModeInfo {
|
|||
pub fn update_keybinds(&mut self, keybinds: Keybinds) {
|
||||
self.keybinds = keybinds.to_keybinds_vec();
|
||||
}
|
||||
pub fn update_default_mode(&mut self, new_default_mode: InputMode) {
|
||||
self.base_mode = Some(new_default_mode);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
|
|
@ -1767,5 +1770,5 @@ pub enum PluginCommand {
|
|||
DumpSessionLayout,
|
||||
CloseSelf,
|
||||
NewTabsWithLayoutInfo(LayoutInfo),
|
||||
RebindKeys(String), // String -> stringified keybindings
|
||||
Reconfigure(String), // String -> stringified configuration
|
||||
}
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ pub enum ScreenContext {
|
|||
RenameSession,
|
||||
DumpLayoutToPlugin,
|
||||
ListClientsMetadata,
|
||||
RebindKeys,
|
||||
Reconfigure,
|
||||
}
|
||||
|
||||
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
|
||||
|
|
@ -409,6 +409,7 @@ pub enum PluginContext {
|
|||
KeybindPipe,
|
||||
DumpLayoutToPlugin,
|
||||
ListClientsMetadata,
|
||||
Reconfigure,
|
||||
}
|
||||
|
||||
/// Stack call representations corresponding to the different types of [`ClientInstruction`]s.
|
||||
|
|
@ -457,7 +458,7 @@ pub enum ServerContext {
|
|||
DisconnectAllClientsExcept,
|
||||
ChangeMode,
|
||||
ChangeModeForAllClients,
|
||||
RebindKeys,
|
||||
Reconfigure,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
|
|
|
|||
|
|
@ -712,16 +712,6 @@ impl Action {
|
|||
pub fn launches_plugin(&self, plugin_url: &str) -> bool {
|
||||
match self {
|
||||
Action::LaunchPlugin(run_plugin_or_alias, ..) => {
|
||||
log::info!(
|
||||
"1: {:?} == {:?}",
|
||||
run_plugin_or_alias.location_string(),
|
||||
plugin_url
|
||||
);
|
||||
eprintln!(
|
||||
"1: {:?} == {:?}",
|
||||
run_plugin_or_alias.location_string(),
|
||||
plugin_url
|
||||
);
|
||||
&run_plugin_or_alias.location_string() == plugin_url
|
||||
},
|
||||
Action::LaunchOrFocusPlugin(run_plugin_or_alias, ..) => {
|
||||
|
|
|
|||
|
|
@ -33,9 +33,10 @@ mod not_wasm {
|
|||
mode: InputMode,
|
||||
attributes: &ClientAttributes,
|
||||
capabilities: PluginCapabilities,
|
||||
keybinds: &Keybinds,
|
||||
base_mode: Option<InputMode>,
|
||||
) -> ModeInfo {
|
||||
let keybinds = attributes.keybinds.to_keybinds_vec();
|
||||
let keybinds = keybinds.to_keybinds_vec();
|
||||
let session_name = envs::get_session_name().ok();
|
||||
|
||||
ModeInfo {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ impl PluginConfig {
|
|||
|| tag == "compact-bar"
|
||||
|| tag == "strider"
|
||||
|| tag == "session-manager"
|
||||
|| tag == "configuration"
|
||||
{
|
||||
Some(PluginConfig {
|
||||
path: PathBuf::from(&tag),
|
||||
|
|
|
|||
|
|
@ -1649,6 +1649,10 @@ impl Options {
|
|||
support_kitty_keyboard_protocol,
|
||||
})
|
||||
}
|
||||
pub fn from_string(stringified_keybindings: &String) -> Result<Self, ConfigError> {
|
||||
let document: KdlDocument = stringified_keybindings.parse()?;
|
||||
Options::from_kdl(&document)
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ enum CommandName {
|
|||
DumpSessionLayout = 84;
|
||||
CloseSelf = 85;
|
||||
NewTabsWithLayoutInfo = 86;
|
||||
RebindKeys = 87;
|
||||
Reconfigure = 87;
|
||||
}
|
||||
|
||||
message PluginCommand {
|
||||
|
|
@ -156,7 +156,7 @@ message PluginCommand {
|
|||
KillSessionsPayload kill_sessions_payload = 60;
|
||||
string scan_host_folder_payload = 61;
|
||||
NewTabsWithLayoutInfoPayload new_tabs_with_layout_info_payload = 62;
|
||||
string rebind_keys_payload = 63;
|
||||
string reconfigure_payload = 63;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -888,11 +888,11 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
|
|||
},
|
||||
_ => Err("Mismatched payload for NewTabsWithLayoutInfo"),
|
||||
},
|
||||
Some(CommandName::RebindKeys) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::RebindKeysPayload(rebind_keys_payload)) => {
|
||||
Ok(PluginCommand::RebindKeys(rebind_keys_payload))
|
||||
Some(CommandName::Reconfigure) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::ReconfigurePayload(reconfigure_payload)) => {
|
||||
Ok(PluginCommand::Reconfigure(reconfigure_payload))
|
||||
},
|
||||
_ => Err("Mismatched payload for RebindKeys"),
|
||||
_ => Err("Mismatched payload for Reconfigure"),
|
||||
},
|
||||
None => Err("Unrecognized plugin command"),
|
||||
}
|
||||
|
|
@ -1426,9 +1426,9 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
|
|||
)),
|
||||
})
|
||||
},
|
||||
PluginCommand::RebindKeys(rebind_keys_payload) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::RebindKeys as i32,
|
||||
payload: Some(Payload::RebindKeysPayload(rebind_keys_payload)),
|
||||
PluginCommand::Reconfigure(reconfigure_payload) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::Reconfigure as i32,
|
||||
payload: Some(Payload::ReconfigurePayload(reconfigure_payload)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@ enum PermissionType {
|
|||
WebAccess = 6;
|
||||
ReadCliPipes = 7;
|
||||
MessageAndLaunchOtherPlugins = 8;
|
||||
RebindKeys = 9;
|
||||
Reconfigure = 9;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ impl TryFrom<ProtobufPermissionType> for PermissionType {
|
|||
ProtobufPermissionType::MessageAndLaunchOtherPlugins => {
|
||||
Ok(PermissionType::MessageAndLaunchOtherPlugins)
|
||||
},
|
||||
ProtobufPermissionType::RebindKeys => Ok(PermissionType::RebindKeys),
|
||||
ProtobufPermissionType::Reconfigure => Ok(PermissionType::Reconfigure),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ impl TryFrom<PermissionType> for ProtobufPermissionType {
|
|||
PermissionType::MessageAndLaunchOtherPlugins => {
|
||||
Ok(ProtobufPermissionType::MessageAndLaunchOtherPlugins)
|
||||
},
|
||||
PermissionType::RebindKeys => Ok(ProtobufPermissionType::RebindKeys),
|
||||
PermissionType::Reconfigure => Ok(ProtobufPermissionType::Reconfigure),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: zellij-utils/src/setup.rs
|
||||
assertion_line: 725
|
||||
assertion_line: 753
|
||||
expression: "format!(\"{:#?}\", config)"
|
||||
---
|
||||
Config {
|
||||
|
|
@ -117,6 +117,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -552,6 +562,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -997,6 +1017,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -1590,6 +1620,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2066,6 +2106,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2441,6 +2491,16 @@ Config {
|
|||
Scroll,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2824,6 +2884,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3224,6 +3294,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3545,6 +3625,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3854,6 +3944,34 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'c',
|
||||
),
|
||||
key_modifiers: {},
|
||||
}: [
|
||||
LaunchOrFocusPlugin(
|
||||
Alias(
|
||||
PluginAlias {
|
||||
name: "configuration",
|
||||
configuration: Some(
|
||||
PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
),
|
||||
initial_cwd: None,
|
||||
run_plugin: None,
|
||||
},
|
||||
),
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
SwitchToMode(
|
||||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'd',
|
||||
|
|
@ -3862,6 +3980,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4238,6 +4366,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4620,6 +4758,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5064,6 +5212,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5409,6 +5567,18 @@ Config {
|
|||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"configuration": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
PluginTag(
|
||||
"configuration",
|
||||
),
|
||||
),
|
||||
configuration: PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"filepicker": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: zellij-utils/src/setup.rs
|
||||
assertion_line: 783
|
||||
assertion_line: 811
|
||||
expression: "format!(\"{:#?}\", config)"
|
||||
---
|
||||
Config {
|
||||
|
|
@ -117,6 +117,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -552,6 +562,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -997,6 +1017,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -1590,6 +1620,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2066,6 +2106,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2441,6 +2491,16 @@ Config {
|
|||
Scroll,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2824,6 +2884,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3224,6 +3294,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3545,6 +3625,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3854,6 +3944,34 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'c',
|
||||
),
|
||||
key_modifiers: {},
|
||||
}: [
|
||||
LaunchOrFocusPlugin(
|
||||
Alias(
|
||||
PluginAlias {
|
||||
name: "configuration",
|
||||
configuration: Some(
|
||||
PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
),
|
||||
initial_cwd: None,
|
||||
run_plugin: None,
|
||||
},
|
||||
),
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
SwitchToMode(
|
||||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'd',
|
||||
|
|
@ -3862,6 +3980,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4238,6 +4366,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4620,6 +4758,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5064,6 +5212,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5409,6 +5567,18 @@ Config {
|
|||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"configuration": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
PluginTag(
|
||||
"configuration",
|
||||
),
|
||||
),
|
||||
configuration: PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"filepicker": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: zellij-utils/src/setup.rs
|
||||
assertion_line: 825
|
||||
assertion_line: 853
|
||||
expression: "format!(\"{:#?}\", config)"
|
||||
---
|
||||
Config {
|
||||
|
|
@ -134,6 +134,18 @@ Config {
|
|||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"configuration": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
PluginTag(
|
||||
"configuration",
|
||||
),
|
||||
),
|
||||
configuration: PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"filepicker": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: zellij-utils/src/setup.rs
|
||||
assertion_line: 811
|
||||
assertion_line: 839
|
||||
expression: "format!(\"{:#?}\", config)"
|
||||
---
|
||||
Config {
|
||||
|
|
@ -117,6 +117,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -552,6 +562,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -997,6 +1017,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -1590,6 +1620,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2066,6 +2106,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2441,6 +2491,16 @@ Config {
|
|||
Scroll,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2824,6 +2884,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3224,6 +3294,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3545,6 +3625,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3854,6 +3944,34 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'c',
|
||||
),
|
||||
key_modifiers: {},
|
||||
}: [
|
||||
LaunchOrFocusPlugin(
|
||||
Alias(
|
||||
PluginAlias {
|
||||
name: "configuration",
|
||||
configuration: Some(
|
||||
PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
),
|
||||
initial_cwd: None,
|
||||
run_plugin: None,
|
||||
},
|
||||
),
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
SwitchToMode(
|
||||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'd',
|
||||
|
|
@ -3862,6 +3980,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4238,6 +4366,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4620,6 +4758,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5064,6 +5212,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5713,6 +5871,18 @@ Config {
|
|||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"configuration": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
PluginTag(
|
||||
"configuration",
|
||||
),
|
||||
),
|
||||
configuration: PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"filepicker": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: zellij-utils/src/setup.rs
|
||||
assertion_line: 797
|
||||
assertion_line: 825
|
||||
expression: "format!(\"{:#?}\", config)"
|
||||
---
|
||||
Config {
|
||||
|
|
@ -117,6 +117,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -552,6 +562,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -997,6 +1017,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -1590,6 +1620,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2066,6 +2106,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2441,6 +2491,16 @@ Config {
|
|||
Scroll,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -2824,6 +2884,16 @@ Config {
|
|||
}: [
|
||||
PageScrollDown,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3224,6 +3294,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3545,6 +3625,16 @@ Config {
|
|||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -3854,6 +3944,34 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'c',
|
||||
),
|
||||
key_modifiers: {},
|
||||
}: [
|
||||
LaunchOrFocusPlugin(
|
||||
Alias(
|
||||
PluginAlias {
|
||||
name: "configuration",
|
||||
configuration: Some(
|
||||
PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
),
|
||||
initial_cwd: None,
|
||||
run_plugin: None,
|
||||
},
|
||||
),
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
SwitchToMode(
|
||||
Normal,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'd',
|
||||
|
|
@ -3862,6 +3980,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4238,6 +4366,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -4620,6 +4758,16 @@ Config {
|
|||
Tmux,
|
||||
),
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5064,6 +5212,16 @@ Config {
|
|||
}: [
|
||||
Detach,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'f',
|
||||
),
|
||||
key_modifiers: {
|
||||
Alt,
|
||||
},
|
||||
}: [
|
||||
ToggleFloatingPanes,
|
||||
],
|
||||
KeyWithModifier {
|
||||
bare_key: Char(
|
||||
'g',
|
||||
|
|
@ -5409,6 +5567,18 @@ Config {
|
|||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"configuration": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
PluginTag(
|
||||
"configuration",
|
||||
),
|
||||
),
|
||||
configuration: PluginUserConfiguration(
|
||||
{},
|
||||
),
|
||||
initial_cwd: None,
|
||||
},
|
||||
"filepicker": RunPlugin {
|
||||
_allow_exec_host_cmd: false,
|
||||
location: Zellij(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue