summaryrefslogtreecommitdiff
path: root/helix-term/src
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src')
-rw-r--r--helix-term/src/commands.rs11
-rw-r--r--helix-term/src/commands/lsp.rs6
-rw-r--r--helix-term/src/commands/typed.rs10
-rw-r--r--helix-term/src/ui/editor.rs52
-rw-r--r--helix-term/src/ui/info.rs5
-rw-r--r--helix-term/src/ui/markdown.rs5
-rw-r--r--helix-term/src/ui/picker.rs7
-rw-r--r--helix-term/src/ui/popup.rs9
-rw-r--r--helix-term/src/ui/prompt.rs5
9 files changed, 58 insertions, 52 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 897712f0..9239b49f 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1747,11 +1747,13 @@ fn global_search(cx: &mut Context) {
let smart_case = config.search.smart_case;
let file_picker_config = config.file_picker.clone();
- let completions = search_completions(cx, None);
+ let reg = cx.register.unwrap_or('/');
+
+ let completions = search_completions(cx, Some(reg));
ui::regex_prompt(
cx,
"global-search:".into(),
- None,
+ Some(reg),
move |_editor: &Editor, input: &str| {
completions
.iter()
@@ -2244,9 +2246,8 @@ pub fn command_palette(cx: &mut Context) {
.iter()
.map(|bind| {
bind.iter()
- .map(|key| key.to_string())
- .collect::<Vec<String>>()
- .join("+")
+ .map(|key| key.key_sequence_format())
+ .collect::<String>()
})
.collect::<Vec<String>>()
.join(", ")
diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs
index ff61ee63..b8c5e5d1 100644
--- a/helix-term/src/commands/lsp.rs
+++ b/helix-term/src/commands/lsp.rs
@@ -287,10 +287,8 @@ pub fn code_action(cx: &mut Context) {
});
picker.move_down(); // pre-select the first item
- let popup = Popup::new("code-action", picker).margin(helix_view::graphics::Margin {
- vertical: 1,
- horizontal: 1,
- });
+ let popup =
+ Popup::new("code-action", picker).margin(helix_view::graphics::Margin::all(1));
compositor.replace_or_push("code-action", popup);
},
)
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index 5b48ca48..19c6a5dc 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -1804,15 +1804,7 @@ pub fn command_mode(cx: &mut Context) {
// Handle typable commands
if let Some(cmd) = typed::TYPABLE_COMMAND_MAP.get(parts[0]) {
- let args = if cfg!(unix) {
- shellwords::shellwords(input)
- } else {
- // Windows doesn't support POSIX, so fallback for now
- parts
- .into_iter()
- .map(|part| part.into())
- .collect::<Vec<_>>()
- };
+ let args = shellwords::shellwords(input);
if let Err(e) = (cmd.fun)(cx, &args[1..], event) {
cx.editor.set_error(format!("{}", e));
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index a8027d1b..dc6362c6 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -13,7 +13,6 @@ use helix_core::{
},
movement::Direction,
syntax::{self, HighlightEvent},
- unicode::segmentation::UnicodeSegmentation,
unicode::width::UnicodeWidthStr,
LineEnding, Position, Range, Selection, Transaction,
};
@@ -131,7 +130,7 @@ impl EditorView {
surface,
theme,
highlights,
- &editor.config().whitespace,
+ &editor.config(),
);
Self::render_gutter(editor, doc, view, view.area, surface, theme, is_focused);
Self::render_rulers(editor, doc, view, inner, surface, theme);
@@ -373,8 +372,9 @@ impl EditorView {
surface: &mut Surface,
theme: &Theme,
highlights: H,
- whitespace: &helix_view::editor::WhitespaceConfig,
+ config: &helix_view::editor::Config,
) {
+ let whitespace = &config.whitespace;
use helix_view::editor::WhitespaceRenderValue;
// It's slightly more efficient to produce a full RopeSlice from the Rope, then slice that a bunch
@@ -397,10 +397,30 @@ impl EditorView {
} else {
" ".to_string()
};
+ let indent_guide_char = config.indent_guides.character.to_string();
let text_style = theme.get("ui.text");
let whitespace_style = theme.get("ui.virtual.whitespace");
+ let mut is_in_indent_area = true;
+ let mut last_line_indent_level = 0;
+ let indent_style = theme.get("ui.virtual.indent-guide");
+
+ let draw_indent_guides = |indent_level, line, surface: &mut Surface| {
+ if !config.indent_guides.render {
+ return;
+ }
+
+ for i in 0..(indent_level / tab_width as u16) {
+ surface.set_string(
+ viewport.x + (i * tab_width as u16) - offset.col as u16,
+ viewport.y + line,
+ &indent_guide_char,
+ indent_style,
+ );
+ }
+ };
+
'outer: for event in highlights {
match event {
HighlightEvent::HighlightStart(span) => {
@@ -453,8 +473,18 @@ impl EditorView {
);
}
+ // This is an empty line; draw indent guides at previous line's
+ // indent level to avoid breaking the guides on blank lines.
+ if visual_x == 0 {
+ draw_indent_guides(last_line_indent_level, line, surface);
+ } else if is_in_indent_area {
+ // A line with whitespace only
+ draw_indent_guides(visual_x, line, surface);
+ }
+
visual_x = 0;
line += 1;
+ is_in_indent_area = true;
// TODO: with proper iter this shouldn't be necessary
if line >= viewport.height {
@@ -464,7 +494,7 @@ impl EditorView {
let grapheme = Cow::from(grapheme);
let is_whitespace;
- let (grapheme, width) = if grapheme == "\t" {
+ let (display_grapheme, width) = if grapheme == "\t" {
is_whitespace = true;
// make sure we display tab as appropriate amount of spaces
let visual_tab_width = tab_width - (visual_x as usize % tab_width);
@@ -491,7 +521,7 @@ impl EditorView {
surface.set_string(
viewport.x + visual_x - offset.col as u16,
viewport.y + line,
- grapheme,
+ display_grapheme,
if is_whitespace {
style.patch(whitespace_style)
} else {
@@ -499,6 +529,11 @@ impl EditorView {
},
);
}
+ if is_in_indent_area && !(grapheme == " " || grapheme == "\t") {
+ draw_indent_guides(visual_x, line, surface);
+ is_in_indent_area = false;
+ last_line_indent_level = visual_x;
+ }
visual_x = visual_x.saturating_add(width as u16);
}
@@ -1355,12 +1390,7 @@ impl Component for EditorView {
disp.push_str(&count.to_string())
}
for key in self.keymaps.pending() {
- let s = key.to_string();
- if s.graphemes(true).count() > 1 {
- disp.push_str(&format!("<{}>", s));
- } else {
- disp.push_str(&s);
- }
+ disp.push_str(&key.key_sequence_format());
}
if let Some(pseudo_pending) = &cx.editor.pseudo_pending {
disp.push_str(pseudo_pending.as_str())
diff --git a/helix-term/src/ui/info.rs b/helix-term/src/ui/info.rs
index 272244c1..cc6b7483 100644
--- a/helix-term/src/ui/info.rs
+++ b/helix-term/src/ui/info.rs
@@ -27,10 +27,7 @@ impl Component for Info {
.borders(Borders::ALL)
.border_style(popup_style);
- let margin = Margin {
- vertical: 0,
- horizontal: 1,
- };
+ let margin = Margin::horizontal(1);
let inner = block.inner(area).inner(&margin);
block.render(area, surface);
diff --git a/helix-term/src/ui/markdown.rs b/helix-term/src/ui/markdown.rs
index 037e2f13..e3ce2cd5 100644
--- a/helix-term/src/ui/markdown.rs
+++ b/helix-term/src/ui/markdown.rs
@@ -323,10 +323,7 @@ impl Component for Markdown {
.wrap(Wrap { trim: false })
.scroll((cx.scroll.unwrap_or_default() as u16, 0));
- let margin = Margin {
- vertical: 1,
- horizontal: 1,
- };
+ let margin = Margin::all(1);
par.render(area.inner(&margin), surface);
}
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs
index 9ffe45c1..ebff9827 100644
--- a/helix-term/src/ui/picker.rs
+++ b/helix-term/src/ui/picker.rs
@@ -200,10 +200,7 @@ impl<T: 'static> Component for FilePicker<T> {
// calculate the inner area inside the box
let inner = block.inner(preview_area);
// 1 column gap on either side
- let margin = Margin {
- vertical: 0,
- horizontal: 1,
- };
+ let margin = Margin::horizontal(1);
let inner = inner.inner(&margin);
block.render(preview_area, surface);
@@ -240,7 +237,7 @@ impl<T: 'static> Component for FilePicker<T> {
surface,
&cx.editor.theme,
highlights,
- &cx.editor.config().whitespace,
+ &cx.editor.config(),
);
// highlight the line
diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs
index 185ec15d..f5b79526 100644
--- a/helix-term/src/ui/popup.rs
+++ b/helix-term/src/ui/popup.rs
@@ -27,10 +27,7 @@ impl<T: Component> Popup<T> {
Self {
contents,
position: None,
- margin: Margin {
- vertical: 0,
- horizontal: 0,
- },
+ margin: Margin::none(),
size: (0, 0),
child_size: (0, 0),
scroll: 0,
@@ -163,8 +160,8 @@ impl<T: Component> Component for Popup<T> {
self.child_size = (width, height);
self.size = (
- (width + self.margin.horizontal * 2).min(max_width),
- (height + self.margin.vertical * 2).min(max_height),
+ (width + self.margin.width()).min(max_width),
+ (height + self.margin.height()).min(max_height),
);
// re-clamp scroll offset
diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs
index 64154bae..7744a161 100644
--- a/helix-term/src/ui/prompt.rs
+++ b/helix-term/src/ui/prompt.rs
@@ -430,10 +430,7 @@ impl Prompt {
.borders(Borders::ALL)
.border_style(background);
- let inner = block.inner(area).inner(&Margin {
- vertical: 0,
- horizontal: 1,
- });
+ let inner = block.inner(area).inner(&Margin::horizontal(1));
block.render(area, surface);
text.render(inner, surface, cx);