forked from nushell/nushell
-
Notifications
You must be signed in to change notification settings - Fork 1
/
plugin_list.rs
101 lines (94 loc) · 3.66 KB
/
plugin_list.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use itertools::Itertools;
use nu_protocol::{
ast::Call,
engine::{Command, EngineState, Stack},
record, Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature,
Type, Value,
};
#[derive(Clone)]
pub struct PluginList;
impl Command for PluginList {
fn name(&self) -> &str {
"plugin list"
}
fn signature(&self) -> Signature {
Signature::build("plugin list")
.input_output_type(
Type::Nothing,
Type::Table(vec![
("name".into(), Type::String),
("is_running".into(), Type::Bool),
("pid".into(), Type::Int),
("filename".into(), Type::String),
("shell".into(), Type::String),
("commands".into(), Type::List(Type::String.into())),
]),
)
.category(Category::Core)
}
fn usage(&self) -> &str {
"List installed plugins."
}
fn examples(&self) -> Vec<nu_protocol::Example> {
vec![
Example {
example: "plugin list",
description: "List installed plugins.",
result: Some(Value::test_list(vec![Value::test_record(record! {
"name" => Value::test_string("inc"),
"is_running" => Value::test_bool(true),
"pid" => Value::test_int(106480),
"filename" => if cfg!(windows) {
Value::test_string(r"C:\nu\plugins\nu_plugin_inc.exe")
} else {
Value::test_string("/opt/nu/plugins/nu_plugin_inc")
},
"shell" => Value::test_nothing(),
"commands" => Value::test_list(vec![Value::test_string("inc")]),
})])),
},
Example {
example: "ps | where pid in (plugin list).pid",
description: "Get process information for running plugins.",
result: None,
},
]
}
fn run(
&self,
engine_state: &EngineState,
_stack: &mut Stack,
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let span = call.span();
// Group plugin decls by plugin identity
let decls = engine_state.plugin_decls().into_group_map_by(|decl| {
decl.plugin_identity()
.expect("plugin decl should have identity")
});
// Build plugins list
let list = engine_state.plugins().iter().map(|plugin| {
// Find commands that belong to the plugin
let commands = decls.get(plugin.identity())
.into_iter()
.flat_map(|decls| {
decls.iter().map(|decl| Value::string(decl.name(), span))
})
.collect();
Value::record(record! {
"name" => Value::string(plugin.identity().name(), span),
"is_running" => Value::bool(plugin.is_running(), span),
"pid" => plugin.pid()
.map(|p| Value::int(p as i64, span))
.unwrap_or(Value::nothing(span)),
"filename" => Value::string(plugin.identity().filename().to_string_lossy(), span),
"shell" => plugin.identity().shell()
.map(|s| Value::string(s.to_string_lossy(), span))
.unwrap_or(Value::nothing(span)),
"commands" => Value::list(commands, span),
}, span)
}).collect::<Vec<Value>>();
Ok(list.into_pipeline_data(engine_state.ctrlc.clone()))
}
}