feat: settings abstraction supports numbers

This commit is contained in:
Hayden Hargreaves 2026-02-13 16:10:43 -07:00
parent be46cae73d
commit d5f0f2413a
3 changed files with 58 additions and 32 deletions

View File

@ -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,
}
}

View File

@ -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(),
}
}

View File

@ -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")