@@ -22,10 +22,10 @@ use anyhow::Error;
23pub use helix_core::diagnostic::Severity;
23pub use helix_core::diagnostic::Severity;
24pub use helix_core::register::Registers;
24pub use helix_core::register::Registers;
25−use helix_core::{hashmap, syntax};
25+use helix_core::syntax;
26use helix_core::{Position, Selection};
26use helix_core::{Position, Selection};
28−use serde::Deserialize;
28+use serde::{Deserialize, Deserializer};
30fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result<Duration, D::Error>
30fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result<Duration, D::Error>
@@ -107,12 +107,28 @@ pub struct Config {
107 pub cursor_shape: CursorShapeConfig,
107 pub cursor_shape: CursorShapeConfig,
110+// Cursor shape is read and used on every rendered frame and so needs
111+// to be fast. Therefore we avoid a hashmap and use an enum indexed array.
110−#[derive(Debug, Clone, PartialEq, Deserialize)]
112+#[derive(Debug, Clone, PartialEq)]
111−#[serde(transparent)]
112−pub struct CursorShapeConfig(HashMap<Mode, CursorKind>);
113+pub struct CursorShapeConfig([CursorKind; 3]);
115+impl<'de> Deserialize<'de> for CursorShapeConfig {
116+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
118+ D: Deserializer<'de>,
120+ let m = HashMap::<Mode, CursorKind>::deserialize(deserializer)?;
121+ let into_cursor = |mode: Mode| m.get(&mode).copied().unwrap_or_default();
122+ Ok(CursorShapeConfig([
123+ into_cursor(Mode::Normal),
124+ into_cursor(Mode::Select),
125+ into_cursor(Mode::Insert),
114impl std::ops::Deref for CursorShapeConfig {
130impl std::ops::Deref for CursorShapeConfig {
115− type Target = HashMap<Mode, CursorKind>;
131+ type Target = [CursorKind; 3];
117 fn deref(&self) -> &Self::Target {
133 fn deref(&self) -> &Self::Target {
@@ -121,11 +137,7 @@ impl std::ops::Deref for CursorShapeConfig {
122impl Default for CursorShapeConfig {
138impl Default for CursorShapeConfig {
123 fn default() -> Self {
139 fn default() -> Self {
125− Mode::Insert => CursorKind::Block,
140+ Self([CursorKind::Block; 3])
126− Mode::Normal => CursorKind::Block,
127− Mode::Select => CursorKind::Block,
@@ -621,7 +633,7 @@ impl Editor {
621 let cursorkind = self
633 let cursorkind = self
623 .cursor_shape
635 .cursor_shape
624− .get(&doc.mode())
636+ .get(doc.mode() as usize)
625 .copied()
637 .copied()
626 .unwrap_or_default();
638 .unwrap_or_default();
627 (Some(pos), cursorkind)
639 (Some(pos), cursorkind)