mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-26 02:32:21 +03:00
poking
This commit is contained in:
parent
3e0174cc4a
commit
c644a1c243
@ -22,6 +22,8 @@ _zellij() {
|
|||||||
'--max-panes=[Maximum panes on screen, caution: opening more panes will close old ones]' \
|
'--max-panes=[Maximum panes on screen, caution: opening more panes will close old ones]' \
|
||||||
'-l+[Path to a layout yaml file]' \
|
'-l+[Path to a layout yaml file]' \
|
||||||
'--layout=[Path to a layout yaml file]' \
|
'--layout=[Path to a layout yaml file]' \
|
||||||
|
'-c+[Path to the configuration yaml file]' \
|
||||||
|
'--config=[Path to the configuration yaml file]' \
|
||||||
'-m[Send "move focused pane" to active zellij session]' \
|
'-m[Send "move focused pane" to active zellij session]' \
|
||||||
'--move-focus[Send "move focused pane" to active zellij session]' \
|
'--move-focus[Send "move focused pane" to active zellij session]' \
|
||||||
'-d[]' \
|
'-d[]' \
|
||||||
|
@ -20,7 +20,7 @@ _zellij() {
|
|||||||
|
|
||||||
case "${cmd}" in
|
case "${cmd}" in
|
||||||
zellij)
|
zellij)
|
||||||
opts=" -m -d -h -V -s -o -l --move-focus --debug --help --version --split --open-file --max-panes --layout "
|
opts=" -m -d -h -V -s -o -l -c --move-focus --debug --help --version --split --open-file --max-panes --layout --config "
|
||||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
return 0
|
return 0
|
||||||
@ -55,6 +55,14 @@ _zellij() {
|
|||||||
COMPREPLY=($(compgen -f "${cur}"))
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
--config)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-c)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
;;
|
;;
|
||||||
|
@ -2,6 +2,7 @@ complete -c zellij -n "__fish_use_subcommand" -s s -l split -d 'Send "split (dir
|
|||||||
complete -c zellij -n "__fish_use_subcommand" -s o -l open-file -d 'Send "open file in new pane" to active zellij session'
|
complete -c zellij -n "__fish_use_subcommand" -s o -l open-file -d 'Send "open file in new pane" to active zellij session'
|
||||||
complete -c zellij -n "__fish_use_subcommand" -l max-panes -d 'Maximum panes on screen, caution: opening more panes will close old ones'
|
complete -c zellij -n "__fish_use_subcommand" -l max-panes -d 'Maximum panes on screen, caution: opening more panes will close old ones'
|
||||||
complete -c zellij -n "__fish_use_subcommand" -s l -l layout -d 'Path to a layout yaml file'
|
complete -c zellij -n "__fish_use_subcommand" -s l -l layout -d 'Path to a layout yaml file'
|
||||||
|
complete -c zellij -n "__fish_use_subcommand" -s c -l config -d 'Path to the configuration yaml file'
|
||||||
complete -c zellij -n "__fish_use_subcommand" -s m -l move-focus -d 'Send "move focused pane" to active zellij session'
|
complete -c zellij -n "__fish_use_subcommand" -s m -l move-focus -d 'Send "move focused pane" to active zellij session'
|
||||||
complete -c zellij -n "__fish_use_subcommand" -s d -l debug
|
complete -c zellij -n "__fish_use_subcommand" -s d -l debug
|
||||||
complete -c zellij -n "__fish_use_subcommand" -s h -l help -d 'Prints help information'
|
complete -c zellij -n "__fish_use_subcommand" -s h -l help -d 'Prints help information'
|
||||||
|
8
config.yaml
Normal file
8
config.yaml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
macro:
|
||||||
|
{name:"closePane", sequence: [NewPane: Right,]}
|
||||||
|
|
||||||
|
keybinds:
|
||||||
|
Normal:
|
||||||
|
Backspace: [NewPane:, NewPane:,]
|
||||||
|
{F: 1}: [NewPane:,]
|
@ -24,6 +24,10 @@ pub struct CliArgs {
|
|||||||
#[structopt(short, long)]
|
#[structopt(short, long)]
|
||||||
pub layout: Option<PathBuf>,
|
pub layout: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Path to the configuration yaml file
|
||||||
|
#[structopt(short, long)]
|
||||||
|
pub config: Option<PathBuf>,
|
||||||
|
|
||||||
#[structopt(short, long)]
|
#[structopt(short, long)]
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
//! Deserializes configuration options.
|
//! Deserializes configuration options.
|
||||||
use std;
|
use std;
|
||||||
use std::collections::HashMap;
|
//use std::collections::HashMap;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self,Read};
|
use std::io::{self, Read};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::input::{keybinds,handler};
|
use super::input::{keybinds, macros};
|
||||||
|
|
||||||
|
use directories_next::ProjectDirs;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
/// Intermediate struct
|
/// Intermediate struct
|
||||||
@ -16,17 +17,17 @@ use serde::Deserialize;
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
/// Intermediate struct
|
/// Intermediate struct
|
||||||
//#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct ConfigFromYaml {
|
pub struct ConfigFromYaml {
|
||||||
keybinds: HashMap<handler::InputMode,Vec<keybinds::Keybinds>>,
|
keybinds: Option<keybinds::Keybinds>,
|
||||||
|
macros: Option<Vec<macros::Macro>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
///// Deserialized config state
|
///// Deserialized config state
|
||||||
#[derive(Debug, Clone, Default, Deserialize)]
|
#[derive(Debug, Clone, Default, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
keybinds: Vec<keybinds::Keybinds>,
|
pub keybinds: keybinds::Keybinds,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -43,37 +44,52 @@ pub enum ConfigError {
|
|||||||
Serde(serde_yaml::Error),
|
Serde(serde_yaml::Error),
|
||||||
//Eof,
|
//Eof,
|
||||||
// io::Error
|
// io::Error
|
||||||
Io(io::Error)
|
Io(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
/// Deserializes from given path
|
/// Deserializes from given path
|
||||||
pub fn new(path: &PathBuf) -> Result<Config,ConfigError> {
|
pub fn new(path: &PathBuf) -> Result<Config, ConfigError> {
|
||||||
let config_deserialized: Config;
|
let config: Config;
|
||||||
|
let config_deserialized: ConfigFromYaml;
|
||||||
let mut config_string = String::new();
|
let mut config_string = String::new();
|
||||||
|
|
||||||
|
// TODO fix this unwrap
|
||||||
match File::open(path) {
|
match File::open(path) {
|
||||||
Ok(mut file) => {
|
Ok(mut file) => {
|
||||||
file.read_to_string(&mut config_string)?;
|
file.read_to_string(&mut config_string)?;
|
||||||
config_deserialized = serde_yaml::from_str(&config_string)?;
|
config_deserialized = serde_yaml::from_str(&config_string)?;
|
||||||
|
config = Config {
|
||||||
|
keybinds: config_deserialized
|
||||||
|
.keybinds
|
||||||
|
.unwrap_or_else(|| keybinds::get_default_keybinds().unwrap()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(e) => {
|
||||||
// TODO logging, if a file is not found
|
// TODO logging, if a file is not found
|
||||||
// at an expected position - should not
|
// at an expected position - should not
|
||||||
// panic @a-kenji
|
// panic @a-kenji
|
||||||
config_deserialized = Config::default();
|
eprintln!("{}", e);
|
||||||
|
config = Config::default();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(config_deserialized)
|
Ok(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_option_or_default(option: Option<PathBuf>) -> Result<Config, ConfigError> {
|
||||||
|
let config;
|
||||||
|
if let Some(config_path) = option {
|
||||||
|
config = Config::new(&config_path)?;
|
||||||
|
} else {
|
||||||
|
let project_dirs = ProjectDirs::from("org", "Zellij Contributors", "Zellij").unwrap();
|
||||||
|
//let config_path = PathBuf::from(project_dirs.config_dir().as_os_str());
|
||||||
|
let config_path = project_dirs.config_dir().to_owned().into();
|
||||||
|
config = Config::new(&config_path)?;
|
||||||
|
}
|
||||||
|
return Ok(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl de::Error for ConfigError {
|
|
||||||
//fn custom<T: Display>(msg: T) -> Self {
|
|
||||||
//ConfigError::Message(msg.to_string())
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
impl Display for ConfigError {
|
impl Display for ConfigError {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
@ -88,25 +104,17 @@ impl Display for ConfigError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for ConfigError {
|
impl std::error::Error for ConfigError {
|
||||||
fn description(&self) -> &str {
|
fn cause(&self) -> Option<&dyn error::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
//ConfigError::Message(ref err) => err,
|
// N.B. Both of these implicitly cast `err` from their concrete
|
||||||
ConfigError::Io(ref err) => err.to_string().as_str(),
|
// types (either `&io::Error` or `&num::ParseIntError`)
|
||||||
ConfigError::Serde(ref err) => err.to_string().as_str(),
|
// to a trait object `&Error`. This works because both error types
|
||||||
|
// implement `Error`.
|
||||||
|
ConfigError::Io(ref err) => Some(err),
|
||||||
|
//ConfigError::Message(ref err) => Some(err),
|
||||||
|
ConfigError::Serde(ref err) => Some(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
match *self {
|
|
||||||
// N.B. Both of these implicitly cast `err` from their concrete
|
|
||||||
// types (either `&io::Error` or `&num::ParseIntError`)
|
|
||||||
// to a trait object `&Error`. This works because both error types
|
|
||||||
// implement `Error`.
|
|
||||||
ConfigError::Io(ref err) => Some(err),
|
|
||||||
//ConfigError::Message(ref err) => Some(err),
|
|
||||||
ConfigError::Serde(ref err) => Some(err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for ConfigError {
|
impl From<io::Error> for ConfigError {
|
||||||
@ -120,10 +128,3 @@ impl From<serde_yaml::Error> for ConfigError {
|
|||||||
ConfigError::Serde(err)
|
ConfigError::Serde(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl From<de::Error::Message> for ConfigError {
|
|
||||||
//fn from(err: de::Error::Message) -> ConfigError {
|
|
||||||
//ConfigError::Message(err)
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use super::actions::Action;
|
use super::actions::Action;
|
||||||
use super::keybinds::get_default_keybinds;
|
use super::keybinds::get_default_keybinds;
|
||||||
|
use crate::common::config::Config;
|
||||||
use crate::common::{update_state, AppInstruction, AppState, SenderWithContext, OPENCALLS};
|
use crate::common::{update_state, AppInstruction, AppState, SenderWithContext, OPENCALLS};
|
||||||
use crate::errors::ContextType;
|
use crate::errors::ContextType;
|
||||||
use crate::os_input_output::OsApi;
|
use crate::os_input_output::OsApi;
|
||||||
@ -22,6 +23,7 @@ struct InputHandler {
|
|||||||
/// The current input mode
|
/// The current input mode
|
||||||
mode: InputMode,
|
mode: InputMode,
|
||||||
os_input: Box<dyn OsApi>,
|
os_input: Box<dyn OsApi>,
|
||||||
|
config: Config,
|
||||||
command_is_executing: CommandIsExecuting,
|
command_is_executing: CommandIsExecuting,
|
||||||
send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
||||||
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||||
@ -34,6 +36,7 @@ impl InputHandler {
|
|||||||
fn new(
|
fn new(
|
||||||
os_input: Box<dyn OsApi>,
|
os_input: Box<dyn OsApi>,
|
||||||
command_is_executing: CommandIsExecuting,
|
command_is_executing: CommandIsExecuting,
|
||||||
|
config: Config,
|
||||||
send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
||||||
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||||
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||||
@ -42,6 +45,7 @@ impl InputHandler {
|
|||||||
InputHandler {
|
InputHandler {
|
||||||
mode: InputMode::Normal,
|
mode: InputMode::Normal,
|
||||||
os_input,
|
os_input,
|
||||||
|
config,
|
||||||
command_is_executing,
|
command_is_executing,
|
||||||
send_screen_instructions,
|
send_screen_instructions,
|
||||||
send_pty_instructions,
|
send_pty_instructions,
|
||||||
@ -59,6 +63,8 @@ impl InputHandler {
|
|||||||
self.send_app_instructions.update(err_ctx);
|
self.send_app_instructions.update(err_ctx);
|
||||||
self.send_screen_instructions.update(err_ctx);
|
self.send_screen_instructions.update(err_ctx);
|
||||||
if let Ok(keybinds) = get_default_keybinds() {
|
if let Ok(keybinds) = get_default_keybinds() {
|
||||||
|
let mut merged_keybinds = keybinds;
|
||||||
|
merged_keybinds.extend(self.config.keybinds.clone().into_iter());
|
||||||
'input_loop: loop {
|
'input_loop: loop {
|
||||||
//@@@ I think this should actually just iterate over stdin directly
|
//@@@ I think this should actually just iterate over stdin directly
|
||||||
let stdin_buffer = self.os_input.read_from_stdin();
|
let stdin_buffer = self.os_input.read_from_stdin();
|
||||||
@ -76,9 +82,14 @@ impl InputHandler {
|
|||||||
// been revised. Sorry about this (@categorille)
|
// been revised. Sorry about this (@categorille)
|
||||||
if {
|
if {
|
||||||
let mut should_break = false;
|
let mut should_break = false;
|
||||||
for action in
|
// Hacked on way to have a means of testing Macros, needs to
|
||||||
key_to_actions(&key, raw_bytes, &self.mode, &keybinds)
|
// get properly integrated
|
||||||
{
|
for action in key_to_actions(
|
||||||
|
&key,
|
||||||
|
raw_bytes,
|
||||||
|
&self.mode,
|
||||||
|
&merged_keybinds,
|
||||||
|
) {
|
||||||
should_break |= self.dispatch_action(action);
|
should_break |= self.dispatch_action(action);
|
||||||
}
|
}
|
||||||
should_break
|
should_break
|
||||||
@ -324,6 +335,7 @@ pub fn get_help(mode: InputMode) -> Help {
|
|||||||
/// its [`InputHandler::handle_input()`] loop.
|
/// its [`InputHandler::handle_input()`] loop.
|
||||||
pub fn input_loop(
|
pub fn input_loop(
|
||||||
os_input: Box<dyn OsApi>,
|
os_input: Box<dyn OsApi>,
|
||||||
|
config: Config,
|
||||||
command_is_executing: CommandIsExecuting,
|
command_is_executing: CommandIsExecuting,
|
||||||
send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
send_screen_instructions: SenderWithContext<ScreenInstruction>,
|
||||||
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||||
@ -333,6 +345,7 @@ pub fn input_loop(
|
|||||||
let _handler = InputHandler::new(
|
let _handler = InputHandler::new(
|
||||||
os_input,
|
os_input,
|
||||||
command_is_executing,
|
command_is_executing,
|
||||||
|
config,
|
||||||
send_screen_instructions,
|
send_screen_instructions,
|
||||||
send_pty_instructions,
|
send_pty_instructions,
|
||||||
send_plugin_instructions,
|
send_plugin_instructions,
|
||||||
|
@ -23,7 +23,7 @@ pub fn get_default_keybinds() -> Result<Keybinds, String> {
|
|||||||
Ok(defaults)
|
Ok(defaults)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the default keybinds for a givent [`InputMode`].
|
/// Returns the default keybinds for a given [`InputMode`].
|
||||||
fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> {
|
fn get_defaults_for_mode(mode: &InputMode) -> Result<ModeKeybinds, String> {
|
||||||
let mut defaults = ModeKeybinds::new();
|
let mut defaults = ModeKeybinds::new();
|
||||||
|
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
//! defined predictable order.
|
//! defined predictable order.
|
||||||
|
|
||||||
use super::actions::Action;
|
use super::actions::Action;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct Macro {
|
pub struct Macro {
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
sequence: Vec<Action>
|
sequence: Vec<Action>,
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod config;
|
|
||||||
pub mod command_is_executing;
|
pub mod command_is_executing;
|
||||||
|
pub mod config;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod install;
|
pub mod install;
|
||||||
@ -46,10 +46,17 @@ pub enum ApiCommand {
|
|||||||
MoveFocus,
|
MoveFocus,
|
||||||
}
|
}
|
||||||
// FIXME: It would be good to add some more things to this over time
|
// FIXME: It would be good to add some more things to this over time
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub input_mode: InputMode,
|
pub input_mode: InputMode,
|
||||||
pub config : Config,
|
}
|
||||||
|
|
||||||
|
impl Default for AppState {
|
||||||
|
fn default() -> Self {
|
||||||
|
AppState {
|
||||||
|
input_mode: InputMode::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Make this a method on the big `Communication` struct, so that app_tx can be extracted
|
// FIXME: Make this a method on the big `Communication` struct, so that app_tx can be extracted
|
||||||
@ -158,8 +165,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
.get_stdout_writer()
|
.get_stdout_writer()
|
||||||
.write(take_snapshot.as_bytes())
|
.write(take_snapshot.as_bytes())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut app_state = AppState::default();
|
let mut app_state = AppState::default();
|
||||||
|
|
||||||
|
let config = Config::from_option_or_default(opts.config)
|
||||||
|
.map_err(|e| eprintln!{"Config Error: {}", e})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let command_is_executing = CommandIsExecuting::new();
|
let command_is_executing = CommandIsExecuting::new();
|
||||||
|
|
||||||
let full_screen_ws = os_input.get_terminal_size_using_fd(0);
|
let full_screen_ws = os_input.get_terminal_size_using_fd(0);
|
||||||
@ -638,9 +650,11 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
|||||||
let send_pty_instructions = send_pty_instructions.clone();
|
let send_pty_instructions = send_pty_instructions.clone();
|
||||||
let send_plugin_instructions = send_plugin_instructions.clone();
|
let send_plugin_instructions = send_plugin_instructions.clone();
|
||||||
let os_input = os_input.clone();
|
let os_input = os_input.clone();
|
||||||
|
let config = config.clone();
|
||||||
move || {
|
move || {
|
||||||
input_loop(
|
input_loop(
|
||||||
os_input,
|
os_input,
|
||||||
|
config,
|
||||||
command_is_executing,
|
command_is_executing,
|
||||||
send_screen_instructions,
|
send_screen_instructions,
|
||||||
send_pty_instructions,
|
send_pty_instructions,
|
||||||
|
Loading…
Reference in New Issue
Block a user