mirror of
https://github.com/helix-editor/helix.git
synced 2025-01-18 21:17:08 +04:00
Add cursorcolumn (#4084)
* Implement cursorcolumn * Add documentation * Separate column style from line with fallback * Fallback to cursorcolumn first * Switch to non-fallback try_get_exact Add new function `try_get_exact`, which doesn't perform fallback, and use that instead because the fallback behaviour is being handled manually.
This commit is contained in:
parent
18cfe864f4
commit
c15f1ea274
@ -45,6 +45,7 @@ ### `[editor]` Section
|
||||
| `shell` | Shell to use when running external commands. | Unix: `["sh", "-c"]`<br/>Windows: `["cmd", "/C"]` |
|
||||
| `line-number` | Line number display: `absolute` simply shows each line's number, while `relative` shows the distance from the current line. When unfocused or in insert mode, `relative` will still show absolute line numbers. | `absolute` |
|
||||
| `cursorline` | Highlight all lines with a cursor. | `false` |
|
||||
| `cursorcolumn` | Highlight all columns with a cursor. | `false` |
|
||||
| `gutters` | Gutters to display: Available are `diagnostics` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "line-numbers"]` |
|
||||
| `auto-completion` | Enable automatic pop up of auto-completion. | `true` |
|
||||
| `auto-format` | Enable automatic formatting on save. | `true` |
|
||||
|
@ -225,51 +225,53 @@ #### Interface
|
||||
- `hover` - for hover popup ui
|
||||
|
||||
|
||||
| Key | Notes |
|
||||
| --- | --- |
|
||||
| `ui.background` | |
|
||||
| `ui.background.separator` | Picker separator below input line |
|
||||
| `ui.cursor` | |
|
||||
| `ui.cursor.insert` | |
|
||||
| `ui.cursor.select` | |
|
||||
| `ui.cursor.match` | Matching bracket etc. |
|
||||
| `ui.cursor.primary` | Cursor with primary selection |
|
||||
| `ui.gutter` | Gutter |
|
||||
| `ui.gutter.selected` | Gutter for the line the cursor is on |
|
||||
| `ui.linenr` | Line numbers |
|
||||
| `ui.linenr.selected` | Line number for the line the cursor is on |
|
||||
| `ui.statusline` | Statusline |
|
||||
| `ui.statusline.inactive` | Statusline (unfocused document) |
|
||||
| `ui.statusline.normal` | Statusline mode during normal mode ([only if `editor.color-modes` is enabled][editor-section]) |
|
||||
| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
|
||||
| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
|
||||
| `ui.statusline.separator` | Separator character in statusline |
|
||||
| `ui.popup` | Documentation popups (e.g space-k) |
|
||||
| `ui.popup.info` | Prompt for multiple key options |
|
||||
| `ui.window` | Border lines separating splits |
|
||||
| `ui.help` | Description box for commands |
|
||||
| `ui.text` | Command prompts, popup text, etc. |
|
||||
| `ui.text.focus` | |
|
||||
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
|
||||
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section])|
|
||||
| `ui.virtual.whitespace` | Visible white-space characters |
|
||||
| `ui.virtual.indent-guide` | Vertical indent width guides |
|
||||
| `ui.menu` | Code and command completion menus |
|
||||
| `ui.menu.selected` | Selected autocomplete item |
|
||||
| `ui.menu.scroll` | `fg` sets thumb color, `bg` sets track color of scrollbar |
|
||||
| `ui.selection` | For selections in the editing area |
|
||||
| `ui.selection.primary` | |
|
||||
| `ui.cursorline.primary` | The line of the primary cursor |
|
||||
| `ui.cursorline.secondary` | The lines of any other cursors |
|
||||
| `warning` | Diagnostics warning (gutter) |
|
||||
| `error` | Diagnostics error (gutter) |
|
||||
| `info` | Diagnostics info (gutter) |
|
||||
| `hint` | Diagnostics hint (gutter) |
|
||||
| `diagnostic` | Diagnostics fallback style (editing area) |
|
||||
| `diagnostic.hint` | Diagnostics hint (editing area) |
|
||||
| `diagnostic.info` | Diagnostics info (editing area) |
|
||||
| `diagnostic.warning` | Diagnostics warning (editing area) |
|
||||
| `diagnostic.error` | Diagnostics error (editing area) |
|
||||
| Key | Notes |
|
||||
| --- | --- |
|
||||
| `ui.background` | |
|
||||
| `ui.background.separator` | Picker separator below input line |
|
||||
| `ui.cursor` | |
|
||||
| `ui.cursor.insert` | |
|
||||
| `ui.cursor.select` | |
|
||||
| `ui.cursor.match` | Matching bracket etc. |
|
||||
| `ui.cursor.primary` | Cursor with primary selection |
|
||||
| `ui.gutter` | Gutter |
|
||||
| `ui.gutter.selected` | Gutter for the line the cursor is on |
|
||||
| `ui.linenr` | Line numbers |
|
||||
| `ui.linenr.selected` | Line number for the line the cursor is on |
|
||||
| `ui.statusline` | Statusline |
|
||||
| `ui.statusline.inactive` | Statusline (unfocused document) |
|
||||
| `ui.statusline.normal` | Statusline mode during normal mode ([only if `editor.color-modes` is enabled][editor-section]) |
|
||||
| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
|
||||
| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
|
||||
| `ui.statusline.separator` | Separator character in statusline |
|
||||
| `ui.popup` | Documentation popups (e.g space-k) |
|
||||
| `ui.popup.info` | Prompt for multiple key options |
|
||||
| `ui.window` | Border lines separating splits |
|
||||
| `ui.help` | Description box for commands |
|
||||
| `ui.text` | Command prompts, popup text, etc. |
|
||||
| `ui.text.focus` | |
|
||||
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
|
||||
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section]) |
|
||||
| `ui.virtual.whitespace` | Visible white-space characters |
|
||||
| `ui.virtual.indent-guide` | Vertical indent width guides |
|
||||
| `ui.menu` | Code and command completion menus |
|
||||
| `ui.menu.selected` | Selected autocomplete item |
|
||||
| `ui.menu.scroll` | `fg` sets thumb color, `bg` sets track color of scrollbar |
|
||||
| `ui.selection` | For selections in the editing area |
|
||||
| `ui.selection.primary` | |
|
||||
| `ui.cursorline.primary` | The line of the primary cursor ([if cursorline is enabled][editor-section]) |
|
||||
| `ui.cursorline.secondary` | The lines of any other cursors ([if cursorline is enabled][editor-section]) |
|
||||
| `ui.cursorcolumn.primary` | The column of the primary cursor ([if cursorcolumn is enabled][editor-section]) |
|
||||
| `ui.cursorcolumn.secondary` | The columns of any other cursors ([if cursorcolumn is enabled][editor-section]) |
|
||||
| `warning` | Diagnostics warning (gutter) |
|
||||
| `error` | Diagnostics error (gutter) |
|
||||
| `info` | Diagnostics info (gutter) |
|
||||
| `hint` | Diagnostics hint (gutter) |
|
||||
| `diagnostic` | Diagnostics fallback style (editing area) |
|
||||
| `diagnostic.hint` | Diagnostics hint (editing area) |
|
||||
| `diagnostic.info` | Diagnostics info (editing area) |
|
||||
| `diagnostic.warning` | Diagnostics warning (editing area) |
|
||||
| `diagnostic.error` | Diagnostics error (editing area) |
|
||||
|
||||
You can check compliance to spec with
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
movement::Direction,
|
||||
syntax::{self, HighlightEvent},
|
||||
unicode::width::UnicodeWidthStr,
|
||||
LineEnding, Position, Range, Selection, Transaction,
|
||||
visual_coords_at_pos, LineEnding, Position, Range, Selection, Transaction,
|
||||
};
|
||||
use helix_view::{
|
||||
document::{Mode, SCRATCH_BUFFER_NAME},
|
||||
@ -118,6 +118,9 @@ pub fn render_view(
|
||||
if is_focused && editor.config().cursorline {
|
||||
Self::highlight_cursorline(doc, view, surface, theme);
|
||||
}
|
||||
if is_focused && editor.config().cursorcolumn {
|
||||
Self::highlight_cursorcolumn(doc, view, surface, theme);
|
||||
}
|
||||
|
||||
let highlights = Self::doc_syntax_highlights(doc, view.offset, inner.height, theme);
|
||||
let highlights = syntax::merge(highlights, Self::doc_diagnostics_highlights(doc, theme));
|
||||
@ -830,6 +833,53 @@ pub fn highlight_cursorline(doc: &Document, view: &View, surface: &mut Surface,
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply the highlighting on the columns where a cursor is active
|
||||
pub fn highlight_cursorcolumn(
|
||||
doc: &Document,
|
||||
view: &View,
|
||||
surface: &mut Surface,
|
||||
theme: &Theme,
|
||||
) {
|
||||
let text = doc.text().slice(..);
|
||||
|
||||
// Manual fallback behaviour:
|
||||
// ui.cursorcolumn.{p/s} -> ui.cursorcolumn -> ui.cursorline.{p/s}
|
||||
let primary_style = theme
|
||||
.try_get_exact("ui.cursorcolumn.primary")
|
||||
.or_else(|| theme.try_get_exact("ui.cursorcolumn"))
|
||||
.unwrap_or_else(|| theme.get("ui.cursorline.primary"));
|
||||
let secondary_style = theme
|
||||
.try_get_exact("ui.cursorcolumn.secondary")
|
||||
.or_else(|| theme.try_get_exact("ui.cursorcolumn"))
|
||||
.unwrap_or_else(|| theme.get("ui.cursorline.secondary"));
|
||||
|
||||
let inner_area = view.inner_area();
|
||||
let offset = view.offset.col;
|
||||
|
||||
let selection = doc.selection(view.id);
|
||||
let primary = selection.primary();
|
||||
for range in selection.iter() {
|
||||
let is_primary = primary == *range;
|
||||
|
||||
let Position { row: _, col } =
|
||||
visual_coords_at_pos(text, range.cursor(text), doc.tab_width());
|
||||
// if the cursor is horizontally in the view
|
||||
if col >= offset && inner_area.width > (col - offset) as u16 {
|
||||
let area = Rect::new(
|
||||
inner_area.x + (col - offset) as u16,
|
||||
view.area.y,
|
||||
1,
|
||||
view.area.height,
|
||||
);
|
||||
if is_primary {
|
||||
surface.set_style(area, primary_style)
|
||||
} else {
|
||||
surface.set_style(area, secondary_style)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle events by looking them up in `self.keymaps`. Returns None
|
||||
/// if event was handled (a command was executed or a subkeymap was
|
||||
/// activated). Only KeymapResult::{NotFound, Cancelled} is returned
|
||||
|
@ -124,6 +124,8 @@ pub struct Config {
|
||||
pub line_number: LineNumber,
|
||||
/// Highlight the lines cursors are currently on. Defaults to false.
|
||||
pub cursorline: bool,
|
||||
/// Highlight the columns cursors are currently on. Defaults to false.
|
||||
pub cursorcolumn: bool,
|
||||
/// Gutters. Default ["diagnostics", "line-numbers"]
|
||||
pub gutters: Vec<GutterType>,
|
||||
/// Middle click paste support. Defaults to true.
|
||||
@ -582,6 +584,7 @@ fn default() -> Self {
|
||||
},
|
||||
line_number: LineNumber::Absolute,
|
||||
cursorline: false,
|
||||
cursorcolumn: false,
|
||||
gutters: vec![GutterType::Diagnostics, GutterType::LineNumbers],
|
||||
middle_click_paste: true,
|
||||
auto_pairs: AutoPairConfig::default(),
|
||||
|
@ -277,6 +277,13 @@ pub fn try_get(&self, scope: &str) -> Option<Style> {
|
||||
.find_map(|s| self.styles.get(s).copied())
|
||||
}
|
||||
|
||||
/// Get the style of a scope, without falling back to dot separated broader
|
||||
/// scopes. For example if `ui.text.focus` is not defined in the theme, it
|
||||
/// will return `None`, even if `ui.text` is.
|
||||
pub fn try_get_exact(&self, scope: &str) -> Option<Style> {
|
||||
self.styles.get(scope).copied()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scopes(&self) -> &[String] {
|
||||
&self.scopes
|
||||
|
Loading…
Reference in New Issue
Block a user