wip: implement windows, buffers and builders
This commit is contained in:
parent
3339dd4409
commit
ea4638d815
@ -22,26 +22,12 @@ type Buffer struct {
|
|||||||
// UndoTree TODO: This will be big
|
// UndoTree TODO: This will be big
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not great, but maybe the best way
|
// ==================================================
|
||||||
var CurrentBufferId int = 1
|
// Helper methods
|
||||||
|
// ==================================================
|
||||||
|
|
||||||
func NewEmptyBuffer(lines []string) *Buffer {
|
// Buffer.Line: Get the line at an index. Returns an empty string if the index
|
||||||
buf := Buffer{
|
// is out of bounds.
|
||||||
Id: CurrentBufferId,
|
|
||||||
Filename: "",
|
|
||||||
Filetype: "",
|
|
||||||
Lines: lines,
|
|
||||||
Modified: false,
|
|
||||||
Loaded: true,
|
|
||||||
Listed: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentBufferId++
|
|
||||||
|
|
||||||
return &buf
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the line at an index
|
|
||||||
func (b *Buffer) Line(idx int) string {
|
func (b *Buffer) Line(idx int) string {
|
||||||
if idx < 0 || idx >= len(b.Lines) {
|
if idx < 0 || idx >= len(b.Lines) {
|
||||||
return ""
|
return ""
|
||||||
@ -49,14 +35,17 @@ func (b *Buffer) Line(idx int) string {
|
|||||||
return b.Lines[idx]
|
return b.Lines[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the content at an index.
|
// Buffer.SetLine: Set the content of the line at an index. Does nothing if the
|
||||||
|
// index is out of bounds.
|
||||||
func (b *Buffer) SetLine(idx int, content string) {
|
func (b *Buffer) SetLine(idx int, content string) {
|
||||||
if idx >= 0 && idx < len(b.Lines) {
|
if idx >= 0 && idx < len(b.Lines) {
|
||||||
b.Lines[idx] = content
|
b.Lines[idx] = content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert a line with content at an index
|
// Buffer.InsertLine: Insert a line with content at an index. The index is clamped
|
||||||
|
// to valid bounds (0 to len(Lines)). The new line is inserted before the line at
|
||||||
|
// the given index.
|
||||||
func (b *Buffer) InsertLine(idx int, content string) {
|
func (b *Buffer) InsertLine(idx int, content string) {
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
idx = 0
|
idx = 0
|
||||||
@ -67,14 +56,56 @@ func (b *Buffer) InsertLine(idx int, content string) {
|
|||||||
b.Lines = append(b.Lines[:idx], append([]string{content}, b.Lines[idx:]...)...)
|
b.Lines = append(b.Lines[:idx], append([]string{content}, b.Lines[idx:]...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a line at an index
|
// Buffer.DeleteLine: Delete a line at an index. Does nothing if the index is out
|
||||||
|
// of bounds.
|
||||||
func (b *Buffer) DeleteLine(idx int) {
|
func (b *Buffer) DeleteLine(idx int) {
|
||||||
if idx >= 0 && idx < len(b.Lines) {
|
if idx >= 0 && idx < len(b.Lines) {
|
||||||
b.Lines = append(b.Lines[:idx], b.Lines[idx+1:]...)
|
b.Lines = append(b.Lines[:idx], b.Lines[idx+1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the number of lines in the buffer
|
// Buffer.LineCount: Get the number of lines in the buffer.
|
||||||
func (b *Buffer) LineCount() int {
|
func (b *Buffer) LineCount() int {
|
||||||
return len(b.Lines)
|
return len(b.Lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================================================
|
||||||
|
// Setters
|
||||||
|
// ==================================================
|
||||||
|
|
||||||
|
// Buffer.SetFilename: Set the filename associated with this buffer. This is
|
||||||
|
// typically the path to the file on disk that this buffer represents.
|
||||||
|
func (b *Buffer) SetFilename(filename string) {
|
||||||
|
b.Filename = filename
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer.SetFiletype: Set the filetype of this buffer. The filetype is used
|
||||||
|
// for syntax highlighting and other language-specific features.
|
||||||
|
func (b *Buffer) SetFiletype(filetype string) {
|
||||||
|
b.Filetype = filetype
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer.SetLines: Replace all lines in the buffer with the provided lines.
|
||||||
|
// This is useful when loading a file or resetting buffer content.
|
||||||
|
func (b *Buffer) SetLines(lines []string) {
|
||||||
|
b.Lines = lines
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer.SetModified: Set the modified flag for this buffer. A modified buffer
|
||||||
|
// has unsaved changes that differ from the file on disk.
|
||||||
|
func (b *Buffer) SetModified(modified bool) {
|
||||||
|
b.Modified = modified
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer.SetLoaded: Set the loaded flag for this buffer. A loaded buffer has
|
||||||
|
// its content in memory, while an unloaded buffer exists only as metadata.
|
||||||
|
func (b *Buffer) SetLoaded(loaded bool) {
|
||||||
|
b.Loaded = loaded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer.SetListed: Set the listed flag for this buffer. A listed buffer appears
|
||||||
|
// in buffer lists (like :ls), while an unlisted buffer is hidden from normal
|
||||||
|
// buffer navigation.
|
||||||
|
func (b *Buffer) SetListed(listed bool) {
|
||||||
|
b.Listed = listed
|
||||||
|
}
|
||||||
|
|||||||
73
internal/action/buffer_builder.go
Normal file
73
internal/action/buffer_builder.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package action
|
||||||
|
|
||||||
|
// Not great, but maybe the best way
|
||||||
|
var CurrentBufferId int = 1
|
||||||
|
|
||||||
|
type BufferBuilder struct {
|
||||||
|
buffer Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBufferBuilder: Creates a new buffer builder. The buffer builder implements a
|
||||||
|
// builder pattern to create a buffer with the defined properties and values.
|
||||||
|
func NewBufferBuilder() *BufferBuilder {
|
||||||
|
return &BufferBuilder{
|
||||||
|
buffer: Buffer{
|
||||||
|
Id: 0, // This is set when built
|
||||||
|
Filename: "",
|
||||||
|
Filetype: "",
|
||||||
|
Lines: []string{""},
|
||||||
|
Modified: false,
|
||||||
|
Loaded: false,
|
||||||
|
Listed: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferBuilder.WithFilename: Attaches a file name to the buffer that is being built.
|
||||||
|
func (b *BufferBuilder) WithFilename(filename string) *BufferBuilder {
|
||||||
|
b.buffer.Filename = filename
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferBuilder.WithFiletype: Attaches a file type to the buffer that is being built.
|
||||||
|
func (b *BufferBuilder) WithFiletype(filetype string) *BufferBuilder {
|
||||||
|
b.buffer.Filetype = filetype
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferBuilder.WithLines: Attaches a lines to the buffer that is being built.
|
||||||
|
func (b *BufferBuilder) WithLines(lines []string) *BufferBuilder {
|
||||||
|
b.buffer.Lines = lines
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferBuilder.Modified: Sets the modified flag of the buffer being built. By default,
|
||||||
|
// buffers are built with the modified flag being false.
|
||||||
|
func (b *BufferBuilder) Modified() *BufferBuilder {
|
||||||
|
b.buffer.Modified = true
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferBuilder.Loaded: Sets the loaded flag of the buffer being built. By default,
|
||||||
|
// buffers are built with the loaded flag being false.
|
||||||
|
func (b *BufferBuilder) Loaded() *BufferBuilder {
|
||||||
|
b.buffer.Loaded = true
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferBuilder.Listed: Sets the listed flag of the buffer being built. By default,
|
||||||
|
// buffers are built with the listed flag being false.
|
||||||
|
func (b *BufferBuilder) Listed() *BufferBuilder {
|
||||||
|
b.buffer.Listed = true
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// BufferBuilder.Build: Build the final buffer and return it to the caller. Final
|
||||||
|
// step in the process. This is where the ID is set, so many buffers can be "in-progress"
|
||||||
|
// but the ID will be set when they are built. Meaning, this is not thread safe.
|
||||||
|
func (b *BufferBuilder) Build() Buffer {
|
||||||
|
b.buffer.Id = CurrentBufferId
|
||||||
|
CurrentBufferId++
|
||||||
|
|
||||||
|
return b.buffer
|
||||||
|
}
|
||||||
@ -16,36 +16,20 @@ type Window struct {
|
|||||||
Anchor Position
|
Anchor Position
|
||||||
|
|
||||||
ScrollY int
|
ScrollY int
|
||||||
Width int
|
|
||||||
Height int
|
Height int
|
||||||
|
Width int
|
||||||
|
|
||||||
// Folds // TODO
|
// Folds // TODO
|
||||||
// Options WinOptions
|
// Options WinOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not great, but maybe the best way
|
// ==================================================
|
||||||
var CurrentWindowId int = 1000
|
// Helper methods
|
||||||
|
// ==================================================
|
||||||
func NewEmptyWindow(lines []string, w, h int) *Window {
|
|
||||||
win := &Window{
|
|
||||||
Id: CurrentWindowId,
|
|
||||||
Number: 1, // Ignored for now
|
|
||||||
|
|
||||||
Buffer: NewEmptyBuffer(lines),
|
|
||||||
|
|
||||||
Cursor: Position{Line: 0, Col: 0},
|
|
||||||
Anchor: Position{Line: 0, Col: 0},
|
|
||||||
|
|
||||||
ScrollY: 0,
|
|
||||||
Width: w,
|
|
||||||
Height: h,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment
|
|
||||||
CurrentWindowId++
|
|
||||||
|
|
||||||
return win
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Window.ClampCursorX: Clamps the cursor in the X direction to ensure the cursor
|
||||||
|
// does not go into an invalid position. Such as negative values or past the end of
|
||||||
|
// the line.
|
||||||
func (w *Window) ClampCursorX() {
|
func (w *Window) ClampCursorX() {
|
||||||
lineLen := len(w.Buffer.Lines[w.Cursor.Line])
|
lineLen := len(w.Buffer.Lines[w.Cursor.Line])
|
||||||
if lineLen == 0 {
|
if lineLen == 0 {
|
||||||
@ -54,3 +38,87 @@ func (w *Window) ClampCursorX() {
|
|||||||
w.Cursor.Col = lineLen
|
w.Cursor.Col = lineLen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================================================
|
||||||
|
// Setters
|
||||||
|
// ==================================================
|
||||||
|
|
||||||
|
// Window.SetNumber: Sets the position-based number of this window. Currently ignored
|
||||||
|
// until splits are implemented.
|
||||||
|
func (w *Window) SetNumber(number int) {
|
||||||
|
w.Number = number
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetBuffer: Sets the buffer that this window should display. This is used when
|
||||||
|
// switching between buffers or opening a new file in the current window.
|
||||||
|
func (w *Window) SetBuffer(buffer *Buffer) {
|
||||||
|
w.Buffer = buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetCursor: Sets the cursor position in this window to the given position.
|
||||||
|
func (w *Window) SetCursor(cursor Position) {
|
||||||
|
w.Cursor = cursor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetCursorLine: Sets the line number of the cursor position.
|
||||||
|
func (w *Window) SetCursorLine(line int) {
|
||||||
|
w.Cursor.Line = line
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetCursorCol: Sets the column number of the cursor position.
|
||||||
|
func (w *Window) SetCursorCol(col int) {
|
||||||
|
w.Cursor.Col = col
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetCursorPos: Sets both the line and column of the cursor position. This is
|
||||||
|
// a convenience method for setting both components at once.
|
||||||
|
func (w *Window) SetCursorPos(line, col int) {
|
||||||
|
w.Cursor.Line = line
|
||||||
|
w.Cursor.Col = col
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetAnchor: Sets the anchor position in this window. The anchor is used for
|
||||||
|
// visual mode selections as the starting point of the selection.
|
||||||
|
func (w *Window) SetAnchor(anchor Position) {
|
||||||
|
w.Anchor = anchor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetAnchorLine: Sets the line number of the anchor position.
|
||||||
|
func (w *Window) SetAnchorLine(line int) {
|
||||||
|
w.Anchor.Line = line
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetAnchorCol: Sets the column number of the anchor position.
|
||||||
|
func (w *Window) SetAnchorCol(col int) {
|
||||||
|
w.Anchor.Col = col
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetAnchorPos: Sets both the line and column of the anchor position. This is
|
||||||
|
// a convenience method for setting both components at once.
|
||||||
|
func (w *Window) SetAnchorPos(line, col int) {
|
||||||
|
w.Anchor.Line = line
|
||||||
|
w.Anchor.Col = col
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetScrollY: Sets the vertical scroll offset of this window. This determines
|
||||||
|
// which line appears at the top of the visible viewport.
|
||||||
|
func (w *Window) SetScrollY(scrollY int) {
|
||||||
|
w.ScrollY = scrollY
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetHeight: Sets the height of this window in lines.
|
||||||
|
func (w *Window) SetHeight(height int) {
|
||||||
|
w.Height = height
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetWidth: Sets the width of this window in columns.
|
||||||
|
func (w *Window) SetWidth(width int) {
|
||||||
|
w.Width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window.SetDimensions: Sets both the width and height of this window. This is a
|
||||||
|
// convenience method for setting both dimensions at once.
|
||||||
|
func (w *Window) SetDimensions(width, height int) {
|
||||||
|
w.Width = width
|
||||||
|
w.Height = height
|
||||||
|
}
|
||||||
|
|||||||
103
internal/action/window_builder.go
Normal file
103
internal/action/window_builder.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package action
|
||||||
|
|
||||||
|
// Not great, but maybe the best way
|
||||||
|
var CurrentWindowId int = 1000
|
||||||
|
|
||||||
|
type WindowBuilder struct {
|
||||||
|
window Window
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWindowBuilder: Creates a new window builder. The window builder implements a
|
||||||
|
// builder pattern to create a window with the defined properties and values.
|
||||||
|
func NewWindowBuilder() *WindowBuilder {
|
||||||
|
return &WindowBuilder{
|
||||||
|
window: Window{
|
||||||
|
Id: 0, // This is set when built
|
||||||
|
Number: 1, // Ignored for now, will be used for splits
|
||||||
|
Buffer: nil,
|
||||||
|
Cursor: Position{Line: 0, Col: 0},
|
||||||
|
Anchor: Position{Line: 0, Col: 0},
|
||||||
|
ScrollY: 0,
|
||||||
|
Height: 0,
|
||||||
|
Width: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithNumber: Attaches a window number to the window that is being built.
|
||||||
|
// Window numbers are position-based and change when windows are rearranged. This is
|
||||||
|
// ignored for now, but will be used when splits are implemented.
|
||||||
|
func (w *WindowBuilder) WithNumber(number int) *WindowBuilder {
|
||||||
|
w.window.Number = number
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithBuffer: Attaches a buffer to the window that is being built. The
|
||||||
|
// window will display and edit the content of this buffer.
|
||||||
|
func (w *WindowBuilder) WithBuffer(buffer *Buffer) *WindowBuilder {
|
||||||
|
w.window.Buffer = buffer
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithCursor: Sets the cursor position in the window that is being built.
|
||||||
|
func (w *WindowBuilder) WithCursor(cursor Position) *WindowBuilder {
|
||||||
|
w.window.Cursor = cursor
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithCursorPos: Sets the cursor position in the window that is being built.
|
||||||
|
// This is an alias for WithCursor that accepts line and column separately.
|
||||||
|
func (w *WindowBuilder) WithCursorPos(line, col int) *WindowBuilder {
|
||||||
|
w.window.Cursor = Position{Line: line, Col: col}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithAnchor: Sets the anchor position in the window that is being built.
|
||||||
|
// The anchor is used for visual mode selections.
|
||||||
|
func (w *WindowBuilder) WithAnchor(anchor Position) *WindowBuilder {
|
||||||
|
w.window.Anchor = anchor
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithAnchorPos: Sets the anchor position in the window that is being built.
|
||||||
|
// This is an alias for WithAnchor that accepts line and column separately.
|
||||||
|
func (w *WindowBuilder) WithAnchorPos(line, col int) *WindowBuilder {
|
||||||
|
w.window.Anchor = Position{Line: line, Col: col}
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithScrollY: Sets the vertical scroll offset of the window that is being built.
|
||||||
|
func (w *WindowBuilder) WithScrollY(scrollY int) *WindowBuilder {
|
||||||
|
w.window.ScrollY = scrollY
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithHeight: Sets the height of the window that is being built.
|
||||||
|
func (w *WindowBuilder) WithHeight(height int) *WindowBuilder {
|
||||||
|
w.window.Height = height
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithWidth: Sets the width of the window that is being built.
|
||||||
|
func (w *WindowBuilder) WithWidth(width int) *WindowBuilder {
|
||||||
|
w.window.Width = width
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.WithDimensions: Sets both width and height of the window that is being built.
|
||||||
|
// This is a convenience method for setting dimensions in one call.
|
||||||
|
func (w *WindowBuilder) WithDimensions(width, height int) *WindowBuilder {
|
||||||
|
w.window.Width = width
|
||||||
|
w.window.Height = height
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// WindowBuilder.Build: Build the final window and return it to the caller. Final
|
||||||
|
// step in the process. This is where the ID is set, so many windows can be "in-progress"
|
||||||
|
// but the ID will be set when they are built. Meaning, this is not thread safe.
|
||||||
|
func (w *WindowBuilder) Build() Window {
|
||||||
|
w.window.Id = CurrentWindowId
|
||||||
|
CurrentWindowId++
|
||||||
|
|
||||||
|
return w.window
|
||||||
|
}
|
||||||
@ -10,31 +10,36 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
// lines []string
|
// Buffers
|
||||||
// cursor cursor
|
buffers []*action.Buffer
|
||||||
// anchor cursor // starting point for visual modes
|
//next buffer id?
|
||||||
// scrollY int
|
|
||||||
mode action.Mode
|
|
||||||
win_h int
|
|
||||||
win_w int
|
|
||||||
|
|
||||||
activeWindow int
|
// Windows
|
||||||
windows []*action.Window
|
windows []*action.Window
|
||||||
|
activeWindowId int
|
||||||
|
|
||||||
|
// Editor wide state
|
||||||
|
mode action.Mode
|
||||||
|
|
||||||
|
// Terminal dimensions
|
||||||
|
termWidth int
|
||||||
|
termHeight int
|
||||||
|
|
||||||
|
// Input and key handling
|
||||||
input *input.Handler
|
input *input.Handler
|
||||||
|
|
||||||
// Insert repetition
|
// Insert mode state & repetition (applied to active window)
|
||||||
insertCount int
|
insertCount int
|
||||||
insertKeys []string
|
insertKeys []string
|
||||||
insertAction action.Action
|
insertAction action.Action
|
||||||
|
|
||||||
// Command mode
|
// Command line state
|
||||||
command string
|
command string
|
||||||
commandCursor int
|
commandCursor int
|
||||||
commandError error
|
commandError error
|
||||||
commandOutput string
|
commandOutput string
|
||||||
|
|
||||||
// Settings
|
// Global settings (TODO: This needs to be refactored)
|
||||||
settings action.Settings
|
settings action.Settings
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
@ -43,12 +48,6 @@ type Model struct {
|
|||||||
|
|
||||||
func NewModel(lines []string, pos action.Position) *Model {
|
func NewModel(lines []string, pos action.Position) *Model {
|
||||||
m := Model{
|
m := Model{
|
||||||
// lines: lines,
|
|
||||||
// cursor: cursor{
|
|
||||||
// x: pos.Col,
|
|
||||||
// y: pos.Line,
|
|
||||||
// },
|
|
||||||
// scrollY: 0,
|
|
||||||
mode: action.NormalMode,
|
mode: action.NormalMode,
|
||||||
command: "",
|
command: "",
|
||||||
input: input.NewHandler(),
|
input: input.NewHandler(),
|
||||||
@ -58,11 +57,22 @@ func NewModel(lines []string, pos action.Position) *Model {
|
|||||||
windows: []*action.Window{},
|
windows: []*action.Window{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary
|
// TODO: Temporary: Build the single buffer and window
|
||||||
win := action.NewEmptyWindow(lines, 0, 0)
|
buf := action.
|
||||||
win.Cursor = pos // Set initial cursor position
|
NewBufferBuilder().
|
||||||
m.windows = append(m.windows, win)
|
WithLines(lines).
|
||||||
m.activeWindow = win.Id
|
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
|
return &m
|
||||||
}
|
}
|
||||||
@ -297,7 +307,7 @@ func (m *Model) Windows() []*action.Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) ActiveWindowId() int {
|
func (m *Model) ActiveWindowId() int {
|
||||||
return m.activeWindow
|
return m.activeWindowId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Model) ActiveWindow() *action.Window {
|
func (m *Model) ActiveWindow() *action.Window {
|
||||||
|
|||||||
@ -10,10 +10,37 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
|
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
m.win_h = msg.Height
|
m.termHeight = msg.Height
|
||||||
m.win_w = msg.Width
|
m.termWidth = msg.Width
|
||||||
|
|
||||||
// TODO: Temp, this is lame
|
// TODO: Implement a layout method that handles this
|
||||||
|
//
|
||||||
|
// func (m *Model) layoutWindows() {
|
||||||
|
// if len(m.windows) == 0 {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if len(m.windows) == 1 {
|
||||||
|
// // Single window - full screen
|
||||||
|
// m.windows[0].Width = m.termWidth
|
||||||
|
// m.windows[0].Height = m.termHeight
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Multiple windows - distribute space
|
||||||
|
// // This is where you'd implement split layout logic
|
||||||
|
// // For example, horizontal split:
|
||||||
|
// halfHeight := m.termHeight / 2
|
||||||
|
// for i, win := range m.windows {
|
||||||
|
// win.Width = m.termWidth
|
||||||
|
// if i < len(m.windows)-1 {
|
||||||
|
// win.Height = halfHeight
|
||||||
|
// } else {
|
||||||
|
// // Last window gets remainder
|
||||||
|
// win.Height = m.termHeight - (halfHeight * (len(m.windows) - 1))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
for i := range m.windows {
|
for i := range m.windows {
|
||||||
m.windows[i].Height = msg.Height
|
m.windows[i].Height = msg.Height
|
||||||
m.windows[i].Width = msg.Width
|
m.windows[i].Width = msg.Width
|
||||||
|
|||||||
@ -146,7 +146,7 @@ func drawStatusBar(m Model) string {
|
|||||||
left := leftBar(m)
|
left := leftBar(m)
|
||||||
right := rightBar(m)
|
right := rightBar(m)
|
||||||
|
|
||||||
diff := m.win_w - (len(left) + len(right))
|
diff := m.termWidth - (len(left) + len(right))
|
||||||
|
|
||||||
// This happens when the terminal spawns
|
// This happens when the terminal spawns
|
||||||
if diff <= 0 {
|
if diff <= 0 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user