fix core-editor ignored (#414) (#419)

This commit is contained in:
pm100 2020-12-07 15:18:51 -08:00 committed by GitHub
parent 7a6dc2b192
commit a6bce24d72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 10 deletions

View File

@ -144,6 +144,29 @@ pub fn stage_addremoved(repo_path: &str, path: &Path) -> Result<()> {
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
pub(crate) fn bytes2string(bytes: &[u8]) -> Result<String> {
Ok(String::from_utf8(bytes.to_vec())?)
@ -177,7 +200,23 @@ mod tests {
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]
fn test_staging_one_file() {
let file_path = Path::new("file1.txt");

View File

@ -8,7 +8,9 @@ use crate::{
ui::{self, style::SharedTheme},
};
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::{
event::Event,
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
@ -66,26 +68,43 @@ impl ExternalEditorComponent {
let editor = env::var("GIT_EDITOR")
.ok()
.or_else(|| get_config_string(CWD, "core.editor").ok()?)
.or_else(|| env::var("VISUAL").ok())
.or_else(|| env::var("EDITOR").ok())
.unwrap_or_else(|| String::from("vi"));
// TODO: proper handling arguments containing whitespaces
// 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(|| {
anyhow!("unable to read editor command")
})?;
// deal with "editor name with spaces" p1 p2 p3
// 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> =
editor.map(|s| OsStr::new(s)).collect();
let command: String = if *echars.peek().ok_or_else(|| {
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)
.args(editor)
.args(args)
.status()
.map_err(|e| anyhow!("\"{}\": {}", command, e))?;