Skip to content

Commit

Permalink
Read config inside felix and update it
Browse files Browse the repository at this point in the history
  • Loading branch information
kyoheiu committed Jan 27, 2024
1 parent 622a6c7 commit fbca887
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 111 deletions.
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl Default for Config {
}
}

fn read_config(p: &Path) -> Result<ConfigWithPath, FxError> {
pub fn read_config(p: &Path) -> Result<ConfigWithPath, FxError> {
let s = read_to_string(p)?;
let deserialized: Config = serde_yaml::from_str(&s)?;
Ok(ConfigWithPath {
Expand Down
50 changes: 48 additions & 2 deletions src/run.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![allow(unreachable_code)]
use super::config::FELIX;
use super::config::{read_config, FELIX};
use super::errors::FxError;
use super::functions::*;
use super::layout::{PreviewType, Split};
Expand All @@ -18,6 +17,8 @@ use std::env;
use std::io::{stdout, Write};
use std::panic;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Instant;

const TRASH: &str = "Trash";
Expand Down Expand Up @@ -169,7 +170,52 @@ fn _run(mut state: State, session_path: PathBuf) -> Result<(), FxError> {
}
screen.flush()?;

// Spawn another thread to watch the config file.
let mut modified_time = match &state.config_path {
Some(config_path) => config_path.metadata().unwrap().modified().ok(),
None => None,
};
let config_updated = Arc::new(Mutex::new(false));
let config_updated_in_another_tread = config_updated.clone();
let config_path_in_another_thread = state.config_path.clone();
// if config file does not exist, no watching.
if modified_time.is_some() {
// Every 2 secondes, check if the config file is updated.
thread::spawn(move || loop {
thread::sleep(std::time::Duration::from_secs(2));
if *config_updated_in_another_tread.lock().unwrap() {
continue;
}
let metadata = config_path_in_another_thread.as_ref().unwrap().metadata();
if let Ok(metadata) = metadata {
let new_modified = metadata.modified().ok();
if modified_time != new_modified {
if let Ok(mut updated) = config_updated_in_another_tread.lock() {
*updated = true;
modified_time = new_modified;
} else {
break;
}
}
}
});
}

'main: loop {
// Check if config file is updated
if let Ok(mut should_be_updated) = config_updated.lock() {
if *should_be_updated {
if let Ok(c) = read_config(state.config_path.as_ref().unwrap()) {
state.set_config(c.config);
state.redraw(state.layout.y);
print_info("New config set.", state.layout.y);
} else {
print_warning("Something wrong with the config file.", state.layout.y);
}
*should_be_updated = false;
}
}

if state.is_out_of_bounds() {
state.layout.nums.reset();
state.redraw(BEGINNING_ROW);
Expand Down
126 changes: 18 additions & 108 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use chrono::prelude::*;
use crossterm::event::KeyEventKind;
use crossterm::event::{Event, KeyCode, KeyEvent};
use crossterm::style::Stylize;
use log::{error, info};
use log::info;
use std::collections::VecDeque;
use std::collections::{BTreeMap, BTreeSet};
use std::env;
Expand All @@ -41,7 +41,7 @@ use std::os::unix::fs::PermissionsExt;
pub const BEGINNING_ROW: u16 = 3;
pub const EMPTY_WARNING: &str = "Are you sure to empty the trash directory? (if yes: y)";

#[derive(Debug)]
#[derive(Debug, Default)]
pub struct State {
pub list: Vec<ItemInfo>,
pub current_dir: PathBuf,
Expand All @@ -63,7 +63,7 @@ pub struct State {
pub is_ro: bool,
}

#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Registers {
pub unnamed: Vec<ItemBuffer>,
pub zero: Vec<ItemBuffer>,
Expand Down Expand Up @@ -243,95 +243,30 @@ impl State {
(None, Config::default())
}
};
let mut state = State::default();
state.set_config(config.clone());

let session = read_session(session_path);
let (original_column, original_row) = terminal_size()?;

// Return error if terminal size may cause panic
if original_column < 4 {
error!("Too small terminal size (less than 4 columns).");
return Err(FxError::TooSmallWindowSize);
};
if original_row < 4 {
error!("Too small terminal size. (less than 4 rows)");
return Err(FxError::TooSmallWindowSize);
};

let (time_start, name_max) = make_layout(original_column);

let color = config.color.unwrap_or_default();

let split = session.split.unwrap_or(Split::Vertical);

let has_bat = check_bat();
let has_chafa = check_chafa();
let has_zoxide = check_zoxide();
let is_kitty = check_kitty_support();

Ok(State {
list: Vec::new(),
registers: Registers {
unnamed: vec![],
zero: vec![],
numbered: VecDeque::new(),
named: BTreeMap::new(),
},
operations: Operation {
pos: 0,
op_list: Vec::new(),
},
current_dir: PathBuf::new(),
trash_dir: PathBuf::new(),
config_path,
lwd_file: None,
match_vim_exit_behavior: config.match_vim_exit_behavior.unwrap_or_default(),
has_zoxide,
default: config
.default
.unwrap_or_else(|| env::var("EDITOR").unwrap_or_default()),
commands: to_extension_map(&config.exec),
layout: Layout {
nums: Num::new(),
y: BEGINNING_ROW,
terminal_row: original_row,
terminal_column: original_column,
name_max_len: name_max,
time_start_pos: time_start,
colors: ConfigColor {
dir_fg: color.dir_fg,
file_fg: color.file_fg,
symlink_fg: color.symlink_fg,
dirty_fg: color.dirty_fg,
},
sort_by: session.sort_by,
show_hidden: session.show_hidden,
side: if session.preview.unwrap_or(false) {
Side::Preview
} else {
Side::None
},
split,
preview_start: match split {
Split::Vertical => (0, 0),
Split::Horizontal => (0, 0),
},
preview_space: match split {
Split::Vertical => (0, 0),
Split::Horizontal => (0, 0),
},
has_bat,
has_chafa,
is_kitty,
},
jumplist: JumpList::default(),
c_memo: Vec::new(),
p_memo: Vec::new(),
keyword: None,
v_start: None,
is_ro: false,
layout: Layout::new(session_path, config)?,
..state
})
}

/// Set configuration from config file.
pub fn set_config(&mut self, config: Config) {
let color = config.color.unwrap_or_default();
self.match_vim_exit_behavior = config.match_vim_exit_behavior.unwrap_or_default();
self.default = config
.default
.unwrap_or_else(|| env::var("EDITOR").unwrap_or_default());
self.commands = to_extension_map(&config.exec);
self.layout.colors = color;
}

/// Select item that the cursor points to.
pub fn get_item(&self) -> Result<&ItemInfo, FxError> {
self.list
Expand Down Expand Up @@ -1928,22 +1863,6 @@ fn read_item(entry: fs::DirEntry) -> ItemInfo {
// Ok(result)
// }

/// Check if bat is installed.
fn check_bat() -> bool {
std::process::Command::new("bat")
.arg("--help")
.output()
.is_ok()
}

/// Check if chafa is installed.
fn check_chafa() -> bool {
std::process::Command::new("chafa")
.arg("--help")
.output()
.is_ok()
}

/// Check if zoxide is installed.
fn check_zoxide() -> bool {
std::process::Command::new("zoxide")
Expand All @@ -1952,15 +1871,6 @@ fn check_zoxide() -> bool {
.is_ok()
}

/// Check if the terminal is Kitty or not
fn check_kitty_support() -> bool {
if let Ok(term) = std::env::var("TERM") {
term.contains("kitty")
} else {
false
}
}

/// Set content type from ItemInfo.
fn set_preview_content_type(item: &mut ItemInfo) {
if item.file_size > MAX_SIZE_TO_PREVIEW {
Expand Down

0 comments on commit fbca887

Please sign in to comment.