Files
nushell/crates/nu_plugin_example/src/commands/view_span.rs
Devyn Cairns 00b3a07efe Add GetSpanContents engine call (#12439)
# Description
This allows plugins to view the source code of spans.

Requested by @ayax79 for implementing `polars ls`. Note that this won't
really help you find the location of the span. I'm planning to add
another engine call that will return information more similar to what
shows up in the miette diagnostics, with filename / line number / some
context, but I'll want to refactor some of the existing logic to make
that happen, so it was easier to just do this first. I hope this is
enough to at least have something somewhat useful show up for `polars
ls`.

# User-Facing Changes
- Example plugin: added `example view span` command

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`

# After Submitting
- [ ] Add to plugin protocol reference
2024-04-09 10:02:17 -04:00

59 lines
1.7 KiB
Rust

use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
use nu_protocol::{Category, Example, LabeledError, Signature, Type, Value};
use crate::ExamplePlugin;
/// `<value> | example view span`
pub struct ViewSpan;
impl SimplePluginCommand for ViewSpan {
type Plugin = ExamplePlugin;
fn name(&self) -> &str {
"example view span"
}
fn usage(&self) -> &str {
"Example command for looking up the contents of a parser span"
}
fn extra_usage(&self) -> &str {
"Shows the original source code of the expression that generated the value passed as input."
}
fn signature(&self) -> Signature {
Signature::build(self.name())
.input_output_type(Type::Any, Type::String)
.category(Category::Experimental)
}
fn search_terms(&self) -> Vec<&str> {
vec!["example"]
}
fn examples(&self) -> Vec<Example> {
vec![Example {
example: "('hello ' ++ 'world') | example view span",
description: "Show the source code of the expression that generated a value",
result: Some(Value::test_string("'hello ' ++ 'world'")),
}]
}
fn run(
&self,
_plugin: &ExamplePlugin,
engine: &EngineInterface,
call: &EvaluatedCall,
input: &Value,
) -> Result<Value, LabeledError> {
let contents = engine.get_span_contents(input.span())?;
Ok(Value::string(String::from_utf8_lossy(&contents), call.head))
}
}
#[test]
fn test_examples() -> Result<(), nu_protocol::ShellError> {
use nu_plugin_test_support::PluginTest;
PluginTest::new("example", ExamplePlugin.into())?.test_command_examples(&ViewSpan)
}