forgot to add files to last commit. L.

This commit is contained in:
mark 2023-04-30 21:35:28 +02:00
parent 0feb1b8778
commit ca3dd4c798
7 changed files with 145 additions and 0 deletions

4
build_scripts/build.sh Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
cd ../mers
cargo build --release
cp target/release/mers ../build_scripts

View File

@ -0,0 +1,5 @@
#!/usr/bin/env sh
cd ../mers
cargo build --features nushell_plugin --profile nushellplugin
cp target/nushellplugin/mers ../build_scripts/nu_plugin_mers
echo "done. now run 'register nu_plugin_mers' in nu. You should then be able to use mers-nu."

View File

@ -0,0 +1,4 @@
#!/usr/bin/env nu
./install_nu_plugin.sh
register nu_plugin_mers
echo "registered plugin automatically."

BIN
build_scripts/mers Executable file

Binary file not shown.

BIN
build_scripts/nu_plugin_mers Executable file

Binary file not shown.

0
custom_type.mers Normal file → Executable file
View File

132
mers/src/nushell_plugin.rs Executable file
View File

@ -0,0 +1,132 @@
use std::{fs, path::PathBuf};
use nu_plugin::{serve_plugin, MsgPackSerializer, Plugin};
use nu_protocol::{PluginExample, PluginSignature, ShellError, Span, Spanned, SyntaxShape, Value};
use crate::{
parse,
script::{
global_info::GlobalScriptInfo,
val_data::{VData, VDataEnum},
},
};
pub fn main() {
serve_plugin(&mut MersNuPlugin(), MsgPackSerializer {});
}
struct MersNuPlugin();
impl Plugin for MersNuPlugin {
fn signature(&self) -> Vec<nu_protocol::PluginSignature> {
vec![PluginSignature::build("mers-nu")
.required(
"mers",
SyntaxShape::String,
"the path to the .mers file to run or the mers source code if -e is set",
)
.optional(
"args",
SyntaxShape::List(Box::new(SyntaxShape::String)),
"the arguments passed to the mers program. defaults to an empty list.",
)
.switch(
"execute",
"instead of reading from a file, interpret the 'mers' input as source code",
Some('e'),
)]
}
fn run(
&mut self,
name: &str,
call: &nu_plugin::EvaluatedCall,
input: &nu_protocol::Value,
) -> Result<nu_protocol::Value, nu_plugin::LabeledError> {
// no need to 'match name {...}' because we only register mers-nu and nothing else.
let source: String = call.req(0)?;
let source_span = Span::unknown(); // source.span;
// let source = source.item;
let mut file = if call.has_flag("execute") {
parse::file::File::new(source, PathBuf::new())
} else {
parse::file::File::new(
match fs::read_to_string(&source) {
Ok(v) => v,
Err(e) => {
return Ok(Value::Error {
error: Box::new(ShellError::FileNotFound(source_span)),
})
}
},
source.into(),
)
};
Ok(match parse::parse::parse(&mut file) {
Ok(code) => {
let args = match call.opt(1)? {
Some(v) => v,
_ => vec![],
};
fn to_nu_val(val: VData, info: &GlobalScriptInfo) -> Value {
let span = Span::unknown();
match val.data {
VDataEnum::Bool(val) => Value::Bool { val, span },
VDataEnum::Int(val) => Value::Int {
val: val as _,
span,
},
VDataEnum::Float(val) => Value::Float { val, span },
VDataEnum::String(val) => Value::String { val, span },
VDataEnum::Tuple(vals) | VDataEnum::List(_, vals) => Value::List {
vals: vals.into_iter().map(|v| to_nu_val(v, info)).collect(),
span,
},
VDataEnum::Reference(r) => to_nu_val(
std::mem::replace(
&mut *r.lock().unwrap(),
VDataEnum::Tuple(vec![]).to(),
),
info,
),
VDataEnum::EnumVariant(variant, val) => {
let name = info
.enum_variants
.iter()
.find_map(|(name, id)| {
if *id == variant {
Some(name.to_owned())
} else {
None
}
})
.unwrap();
Value::Record {
cols: vec![format!("Enum"), format!("Value")],
vals: vec![
Value::String {
val: name,
span: span,
},
to_nu_val(*val, info),
],
span,
}
}
VDataEnum::Function(func) => Value::Nothing { span },
VDataEnum::Thread(t, _) => to_nu_val(t.get(), info),
}
}
to_nu_val(code.run(args), code.info().as_ref())
}
Err(e) => Value::Error {
error: Box::new(ShellError::IncorrectValue {
msg: format!(
"Couldn't compile mers, error: {}",
e.0.with_file_and_gsinfo(&file, e.1.as_ref())
),
span: source_span,
}),
},
})
}
}