diff --git a/internal/action/settings.go b/internal/action/settings.go index 448d985..f9ee011 100644 --- a/internal/action/settings.go +++ b/internal/action/settings.go @@ -1,7 +1,20 @@ package action type Settings struct { - GutterSize int - TabSize int - ScrollOff int + Number bool + RelativeNumber bool + GutterSize int + TabSize int + ScrollOff int + // TODO: Colors +} + +func NewDefaultSettings() Settings { + return Settings{ + Number: true, + RelativeNumber: true, + GutterSize: 5, + TabSize: 2, + ScrollOff: 8, + } } diff --git a/internal/editor/model.go b/internal/editor/model.go index 05ed664..36eb7c9 100644 --- a/internal/editor/model.go +++ b/internal/editor/model.go @@ -40,15 +40,11 @@ func NewModel(lines []string, pos action.Position) Model { x: pos.Col, y: pos.Line, }, - scrollY: 0, - mode: action.NormalMode, - command: "", - input: input.NewHandler(), - settings: action.Settings{ - GutterSize: 5, - TabSize: 2, - ScrollOff: 8, - }, + scrollY: 0, + mode: action.NormalMode, + command: "", + input: input.NewHandler(), + settings: action.NewDefaultSettings(), } } diff --git a/internal/editor/view.go b/internal/editor/view.go index 44ea54b..9a1be5b 100644 --- a/internal/editor/view.go +++ b/internal/editor/view.go @@ -67,27 +67,39 @@ func (m Model) View() string { if i < m.LineCount() { - var ( - gutter string - currentLine bool = false - lineNumber int - ) - if i > m.CursorY() { - lineNumber = i - m.CursorY() - gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-1, lineNumber) - } else if i < m.CursorY() { - lineNumber = m.CursorY() - i - gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-1, lineNumber) - } else { - lineNumber = i + 1 - currentLine = true - if lineNumber < 100 { - gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-2, lineNumber) - } else { + if m.Settings().Number || m.Settings().RelativeNumber { + var ( + gutter string + currentLine bool = false + lineNumber int + ) + + if m.Settings().RelativeNumber { + // Relative line numbers: show distance from cursor, current line shows absolute + if i > m.CursorY() { + lineNumber = i - m.CursorY() + gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-1, lineNumber) + } else if i < m.CursorY() { + lineNumber = m.CursorY() - i + gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-1, lineNumber) + } else { + // Current line: show absolute number if Number is also set, otherwise show 0 + currentLine = true + if m.Settings().Number { + lineNumber = i + 1 + gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-1, lineNumber) + } else { + gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-1, 0) + } + } + } else if m.Settings().Number { + // Absolute line numbers only + lineNumber = i + 1 + currentLine = (i == m.CursorY()) gutter = fmt.Sprintf("%*d ", m.Settings().GutterSize-1, lineNumber) } + view.WriteString(m.gutterStyle(currentLine).Render(gutter)) } - view.WriteString(m.gutterStyle(currentLine).Render(gutter)) runes := []rune(m.Line(i)) for x := 0; x <= len(runes); x++ { @@ -111,8 +123,13 @@ func (m Model) View() string { } } } else { - format := fmt.Sprintf("%%-%ds ", m.Settings().GutterSize-1) - fmt.Fprintf(&view, format, "~") + // Empty lines beyond file content + if m.Settings().Number || m.Settings().RelativeNumber { + format := fmt.Sprintf("%%-%ds ", m.Settings().GutterSize-1) + fmt.Fprintf(&view, format, "~") + } else { + view.WriteString("~") + } } view.WriteString("\n")