mirror of
https://github.com/nushell/nushell.git
synced 2025-04-28 15:18:18 +02:00
This PR sets the current working directory to the location of the Nushell executable at startup, using `std::env::set_current_dir()`. This is desirable because after PR https://github.com/nushell/nushell/pull/12922, we no longer change our current working directory even after `cd` is executed, and some OS might lock the directory where Nushell started. The location of the Nushell executable is chosen because it cannot be removed while Nushell is running anyways, so we don't have to worry about OS locking it. This PR has the side effect that it breaks buggy command even harder. I'll keep this PR as a draft until these commands are fixed, but it might be helpful to pull this PR if you're working on fixing one of those bugs. --------- Co-authored-by: Devyn Cairns <devyn.cairns@gmail.com> Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
97 lines
3.4 KiB
Rust
97 lines
3.4 KiB
Rust
use nu_protocol::{
|
|
engine::{EngineState, Stack},
|
|
Range, ShellError, Span, Value,
|
|
};
|
|
use std::ops::Bound;
|
|
|
|
type MakeRangeError = fn(&str, Span) -> ShellError;
|
|
|
|
/// Returns a inclusive pair of boundary in given `range`.
|
|
pub fn process_range(range: &Range) -> Result<(isize, isize), MakeRangeError> {
|
|
match range {
|
|
Range::IntRange(range) => {
|
|
let start = range.start().try_into().unwrap_or(0);
|
|
let end = match range.end() {
|
|
Bound::Included(v) => v as isize,
|
|
Bound::Excluded(v) => (v - 1) as isize,
|
|
Bound::Unbounded => isize::MAX,
|
|
};
|
|
Ok((start, end))
|
|
}
|
|
Range::FloatRange(_) => Err(|msg, span| ShellError::TypeMismatch {
|
|
err_message: msg.to_string(),
|
|
span,
|
|
}),
|
|
}
|
|
}
|
|
|
|
const HELP_MSG: &str = "Nushell's config file can be found with the command: $nu.config-path. \
|
|
For more help: (https://nushell.sh/book/configuration.html#configurations-with-built-in-commands)";
|
|
|
|
fn get_editor_commandline(
|
|
value: &Value,
|
|
var_name: &str,
|
|
) -> Result<(String, Vec<String>), ShellError> {
|
|
match value {
|
|
Value::String { val, .. } if !val.is_empty() => Ok((val.to_string(), Vec::new())),
|
|
Value::List { vals, .. } if !vals.is_empty() => {
|
|
let mut editor_cmd = vals.iter().map(|l| l.coerce_string());
|
|
match editor_cmd.next().transpose()? {
|
|
Some(editor) if !editor.is_empty() => {
|
|
let params = editor_cmd.collect::<Result<_, ShellError>>()?;
|
|
Ok((editor, params))
|
|
}
|
|
_ => Err(ShellError::GenericError {
|
|
error: "Editor executable is missing".into(),
|
|
msg: "Set the first element to an executable".into(),
|
|
span: Some(value.span()),
|
|
help: Some(HELP_MSG.into()),
|
|
inner: vec![],
|
|
}),
|
|
}
|
|
}
|
|
Value::String { .. } | Value::List { .. } => Err(ShellError::GenericError {
|
|
error: format!("{var_name} should be a non-empty string or list<String>"),
|
|
msg: "Specify an executable here".into(),
|
|
span: Some(value.span()),
|
|
help: Some(HELP_MSG.into()),
|
|
inner: vec![],
|
|
}),
|
|
x => Err(ShellError::CantConvert {
|
|
to_type: "string or list<string>".into(),
|
|
from_type: x.get_type().to_string(),
|
|
span: value.span(),
|
|
help: None,
|
|
}),
|
|
}
|
|
}
|
|
|
|
pub fn get_editor(
|
|
engine_state: &EngineState,
|
|
stack: &Stack,
|
|
span: Span,
|
|
) -> Result<(String, Vec<String>), ShellError> {
|
|
let config = engine_state.get_config();
|
|
let env_vars = stack.get_env_vars(engine_state);
|
|
|
|
if let Ok(buff_editor) =
|
|
get_editor_commandline(&config.buffer_editor, "$env.config.buffer_editor")
|
|
{
|
|
Ok(buff_editor)
|
|
} else if let Some(value) = env_vars.get("EDITOR") {
|
|
get_editor_commandline(value, "$env.EDITOR")
|
|
} else if let Some(value) = env_vars.get("VISUAL") {
|
|
get_editor_commandline(value, "$env.VISUAL")
|
|
} else {
|
|
Err(ShellError::GenericError {
|
|
error: "No editor configured".into(),
|
|
msg:
|
|
"Please specify one via `$env.config.buffer_editor` or `$env.EDITOR`/`$env.VISUAL`"
|
|
.into(),
|
|
span: Some(span),
|
|
help: Some(HELP_MSG.into()),
|
|
inner: vec![],
|
|
})
|
|
}
|
|
}
|