diff --git a/cmd/gim/main.go b/cmd/gim/main.go index 0766a75..50c3c96 100644 --- a/cmd/gim/main.go +++ b/cmd/gim/main.go @@ -1,28 +1,35 @@ package main import ( - "fmt" - "git.gophernest.net/azpect/TextEditor/internal/action" "git.gophernest.net/azpect/TextEditor/internal/editor" tea "github.com/charmbracelet/bubbletea" ) func main() { - m, _ := tea.NewProgram( - editor.NewModel([]string{""}, action.Position{Line: 0, Col: 0}), - tea.WithAltScreen(), - ).Run() + buf := action.NewBufferBuilder(). + Build() - final, ok := m.(*editor.Model) - if ok { - fmt.Printf("PRINTING WINDOWS: %+v\n", final.Windows()) - fmt.Printf("PRINTING ACTIVE WINDOW: %+v\n", final.ActiveWindow()) - for _, win := range final.Windows() { - fmt.Printf("\t%+v\n", *win.Buffer) - } - } else { - fmt.Printf("PRINTING ALL: %+v\n", m) - } + win := action.NewWindowBuilder(). + WithBuffer(&buf). + Build() + model := editor.NewModelBuilder(). + AddBuffer(&buf). + AddWindow(&win). + WithActiveWindowId(win.Id). + Build() + + tea.NewProgram(model, tea.WithAltScreen()).Run() + + // final, ok := m.(*editor.Model) + // if ok { + // fmt.Printf("PRINTING WINDOWS: %+v\n", final.Windows()) + // fmt.Printf("PRINTING ACTIVE WINDOW: %+v\n", final.ActiveWindow()) + // for _, win := range final.Windows() { + // fmt.Printf("\t%+v\n", *win.Buffer) + // } + // } else { + // fmt.Printf("PRINTING ALL: %+v\n", m) + // } } diff --git a/internal/editor/gim b/internal/editor/gim deleted file mode 100755 index b8a7b85..0000000 Binary files a/internal/editor/gim and /dev/null differ diff --git a/internal/editor/model.go b/internal/editor/model.go index d1c068f..727aeb8 100644 --- a/internal/editor/model.go +++ b/internal/editor/model.go @@ -46,37 +46,6 @@ type Model struct { registers map[rune]action.Register // name -> register } -func NewModel(lines []string, pos action.Position) *Model { - m := Model{ - mode: action.NormalMode, - command: "", - input: input.NewHandler(), - settings: action.NewDefaultSettings(), - registers: action.DefaultRegisters(), - - windows: []*action.Window{}, - } - - // TODO: Temporary: Build the single buffer and window - buf := action. - NewBufferBuilder(). - WithLines(lines). - Build() - - m.buffers = append(m.buffers, &buf) - - win := action. - NewWindowBuilder(). - WithBuffer(&buf). - WithCursor(pos). - Build() - - m.windows = append(m.windows, &win) - m.activeWindowId = win.Id - - return &m -} - // Model.Init: Initialize the model and start any commands that may need to run. Required // for the bubbletea architecture. func (m Model) Init() tea.Cmd { @@ -222,13 +191,11 @@ func (m *Model) processInsertKey(key string) { case "up": if line > 0 { win.SetCursorLine(line - 1) - win.ClampCursorX() } case "down": if line+1 < buf.LineCount() { win.SetCursorLine(line + 1) - win.ClampCursorX() } case "left": diff --git a/internal/editor/model_builder.go b/internal/editor/model_builder.go new file mode 100644 index 0000000..98fd332 --- /dev/null +++ b/internal/editor/model_builder.go @@ -0,0 +1,132 @@ +package editor + +import ( + "git.gophernest.net/azpect/TextEditor/internal/action" + "git.gophernest.net/azpect/TextEditor/internal/input" +) + +type ModelBuilder struct { + model Model +} + +func NewModelBuilder() *ModelBuilder { + return &ModelBuilder{ + model: Model{ + buffers: []*action.Buffer{}, + windows: []*action.Window{}, + activeWindowId: -1, + mode: action.NormalMode, + termWidth: 0, + termHeight: 0, + input: input.NewHandler(), + insertCount: 0, + insertKeys: []string{}, + insertAction: nil, + command: "", + commandCursor: 0, + commandError: nil, + commandOutput: "", + settings: action.NewDefaultSettings(), + registers: action.DefaultRegisters(), + }, + } +} + +// ModelBuilder.WithBuffers: Set the buffers for the model. Buffers represent +// the in-memory text content of files being edited. +func (mb *ModelBuilder) WithBuffers(buffers []*action.Buffer) *ModelBuilder { + mb.model.buffers = buffers + return mb +} + +// ModelBuilder.AddBuffer: Add a single buffer to the model's buffer list. +func (mb *ModelBuilder) AddBuffer(buffer *action.Buffer) *ModelBuilder { + mb.model.buffers = append(mb.model.buffers, buffer) + return mb +} + +// ModelBuilder.WithWindows: Set the windows for the model. Windows are viewports +// that display buffer content with their own cursor position and scroll state. +func (mb *ModelBuilder) WithWindows(windows []*action.Window) *ModelBuilder { + mb.model.windows = windows + return mb +} + +// ModelBuilder.AddWindow: Add a single window to the model's window list. +func (mb *ModelBuilder) AddWindow(window *action.Window) *ModelBuilder { + mb.model.windows = append(mb.model.windows, window) + return mb +} + +// ModelBuilder.WithActiveWindowId: Set the ID of the currently active window. +// This determines which window receives input and displays the cursor. +func (mb *ModelBuilder) WithActiveWindowId(id int) *ModelBuilder { + mb.model.activeWindowId = id + return mb +} + +// ModelBuilder.WithMode: Set the editor mode (Normal, Insert, Visual, etc). +func (mb *ModelBuilder) WithMode(mode action.Mode) *ModelBuilder { + mb.model.mode = mode + return mb +} + +// ModelBuilder.WithTermSize: Set the terminal dimensions in columns and rows. +func (mb *ModelBuilder) WithTermSize(width, height int) *ModelBuilder { + mb.model.termWidth = width + mb.model.termHeight = height + return mb +} + +// ModelBuilder.WithTermWidth: Set the terminal width in columns. +func (mb *ModelBuilder) WithTermWidth(width int) *ModelBuilder { + mb.model.termWidth = width + return mb +} + +// ModelBuilder.WithTermHeight: Set the terminal height in rows. +func (mb *ModelBuilder) WithTermHeight(height int) *ModelBuilder { + mb.model.termHeight = height + return mb +} + +// ModelBuilder.WithSettings: Set the editor settings (tabstop, scrolloff, etc). +func (mb *ModelBuilder) WithSettings(settings action.Settings) *ModelBuilder { + mb.model.settings = settings + return mb +} + +// ModelBuilder.WithRegisters: Set the register map for yank/delete/paste operations. +func (mb *ModelBuilder) WithRegisters(registers map[rune]action.Register) *ModelBuilder { + mb.model.registers = registers + return mb +} + +// ModelBuilder.WithCommand: Set the command line text. +func (mb *ModelBuilder) WithCommand(command string) *ModelBuilder { + mb.model.command = command + return mb +} + +// ModelBuilder.WithCommandCursor: Set the cursor position in the command line. +func (mb *ModelBuilder) WithCommandCursor(cursor int) *ModelBuilder { + mb.model.commandCursor = cursor + return mb +} + +// ModelBuilder.WithCommandError: Set the command line error state. +func (mb *ModelBuilder) WithCommandError(err error) *ModelBuilder { + mb.model.commandError = err + return mb +} + +// ModelBuilder.WithCommandOutput: Set the command line output text. +func (mb *ModelBuilder) WithCommandOutput(output string) *ModelBuilder { + mb.model.commandOutput = output + return mb +} + +// ModelBuilder.Build: Build and return the configured Model instance. +func (mb *ModelBuilder) Build() *Model { + return &mb.model +}