feat: add editor.first-file-sets-work-dir config option

When starting helix, it already supports updating the working directory
by argument or if the first argument is a directory itself.
The missing piece is updating the working directory when the first argument is a file.

The user can set this in their configuration now.
pull/11410/head
LoveIsGrief 4 months ago
parent 1b5295a3f3
commit 7138860ce8
No known key found for this signature in database
GPG Key ID: E96D1EDFA05345EB

@ -33,11 +33,21 @@ pub fn current_working_dir() -> PathBuf {
cwd
}
pub fn set_current_working_dir(path: impl AsRef<Path>) -> std::io::Result<()> {
/// Updates the current working directory of the current thread
///
/// Should the given path be a file, it will fail **unless** `allow_file` is passed and its parent
/// can be found.
pub fn set_current_working_dir(path: impl AsRef<Path>, allow_file: bool) -> std::io::Result<()> {
let path = crate::path::canonicalize(path);
std::env::set_current_dir(&path)?;
if path.is_file() && allow_file {
std::env::set_current_dir(path.parent().ok_or_else(|| {
std::io::Error::new(std::io::ErrorKind::NotFound, "File has no parent?")
})?)?;
} else {
std::env::set_current_dir(&path)?;
}
let mut cwd = CWD.write().unwrap();
*cwd = Some(path);
*cwd = Some(std::env::current_dir()?);
Ok(())
}
@ -83,7 +93,7 @@ mod tests {
let cwd = current_working_dir();
assert_ne!(cwd, new_path);
set_current_working_dir(&new_path).expect("Couldn't set new path");
set_current_working_dir(&new_path, false).expect("Couldn't set new path");
let cwd = current_working_dir();
assert_eq!(cwd, new_path);

@ -1093,7 +1093,7 @@ fn change_current_directory(
.as_ref();
let dir = helix_stdx::path::expand_tilde(Path::new(dir));
helix_stdx::env::set_current_working_dir(dir)?;
helix_stdx::env::set_current_working_dir(dir, false)?;
cx.editor.set_status(format!(
"Current working directory is now {}",

@ -122,12 +122,17 @@ FLAGS:
}
// NOTE: Set the working directory early so the correct configuration is loaded. Be aware that
// Application::new() depends on this logic so it must be updated if this changes.
if let Some(path) = &args.working_directory {
helix_stdx::env::set_current_working_dir(path)?;
} else if let Some((path, _)) = args.files.first().filter(|p| p.0.is_dir()) {
let first_arg = args.files.first();
let cwd_changed = if let Some(path) = &args.working_directory {
helix_stdx::env::set_current_working_dir(path, false)?;
true
} else if let Some((path, _)) = first_arg.filter(|p| p.0.is_dir()) {
// If the first file is a directory, it will be the working directory unless -w was specified
helix_stdx::env::set_current_working_dir(path)?;
}
helix_stdx::env::set_current_working_dir(path, false)?;
true
} else {
false
};
let config = match Config::load_default() {
Ok(config) => config,
@ -144,6 +149,12 @@ FLAGS:
}
};
if let Some((path, _)) = first_arg {
if !cwd_changed && config.editor.first_file_sets_work_dir {
helix_stdx::env::set_current_working_dir(path, true)?;
}
}
let lang_loader = helix_core::config::user_lang_loader().unwrap_or_else(|err| {
eprintln!("{}", err);
eprintln!("Press <ENTER> to continue with default language config");

@ -345,6 +345,8 @@ pub struct Config {
/// Display diagnostic below the line they occur.
pub inline_diagnostics: InlineDiagnosticsConfig,
pub end_of_line_diagnostics: DiagnosticFilter,
/// Should the first CLI arg be a file, the working directory may be set to its parent
pub first_file_sets_work_dir: bool,
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
@ -979,6 +981,7 @@ impl Default for Config {
jump_label_alphabet: ('a'..='z').collect(),
inline_diagnostics: InlineDiagnosticsConfig::default(),
end_of_line_diagnostics: DiagnosticFilter::Disable,
first_file_sets_work_dir: false,
}
}
}

Loading…
Cancel
Save