on master help sign in
config: Rename [terminal] to [editor] and pass it into Editor
a2ccfffBlaž Hrastnik
helix-term/src/application.rs+7−2
@@ -80,7 +80,12 @@ impl Application {
80 let syn_loader_conf = toml::from_slice(lang_conf).expect("Could not parse languages.toml");
80 let syn_loader_conf = toml::from_slice(lang_conf).expect("Could not parse languages.toml");
81 let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf));
81 let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf));
82
82
83− let mut editor = Editor::new(size, theme_loader.clone(), syn_loader.clone());
83+ let mut editor = Editor::new(
84+ size,
85+ theme_loader.clone(),
86+ syn_loader.clone(),
87+ config.editor.clone(),
88+ );
84
89
85 let editor_view = Box::new(ui::EditorView::new(std::mem::take(&mut config.keys)));
90 let editor_view = Box::new(ui::EditorView::new(std::mem::take(&mut config.keys)));
86 compositor.push(editor_view);
91 compositor.push(editor_view);
@@ -489,7 +494,7 @@ impl Application {
489 terminal::enable_raw_mode()?;
494 terminal::enable_raw_mode()?;
490 let mut stdout = stdout();
495 let mut stdout = stdout();
491 execute!(stdout, terminal::EnterAlternateScreen)?;
496 execute!(stdout, terminal::EnterAlternateScreen)?;
492− if self.config.terminal.mouse {
497+ if self.config.editor.mouse {
493 execute!(stdout, EnableMouseCapture)?;
498 execute!(stdout, EnableMouseCapture)?;
494 }
499 }
495 Ok(())
500 Ok(())
helix-term/src/commands.rs+15−12
@@ -12,12 +12,8 @@ use helix_core::{
12};
12};
13
13
14use helix_view::{
14use helix_view::{
15− document::Mode,
15+ document::Mode, editor::Action, input::KeyEvent, keyboard::KeyCode, view::View, Document,
16− editor::Action,
17− input::KeyEvent,
18− keyboard::KeyCode,
19− view::{View, PADDING},
20− Document, DocumentId, Editor, ViewId,
16+ DocumentId, Editor, ViewId,
21};
17};
22
18
23use anyhow::{anyhow, bail, Context as _};
19use anyhow::{anyhow, bail, Context as _};
@@ -452,7 +448,11 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
452fn goto_window(cx: &mut Context, align: Align) {
448fn goto_window(cx: &mut Context, align: Align) {
453 let (view, doc) = current!(cx.editor);
449 let (view, doc) = current!(cx.editor);
454
450
451+ let scrolloff = cx
452+ .editor
453+ .config
454+ .scrolloff
455− let scrolloff = PADDING.min(view.area.height as usize / 2); // TODO: user pref
455+ .min(view.area.height as usize / 2); // TODO: user pref
456
456
457 let last_line = view.last_line(doc);
457 let last_line = view.last_line(doc);
458
458
@@ -890,7 +890,11 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
890 return;
890 return;
891 }
891 }
892
892
893+ let scrolloff = cx
894+ .editor
895+ .config
896+ .scrolloff
893− let scrolloff = PADDING.min(view.area.height as usize / 2); // TODO: user pref
897+ .min(view.area.height as usize / 2); // TODO: user pref
894
898
895 view.first_line = match direction {
899 view.first_line = match direction {
896 Forward => view.first_line + offset,
900 Forward => view.first_line + offset,
@@ -3927,10 +3931,9 @@ fn align_view_middle(cx: &mut Context) {
3927 .cursor(doc.text().slice(..));
3931 .cursor(doc.text().slice(..));
3928 let pos = coords_at_pos(doc.text().slice(..), pos);
3932 let pos = coords_at_pos(doc.text().slice(..), pos);
3929
3933
3930− const OFFSET: usize = 7; // gutters
3931− view.first_col = pos
3934+ view.first_col = pos.col.saturating_sub(
3932− .col
3933− .saturating_sub(((view.area.width as usize).saturating_sub(OFFSET)) / 2);
3935+ ((view.area.width as usize).saturating_sub(crate::ui::editor::GUTTER_OFFSET as usize)) / 2,
3936+ );
3934}
3937}
3935
3938
3936fn scroll_up(cx: &mut Context) {
3939fn scroll_up(cx: &mut Context) {
helix-term/src/config.rs+1−13
@@ -10,7 +10,7 @@ pub struct Config {
10 #[serde(default)]
10 #[serde(default)]
11 pub keys: Keymaps,
11 pub keys: Keymaps,
12 #[serde(default)]
12 #[serde(default)]
13− pub terminal: TerminalConfig,
13+ pub editor: helix_view::editor::Config,
14}
14}
15
15
16#[derive(Debug, Default, Clone, PartialEq, Deserialize)]
16#[derive(Debug, Default, Clone, PartialEq, Deserialize)]
@@ -19,18 +19,6 @@ pub struct LspConfig {
19 pub display_messages: bool,
19 pub display_messages: bool,
20}
20}
21
21
22−#[derive(Debug, Clone, PartialEq, Deserialize)]
23−#[serde(rename_all = "kebab-case")]
24−pub struct TerminalConfig {
25− pub mouse: bool,
26−}
27−
28−impl Default for TerminalConfig {
29− fn default() -> Self {
30− Self { mouse: true }
31− }
32−}
33−
34#[test]
22#[test]
35fn parsing_keymaps_config_file() {
23fn parsing_keymaps_config_file() {
36 use crate::keymap;
24 use crate::keymap;
helix-term/src/ui/editor.rs+7−7
@@ -36,7 +36,7 @@ pub struct EditorView {
36 pub autoinfo: Option<Info>,
36 pub autoinfo: Option<Info>,
37}
37}
38
38
39−const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
39+pub const GUTTER_OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
40
40
41impl Default for EditorView {
41impl Default for EditorView {
42 fn default() -> Self {
42 fn default() -> Self {
@@ -72,9 +72,9 @@ impl EditorView {
72 loader: &syntax::Loader,
72 loader: &syntax::Loader,
73 ) {
73 ) {
74 let area = Rect::new(
74 let area = Rect::new(
75− view.area.x + OFFSET,
75+ view.area.x + GUTTER_OFFSET,
76 view.area.y,
76 view.area.y,
77− view.area.width - OFFSET,
77+ view.area.width - GUTTER_OFFSET,
78 view.area.height.saturating_sub(1),
78 view.area.height.saturating_sub(1),
79 ); // - 1 for statusline
79 ); // - 1 for statusline
80
80
@@ -339,7 +339,7 @@ impl EditorView {
339 use helix_core::diagnostic::Severity;
339 use helix_core::diagnostic::Severity;
340 if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
340 if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
341 surface.set_stringn(
341 surface.set_stringn(
342− viewport.x - OFFSET,
342+ viewport.x - GUTTER_OFFSET,
343 viewport.y + i as u16,
343 viewport.y + i as u16,
344 "●",
344 "●",
345 1,
345 1,
@@ -360,7 +360,7 @@ impl EditorView {
360 format!("{:>5}", line + 1)
360 format!("{:>5}", line + 1)
361 };
361 };
362 surface.set_stringn(
362 surface.set_stringn(
363− viewport.x + 1 - OFFSET,
363+ viewport.x + 1 - GUTTER_OFFSET,
364 viewport.y + i as u16,
364 viewport.y + i as u16,
365 line_number_text,
365 line_number_text,
366 5,
366 5,
@@ -401,7 +401,7 @@ impl EditorView {
401 format!("{:>5}", line_number + 1)
401 format!("{:>5}", line_number + 1)
402 };
402 };
403 surface.set_stringn(
403 surface.set_stringn(
404− viewport.x + 1 - OFFSET,
404+ viewport.x + 1 - GUTTER_OFFSET,
405 viewport.y + head.row as u16,
405 viewport.y + head.row as u16,
406 line_number_text,
406 line_number_text,
407 5,
407 5,
@@ -778,7 +778,7 @@ impl Component for EditorView {
778 }
778 }
779
779
780 let (view, doc) = current!(cx.editor);
780 let (view, doc) = current!(cx.editor);
781− view.ensure_cursor_in_view(doc);
781+ view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff);
782
782
783 // mode transitions
783 // mode transitions
784 match (mode, doc.mode()) {
784 match (mode, doc.mode()) {
helix-term/src/ui/mod.rs+2−2
@@ -1,5 +1,5 @@
1mod completion;
1mod completion;
2−mod editor;
2+pub(crate) mod editor;
3mod info;
3mod info;
4mod markdown;
4mod markdown;
5mod menu;
5mod menu;
@@ -63,7 +63,7 @@ pub fn regex_prompt(
63
63
64 fun(view, doc, registers, regex);
64 fun(view, doc, registers, regex);
65
65
66− view.ensure_cursor_in_view(doc);
66+ view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff);
67 }
67 }
68 Err(_err) => (), // TODO: mark command line as error
68 Err(_err) => (), // TODO: mark command line as error
69 }
69 }
helix-view/src/editor.rs+26−2
@@ -18,6 +18,26 @@ pub use helix_core::register::Registers;
18use helix_core::syntax;
18use helix_core::syntax;
19use helix_core::Position;
19use helix_core::Position;
20
20
21+use serde::Deserialize;
22+
23+#[derive(Debug, Clone, PartialEq, Deserialize)]
24+#[serde(rename_all = "kebab-case")]
25+pub struct Config {
26+ /// Padding to keep between the edge of the screen and the cursor when scrolling. Defaults to 5.
27+ pub scrolloff: usize,
28+ /// Mouse support. Defaults to true.
29+ pub mouse: bool,
30+}
31+
32+impl Default for Config {
33+ fn default() -> Self {
34+ Self {
35+ scrolloff: 5,
36+ mouse: true,
37+ }
38+ }
39+}
40+
21#[derive(Debug)]
41#[derive(Debug)]
22pub struct Editor {
42pub struct Editor {
23 pub tree: Tree,
43 pub tree: Tree,
@@ -33,6 +53,8 @@ pub struct Editor {
33 pub theme_loader: Arc<theme::Loader>,
53 pub theme_loader: Arc<theme::Loader>,
34
54
35 pub status_msg: Option<(String, Severity)>,
55 pub status_msg: Option<(String, Severity)>,
56+
57+ pub config: Config,
36}
58}
37
59
38#[derive(Debug, Copy, Clone)]
60#[derive(Debug, Copy, Clone)]
@@ -48,6 +70,7 @@ impl Editor {
48 mut area: Rect,
70 mut area: Rect,
49 themes: Arc<theme::Loader>,
71 themes: Arc<theme::Loader>,
50 config_loader: Arc<syntax::Loader>,
72 config_loader: Arc<syntax::Loader>,
73+ config: Config,
51 ) -> Self {
74 ) -> Self {
52 let language_servers = helix_lsp::Registry::new();
75 let language_servers = helix_lsp::Registry::new();
53
76
@@ -66,6 +89,7 @@ impl Editor {
66 registers: Registers::default(),
89 registers: Registers::default(),
67 clipboard_provider: get_clipboard_provider(),
90 clipboard_provider: get_clipboard_provider(),
68 status_msg: None,
91 status_msg: None,
92+ config,
69 }
93 }
70 }
94 }
71
95
@@ -108,7 +132,7 @@ impl Editor {
108 fn _refresh(&mut self) {
132 fn _refresh(&mut self) {
109 for (view, _) in self.tree.views_mut() {
133 for (view, _) in self.tree.views_mut() {
110 let doc = &self.documents[view.doc];
134 let doc = &self.documents[view.doc];
111− view.ensure_cursor_in_view(doc)
135+ view.ensure_cursor_in_view(doc, self.config.scrolloff)
112 }
136 }
113 }
137 }
114
138
@@ -267,7 +291,7 @@ impl Editor {
267 pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
291 pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
268 let view = self.tree.get_mut(id);
292 let view = self.tree.get_mut(id);
269 let doc = &self.documents[view.doc];
293 let doc = &self.documents[view.doc];
270− view.ensure_cursor_in_view(doc)
294+ view.ensure_cursor_in_view(doc, self.config.scrolloff)
271 }
295 }
272
296
273 pub fn document(&self, id: DocumentId) -> Option<&Document> {
297 pub fn document(&self, id: DocumentId) -> Option<&Document> {
helix-view/src/view.rs+2−4
@@ -8,8 +8,6 @@ use helix_core::{
8 Position, RopeSlice, Selection,
8 Position, RopeSlice, Selection,
9};
9};
10
10
11−pub const PADDING: usize = 5;
12−
13type Jump = (DocumentId, Selection);
11type Jump = (DocumentId, Selection);
14
12
15#[derive(Debug)]
13#[derive(Debug)]
@@ -84,7 +82,7 @@ impl View {
84 }
82 }
85 }
83 }
86
84
87− pub fn ensure_cursor_in_view(&mut self, doc: &Document) {
85+ pub fn ensure_cursor_in_view(&mut self, doc: &Document, scrolloff: usize) {
88 let cursor = doc
86 let cursor = doc
89 .selection(self.id)
87 .selection(self.id)
90 .primary()
88 .primary()
@@ -95,7 +93,7 @@ impl View {
95 let height = self.area.height.saturating_sub(1); // - 1 for statusline
93 let height = self.area.height.saturating_sub(1); // - 1 for statusline
96 let last_line = (self.first_line + height as usize).saturating_sub(1);
94 let last_line = (self.first_line + height as usize).saturating_sub(1);
97
95
98− let scrolloff = PADDING.min(self.area.height as usize / 2); // TODO: user pref
96+ let scrolloff = scrolloff.min(self.area.height as usize / 2);
99
97
100 // TODO: not ideal
98 // TODO: not ideal
101 const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter
99 const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter