mirror of
https://github.com/nushell/nushell
synced 2025-01-15 14:44:14 +00:00
Merge pull request #49 from nushell/git_branch_completion
Very early proof-of-concept git branch completion
This commit is contained in:
commit
22e30d5ea7
11 changed files with 293 additions and 4 deletions
|
@ -1,7 +1,11 @@
|
|||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use nu_engine::eval_block;
|
||||
use nu_parser::{flatten_block, parse};
|
||||
use nu_protocol::engine::{EngineState, StateWorkingSet};
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, EvaluationContext, Stack, StateWorkingSet},
|
||||
Value,
|
||||
};
|
||||
use reedline::Completer;
|
||||
|
||||
pub struct NuCompleter {
|
||||
|
@ -26,7 +30,39 @@ impl Completer for NuCompleter {
|
|||
|
||||
for flat in flattened {
|
||||
if pos >= flat.0.start && pos <= flat.0.end {
|
||||
match flat.1 {
|
||||
match &flat.1 {
|
||||
nu_parser::FlatShape::Custom(custom_completion) => {
|
||||
let prefix = working_set.get_span_contents(flat.0).to_vec();
|
||||
|
||||
let (block, ..) =
|
||||
parse(&mut working_set, None, custom_completion.as_bytes(), false);
|
||||
let context = EvaluationContext {
|
||||
engine_state: self.engine_state.clone(),
|
||||
stack: Stack::default(),
|
||||
};
|
||||
let result = eval_block(&context, &block, Value::nothing());
|
||||
|
||||
let v: Vec<_> = match result {
|
||||
Ok(Value::List { vals, .. }) => vals
|
||||
.into_iter()
|
||||
.map(move |x| {
|
||||
let s = x.as_string().expect("FIXME");
|
||||
|
||||
(
|
||||
reedline::Span {
|
||||
start: flat.0.start - offset,
|
||||
end: flat.0.end - offset,
|
||||
},
|
||||
s,
|
||||
)
|
||||
})
|
||||
.filter(|x| x.1.as_bytes().starts_with(&prefix))
|
||||
.collect(),
|
||||
_ => vec![],
|
||||
};
|
||||
|
||||
return v;
|
||||
}
|
||||
nu_parser::FlatShape::External | nu_parser::FlatShape::InternalCall => {
|
||||
let prefix = working_set.get_span_contents(flat.0);
|
||||
let results = working_set.find_commands_by_prefix(prefix);
|
||||
|
|
|
@ -39,6 +39,7 @@ impl Highlighter for NuHighlighter {
|
|||
[(shape.0.start - global_span_offset)..(shape.0.end - global_span_offset)]
|
||||
.to_string();
|
||||
match shape.1 {
|
||||
FlatShape::Custom(..) => output.push((Style::new().bold(), next_token)),
|
||||
FlatShape::External => output.push((Style::new().bold(), next_token)),
|
||||
FlatShape::ExternalArg => output.push((Style::new().bold(), next_token)),
|
||||
FlatShape::Garbage => output.push((
|
||||
|
|
|
@ -6,8 +6,8 @@ use nu_protocol::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
where_::Where, Alias, Benchmark, BuildString, Def, Do, Each, For, If, Length, Let, LetEnv, Ls,
|
||||
Table,
|
||||
where_::Where, Alias, Benchmark, BuildString, Def, Do, Each, For, Git, GitCheckout, If, Length,
|
||||
Let, LetEnv, ListGitBranches, Ls, Table,
|
||||
};
|
||||
|
||||
pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
||||
|
@ -48,6 +48,11 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
|||
|
||||
working_set.add_decl(Box::new(Table));
|
||||
|
||||
// This is a WIP proof of concept
|
||||
working_set.add_decl(Box::new(ListGitBranches));
|
||||
working_set.add_decl(Box::new(Git));
|
||||
working_set.add_decl(Box::new(GitCheckout));
|
||||
|
||||
let sig = Signature::build("exit");
|
||||
working_set.add_decl(sig.predeclare());
|
||||
let sig = Signature::build("vars");
|
||||
|
|
51
crates/nu-command/src/git.rs
Normal file
51
crates/nu-command/src/git.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, Value};
|
||||
|
||||
pub struct Git;
|
||||
|
||||
impl Command for Git {
|
||||
fn name(&self) -> &str {
|
||||
"git"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Run a block"
|
||||
}
|
||||
|
||||
fn signature(&self) -> nu_protocol::Signature {
|
||||
Signature::build("git")
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
use std::process::Command as ProcessCommand;
|
||||
use std::process::Stdio;
|
||||
|
||||
let proc = ProcessCommand::new("git").stdout(Stdio::piped()).spawn();
|
||||
|
||||
match proc {
|
||||
Ok(child) => {
|
||||
match child.wait_with_output() {
|
||||
Ok(val) => {
|
||||
let result = val.stdout;
|
||||
|
||||
Ok(Value::string(&String::from_utf8_lossy(&result), call.head))
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME
|
||||
Ok(Value::nothing())
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME
|
||||
Ok(Value::nothing())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
66
crates/nu-command/src/git_checkout.rs
Normal file
66
crates/nu-command/src/git_checkout.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
|
||||
pub struct GitCheckout;
|
||||
|
||||
impl Command for GitCheckout {
|
||||
fn name(&self) -> &str {
|
||||
"git checkout"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Checkout a git revision"
|
||||
}
|
||||
|
||||
fn signature(&self) -> nu_protocol::Signature {
|
||||
Signature::build("git checkout").required(
|
||||
"branch",
|
||||
SyntaxShape::Custom(Box::new(SyntaxShape::String), "list-git-branches".into()),
|
||||
"the branch to checkout",
|
||||
)
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
use std::process::Command as ProcessCommand;
|
||||
use std::process::Stdio;
|
||||
|
||||
let block = &call.positional[0];
|
||||
|
||||
let out = eval_expression(context, block)?;
|
||||
|
||||
let out = out.as_string()?;
|
||||
|
||||
let proc = ProcessCommand::new("git")
|
||||
.arg("checkout")
|
||||
.arg(out)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn();
|
||||
|
||||
match proc {
|
||||
Ok(child) => {
|
||||
match child.wait_with_output() {
|
||||
Ok(val) => {
|
||||
let result = val.stdout;
|
||||
|
||||
Ok(Value::string(&String::from_utf8_lossy(&result), call.head))
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME
|
||||
Ok(Value::nothing())
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_err) => {
|
||||
// FIXME
|
||||
Ok(Value::nothing())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,10 +6,13 @@ mod default_context;
|
|||
mod do_;
|
||||
mod each;
|
||||
mod for_;
|
||||
mod git;
|
||||
mod git_checkout;
|
||||
mod if_;
|
||||
mod length;
|
||||
mod let_;
|
||||
mod let_env;
|
||||
mod list_git_branches;
|
||||
mod ls;
|
||||
mod table;
|
||||
mod where_;
|
||||
|
@ -22,9 +25,12 @@ pub use default_context::create_default_context;
|
|||
pub use do_::Do;
|
||||
pub use each::Each;
|
||||
pub use for_::For;
|
||||
pub use git::Git;
|
||||
pub use git_checkout::GitCheckout;
|
||||
pub use if_::If;
|
||||
pub use length::Length;
|
||||
pub use let_::Let;
|
||||
pub use let_env::LetEnv;
|
||||
pub use list_git_branches::ListGitBranches;
|
||||
pub use ls::Ls;
|
||||
pub use table::Table;
|
||||
|
|
69
crates/nu-command/src/list_git_branches.rs
Normal file
69
crates/nu-command/src/list_git_branches.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Note: this is a temporary command that later will be converted into a pipeline
|
||||
|
||||
use std::process::Command as ProcessCommand;
|
||||
use std::process::Stdio;
|
||||
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{Signature, Value};
|
||||
|
||||
pub struct ListGitBranches;
|
||||
|
||||
//NOTE: this is not a real implementation :D. It's just a simple one to test with until we port the real one.
|
||||
impl Command for ListGitBranches {
|
||||
fn name(&self) -> &str {
|
||||
"list-git-branches"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"List the git branches of the current directory."
|
||||
}
|
||||
|
||||
fn signature(&self) -> nu_protocol::Signature {
|
||||
Signature::build("list-git-branches")
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||
let list_branches = ProcessCommand::new("git")
|
||||
.arg("branch")
|
||||
.stdout(Stdio::piped())
|
||||
.spawn();
|
||||
|
||||
if let Ok(child) = list_branches {
|
||||
if let Ok(output) = child.wait_with_output() {
|
||||
let val = output.stdout;
|
||||
|
||||
let s = String::from_utf8_lossy(&val).to_string();
|
||||
|
||||
let lines: Vec<_> = s
|
||||
.lines()
|
||||
.filter_map(|x| {
|
||||
if x.starts_with("* ") {
|
||||
None
|
||||
} else {
|
||||
Some(x.trim())
|
||||
}
|
||||
})
|
||||
.map(|x| Value::String {
|
||||
val: x.into(),
|
||||
span: call.head,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(Value::List {
|
||||
vals: lines,
|
||||
span: call.head,
|
||||
})
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
}
|
||||
} else {
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ pub enum FlatShape {
|
|||
Signature,
|
||||
String,
|
||||
Variable,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
pub fn flatten_block(working_set: &StateWorkingSet, block: &Block) -> Vec<(Span, FlatShape)> {
|
||||
|
@ -40,6 +41,10 @@ pub fn flatten_expression(
|
|||
working_set: &StateWorkingSet,
|
||||
expr: &Expression,
|
||||
) -> Vec<(Span, FlatShape)> {
|
||||
if let Some(custom_completion) = &expr.custom_completion {
|
||||
return vec![(expr.span, FlatShape::Custom(custom_completion.clone()))];
|
||||
}
|
||||
|
||||
match &expr.expr {
|
||||
Expr::BinaryOp(lhs, op, rhs) => {
|
||||
let mut output = vec![];
|
||||
|
|
|
@ -113,6 +113,7 @@ pub fn parse_external_call(
|
|||
expr: Expr::ExternalCall(name, args),
|
||||
span: span(spans),
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -360,6 +361,7 @@ fn parse_multispan_value(
|
|||
),
|
||||
span: arg_span,
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
);
|
||||
|
@ -374,6 +376,7 @@ fn parse_multispan_value(
|
|||
expr: Expr::Keyword(keyword.clone(), keyword_span, Box::new(expr)),
|
||||
span: arg_span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
|
@ -553,12 +556,14 @@ pub fn parse_call(
|
|||
expr: Expr::Call(mut call),
|
||||
span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
} => {
|
||||
call.head = orig_span;
|
||||
Expression {
|
||||
expr: Expr::Call(call),
|
||||
span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
}
|
||||
}
|
||||
x => x,
|
||||
|
@ -596,12 +601,14 @@ pub fn parse_call(
|
|||
expr: Expr::Call(mut call),
|
||||
span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
} => {
|
||||
call.head = orig_span;
|
||||
Expression {
|
||||
expr: Expr::Call(call),
|
||||
span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
}
|
||||
}
|
||||
x => x,
|
||||
|
@ -644,6 +651,7 @@ pub fn parse_call(
|
|||
expr: Expr::Call(call),
|
||||
span: span(spans),
|
||||
ty: Type::Unknown, // FIXME
|
||||
custom_completion: None,
|
||||
},
|
||||
err,
|
||||
)
|
||||
|
@ -668,6 +676,7 @@ pub fn parse_int(token: &[u8], span: Span) -> (Expression, Option<ParseError>) {
|
|||
expr: Expr::Int(v),
|
||||
span,
|
||||
ty: Type::Int,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -688,6 +697,7 @@ pub fn parse_int(token: &[u8], span: Span) -> (Expression, Option<ParseError>) {
|
|||
expr: Expr::Int(v),
|
||||
span,
|
||||
ty: Type::Int,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -708,6 +718,7 @@ pub fn parse_int(token: &[u8], span: Span) -> (Expression, Option<ParseError>) {
|
|||
expr: Expr::Int(v),
|
||||
span,
|
||||
ty: Type::Int,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -727,6 +738,7 @@ pub fn parse_int(token: &[u8], span: Span) -> (Expression, Option<ParseError>) {
|
|||
expr: Expr::Int(x),
|
||||
span,
|
||||
ty: Type::Int,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -745,6 +757,7 @@ pub fn parse_float(token: &[u8], span: Span) -> (Expression, Option<ParseError>)
|
|||
expr: Expr::Float(x),
|
||||
span,
|
||||
ty: Type::Float,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -901,6 +914,7 @@ pub fn parse_range(
|
|||
expr: Expr::Range(from, next, to, range_op),
|
||||
span,
|
||||
ty: Type::Range,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -971,6 +985,7 @@ pub fn parse_string_interpolation(
|
|||
expr: Expr::String(String::from_utf8_lossy(str_contents).to_string()),
|
||||
span,
|
||||
ty: Type::String,
|
||||
custom_completion: None,
|
||||
});
|
||||
}
|
||||
token_start = b;
|
||||
|
@ -1013,6 +1028,7 @@ pub fn parse_string_interpolation(
|
|||
expr: Expr::String(String::from_utf8_lossy(str_contents).to_string()),
|
||||
span,
|
||||
ty: Type::String,
|
||||
custom_completion: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1044,6 +1060,7 @@ pub fn parse_string_interpolation(
|
|||
})),
|
||||
span,
|
||||
ty: Type::String,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
|
@ -1067,6 +1084,7 @@ pub fn parse_variable_expr(
|
|||
expr: Expr::Bool(true),
|
||||
span,
|
||||
ty: Type::Bool,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
@ -1076,6 +1094,7 @@ pub fn parse_variable_expr(
|
|||
expr: Expr::Bool(false),
|
||||
span,
|
||||
ty: Type::Bool,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
@ -1090,6 +1109,7 @@ pub fn parse_variable_expr(
|
|||
expr: Expr::Var(id),
|
||||
span,
|
||||
ty: working_set.get_variable(id).clone(),
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -1159,6 +1179,7 @@ pub fn parse_full_column_path(
|
|||
expr: Expr::Subexpression(block_id),
|
||||
span,
|
||||
ty: Type::Unknown, // FIXME
|
||||
custom_completion: None,
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
@ -1175,6 +1196,7 @@ pub fn parse_full_column_path(
|
|||
expr: Expr::Var(var_id),
|
||||
span: Span::unknown(),
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
},
|
||||
false,
|
||||
)
|
||||
|
@ -1241,6 +1263,7 @@ pub fn parse_full_column_path(
|
|||
expr: Expr::FullCellPath(Box::new(FullCellPath { head, tail })),
|
||||
ty: Type::Unknown,
|
||||
span: full_column_span,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
|
@ -1268,6 +1291,7 @@ pub fn parse_string(
|
|||
expr: Expr::String(token),
|
||||
span,
|
||||
ty: Type::String,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -1337,6 +1361,7 @@ pub fn parse_var_with_opt_type(
|
|||
expr: Expr::Var(id),
|
||||
span: span(&spans[*spans_idx - 1..*spans_idx + 1]),
|
||||
ty,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -1347,6 +1372,7 @@ pub fn parse_var_with_opt_type(
|
|||
expr: Expr::Var(id),
|
||||
span: spans[*spans_idx],
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
},
|
||||
Some(ParseError::MissingType(spans[*spans_idx])),
|
||||
)
|
||||
|
@ -1359,6 +1385,7 @@ pub fn parse_var_with_opt_type(
|
|||
expr: Expr::Var(id),
|
||||
span: span(&spans[*spans_idx..*spans_idx + 1]),
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -1395,6 +1422,7 @@ pub fn parse_row_condition(
|
|||
ty: Type::Bool,
|
||||
span,
|
||||
expr: Expr::RowCondition(var_id, Box::new(expression)),
|
||||
custom_completion: None,
|
||||
},
|
||||
err,
|
||||
)
|
||||
|
@ -1435,6 +1463,7 @@ pub fn parse_signature(
|
|||
expr: Expr::Signature(sig),
|
||||
span,
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
|
@ -1834,6 +1863,7 @@ pub fn parse_list_expression(
|
|||
} else {
|
||||
Type::Unknown
|
||||
})),
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
|
@ -1882,6 +1912,7 @@ pub fn parse_table_expression(
|
|||
expr: Expr::List(vec![]),
|
||||
span,
|
||||
ty: Type::List(Box::new(Type::Unknown)),
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
),
|
||||
|
@ -1947,6 +1978,7 @@ pub fn parse_table_expression(
|
|||
expr: Expr::Table(table_headers, rows),
|
||||
span,
|
||||
ty: Type::Table,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
|
@ -2089,6 +2121,7 @@ pub fn parse_block_expression(
|
|||
expr: Expr::Block(block_id),
|
||||
span,
|
||||
ty: Type::Block,
|
||||
custom_completion: None,
|
||||
},
|
||||
error,
|
||||
)
|
||||
|
@ -2142,6 +2175,11 @@ pub fn parse_value(
|
|||
}
|
||||
|
||||
match shape {
|
||||
SyntaxShape::Custom(shape, custom_completion) => {
|
||||
let (mut expression, err) = parse_value(working_set, span, shape);
|
||||
expression.custom_completion = Some(custom_completion.clone());
|
||||
(expression, err)
|
||||
}
|
||||
SyntaxShape::Number => parse_number(bytes, span),
|
||||
SyntaxShape::Int => parse_int(bytes, span),
|
||||
SyntaxShape::Range => parse_range(working_set, span),
|
||||
|
@ -2254,6 +2292,7 @@ pub fn parse_operator(
|
|||
expr: Expr::Operator(operator),
|
||||
span,
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
@ -2333,6 +2372,7 @@ pub fn parse_math_expression(
|
|||
expr: Expr::BinaryOp(Box::new(lhs), Box::new(op), Box::new(rhs)),
|
||||
span: op_span,
|
||||
ty: result_ty,
|
||||
custom_completion: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -2367,6 +2407,7 @@ pub fn parse_math_expression(
|
|||
expr: Expr::BinaryOp(Box::new(lhs), Box::new(op), Box::new(rhs)),
|
||||
span: binary_op_span,
|
||||
ty: result_ty,
|
||||
custom_completion: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2496,6 +2537,7 @@ pub fn parse_def(
|
|||
expr: Expr::Call(call),
|
||||
span: span(spans),
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
}])),
|
||||
error,
|
||||
)
|
||||
|
@ -2559,6 +2601,7 @@ pub fn parse_alias(
|
|||
expr: Expr::Call(call),
|
||||
span: call_span,
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
}])),
|
||||
None,
|
||||
);
|
||||
|
@ -2607,6 +2650,7 @@ pub fn parse_let(
|
|||
expr: Expr::Call(call),
|
||||
span: call_span,
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
}])),
|
||||
err,
|
||||
);
|
||||
|
|
|
@ -6,6 +6,7 @@ pub struct Expression {
|
|||
pub expr: Expr,
|
||||
pub span: Span,
|
||||
pub ty: Type,
|
||||
pub custom_completion: Option<String>,
|
||||
}
|
||||
|
||||
impl Expression {
|
||||
|
@ -14,6 +15,7 @@ impl Expression {
|
|||
expr: Expr::Garbage,
|
||||
span,
|
||||
ty: Type::Unknown,
|
||||
custom_completion: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ pub enum SyntaxShape {
|
|||
|
||||
/// A general expression, eg `1 + 2` or `foo --bar`
|
||||
Expression,
|
||||
|
||||
/// A custom shape with custom completion logic
|
||||
Custom(Box<SyntaxShape>, String),
|
||||
}
|
||||
|
||||
impl SyntaxShape {
|
||||
|
@ -77,6 +80,7 @@ impl SyntaxShape {
|
|||
SyntaxShape::Any => Type::Unknown,
|
||||
SyntaxShape::Block(_) => Type::Block,
|
||||
SyntaxShape::CellPath => Type::Unknown,
|
||||
SyntaxShape::Custom(custom, _) => custom.to_type(),
|
||||
SyntaxShape::Duration => Type::Duration,
|
||||
SyntaxShape::Expression => Type::Unknown,
|
||||
SyntaxShape::FilePath => Type::FilePath,
|
||||
|
|
Loading…
Reference in a new issue