fix: cleaned up and fixed the settings that needed updating
This commit is contained in:
parent
dc9a814508
commit
098641f5c0
@ -16,6 +16,7 @@ func main() {
|
||||
|
||||
win := core.NewWindowBuilder().
|
||||
WithBuffer(&buf).
|
||||
WithOptions(core.NewDefaultWinOptions()).
|
||||
Build()
|
||||
|
||||
model := editor.NewModelBuilder().
|
||||
|
||||
@ -241,7 +241,7 @@ func (a InsertTab) Execute(m Model) tea.Cmd {
|
||||
|
||||
x, y := win.Cursor.Col, win.Cursor.Line
|
||||
l := buf.Lines[y]
|
||||
tabs := strings.Repeat(" ", m.Settings().TabSize)
|
||||
tabs := strings.Repeat(" ", m.Settings().TabStop)
|
||||
if x < len(l) {
|
||||
buf.SetLine(y, l[:x]+tabs+l[x:])
|
||||
} else {
|
||||
|
||||
@ -45,8 +45,8 @@ type Model interface {
|
||||
Mode() core.Mode
|
||||
SetMode(mode core.Mode)
|
||||
|
||||
Settings() core.Settings
|
||||
SetSettings(s core.Settings)
|
||||
Settings() core.EditorSettings
|
||||
SetSettings(s core.EditorSettings)
|
||||
|
||||
// ==================================================
|
||||
// Registers
|
||||
@ -55,7 +55,6 @@ type Model interface {
|
||||
GetRegister(name rune) (core.Register, bool)
|
||||
SetRegister(name rune, t core.RegisterType, cnt []string) error
|
||||
UpdateDefaultRegister(t core.RegisterType, cnt []string)
|
||||
|
||||
}
|
||||
|
||||
// Action is the base interface - anything executable
|
||||
|
||||
@ -110,7 +110,15 @@ type Setting struct {
|
||||
Name string
|
||||
ShortForm string
|
||||
Type SettingType
|
||||
Get func(s core.Settings) any
|
||||
Get func(s core.EditorSettings) any
|
||||
Set func(m action.Model, val any)
|
||||
}
|
||||
|
||||
type WindowSetting struct {
|
||||
Name string
|
||||
ShortForm string
|
||||
Type SettingType
|
||||
Get func(m action.Model) any
|
||||
Set func(m action.Model, val any)
|
||||
}
|
||||
|
||||
@ -123,50 +131,69 @@ const (
|
||||
StringSetting
|
||||
)
|
||||
|
||||
// settingsMap defines all available settings
|
||||
// settingsMap defines all available editor settings
|
||||
var settingsMap = []Setting{
|
||||
{
|
||||
Name: "tabstop",
|
||||
ShortForm: "ts",
|
||||
Type: IntSetting,
|
||||
Get: func(s core.EditorSettings) any { return s.TabStop },
|
||||
Set: func(m action.Model, val any) {
|
||||
s := m.Settings()
|
||||
s.TabStop = val.(int)
|
||||
m.SetSettings(s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// windowSettingsMap defines all available window settings
|
||||
var windowSettingsMap = []WindowSetting{
|
||||
{
|
||||
Name: "number",
|
||||
ShortForm: "nu",
|
||||
Type: BoolSetting,
|
||||
Get: func(s core.Settings) any { return s.Number },
|
||||
Get: func(m action.Model) any { return m.ActiveWindow().Options.Number },
|
||||
Set: func(m action.Model, val any) {
|
||||
s := m.Settings()
|
||||
s.Number = val.(bool)
|
||||
m.SetSettings(s)
|
||||
w := m.ActiveWindow()
|
||||
o := w.Options
|
||||
o.Number = val.(bool)
|
||||
w.SetOptions(o)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "relativenumber",
|
||||
ShortForm: "rnu",
|
||||
Type: BoolSetting,
|
||||
Get: func(s core.Settings) any { return s.RelativeNumber },
|
||||
Get: func(m action.Model) any { return m.ActiveWindow().Options.RelativeNumber },
|
||||
Set: func(m action.Model, val any) {
|
||||
s := m.Settings()
|
||||
s.RelativeNumber = val.(bool)
|
||||
m.SetSettings(s)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "tabstop",
|
||||
ShortForm: "ts",
|
||||
Type: IntSetting,
|
||||
Get: func(s core.Settings) any { return s.TabSize },
|
||||
Set: func(m action.Model, val any) {
|
||||
s := m.Settings()
|
||||
s.TabSize = val.(int)
|
||||
m.SetSettings(s)
|
||||
w := m.ActiveWindow()
|
||||
o := w.Options
|
||||
o.RelativeNumber = val.(bool)
|
||||
w.SetOptions(o)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "scrolloff",
|
||||
ShortForm: "so",
|
||||
Type: IntSetting,
|
||||
Get: func(s core.Settings) any { return s.ScrollOff },
|
||||
Get: func(m action.Model) any { return m.ActiveWindow().Options.ScrollOff },
|
||||
Set: func(m action.Model, val any) {
|
||||
s := m.Settings()
|
||||
s.ScrollOff = val.(int)
|
||||
m.SetSettings(s)
|
||||
w := m.ActiveWindow()
|
||||
o := w.Options
|
||||
o.ScrollOff = val.(int)
|
||||
w.SetOptions(o)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "guttersize",
|
||||
ShortForm: "gu",
|
||||
Type: IntSetting,
|
||||
Get: func(m action.Model) any { return m.ActiveWindow().Options.GutterSize },
|
||||
Set: func(m action.Model, val any) {
|
||||
w := m.ActiveWindow()
|
||||
o := w.Options
|
||||
o.GutterSize = val.(int)
|
||||
w.SetOptions(o)
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -186,14 +213,27 @@ func lookupSetting(name string) *Setting {
|
||||
return nil
|
||||
}
|
||||
|
||||
// lookupWindowSetting: Finds a window setting by name, short form, or prefix.
|
||||
func lookupWindowSetting(name string) *WindowSetting {
|
||||
for i := range windowSettingsMap {
|
||||
s := &windowSettingsMap[i]
|
||||
if name == s.Name || name == s.ShortForm {
|
||||
return s
|
||||
}
|
||||
// Prefix matching
|
||||
if len(name) >= len(s.ShortForm) && strings.HasPrefix(s.Name, name) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseSetOption: Parses and applies a single :set option.
|
||||
func parseSetOption(m action.Model, opt string) error {
|
||||
// Handle toggle: option!
|
||||
if name, ok := strings.CutSuffix(opt, "!"); ok {
|
||||
setting := lookupSetting(name)
|
||||
if setting == nil {
|
||||
return nil // Unknown setting
|
||||
}
|
||||
if setting != nil {
|
||||
if setting.Type == BoolSetting {
|
||||
// Toggle the boolean
|
||||
currentVal := setting.Get(m.Settings()).(bool)
|
||||
@ -202,26 +242,47 @@ func parseSetOption(m action.Model, opt string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
windowSetting := lookupWindowSetting(name)
|
||||
if windowSetting != nil {
|
||||
if windowSetting.Type == BoolSetting {
|
||||
// Toggle the boolean
|
||||
currentVal := windowSetting.Get(m).(bool)
|
||||
windowSetting.Set(m, !currentVal)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle disable: nooption
|
||||
if name, ok := strings.CutPrefix(opt, "no"); ok {
|
||||
setting := lookupSetting(name)
|
||||
if setting == nil {
|
||||
return nil
|
||||
}
|
||||
if setting != nil {
|
||||
if setting.Type == BoolSetting {
|
||||
setting.Set(m, false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
windowSetting := lookupWindowSetting(name)
|
||||
if windowSetting != nil {
|
||||
if windowSetting.Type == BoolSetting {
|
||||
windowSetting.Set(m, false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle assignment: option=value
|
||||
if strings.Contains(opt, "=") {
|
||||
parts := strings.SplitN(opt, "=", 2)
|
||||
name, value := parts[0], parts[1]
|
||||
|
||||
setting := lookupSetting(name)
|
||||
if setting == nil {
|
||||
return nil
|
||||
}
|
||||
if setting != nil {
|
||||
switch setting.Type {
|
||||
case IntSetting:
|
||||
intVal, err := strconv.Atoi(value)
|
||||
@ -239,13 +300,43 @@ func parseSetOption(m action.Model, opt string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle enable: option (boolean only)
|
||||
setting := lookupSetting(opt)
|
||||
if setting == nil {
|
||||
return nil
|
||||
windowSetting := lookupWindowSetting(name)
|
||||
if windowSetting != nil {
|
||||
switch windowSetting.Type {
|
||||
case IntSetting:
|
||||
intVal, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if setting.Type == BoolSetting {
|
||||
setting.Set(m, true)
|
||||
windowSetting.Set(m, intVal)
|
||||
case StringSetting:
|
||||
windowSetting.Set(m, value)
|
||||
case BoolSetting:
|
||||
// Handle :set option=true / :set option=false
|
||||
boolVal := value == "true" || value == "1" || value == "yes"
|
||||
windowSetting.Set(m, boolVal)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle enable: option (boolean only)
|
||||
setting := lookupSetting(opt)
|
||||
if setting != nil {
|
||||
if setting.Type == BoolSetting {
|
||||
setting.Set(m, true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
windowSetting := lookupWindowSetting(opt)
|
||||
if windowSetting != nil {
|
||||
if windowSetting.Type == BoolSetting {
|
||||
windowSetting.Set(m, true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -1,23 +1,15 @@
|
||||
package core
|
||||
|
||||
// Settings: Configuration options for editor display and behavior.
|
||||
type Settings struct {
|
||||
Number bool
|
||||
RelativeNumber bool
|
||||
GutterSize int
|
||||
TabSize int
|
||||
ScrollOff int
|
||||
// EditorSettings: Configuration options for editor display and behavior.
|
||||
type EditorSettings struct {
|
||||
TabStop int
|
||||
// TODO: Colors
|
||||
}
|
||||
|
||||
// NewDefaultSettings: Creates a Settings struct with sensible defaults for
|
||||
// line numbers, gutter width, tab size, and scroll offset.
|
||||
func NewDefaultSettings() Settings {
|
||||
return Settings{
|
||||
Number: true,
|
||||
RelativeNumber: true,
|
||||
GutterSize: 5,
|
||||
TabSize: 2,
|
||||
ScrollOff: 8,
|
||||
func NewDefaultSettings() EditorSettings {
|
||||
return EditorSettings{
|
||||
TabStop: 2,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,12 +2,22 @@ package core
|
||||
|
||||
// TODO: No more global settings, window-wide settings
|
||||
type WinOptions struct {
|
||||
// Number bool
|
||||
Number bool
|
||||
RelativeNumber bool
|
||||
GutterSize int
|
||||
// Wrap bool
|
||||
// Relnumber bool
|
||||
ScrollOff int
|
||||
}
|
||||
|
||||
func NewDefaultWinOptions() WinOptions {
|
||||
return WinOptions{
|
||||
Number: true,
|
||||
RelativeNumber: true,
|
||||
GutterSize: 5,
|
||||
ScrollOff: 8,
|
||||
}
|
||||
}
|
||||
|
||||
type Window struct {
|
||||
Id int
|
||||
Number int // Ignored for now, will be used when splits come into play
|
||||
@ -181,3 +191,8 @@ func (w *Window) SetDimensions(width, height int) {
|
||||
w.Width = width
|
||||
w.Height = height
|
||||
}
|
||||
|
||||
// Window.SetOptions: Sets the options of this window.
|
||||
func (w *Window) SetOptions(opts WinOptions) {
|
||||
w.Options = opts
|
||||
}
|
||||
|
||||
@ -102,8 +102,8 @@ func TestCommandSetInteger(t *testing.T) {
|
||||
sendKeys(tm, ":", "s", "e", "t", " ", "t", "a", "b", "s", "t", "o", "p", "=", "4", "enter")
|
||||
|
||||
m := getFinalModel(t, tm)
|
||||
if m.Settings().TabSize != 4 {
|
||||
t.Errorf("TabSize = %d, want 4", m.Settings().TabSize)
|
||||
if m.Settings().TabStop != 4 {
|
||||
t.Errorf("TabSize = %d, want 4", m.Settings().TabStop)
|
||||
}
|
||||
})
|
||||
|
||||
@ -114,8 +114,8 @@ func TestCommandSetInteger(t *testing.T) {
|
||||
sendKeys(tm, ":", "s", "e", "t", " ", "t", "s", "=", "8", "enter")
|
||||
|
||||
m := getFinalModel(t, tm)
|
||||
if m.Settings().TabSize != 8 {
|
||||
t.Errorf("TabSize = %d, want 8", m.Settings().TabSize)
|
||||
if m.Settings().TabStop != 8 {
|
||||
t.Errorf("TabSize = %d, want 8", m.Settings().TabStop)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ type Model struct {
|
||||
commandOutput string
|
||||
|
||||
// Global settings (TODO: This needs to be refactored)
|
||||
settings core.Settings
|
||||
settings core.EditorSettings
|
||||
|
||||
// Registers
|
||||
registers map[rune]core.Register // name -> register
|
||||
@ -185,7 +185,7 @@ func (m *Model) processInsertKey(key string) {
|
||||
}
|
||||
|
||||
case "tab":
|
||||
tabs := strings.Repeat(" ", m.Settings().TabSize)
|
||||
tabs := strings.Repeat(" ", m.Settings().TabStop)
|
||||
if col < len(l) {
|
||||
buf.SetLine(line, l[:col]+tabs+l[col:])
|
||||
} else {
|
||||
@ -282,11 +282,11 @@ func (m *Model) SetMode(mode core.Mode) {
|
||||
m.mode = mode
|
||||
}
|
||||
|
||||
func (m *Model) Settings() core.Settings {
|
||||
func (m *Model) Settings() core.EditorSettings {
|
||||
return m.settings
|
||||
}
|
||||
|
||||
func (m *Model) SetSettings(s core.Settings) {
|
||||
func (m *Model) SetSettings(s core.EditorSettings) {
|
||||
m.settings = s
|
||||
}
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ func (mb *ModelBuilder) WithTermHeight(height int) *ModelBuilder {
|
||||
}
|
||||
|
||||
// ModelBuilder.WithSettings: Set the editor settings (tabstop, scrolloff, etc).
|
||||
func (mb *ModelBuilder) WithSettings(settings core.Settings) *ModelBuilder {
|
||||
func (mb *ModelBuilder) WithSettings(settings core.EditorSettings) *ModelBuilder {
|
||||
mb.model.settings = settings
|
||||
return mb
|
||||
}
|
||||
|
||||
@ -19,10 +19,10 @@ func (m Model) View() string {
|
||||
// Each window has its own status bar and mode
|
||||
|
||||
styles := m.Styles()
|
||||
settings := m.Settings()
|
||||
options := win.Options
|
||||
|
||||
// Draw window
|
||||
view := viewWindow(win, styles, settings, m.Mode())
|
||||
view := viewWindow(win, styles, options, m.Mode())
|
||||
|
||||
// Command bar is seperate
|
||||
cmdBar := drawCommandBar(m)
|
||||
@ -31,7 +31,7 @@ func (m Model) View() string {
|
||||
|
||||
// viewWindow: Renders a single window's content including line numbers and buffer text.
|
||||
// Each window has its own line numbers, gutter, and viewport dimensions.
|
||||
func viewWindow(w *core.Window, styles style.Styles, settings core.Settings, mode core.Mode) string {
|
||||
func viewWindow(w *core.Window, styles style.Styles, options core.WinOptions, mode core.Mode) string {
|
||||
buf := w.Buffer
|
||||
var view strings.Builder
|
||||
|
||||
@ -42,7 +42,7 @@ func viewWindow(w *core.Window, styles style.Styles, settings core.Settings, mod
|
||||
// Draw buffer lines
|
||||
for lineNum := start; lineNum < end; lineNum++ {
|
||||
if lineNum < buf.LineCount() {
|
||||
line := drawLine(w, styles, settings, mode, buf.Line(lineNum), lineNum)
|
||||
line := drawLine(w, styles, options, mode, buf.Line(lineNum), lineNum)
|
||||
view.WriteString(line)
|
||||
}
|
||||
view.WriteRune('\n')
|
||||
@ -57,7 +57,7 @@ func viewWindow(w *core.Window, styles style.Styles, settings core.Settings, mod
|
||||
|
||||
// drawLine: Renders a single line with syntax highlighting, cursor, and visual selection.
|
||||
// Handles gutter, cursor rendering, and visual mode highlighting.
|
||||
func drawLine(w *core.Window, styles style.Styles, settings core.Settings, mode core.Mode, line string, lineNumber int) string {
|
||||
func drawLine(w *core.Window, styles style.Styles, options core.WinOptions, mode core.Mode, line string, lineNumber int) string {
|
||||
runes := []rune(line)
|
||||
|
||||
curStyle := styles.CursorStyle(mode)
|
||||
@ -66,7 +66,7 @@ func drawLine(w *core.Window, styles style.Styles, settings core.Settings, mode
|
||||
var view strings.Builder
|
||||
|
||||
// Draw gutter first
|
||||
gutter := drawGutter(w, styles, settings, lineNumber)
|
||||
gutter := drawGutter(w, styles, options, lineNumber)
|
||||
view.WriteString(gutter)
|
||||
|
||||
// Now draw the line content
|
||||
@ -97,15 +97,15 @@ func drawLine(w *core.Window, styles style.Styles, settings core.Settings, mode
|
||||
|
||||
// drawGutter: Renders the line number gutter with support for both absolute and
|
||||
// relative line numbers, highlighting the current line differently.
|
||||
func drawGutter(w *core.Window, styles style.Styles, settings core.Settings, curLine int) string {
|
||||
if !(settings.Number || settings.RelativeNumber) {
|
||||
func drawGutter(w *core.Window, styles style.Styles, options core.WinOptions, curLine int) string {
|
||||
if !(options.Number || options.RelativeNumber) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Required vars
|
||||
var (
|
||||
view strings.Builder
|
||||
gutSize int = settings.GutterSize - 1 // -1 is for padding
|
||||
gutSize int = options.GutterSize - 1 // -1 is for padding
|
||||
currentLine bool = curLine == w.Cursor.Line
|
||||
lineNumber int
|
||||
|
||||
@ -115,7 +115,7 @@ func drawGutter(w *core.Window, styles style.Styles, settings core.Settings, cur
|
||||
)
|
||||
|
||||
// If we have relative setting, set the numbers relatively
|
||||
if settings.RelativeNumber {
|
||||
if options.RelativeNumber {
|
||||
if curLine > w.Cursor.Line {
|
||||
lineNumber = curLine - w.Cursor.Line
|
||||
}
|
||||
@ -126,7 +126,7 @@ func drawGutter(w *core.Window, styles style.Styles, settings core.Settings, cur
|
||||
}
|
||||
|
||||
// If we have number setting AND not relative setting OR we are on current line, use current line number
|
||||
if (settings.Number && !settings.RelativeNumber) || (settings.Number && currentLine) {
|
||||
if (options.Number && !options.RelativeNumber) || (options.Number && currentLine) {
|
||||
lineNumber = curLine + 1
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user