mirror of
https://github.com/nushell/nushell.git
synced 2025-08-15 23:28:19 +02:00
Plugin with evaluated call (#393)
* plugin trait * impl of trait * record and absolute path * plugin example crate * clippy error * correcting cargo * evaluated call for plugin
This commit is contained in:
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{ast::Call, BlockId, Example, PipelineData, ShellError, Signature};
|
||||
|
||||
use super::{EngineState, Stack};
|
||||
@ -47,7 +49,7 @@ pub trait Command: Send + Sync + CommandClone {
|
||||
}
|
||||
|
||||
// Is a plugin command
|
||||
fn is_plugin(&self) -> Option<&str> {
|
||||
fn is_plugin(&self) -> Option<&PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -222,26 +222,27 @@ impl EngineState {
|
||||
if let Some(plugin_path) = &self.plugin_signatures {
|
||||
// Always creating the file which will erase previous signatures
|
||||
let mut plugin_file = std::fs::File::create(plugin_path.as_path())
|
||||
.map_err(|err| ShellError::PluginError(err.to_string()))?;
|
||||
.map_err(|err| ShellError::InternalError(err.to_string()))?;
|
||||
|
||||
// Plugin definitions with parsed signature
|
||||
for decl in self.plugin_decls() {
|
||||
// A successful plugin registration already includes the plugin filename
|
||||
// No need to check the None option
|
||||
let file_name = decl.is_plugin().expect("plugin should have file name");
|
||||
let path = decl.is_plugin().expect("plugin should have file name");
|
||||
let file_name = path.to_str().expect("path should be a str");
|
||||
|
||||
let line = serde_json::to_string_pretty(&decl.signature())
|
||||
.map(|signature| format!("register {} {}\n", file_name, signature))
|
||||
.map_err(|err| ShellError::PluginError(err.to_string()))?;
|
||||
.map_err(|err| ShellError::InternalError(err.to_string()))?;
|
||||
|
||||
plugin_file
|
||||
.write_all(line.as_bytes())
|
||||
.map_err(|err| ShellError::PluginError(err.to_string()))?;
|
||||
.map_err(|err| ShellError::InternalError(err.to_string()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ShellError::PluginError("Plugin file not found".into()))
|
||||
Err(ShellError::InternalError("Plugin file not found".into()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,11 +511,13 @@ pub struct StateDelta {
|
||||
pub(crate) file_contents: Vec<(Vec<u8>, usize, usize)>,
|
||||
vars: Vec<Type>, // indexed by VarId
|
||||
decls: Vec<Box<dyn Command>>, // indexed by DeclId
|
||||
#[cfg(feature = "plugin")]
|
||||
plugin_decls: Vec<Box<dyn Command>>, // indexed by DeclId
|
||||
blocks: Vec<Block>, // indexed by BlockId
|
||||
overlays: Vec<Overlay>, // indexed by OverlayId
|
||||
pub scope: Vec<ScopeFrame>,
|
||||
#[cfg(feature = "plugin")]
|
||||
pub plugin_signatures: Vec<(PathBuf, Option<Signature>)>,
|
||||
#[cfg(feature = "plugin")]
|
||||
plugin_decls: Vec<Box<dyn Command>>,
|
||||
}
|
||||
|
||||
impl StateDelta {
|
||||
@ -551,11 +554,13 @@ impl<'a> StateWorkingSet<'a> {
|
||||
file_contents: vec![],
|
||||
vars: vec![],
|
||||
decls: vec![],
|
||||
#[cfg(feature = "plugin")]
|
||||
plugin_decls: vec![],
|
||||
blocks: vec![],
|
||||
overlays: vec![],
|
||||
scope: vec![ScopeFrame::new()],
|
||||
#[cfg(feature = "plugin")]
|
||||
plugin_signatures: vec![],
|
||||
#[cfg(feature = "plugin")]
|
||||
plugin_decls: vec![],
|
||||
},
|
||||
permanent_state,
|
||||
}
|
||||
@ -624,8 +629,20 @@ impl<'a> StateWorkingSet<'a> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
pub fn add_plugin_decl(&mut self, decl: Box<dyn Command>) {
|
||||
self.delta.plugin_decls.push(decl);
|
||||
pub fn add_plugin_decls(&mut self, decls: Vec<Box<dyn Command>>) {
|
||||
for decl in decls {
|
||||
self.delta.plugin_decls.push(decl);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
pub fn add_plugin_signature(&mut self, path: PathBuf, signature: Option<Signature>) {
|
||||
self.delta.plugin_signatures.push((path, signature));
|
||||
}
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
pub fn get_signatures(&self) -> impl Iterator<Item = &(PathBuf, Option<Signature>)> {
|
||||
self.delta.plugin_signatures.iter()
|
||||
}
|
||||
|
||||
pub fn merge_predecl(&mut self, name: &[u8]) -> Option<DeclId> {
|
||||
|
Reference in New Issue
Block a user