forked from extern/nushell
Add LIB_DIRS and PLUGIN_DIRS (#4829)
* Add LIB_DIRS and PLUGIN_DIRS * Put plugin dirs behind plugin feature
This commit is contained in:
parent
0ff9cc679e
commit
c73d8d5f95
@ -8,6 +8,11 @@ use nu_protocol::{
|
|||||||
span, Exportable, Overlay, PositionalArg, Span, SyntaxShape, Type, CONFIG_VARIABLE_ID,
|
span, Exportable, Overlay, PositionalArg, Span, SyntaxShape, Type, CONFIG_VARIABLE_ID,
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
static LIB_DIRS_ENV: &str = "NU_LIB_DIRS";
|
||||||
|
#[cfg(feature = "plugin")]
|
||||||
|
static PLUGIN_DIRS_ENV: &str = "NU_PLUGIN_DIRS";
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
known_external::KnownExternal,
|
known_external::KnownExternal,
|
||||||
@ -1097,7 +1102,9 @@ pub fn parse_use(
|
|||||||
if let Ok(module_filename) =
|
if let Ok(module_filename) =
|
||||||
String::from_utf8(trim_quotes(&import_pattern.head.name).to_vec())
|
String::from_utf8(trim_quotes(&import_pattern.head.name).to_vec())
|
||||||
{
|
{
|
||||||
if let Ok(module_path) = canonicalize_with(&module_filename, cwd) {
|
if let Some(module_path) =
|
||||||
|
find_in_dirs(&module_filename, working_set, &cwd, LIB_DIRS_ENV)
|
||||||
|
{
|
||||||
let module_name = if let Some(stem) = module_path.file_stem() {
|
let module_name = if let Some(stem) = module_path.file_stem() {
|
||||||
stem.to_string_lossy().to_string()
|
stem.to_string_lossy().to_string()
|
||||||
} else {
|
} else {
|
||||||
@ -1561,7 +1568,7 @@ pub fn parse_source(
|
|||||||
let name_expr = working_set.get_span_contents(spans[1]);
|
let name_expr = working_set.get_span_contents(spans[1]);
|
||||||
let name_expr = trim_quotes(name_expr);
|
let name_expr = trim_quotes(name_expr);
|
||||||
if let Ok(filename) = String::from_utf8(name_expr.to_vec()) {
|
if let Ok(filename) = String::from_utf8(name_expr.to_vec()) {
|
||||||
if let Ok(path) = canonicalize_with(&filename, cwd) {
|
if let Some(path) = find_in_dirs(&filename, working_set, &cwd, LIB_DIRS_ENV) {
|
||||||
if let Ok(contents) = std::fs::read(&path) {
|
if let Ok(contents) = std::fs::read(&path) {
|
||||||
// This will load the defs from the file into the
|
// This will load the defs from the file into the
|
||||||
// working set, if it was a successful parse.
|
// working set, if it was a successful parse.
|
||||||
@ -1697,7 +1704,6 @@ pub fn parse_register(
|
|||||||
// Extracting the required arguments from the call and keeping them together in a tuple
|
// Extracting the required arguments from the call and keeping them together in a tuple
|
||||||
// The ? operator is not used because the error has to be kept to be printed in the shell
|
// The ? operator is not used because the error has to be kept to be printed in the shell
|
||||||
// For that reason the values are kept in a result that will be passed at the end of this call
|
// For that reason the values are kept in a result that will be passed at the end of this call
|
||||||
let cwd_clone = cwd.clone();
|
|
||||||
let arguments = call
|
let arguments = call
|
||||||
.positional
|
.positional
|
||||||
.get(0)
|
.get(0)
|
||||||
@ -1707,9 +1713,12 @@ pub fn parse_register(
|
|||||||
let name_expr = trim_quotes(name_expr);
|
let name_expr = trim_quotes(name_expr);
|
||||||
String::from_utf8(name_expr.to_vec())
|
String::from_utf8(name_expr.to_vec())
|
||||||
.map_err(|_| ParseError::NonUtf8(expr.span))
|
.map_err(|_| ParseError::NonUtf8(expr.span))
|
||||||
.and_then(move |name| {
|
.and_then(|name| {
|
||||||
canonicalize_with(&name, cwd_clone)
|
if let Some(p) = find_in_dirs(&name, working_set, &cwd, PLUGIN_DIRS_ENV) {
|
||||||
.map_err(|_| ParseError::FileNotFound(name, expr.span))
|
Ok(p)
|
||||||
|
} else {
|
||||||
|
Err(ParseError::FileNotFound(name, expr.span))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.and_then(|path| {
|
.and_then(|path| {
|
||||||
if path.exists() & path.is_file() {
|
if path.exists() & path.is_file() {
|
||||||
@ -1832,3 +1841,41 @@ pub fn parse_register(
|
|||||||
error,
|
error,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_in_dirs(
|
||||||
|
filename: &str,
|
||||||
|
working_set: &StateWorkingSet,
|
||||||
|
cwd: &str,
|
||||||
|
dirs_env: &str,
|
||||||
|
) -> Option<PathBuf> {
|
||||||
|
if let Ok(p) = canonicalize_with(filename, cwd) {
|
||||||
|
Some(p)
|
||||||
|
} else {
|
||||||
|
let path = Path::new(filename);
|
||||||
|
|
||||||
|
if path.is_relative() {
|
||||||
|
if let Some(lib_dirs) = working_set.get_env(dirs_env) {
|
||||||
|
if let Ok(dirs) = lib_dirs.as_list() {
|
||||||
|
for lib_dir in dirs {
|
||||||
|
if let Ok(dir) = lib_dir.as_path() {
|
||||||
|
if let Ok(dir_abs) = canonicalize_with(&dir, cwd) {
|
||||||
|
// make sure the dir is absolute path
|
||||||
|
if let Ok(path) = canonicalize_with(filename, dir_abs) {
|
||||||
|
return Some(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,6 +16,8 @@ use std::path::Path;
|
|||||||
#[cfg(feature = "plugin")]
|
#[cfg(feature = "plugin")]
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
static PWD_ENV: &str = "PWD";
|
||||||
|
|
||||||
// Tells whether a decl etc. is visible or not
|
// Tells whether a decl etc. is visible or not
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Visibility {
|
struct Visibility {
|
||||||
@ -1175,11 +1177,15 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
let pwd = self
|
let pwd = self
|
||||||
.permanent_state
|
.permanent_state
|
||||||
.env_vars
|
.env_vars
|
||||||
.get("PWD")
|
.get(PWD_ENV)
|
||||||
.expect("internal error: can't find PWD");
|
.expect("internal error: can't find PWD");
|
||||||
pwd.as_string().expect("internal error: PWD not a string")
|
pwd.as_string().expect("internal error: PWD not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_env(&self, name: &str) -> Option<&Value> {
|
||||||
|
self.permanent_state.env_vars.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_variable_type(&mut self, var_id: VarId, ty: Type) {
|
pub fn set_variable_type(&mut self, var_id: VarId, ty: Type) {
|
||||||
let num_permanent_vars = self.permanent_state.num_vars();
|
let num_permanent_vars = self.permanent_state.num_vars();
|
||||||
if var_id < num_permanent_vars {
|
if var_id < num_permanent_vars {
|
||||||
|
@ -40,6 +40,20 @@ let-env ENV_CONVERSIONS = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Directories to search for scripts when calling source or use
|
||||||
|
#
|
||||||
|
# By default, <nushell-config-dir>/scripts is added
|
||||||
|
let-env NU_LIB_DIRS = [
|
||||||
|
($nu.config-path | path dirname | path join 'scripts')
|
||||||
|
]
|
||||||
|
|
||||||
|
# Directories to search for plugin binaries when calling register
|
||||||
|
#
|
||||||
|
# By default, <nushell-config-dir>/plugins is added
|
||||||
|
let-env NU_PLUGIN_DIRS = [
|
||||||
|
($nu.config-path | path dirname | path join 'plugins')
|
||||||
|
]
|
||||||
|
|
||||||
# Custom completions for external commands (those outside of Nushell)
|
# Custom completions for external commands (those outside of Nushell)
|
||||||
# Each completions has two parts: the form of the external command, including its flags and parameters
|
# Each completions has two parts: the form of the external command, including its flags and parameters
|
||||||
# and a helper command that knows how to complete values for those flags and parameters
|
# and a helper command that knows how to complete values for those flags and parameters
|
||||||
@ -229,7 +243,7 @@ let $config = {
|
|||||||
name: history_previous
|
name: history_previous
|
||||||
modifier: control
|
modifier: control
|
||||||
keycode: char_z
|
keycode: char_z
|
||||||
mode: emacs
|
mode: emacs
|
||||||
event: {
|
event: {
|
||||||
until: [
|
until: [
|
||||||
{ send: menupageprevious }
|
{ send: menupageprevious }
|
||||||
|
Loading…
Reference in New Issue
Block a user