Skip to content

Commit 47c8a13

Browse files
committed
fix: highlighting for aliased external calls
1 parent 42f0d4b commit 47c8a13

File tree

3 files changed

+84
-100
lines changed

3 files changed

+84
-100
lines changed

crates/nu-cli/src/syntax_highlight.rs

Lines changed: 77 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,6 @@ impl Highlighter for NuHighlighter {
2323
}
2424
}
2525

26-
// <<<<<<< HEAD
27-
// =======
28-
// let config = self.stack.get_config(&self.engine_state);
29-
// let highlight_resolved_externals = config.highlight_resolved_externals;
30-
// let mut working_set = StateWorkingSet::new(&self.engine_state);
31-
// let block = parse(&mut working_set, None, line.as_bytes(), false);
32-
// let (shapes, global_span_offset) = {
33-
// let mut shapes = flatten_block(&working_set, &block);
34-
// // Highlighting externals has a config point because of concerns that using which to resolve
35-
// // externals may slow down things too much.
36-
// if highlight_resolved_externals {
37-
// for (span, shape) in shapes.iter_mut() {
38-
// if let FlatShape::External(aliased_command_span) = *shape {
39-
// let str_contents = working_set.get_span_contents(aliased_command_span);
40-
// >>>>>>> df798b657 (Fix highlighting of aliases to external commands)
41-
4226
/// Result of a syntax highlight operation
4327
#[derive(Default)]
4428
pub(crate) struct HighlightResult {
@@ -60,34 +44,10 @@ pub(crate) fn highlight_syntax(
6044
let highlight_resolved_externals = config.highlight_resolved_externals;
6145
let mut working_set = StateWorkingSet::new(engine_state);
6246
let block = parse(&mut working_set, None, line.as_bytes(), false);
63-
let (shapes, global_span_offset) = {
64-
let mut shapes = flatten_block(&working_set, &block);
65-
// Highlighting externals has a config point because of concerns that using which to resolve
66-
// externals may slow down things too much.
67-
if highlight_resolved_externals {
68-
for (span, shape) in shapes.iter_mut() {
69-
if let FlatShape::External(aliased_command_span) = shape {
70-
let str_contents = working_set.get_span_contents(**aliased_command_span);
71-
let str_word = String::from_utf8_lossy(str_contents).to_string();
72-
let paths = env::path_str(engine_state, stack, *span).ok();
73-
let res = if let Ok(cwd) = engine_state.cwd(Some(stack)) {
74-
which::which_in(str_word, paths.as_ref(), cwd).ok()
75-
} else {
76-
which::which_in_global(str_word, paths.as_ref())
77-
.ok()
78-
.and_then(|mut i| i.next())
79-
};
80-
if res.is_some() {
81-
*shape = FlatShape::ExternalResolved;
82-
}
83-
}
84-
}
85-
}
86-
(shapes, engine_state.next_span_start())
87-
};
88-
47+
let shapes = flatten_block(&working_set, &block);
48+
let global_span_offset = engine_state.next_span_start();
8949
let mut result = HighlightResult::default();
90-
let mut last_seen_span = global_span_offset;
50+
let mut last_seen_span_end = global_span_offset;
9151

9252
let global_cursor_offset = cursor + global_span_offset;
9353
let matching_brackets_pos = find_matching_brackets(
@@ -98,101 +58,125 @@ pub(crate) fn highlight_syntax(
9858
global_cursor_offset,
9959
);
10060

101-
for shape in &shapes {
102-
if shape.0.end <= last_seen_span
103-
|| last_seen_span < global_span_offset
104-
|| shape.0.start < global_span_offset
61+
for (raw_span, flat_shape) in &shapes {
62+
// NOTE: Currently we expand aliaes while flattening for tasks such as completion
63+
// https://github.com/nushell/nushell/issues/16944
64+
let span = if let FlatShape::External(alias_span) = flat_shape {
65+
alias_span
66+
} else {
67+
raw_span
68+
};
69+
70+
if span.end <= last_seen_span_end
71+
|| last_seen_span_end < global_span_offset
72+
|| span.start < global_span_offset
10573
{
10674
// We've already output something for this span
10775
// so just skip this one
10876
continue;
10977
}
110-
if shape.0.start > last_seen_span {
78+
if span.start > last_seen_span_end {
11179
let gap = line
112-
[(last_seen_span - global_span_offset)..(shape.0.start - global_span_offset)]
80+
[(last_seen_span_end - global_span_offset)..(span.start - global_span_offset)]
11381
.to_string();
11482
result.text.push((Style::new(), gap));
11583
}
116-
let next_token = line
117-
[(shape.0.start - global_span_offset)..(shape.0.end - global_span_offset)]
118-
.to_string();
84+
let next_token =
85+
line[(span.start - global_span_offset)..(span.end - global_span_offset)].to_string();
11986

12087
let mut add_colored_token = |shape: &FlatShape, text: String| {
12188
result
12289
.text
12390
.push((get_shape_color(shape.as_str(), &config), text));
12491
};
12592

126-
match shape.1 {
93+
match flat_shape {
12794
FlatShape::Garbage => {
12895
result.found_garbage.get_or_insert_with(|| {
12996
Span::new(
130-
shape.0.start - global_span_offset,
131-
shape.0.end - global_span_offset,
97+
span.start - global_span_offset,
98+
span.end - global_span_offset,
13299
)
133100
});
134-
add_colored_token(&shape.1, next_token)
101+
add_colored_token(flat_shape, next_token)
102+
}
103+
FlatShape::Nothing
104+
| FlatShape::Binary
105+
| FlatShape::Bool
106+
| FlatShape::Int
107+
| FlatShape::Float
108+
| FlatShape::Range
109+
| FlatShape::InternalCall(_)
110+
| FlatShape::ExternalArg
111+
| FlatShape::ExternalResolved
112+
| FlatShape::Keyword
113+
| FlatShape::Literal
114+
| FlatShape::Operator
115+
| FlatShape::Signature
116+
| FlatShape::String
117+
| FlatShape::RawString
118+
| FlatShape::StringInterpolation
119+
| FlatShape::DateTime
120+
| FlatShape::Filepath
121+
| FlatShape::Directory
122+
| FlatShape::GlobInterpolation
123+
| FlatShape::GlobPattern
124+
| FlatShape::Variable(_)
125+
| FlatShape::VarDecl(_)
126+
| FlatShape::Flag
127+
| FlatShape::Pipe
128+
| FlatShape::Redirection
129+
| FlatShape::Custom(..)
130+
| FlatShape::MatchPattern => add_colored_token(flat_shape, next_token),
131+
FlatShape::External(_) => {
132+
let mut true_shape = flat_shape.clone();
133+
// Highlighting externals has a config point because of concerns that using which to resolve
134+
// externals may slow down things too much.
135+
if highlight_resolved_externals {
136+
// use `raw_span` here for aliased external calls
137+
let str_contents = working_set.get_span_contents(*raw_span);
138+
let str_word = String::from_utf8_lossy(str_contents).to_string();
139+
let paths = env::path_str(engine_state, stack, *raw_span).ok();
140+
let res = if let Ok(cwd) = engine_state.cwd(Some(stack)) {
141+
which::which_in(str_word, paths.as_ref(), cwd).ok()
142+
} else {
143+
which::which_in_global(str_word, paths.as_ref())
144+
.ok()
145+
.and_then(|mut i| i.next())
146+
};
147+
if res.is_some() {
148+
true_shape = FlatShape::ExternalResolved;
149+
}
150+
}
151+
add_colored_token(&true_shape, next_token);
135152
}
136-
FlatShape::Nothing => add_colored_token(&shape.1, next_token),
137-
FlatShape::Binary => add_colored_token(&shape.1, next_token),
138-
FlatShape::Bool => add_colored_token(&shape.1, next_token),
139-
FlatShape::Int => add_colored_token(&shape.1, next_token),
140-
FlatShape::Float => add_colored_token(&shape.1, next_token),
141-
FlatShape::Range => add_colored_token(&shape.1, next_token),
142-
FlatShape::InternalCall(_) => add_colored_token(&shape.1, next_token),
143-
FlatShape::External(_) => add_colored_token(&shape.1, next_token),
144-
FlatShape::ExternalArg => add_colored_token(&shape.1, next_token),
145-
FlatShape::ExternalResolved => add_colored_token(&shape.1, next_token),
146-
FlatShape::Keyword => add_colored_token(&shape.1, next_token),
147-
FlatShape::Literal => add_colored_token(&shape.1, next_token),
148-
FlatShape::Operator => add_colored_token(&shape.1, next_token),
149-
FlatShape::Signature => add_colored_token(&shape.1, next_token),
150-
FlatShape::String => add_colored_token(&shape.1, next_token),
151-
FlatShape::RawString => add_colored_token(&shape.1, next_token),
152-
FlatShape::StringInterpolation => add_colored_token(&shape.1, next_token),
153-
FlatShape::DateTime => add_colored_token(&shape.1, next_token),
154153
FlatShape::List
155154
| FlatShape::Table
156155
| FlatShape::Record
157156
| FlatShape::Block
158157
| FlatShape::Closure => {
159-
let span = shape.0;
160-
let shape = &shape.1;
161158
let spans = split_span_by_highlight_positions(
162159
line,
163-
span,
160+
*span,
164161
&matching_brackets_pos,
165162
global_span_offset,
166163
);
167164
for (part, highlight) in spans {
168165
let start = part.start - span.start;
169166
let end = part.end - span.start;
170167
let text = next_token[start..end].to_string();
171-
let mut style = get_shape_color(shape.as_str(), &config);
168+
let mut style = get_shape_color(flat_shape.as_str(), &config);
172169
if highlight {
173170
style = get_matching_brackets_style(style, &config);
174171
}
175172
result.text.push((style, text));
176173
}
177174
}
178-
179-
FlatShape::Filepath => add_colored_token(&shape.1, next_token),
180-
FlatShape::Directory => add_colored_token(&shape.1, next_token),
181-
FlatShape::GlobInterpolation => add_colored_token(&shape.1, next_token),
182-
FlatShape::GlobPattern => add_colored_token(&shape.1, next_token),
183-
FlatShape::Variable(_) | FlatShape::VarDecl(_) => {
184-
add_colored_token(&shape.1, next_token)
185-
}
186-
FlatShape::Flag => add_colored_token(&shape.1, next_token),
187-
FlatShape::Pipe => add_colored_token(&shape.1, next_token),
188-
FlatShape::Redirection => add_colored_token(&shape.1, next_token),
189-
FlatShape::Custom(..) => add_colored_token(&shape.1, next_token),
190-
FlatShape::MatchPattern => add_colored_token(&shape.1, next_token),
191175
}
192-
last_seen_span = shape.0.end;
176+
last_seen_span_end = span.end;
193177
}
194178

195-
let remainder = line[(last_seen_span - global_span_offset)..].to_string();
179+
let remainder = line[(last_seen_span_end - global_span_offset)..].to_string();
196180
if !remainder.is_empty() {
197181
result.text.push((Style::new(), remainder));
198182
}

crates/nu-parser/src/flatten.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ pub enum FlatShape {
1818
Custom(DeclId),
1919
DateTime,
2020
Directory,
21-
// The stored span contains the name of the called external command:
22-
// This is only different from the span containing the call's head if this
23-
// call is through an alias, and is only useful for its contents (not its location).
21+
// The stored span contains the call's head if this call is through an alias:
22+
// This is only different from the name of the called external command,
23+
// and is only useful for its location (not its contents).
2424
External(Box<Span>),
2525
ExternalArg,
2626
ExternalResolved,
@@ -331,7 +331,7 @@ fn flatten_expression_into(
331331
// and then just overwriting the `span` field - but `span_id` still points to
332332
// the original span, so we can recover it from there.
333333
let span = working_set.get_span(head.span_id);
334-
output.push((span, FlatShape::External(Box::new(span))));
334+
output.push((span, FlatShape::External(Box::new(head.span))));
335335
} else {
336336
flatten_expression_into(working_set, head, output);
337337
}

src/ide.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,13 @@ pub fn hover(engine_state: &mut EngineState, file_path: &str, location: &Value)
403403
}
404404
})
405405
),
406-
FlatShape::External(_) => println!(
406+
FlatShape::External(alias_span) => println!(
407407
"{}",
408408
json!({
409409
"hover": "external",
410410
"span": {
411-
"start": span.start - offset,
412-
"end": span.end - offset
411+
"start": alias_span.start - offset,
412+
"end": alias_span.end - offset
413413
}
414414
})
415415
),

0 commit comments

Comments
 (0)