aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Baranski2021-08-16 02:11:53 +0000
committerGitHub2021-08-16 02:11:53 +0000
commit78923496a6134ab456dbfe8c0a58270d32e4b239 (patch)
tree2e912ea7f8475cdfb8e84570a64e077c946f476b
parentaaccc9419a9710f13db3ddc0aad068e606667154 (diff)
feat: relative numbers (#485)
* feat(helix-view): configuring line-number * feat(helix-term): relative line numbers * feat(helix-term): passing editor::Config to render * fix(helix-view): remove LineNumber::None * feat(helix-term): rendering line-number according to configuration * fix(term): put calculating current line above line iteration * fix: add abs_diff function * deps: cargo update * fix: pass config argument
-rw-r--r--helix-term/src/ui/editor.rs26
-rw-r--r--helix-view/src/editor.rs13
2 files changed, 37 insertions, 2 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 8c46eef9..5e1e8f50 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -17,6 +17,7 @@ use helix_core::{
};
use helix_view::{
document::Mode,
+ editor::LineNumber,
graphics::{CursorKind, Modifier, Rect, Style},
info::Info,
input::KeyEvent,
@@ -71,6 +72,7 @@ impl EditorView {
theme: &Theme,
is_focused: bool,
loader: &syntax::Loader,
+ config: &helix_view::editor::Config,
) {
let area = Rect::new(
view.area.x + GUTTER_OFFSET,
@@ -93,7 +95,7 @@ impl EditorView {
};
Self::render_text_highlights(doc, offset, area, surface, theme, highlights);
- Self::render_gutter(doc, view, area, surface, theme);
+ Self::render_gutter(doc, view, area, surface, theme, config);
if is_focused {
Self::render_focused_view_elements(view, doc, area, theme, surface);
@@ -459,6 +461,7 @@ impl EditorView {
viewport: Rect,
surface: &mut Surface,
theme: &Theme,
+ config: &helix_view::editor::Config,
) {
let text = doc.text().slice(..);
let last_line = view.last_line(doc);
@@ -473,6 +476,9 @@ impl EditorView {
// document or not. We only draw it if it's not an empty line.
let draw_last = text.line_to_byte(last_line) < text.len_bytes();
+ let current_line = doc
+ .text()
+ .char_to_line(doc.selection(view.id).primary().anchor);
for (i, line) in (view.first_line..(last_line + 1)).enumerate() {
use helix_core::diagnostic::Severity;
if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
@@ -495,7 +501,13 @@ impl EditorView {
let line_number_text = if line == last_line && !draw_last {
" ~".into()
} else {
- format!("{:>5}", line + 1)
+ match config.line_number {
+ LineNumber::Absolute => format!("{:>5}", line + 1),
+ LineNumber::Relative => {
+ let relative_line = abs_diff(current_line, line);
+ format!("{:>5}", relative_line)
+ }
+ }
};
surface.set_stringn(
viewport.x + 1 - GUTTER_OFFSET,
@@ -1042,6 +1054,7 @@ impl Component for EditorView {
&cx.editor.theme,
is_focused,
loader,
+ &cx.editor.config,
);
}
@@ -1115,3 +1128,12 @@ fn canonicalize_key(key: &mut KeyEvent) {
key.modifiers.remove(KeyModifiers::SHIFT)
}
}
+
+#[inline]
+fn abs_diff(a: usize, b: usize) -> usize {
+ if a > b {
+ a - b
+ } else {
+ b - a
+ }
+}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 413b7913..32f5fe86 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -33,16 +33,29 @@ pub struct Config {
pub scroll_lines: isize,
/// Mouse support. Defaults to true.
pub mouse: bool,
+ /// Line number mode.
+ pub line_number: LineNumber,
/// Middle click paste support. Defaults to true
pub middle_click_paste: bool,
}
+#[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,
+}
+
impl Default for Config {
fn default() -> Self {
Self {
scrolloff: 5,
scroll_lines: 3,
mouse: true,
+ line_number: LineNumber::Absolute,
middle_click_paste: true,
}
}