Skip to content

Commit

Permalink
Change cursor shape on mode change
Browse files Browse the repository at this point in the history
Fixes helix-editor#323. Due to terminal limitations we can only
change the shape of the primary cursor.
  • Loading branch information
sudormrfbin committed Nov 24, 2021
1 parent 21143e8 commit db238d6
Show file tree
Hide file tree
Showing 4 changed files with 732 additions and 626 deletions.
42 changes: 40 additions & 2 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,26 @@ To override global configuration parameters, create a `config.toml` file located
* Linux and Mac: `~/.config/helix/config.toml`
* Windows: `%AppData%\helix\config.toml`

Example config:

```toml
theme = "onedark"

[editor]
line-number = "relative"
mouse = false

[editor.cursor-shape]
normal = "underline"
insert = "block"

[editor.file-picker]
hidden = false
```

## Editor

`[editor]` section of the config.
### `[editor]` Section

| Key | Description | Default |
|--|--|---------|
Expand All @@ -24,7 +41,28 @@ To override global configuration parameters, create a `config.toml` file located
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
| `auto-info` | Whether to display infoboxes | `true` |

`[editor.filepicker]` section of the config. Sets options for file picker and global search. All but the last key listed in the default file-picker configuration below are IgnoreOptions: whether hidden files and files listed within ignore files are ignored by (not visible in) the helix file picker and global search. There is also one other key, `max-depth` available, which is not defined by default.
### `[editor.cursor-shape]` Section

Defines the shape of cursor in each mode. Note that due to limitations
of the terminal environment, only the primary cursor can change shape.

| Key | Description | Default |
| --- | ----------- | -------- |
| `normal` | Cursor shape in [normal mode][normal mode] | `block` |
| `insert` | Cursor shape in [insert mode][insert mode] | `bar` |
| `select` | Cursor shape in [select mode][select mode] | `underline` |

[normal mode]: ./keymap.md#normal-mode
[insert mode]: ./keymap.md#insert-mode
[select mode]: ./keymap.md#select--extend-mode

### `[editor.filepicker]` Section

Sets options for file picker and global search. All but the last key listed in
the default file-picker configuration below are IgnoreOptions: whether hidden
files and files listed within ignore files are ignored by (not visible in) the
helix file picker and global search. There is also one other key, `max-depth`
available, which is not defined by default.

| Key | Description | Default |
|--|--|---------|
Expand Down
12 changes: 9 additions & 3 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,9 @@ impl EditorView {

// Special-case: cursor at end of the rope.
if range.head == range.anchor && range.head == text.len_chars() {
spans.push((cursor_scope, range.head..range.head + 1));
if i != primary_idx {
spans.push((cursor_scope, range.head..range.head + 1));
}
continue;
}

Expand All @@ -259,11 +261,15 @@ impl EditorView {
// Standard case.
let cursor_start = prev_grapheme_boundary(text, range.head);
spans.push((selection_scope, range.anchor..cursor_start));
spans.push((cursor_scope, cursor_start..range.head));
if i != primary_idx {
spans.push((cursor_scope, cursor_start..range.head));
}
} else {
// Reverse case.
let cursor_end = next_grapheme_boundary(text, range.head);
spans.push((cursor_scope, range.head..cursor_end));
if i != primary_idx {
spans.push((cursor_scope, range.head..cursor_end));
}
spans.push((selection_scope, cursor_end..range.anchor));
}
}
Expand Down
42 changes: 36 additions & 6 deletions helix-view/src/editor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
clipboard::{get_clipboard_provider, ClipboardProvider},
document::SCRATCH_BUFFER_NAME,
document::{Mode, SCRATCH_BUFFER_NAME},
graphics::{CursorKind, Rect},
theme::{self, Theme},
tree::{self, Tree},
Expand All @@ -9,7 +9,7 @@ use crate::{

use futures_util::future;
use std::{
collections::BTreeMap,
collections::{BTreeMap, HashMap},
io::stdin,
path::{Path, PathBuf},
pin::Pin,
Expand All @@ -22,7 +22,7 @@ use anyhow::Error;

pub use helix_core::diagnostic::Severity;
pub use helix_core::register::Registers;
use helix_core::syntax;
use helix_core::{hashmap, syntax};
use helix_core::{Position, Selection};

use serde::Deserialize;
Expand Down Expand Up @@ -103,14 +103,37 @@ pub struct Config {
/// Whether to display infoboxes. Defaults to true.
pub auto_info: bool,
pub file_picker: FilePickerConfig,
/// Shape for cursor in each mode
pub cursor_shape: CursorShapeConfig,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(transparent)]
pub struct CursorShapeConfig(HashMap<Mode, CursorKind>);

impl std::ops::Deref for CursorShapeConfig {
type Target = HashMap<Mode, CursorKind>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl Default for CursorShapeConfig {
fn default() -> Self {
Self(hashmap!(
Mode::Insert => CursorKind::Bar,
Mode::Normal => CursorKind::Block,
Mode::Select => CursorKind::Underline,
))
}
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum LineNumber {
/// Show absolute line number
Absolute,

/// Show relative line number to the primary cursor
Relative,
}
Expand All @@ -135,6 +158,7 @@ impl Default for Config {
completion_trigger_len: 2,
auto_info: true,
file_picker: FilePickerConfig::default(),
cursor_shape: CursorShapeConfig::default(),
}
}
}
Expand Down Expand Up @@ -594,9 +618,15 @@ impl Editor {
let inner = view.inner_area();
pos.col += inner.x as usize;
pos.row += inner.y as usize;
(Some(pos), CursorKind::Hidden)
let cursorkind = self
.config
.cursor_shape
.get(&doc.mode())
.copied()
.unwrap_or_default();
(Some(pos), cursorkind)
} else {
(None, CursorKind::Hidden)
(None, CursorKind::default())
}
}

Expand Down
Loading

0 comments on commit db238d6

Please sign in to comment.