Skip to content

Commit

Permalink
fix core-editor ignored (#414) (#419)
Browse files Browse the repository at this point in the history
  • Loading branch information
pm100 authored Dec 7, 2020
1 parent 7a6dc2b commit a6bce24
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 10 deletions.
39 changes: 39 additions & 0 deletions asyncgit/src/sync/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())?)
Expand Down Expand Up @@ -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");
Expand Down
39 changes: 29 additions & 10 deletions src/components/externaleditor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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 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()
};

let remainder_str = echars.collect::<String>();
let remainder = remainder_str.split_whitespace();

let mut editor: Vec<&OsStr> =
editor.map(|s| OsStr::new(s)).collect();
let mut args: Vec<&OsStr> =
remainder.map(|s| OsStr::new(s)).collect();

editor.push(path.as_os_str());
args.push(path.as_os_str());

Command::new(command)
Command::new(command.clone())
.current_dir(work_dir)
.args(editor)
.args(args)
.status()
.map_err(|e| anyhow!("\"{}\": {}", command, e))?;

Expand Down

0 comments on commit a6bce24

Please sign in to comment.