Add 'export def' command

This commit is contained in:
Jakub Žádník 2021-09-28 21:03:53 +03:00
parent 561feff365
commit 93521da9d8
3 changed files with 78 additions and 2 deletions

View File

@ -6,7 +6,7 @@ use nu_protocol::{
};
use crate::{
Alias, Benchmark, BuildString, Def, Do, Each, External, For, From, FromJson, Git, GitCheckout,
Alias, Benchmark, BuildString, Def, Do, Each, ExportDef, External, For, From, FromJson, Git, GitCheckout,
If, Length, Let, LetEnv, Lines, ListGitBranches, Ls, Module, Sys, Table, Use, Where,
};
@ -20,12 +20,20 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition");
working_set.add_decl(sig.predeclare());
working_set.add_decl(Box::new(If));
working_set.add_decl(Box::new(Let));
working_set.add_decl(Box::new(LetEnv));
working_set.add_decl(Box::new(Alias));
working_set.add_decl(Box::new(Benchmark));
working_set.add_decl(Box::new(BuildString));
working_set.add_decl(Box::new(Def));
working_set.add_decl(Box::new(Do));
working_set.add_decl(Box::new(Each));
working_set.add_decl(Box::new(ExportDef));
working_set.add_decl(Box::new(External));
working_set.add_decl(Box::new(For));
working_set.add_decl(Box::new(From));

View File

@ -0,0 +1,35 @@
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EvaluationContext};
use nu_protocol::{Signature, SyntaxShape, Value};
pub struct ExportDef;
impl Command for ExportDef {
fn name(&self) -> &str {
"export def"
}
fn usage(&self) -> &str {
"Define a custom command and export it from a module"
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("export def")
.required("target", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters")
.required(
"block",
SyntaxShape::Block(Some(vec![])),
"body of the definition",
)
}
fn run(
&self,
_context: &EvaluationContext,
call: &Call,
_input: Value,
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
Ok(Value::Nothing { span: call.head })
}
}

View File

@ -235,7 +235,40 @@ pub fn parse_export(
let export_name = working_set.get_span_contents(spans[1]);
match export_name {
b"def" => parse_def(working_set, &spans[1..]),
b"def" => {
let (stmt, err) = parse_def(working_set, &spans[1..]);
let export_def_decl_id = working_set
.find_decl(b"export def")
.expect("internal error: missing 'export def' command");
// Trying to warp the 'def' call into the 'export def' in a very clumsy way
let stmt = if let Statement::Pipeline(ref pipe) = stmt {
if !pipe.expressions.is_empty() {
if let Expr::Call(ref call) = pipe.expressions[0].expr {
let mut call = call.clone();
call.head = span(&spans[0..=1]);
call.decl_id = export_def_decl_id;
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
expr: Expr::Call(call),
span: span(spans),
ty: Type::Unknown,
custom_completion: None,
}]))
} else {
stmt
}
} else {
stmt
}
} else {
stmt
};
(stmt, err)
}
_ => (
garbage_statement(spans),
Some(ParseError::Expected(