mirror of
https://github.com/gitui-org/gitui
synced 2026-05-24 09:28:21 +00:00
parent
7a6dc2b192
commit
a6bce24d72
2 changed files with 68 additions and 10 deletions
|
|
@ -144,6 +144,29 @@ pub fn stage_addremoved(repo_path: &str, path: &Path) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get string from config
|
||||||
|
pub fn get_config_string(
|
||||||
|
repo_path: &str,
|
||||||
|
key: &str,
|
||||||
|
) -> Result<Option<String>> {
|
||||||
|
let repo = repo(repo_path)?;
|
||||||
|
let cfg = repo.config()?;
|
||||||
|
|
||||||
|
// this code doesnt match what the doc says regarding what
|
||||||
|
// gets returned when but it actually works
|
||||||
|
let entry_res = cfg.get_entry(key);
|
||||||
|
|
||||||
|
let entry = match entry_res {
|
||||||
|
Ok(ent) => ent,
|
||||||
|
Err(_) => return Ok(None),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !entry.has_value() {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
Ok(entry.value().map(|s| s.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
/// helper function
|
/// helper function
|
||||||
pub(crate) fn bytes2string(bytes: &[u8]) -> Result<String> {
|
pub(crate) fn bytes2string(bytes: &[u8]) -> Result<String> {
|
||||||
Ok(String::from_utf8(bytes.to_vec())?)
|
Ok(String::from_utf8(bytes.to_vec())?)
|
||||||
|
|
@ -177,7 +200,23 @@ mod tests {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_get_config() {
|
||||||
|
let bad_dir_cfg =
|
||||||
|
get_config_string("oodly_noodly", "this.doesnt.exist");
|
||||||
|
assert!(bad_dir_cfg.is_err());
|
||||||
|
|
||||||
|
let (_td, repo) = repo_init().unwrap();
|
||||||
|
let path = repo.path();
|
||||||
|
let rpath = path.as_os_str().to_str().unwrap();
|
||||||
|
let bad_cfg = get_config_string(rpath, "this.doesnt.exist");
|
||||||
|
assert!(bad_cfg.is_ok());
|
||||||
|
assert!(bad_cfg.unwrap().is_none());
|
||||||
|
// repo init sets user.name
|
||||||
|
let good_cfg = get_config_string(rpath, "user.name");
|
||||||
|
assert!(good_cfg.is_ok());
|
||||||
|
assert!(good_cfg.unwrap().is_some());
|
||||||
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_staging_one_file() {
|
fn test_staging_one_file() {
|
||||||
let file_path = Path::new("file1.txt");
|
let file_path = Path::new("file1.txt");
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@ use crate::{
|
||||||
ui::{self, style::SharedTheme},
|
ui::{self, style::SharedTheme},
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use asyncgit::{sync::utils::repo_work_dir, CWD};
|
use asyncgit::{
|
||||||
|
sync::utils::get_config_string, sync::utils::repo_work_dir, CWD,
|
||||||
|
};
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
event::Event,
|
event::Event,
|
||||||
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
|
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
|
||||||
|
|
@ -66,26 +68,43 @@ impl ExternalEditorComponent {
|
||||||
|
|
||||||
let editor = env::var("GIT_EDITOR")
|
let editor = env::var("GIT_EDITOR")
|
||||||
.ok()
|
.ok()
|
||||||
|
.or_else(|| get_config_string(CWD, "core.editor").ok()?)
|
||||||
.or_else(|| env::var("VISUAL").ok())
|
.or_else(|| env::var("VISUAL").ok())
|
||||||
.or_else(|| env::var("EDITOR").ok())
|
.or_else(|| env::var("EDITOR").ok())
|
||||||
.unwrap_or_else(|| String::from("vi"));
|
.unwrap_or_else(|| String::from("vi"));
|
||||||
|
|
||||||
// TODO: proper handling arguments containing whitespaces
|
// TODO: proper handling arguments containing whitespaces
|
||||||
// This does not do the right thing if the input is `editor --something "with spaces"`
|
// This does not do the right thing if the input is `editor --something "with spaces"`
|
||||||
let mut editor = editor.split_whitespace();
|
|
||||||
|
|
||||||
let command = editor.next().ok_or_else(|| {
|
// deal with "editor name with spaces" p1 p2 p3
|
||||||
anyhow!("unable to read editor command")
|
// and with "editor_no_spaces" p1 p2 p3
|
||||||
})?;
|
// does not address spaces in pn
|
||||||
|
let mut echars = editor.chars().peekable();
|
||||||
|
|
||||||
let mut editor: Vec<&OsStr> =
|
let command: String = if *echars.peek().ok_or_else(|| {
|
||||||
editor.map(|s| OsStr::new(s)).collect();
|
anyhow!("editor configuration set to empty string")
|
||||||
|
})? == '\"'
|
||||||
|
{
|
||||||
|
echars
|
||||||
|
.by_ref()
|
||||||
|
.skip(1)
|
||||||
|
.take_while(|c| *c != '\"')
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
echars.by_ref().take_while(|c| *c != ' ').collect()
|
||||||
|
};
|
||||||
|
|
||||||
editor.push(path.as_os_str());
|
let remainder_str = echars.collect::<String>();
|
||||||
|
let remainder = remainder_str.split_whitespace();
|
||||||
|
|
||||||
Command::new(command)
|
let mut args: Vec<&OsStr> =
|
||||||
|
remainder.map(|s| OsStr::new(s)).collect();
|
||||||
|
|
||||||
|
args.push(path.as_os_str());
|
||||||
|
|
||||||
|
Command::new(command.clone())
|
||||||
.current_dir(work_dir)
|
.current_dir(work_dir)
|
||||||
.args(editor)
|
.args(args)
|
||||||
.status()
|
.status()
|
||||||
.map_err(|e| anyhow!("\"{}\": {}", command, e))?;
|
.map_err(|e| anyhow!("\"{}\": {}", command, e))?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue