mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 13:15:58 +02:00
Change the usage misnomer to "description" (#13598)
# Description The meaning of the word usage is specific to describing how a command function is *used* and not a synonym for general description. Usage can be used to describe the SYNOPSIS or EXAMPLES sections of a man page where the permitted argument combinations are shown or example *uses* are given. Let's not confuse people and call it what it is a description. Our `help` command already creates its own *Usage* section based on the available arguments and doesn't refer to the description with usage. # User-Facing Changes `help commands` and `scope commands` will now use `description` or `extra_description` `usage`-> `description` `extra_usage` -> `extra_description` Breaking change in the plugin protocol: In the signature record communicated with the engine. `usage`-> `description` `extra_usage` -> `extra_description` The same rename also takes place for the methods on `SimplePluginCommand` and `PluginCommand` # Tests + Formatting - Updated plugin protocol specific changes # After Submitting - [ ] update plugin protocol doc
This commit is contained in:
committed by
GitHub
parent
3ab9f0b90a
commit
95b78eee25
@ -15,8 +15,8 @@ pub struct Alias {
|
||||
/// Wrapped inner [`Command`]. `None` if alias of external call
|
||||
pub command: Option<Box<dyn Command>>,
|
||||
pub wrapped_call: Expression,
|
||||
pub usage: String,
|
||||
pub extra_usage: String,
|
||||
pub description: String,
|
||||
pub extra_description: String,
|
||||
}
|
||||
|
||||
impl Command for Alias {
|
||||
@ -32,12 +32,12 @@ impl Command for Alias {
|
||||
}
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
&self.usage
|
||||
fn description(&self) -> &str {
|
||||
&self.description
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
&self.extra_usage
|
||||
fn extra_description(&self) -> &str {
|
||||
&self.extra_description
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
@ -31,9 +31,15 @@ pub trait Command: Send + Sync + CommandClone {
|
||||
|
||||
fn signature(&self) -> Signature;
|
||||
|
||||
fn usage(&self) -> &str;
|
||||
/// Short preferably single sentence description for the command.
|
||||
///
|
||||
/// Will be shown with the completions etc.
|
||||
fn description(&self) -> &str;
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
/// Longer documentation description, if necessary.
|
||||
///
|
||||
/// Will be shown below `description`
|
||||
fn extra_description(&self) -> &str {
|
||||
""
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
use crate::{ModuleId, Span};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Organizes usage messages for various primitives
|
||||
/// Organizes documentation comments for various primitives
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct Usage {
|
||||
// TODO: Move decl usages here
|
||||
pub(super) struct Doccomments {
|
||||
// TODO: Move decl doccomments here
|
||||
module_comments: HashMap<ModuleId, Vec<Span>>,
|
||||
}
|
||||
|
||||
impl Usage {
|
||||
impl Doccomments {
|
||||
pub fn new() -> Self {
|
||||
Usage {
|
||||
Doccomments {
|
||||
module_comments: HashMap::new(),
|
||||
}
|
||||
}
|
||||
@ -24,24 +24,24 @@ impl Usage {
|
||||
}
|
||||
|
||||
/// Overwrite own values with the other
|
||||
pub fn merge_with(&mut self, other: Usage) {
|
||||
pub fn merge_with(&mut self, other: Doccomments) {
|
||||
self.module_comments.extend(other.module_comments);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Usage {
|
||||
impl Default for Doccomments {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn build_usage(comment_lines: &[&[u8]]) -> (String, String) {
|
||||
let mut usage = String::new();
|
||||
pub(super) fn build_desc(comment_lines: &[&[u8]]) -> (String, String) {
|
||||
let mut description = String::new();
|
||||
|
||||
let mut num_spaces = 0;
|
||||
let mut first = true;
|
||||
|
||||
// Use the comments to build the usage
|
||||
// Use the comments to build the item/command description
|
||||
for contents in comment_lines {
|
||||
let comment_line = if first {
|
||||
// Count the number of spaces still at the front, skipping the '#'
|
||||
@ -75,17 +75,17 @@ pub(super) fn build_usage(comment_lines: &[&[u8]]) -> (String, String) {
|
||||
String::from_utf8_lossy(&contents[pos..]).to_string()
|
||||
};
|
||||
|
||||
if !usage.is_empty() {
|
||||
usage.push('\n');
|
||||
if !description.is_empty() {
|
||||
description.push('\n');
|
||||
}
|
||||
usage.push_str(&comment_line);
|
||||
description.push_str(&comment_line);
|
||||
}
|
||||
|
||||
if let Some((brief_usage, extra_usage)) = usage.split_once("\r\n\r\n") {
|
||||
(brief_usage.to_string(), extra_usage.to_string())
|
||||
} else if let Some((brief_usage, extra_usage)) = usage.split_once("\n\n") {
|
||||
(brief_usage.to_string(), extra_usage.to_string())
|
||||
if let Some((brief_desc, extra_desc)) = description.split_once("\r\n\r\n") {
|
||||
(brief_desc.to_string(), extra_desc.to_string())
|
||||
} else if let Some((brief_desc, extra_desc)) = description.split_once("\n\n") {
|
||||
(brief_desc.to_string(), extra_desc.to_string())
|
||||
} else {
|
||||
(usage, String::default())
|
||||
(description, String::default())
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ use crate::{
|
||||
ast::Block,
|
||||
debugger::{Debugger, NoopDebugger},
|
||||
engine::{
|
||||
usage::{build_usage, Usage},
|
||||
description::{build_desc, Doccomments},
|
||||
CachedFile, Command, CommandType, EnvVars, OverlayFrame, ScopeFrame, Stack, StateDelta,
|
||||
Variable, Visibility, DEFAULT_OVERLAY_NAME,
|
||||
},
|
||||
@ -84,7 +84,7 @@ pub struct EngineState {
|
||||
pub(super) blocks: Arc<Vec<Arc<Block>>>,
|
||||
pub(super) modules: Arc<Vec<Arc<Module>>>,
|
||||
pub spans: Vec<Span>,
|
||||
usage: Usage,
|
||||
doccomments: Doccomments,
|
||||
pub scope: ScopeFrame,
|
||||
signals: Signals,
|
||||
pub signal_handlers: Option<Handlers>,
|
||||
@ -140,7 +140,7 @@ impl EngineState {
|
||||
DEFAULT_OVERLAY_NAME.as_bytes().to_vec(),
|
||||
))]),
|
||||
spans: vec![Span::unknown()],
|
||||
usage: Usage::new(),
|
||||
doccomments: Doccomments::new(),
|
||||
// make sure we have some default overlay:
|
||||
scope: ScopeFrame::with_empty_overlay(
|
||||
DEFAULT_OVERLAY_NAME.as_bytes().to_vec(),
|
||||
@ -209,7 +209,7 @@ impl EngineState {
|
||||
self.virtual_paths.extend(delta.virtual_paths);
|
||||
self.vars.extend(delta.vars);
|
||||
self.spans.extend(delta.spans);
|
||||
self.usage.merge_with(delta.usage);
|
||||
self.doccomments.merge_with(delta.doccomments);
|
||||
|
||||
// Avoid potentially cloning the Arcs if we aren't adding anything
|
||||
if !delta.decls.is_empty() {
|
||||
@ -644,7 +644,7 @@ impl EngineState {
|
||||
}
|
||||
|
||||
pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> {
|
||||
self.usage.get_module_comments(module_id)
|
||||
self.doccomments.get_module_comments(module_id)
|
||||
}
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
@ -715,7 +715,7 @@ impl EngineState {
|
||||
}
|
||||
output.push((
|
||||
decl.0.clone(),
|
||||
Some(command.usage().to_string()),
|
||||
Some(command.description().to_string()),
|
||||
command.command_type(),
|
||||
));
|
||||
}
|
||||
@ -897,17 +897,17 @@ impl EngineState {
|
||||
self.config_path.get(key)
|
||||
}
|
||||
|
||||
pub fn build_usage(&self, spans: &[Span]) -> (String, String) {
|
||||
pub fn build_desc(&self, spans: &[Span]) -> (String, String) {
|
||||
let comment_lines: Vec<&[u8]> = spans
|
||||
.iter()
|
||||
.map(|span| self.get_span_contents(*span))
|
||||
.collect();
|
||||
build_usage(&comment_lines)
|
||||
build_desc(&comment_lines)
|
||||
}
|
||||
|
||||
pub fn build_module_usage(&self, module_id: ModuleId) -> Option<(String, String)> {
|
||||
pub fn build_module_desc(&self, module_id: ModuleId) -> Option<(String, String)> {
|
||||
self.get_module_comments(module_id)
|
||||
.map(|comment_spans| self.build_usage(comment_spans))
|
||||
.map(|comment_spans| self.build_desc(comment_spans))
|
||||
}
|
||||
|
||||
/// Returns the current working directory, which is guaranteed to be canonicalized.
|
||||
|
@ -5,6 +5,7 @@ mod call;
|
||||
mod call_info;
|
||||
mod capture_block;
|
||||
mod command;
|
||||
mod description;
|
||||
mod engine_state;
|
||||
mod error_handler;
|
||||
mod overlay;
|
||||
@ -14,7 +15,6 @@ mod stack;
|
||||
mod stack_out_dest;
|
||||
mod state_delta;
|
||||
mod state_working_set;
|
||||
mod usage;
|
||||
mod variable;
|
||||
|
||||
pub use cached_file::CachedFile;
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
ast::Block,
|
||||
engine::{
|
||||
usage::Usage, CachedFile, Command, EngineState, OverlayFrame, ScopeFrame, Variable,
|
||||
VirtualPath,
|
||||
description::Doccomments, CachedFile, Command, EngineState, OverlayFrame, ScopeFrame,
|
||||
Variable, VirtualPath,
|
||||
},
|
||||
Module, Span,
|
||||
};
|
||||
@ -22,7 +22,7 @@ pub struct StateDelta {
|
||||
pub blocks: Vec<Arc<Block>>, // indexed by BlockId
|
||||
pub(super) modules: Vec<Arc<Module>>, // indexed by ModuleId
|
||||
pub spans: Vec<Span>, // indexed by SpanId
|
||||
pub(super) usage: Usage,
|
||||
pub(super) doccomments: Doccomments,
|
||||
pub scope: Vec<ScopeFrame>,
|
||||
#[cfg(feature = "plugin")]
|
||||
pub(super) plugins: Vec<Arc<dyn RegisteredPlugin>>,
|
||||
@ -48,7 +48,7 @@ impl StateDelta {
|
||||
modules: vec![],
|
||||
spans: vec![],
|
||||
scope: vec![scope_frame],
|
||||
usage: Usage::new(),
|
||||
doccomments: Doccomments::new(),
|
||||
#[cfg(feature = "plugin")]
|
||||
plugins: vec![],
|
||||
#[cfg(feature = "plugin")]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
ast::Block,
|
||||
engine::{
|
||||
usage::build_usage, CachedFile, Command, CommandType, EngineState, OverlayFrame,
|
||||
description::build_desc, CachedFile, Command, CommandType, EngineState, OverlayFrame,
|
||||
StateDelta, Variable, VirtualPath, Visibility,
|
||||
},
|
||||
BlockId, Category, CompileError, Config, DeclId, FileId, GetSpan, Module, ModuleId, ParseError,
|
||||
@ -278,7 +278,9 @@ impl<'a> StateWorkingSet<'a> {
|
||||
let module_id = self.num_modules() - 1;
|
||||
|
||||
if !comments.is_empty() {
|
||||
self.delta.usage.add_module_comments(module_id, comments);
|
||||
self.delta
|
||||
.doccomments
|
||||
.add_module_comments(module_id, comments);
|
||||
}
|
||||
|
||||
self.last_overlay_mut().modules.insert(name, module_id);
|
||||
@ -288,7 +290,7 @@ impl<'a> StateWorkingSet<'a> {
|
||||
|
||||
pub fn get_module_comments(&self, module_id: ModuleId) -> Option<&[Span]> {
|
||||
self.delta
|
||||
.usage
|
||||
.doccomments
|
||||
.get_module_comments(module_id)
|
||||
.or_else(|| self.permanent_state.get_module_comments(module_id))
|
||||
}
|
||||
@ -727,7 +729,7 @@ impl<'a> StateWorkingSet<'a> {
|
||||
}
|
||||
output.push((
|
||||
decl.0.clone(),
|
||||
Some(command.usage().to_string()),
|
||||
Some(command.description().to_string()),
|
||||
command.command_type(),
|
||||
));
|
||||
}
|
||||
@ -952,12 +954,12 @@ impl<'a> StateWorkingSet<'a> {
|
||||
self.delta
|
||||
}
|
||||
|
||||
pub fn build_usage(&self, spans: &[Span]) -> (String, String) {
|
||||
pub fn build_desc(&self, spans: &[Span]) -> (String, String) {
|
||||
let comment_lines: Vec<&[u8]> = spans
|
||||
.iter()
|
||||
.map(|span| self.get_span_contents(*span))
|
||||
.collect();
|
||||
build_usage(&comment_lines)
|
||||
build_desc(&comment_lines)
|
||||
}
|
||||
|
||||
pub fn find_block_by_span(&self, span: Span) -> Option<Arc<Block>> {
|
||||
|
@ -45,7 +45,7 @@ fn bar_plugin() -> PluginRegistryItem {
|
||||
},
|
||||
commands: vec![PluginSignature {
|
||||
sig: Signature::new("bar")
|
||||
.usage("overwrites files with random data")
|
||||
.description("overwrites files with random data")
|
||||
.switch("force", "ignore errors", Some('f'))
|
||||
.required(
|
||||
"path",
|
||||
|
@ -109,8 +109,8 @@ impl std::fmt::Display for Category {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Signature {
|
||||
pub name: String,
|
||||
pub usage: String,
|
||||
pub extra_usage: String,
|
||||
pub description: String,
|
||||
pub extra_description: String,
|
||||
pub search_terms: Vec<String>,
|
||||
pub required_positional: Vec<PositionalArg>,
|
||||
pub optional_positional: Vec<PositionalArg>,
|
||||
@ -128,7 +128,7 @@ pub struct Signature {
|
||||
impl PartialEq for Signature {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
&& self.usage == other.usage
|
||||
&& self.description == other.description
|
||||
&& self.required_positional == other.required_positional
|
||||
&& self.optional_positional == other.optional_positional
|
||||
&& self.rest_positional == other.rest_positional
|
||||
@ -142,8 +142,8 @@ impl Signature {
|
||||
pub fn new(name: impl Into<String>) -> Signature {
|
||||
Signature {
|
||||
name: name.into(),
|
||||
usage: String::new(),
|
||||
extra_usage: String::new(),
|
||||
description: String::new(),
|
||||
extra_description: String::new(),
|
||||
search_terms: vec![],
|
||||
required_positional: vec![],
|
||||
optional_positional: vec![],
|
||||
@ -220,14 +220,19 @@ impl Signature {
|
||||
}
|
||||
|
||||
/// Add a description to the signature
|
||||
pub fn usage(mut self, msg: impl Into<String>) -> Signature {
|
||||
self.usage = msg.into();
|
||||
///
|
||||
/// This should be a single sentence as it is the part shown for example in the completion
|
||||
/// menu.
|
||||
pub fn description(mut self, msg: impl Into<String>) -> Signature {
|
||||
self.description = msg.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Add an extra description to the signature
|
||||
pub fn extra_usage(mut self, msg: impl Into<String>) -> Signature {
|
||||
self.extra_usage = msg.into();
|
||||
/// Add an extra description to the signature.
|
||||
///
|
||||
/// Here additional documentation can be added
|
||||
pub fn extra_description(mut self, msg: impl Into<String>) -> Signature {
|
||||
self.extra_description = msg.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -244,8 +249,8 @@ impl Signature {
|
||||
.into_iter()
|
||||
.map(|term| term.to_string())
|
||||
.collect();
|
||||
self.extra_usage = command.extra_usage().to_string();
|
||||
self.usage = command.usage().to_string();
|
||||
self.extra_description = command.extra_description().to_string();
|
||||
self.description = command.description().to_string();
|
||||
self
|
||||
}
|
||||
|
||||
@ -627,12 +632,12 @@ impl Command for Predeclaration {
|
||||
self.signature.clone()
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
&self.signature.usage
|
||||
fn description(&self) -> &str {
|
||||
&self.signature.description
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
&self.signature.extra_usage
|
||||
fn extra_description(&self) -> &str {
|
||||
&self.signature.extra_description
|
||||
}
|
||||
|
||||
fn run(
|
||||
@ -680,12 +685,12 @@ impl Command for BlockCommand {
|
||||
self.signature.clone()
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
&self.signature.usage
|
||||
fn description(&self) -> &str {
|
||||
&self.signature.description
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
&self.signature.extra_usage
|
||||
fn extra_description(&self) -> &str {
|
||||
&self.signature.extra_description
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
Reference in New Issue
Block a user