Johan Rong преди 1 месец
родител
ревизия
1e2d2c599a
променени са 7 файла, в които са добавени 157 реда и са изтрити 150 реда
  1. 1 0
      cmd/moose/main.go
  2. 1 1
      internal/editor/action.go
  3. 137 5
      internal/editor/draw.go
  4. 4 4
      internal/editor/keyinput.go
  5. 0 140
      internal/editor/render.go
  6. 4 0
      internal/layout/layout.go
  7. 10 0
      internal/util/util.go

+ 1 - 0
cmd/moose/main.go

@@ -44,6 +44,7 @@ func main() {
 		}
 
 		spew.Dump(m.LM.Workspaces[0].RootContainer)
+		fmt.Println(m.DebugLog)
 	}
 	defer quit()
 

+ 1 - 1
internal/editor/action.go

@@ -379,7 +379,7 @@ func DefaultActionManager() ActionManager {
 				Bindings: []Binding{
 					Binding{
 						Type:  BindingChord,
-						Chord: []string{"l", "enter"},
+						Chord: []string{"l", "enter"}, // TODO: dette fungerer ikkje, kvifor, det veit eg ikkje...
 					},
 				},
 				Commands: []string{"lbuf"},

+ 137 - 5
internal/editor/draw.go

@@ -3,13 +3,72 @@ package editor
 import (
 	"moose/internal/layout"
 	"moose/internal/buffer"
+	"moose/internal/util"
 	"fmt"
 	"strings"
+	"strconv"
 	"github.com/gdamore/tcell/v3/color"
 )
 
 func (m *Model) Draw() {
-	m.DrawWorkspace(&m.LM.Workspaces[m.LM.ActiveIdx], layout.RectFromScren(m.Screen))
+	screen := layout.RectFromScren(m.Screen)
+	main := layout.Rect{
+		X: screen.X,
+		Y: screen.Y,
+		Width: screen.Width,
+		Height: screen.Height - 2,
+	}
+	palette := layout.Rect{
+		X: screen.X,
+		Y: main.Height,
+		Width: screen.Width,
+		Height: 2,
+	}
+
+	m.DrawWorkspace(&m.LM.Workspaces[m.LM.ActiveIdx], main)
+	m.DrawPalette(palette)	
+}
+
+func (m *Model) DrawPalette(rect layout.Rect) {
+	for col := 0; col < rect.Width; col++ {
+		m.Screen.SetContent(rect.X + col, rect.Y, ' ', nil, m.Style.Background(color.Black))
+	}
+
+	modeStr := m.Mode.String()
+	if m.Mode == ModePalette {
+		if strings.HasPrefix(m.BM.PaletteBuffer.String(), "/") {
+			modeStr += " (command)"
+		} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "?") {
+			modeStr += " (find)"
+		} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "=") {
+			modeStr += " (replace)"
+		}
+	}
+
+	m.Screen.PutStrStyled(rect.Width - (len(modeStr) + 1), rect.Y, strings.ToUpper(modeStr), m.Style.Background(color.Black))
+	
+	logStr := m.DebugLog + ", " + strings.Join(m.AM.CM.Recorded, "+") + ", " + strconv.FormatBool(m.AM.CM.Recording)
+	m.Screen.PutStrStyled(1, rect.Y, logStr, m.Style.Background(color.Black))
+
+	if m.Mode == ModePalette {
+		m.Screen.PutStrStyled(0, rect.Y + 1, m.BM.PaletteBuffer.String(), m.Style)
+
+		for _, cur := range m.BM.PaletteBuffer.CM.Cursors {
+			line, col := buffer.LineCol(&m.BM.PaletteBuffer, cur.Offset)
+			if line + rect.Y != rect.Y { continue }
+			if col + 1 > rect.Width { continue }
+
+			ch := buffer.RuneAt(&m.BM.PaletteBuffer, cur.Offset)
+
+			m.Screen.SetContent(col, rect.Y + 1, ch, nil, m.Style.Reverse(true))
+		}
+	} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "moose.info:") {
+		m.Screen.PutStrStyled(0, rect.Y + 1, string([]rune(m.BM.PaletteBuffer.String())[11:]), m.Style.Foreground(color.LightGray))
+	} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "moose.warn:") {
+		m.Screen.PutStrStyled(0, rect.Y + 1, string([]rune(m.BM.PaletteBuffer.String())[11:]), m.Style.Foreground(color.Orange))
+	} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "moose.error:") {
+		m.Screen.PutStrStyled(0, rect.Y + 1, string([]rune(m.BM.PaletteBuffer.String())[12:]), m.Style.Foreground(color.Red))
+	}
 }
 
 func (m *Model) DrawWorkspace(w *layout.Workspace, rect layout.Rect) {
@@ -17,23 +76,61 @@ func (m *Model) DrawWorkspace(w *layout.Workspace, rect layout.Rect) {
 }
 
 func (m *Model) DrawContainer(c *layout.Container, rect layout.Rect) {
-	length := len(c.Children)
+	length := util.NonNilLen(c.Children[:])
+	rect = layout.Rect{
+		X: rect.X,
+		Y: rect.Y + 1,
+		Width: rect.Width,
+		Height: rect.Height,
+	}
 	rect = layout.RectDivide(rect, c.Split, length)
 
 	for i, child := range c.Children {
+		main := layout.RectDisplace(rect, c.Split, i)
 		switch child.(type) {
 		case layout.ContainerBuffers: {
 			cb := child.(layout.ContainerBuffers)
-			m.DrawContainerBuffers(&cb, layout.RectDisplace(rect, c.Split, i))
+			tabs := layout.Rect{
+				X: main.X,
+				Y: main.Y - 1,
+				Width: main.Width,
+				Height: 1,
+			}
+			
+			m.DrawContainerTabs(&cb, tabs)
+			m.DrawContainerBuffers(&cb, main)
 		}
 		case layout.Container: {
 			c := child.(layout.Container)
-			m.DrawContainer(&c, layout.RectDisplace(rect, c.Split, i))
+			m.DrawContainer(&c, main)
 		}
 		}
 	}
 }
 
+func (m *Model) DrawContainerTabs(c *layout.ContainerBuffers, rect layout.Rect) {
+	tabs := []string{}
+	for _, bufIdx := range c.Buffers {
+		buf := m.BM.Buffers[bufIdx]
+		if buf.Path == "" {
+			tabs = append(tabs, "Buffer " + strconv.Itoa(bufIdx))
+		} else {
+			tabs = append(tabs, buf.Path)
+		}		
+	}
+
+	length := 0
+	for _, tab := range tabs {
+		if length + len(tab) + 2 > rect.Width {
+			m.Screen.PutStrStyled(rect.X + length, rect.Y, ">", m.Style.Foreground(color.White))
+			return
+		}
+
+		m.Screen.PutStrStyled(rect.X + length, rect.Y, tab, m.Style.Background(color.Black).Foreground(color.White))
+		length += len(tab) + 1
+	}
+}
+
 func (m *Model) DrawContainerBuffers(c *layout.ContainerBuffers, rect layout.Rect) {
 	m.DrawBuffer(&m.BM.Buffers[c.Buffers[c.ActiveIdx]], c.Buffers[c.ActiveIdx] == m.BM.CurrentIdx, rect)
 }
@@ -81,4 +178,39 @@ func (m *Model) DrawBuffer(buf *buffer.Buffer, isActive bool, rect layout.Rect)
 			}
 		}
 	}
-}
+}
+
+const tabWidth = 4
+
+func expandTabs(s string) string {
+	var b strings.Builder
+	col := 0
+	for _, r := range s {
+		if r == '\t' {
+			spaces := tabWidth - (col % tabWidth)
+			b.WriteString(strings.Repeat(" ", spaces))
+			col += spaces
+		} else {
+			b.WriteRune(r)
+			col++
+		}
+	}
+	return b.String()
+}
+
+func visualCol(lineText string, runeCol int) int {
+	col := 0
+	n := 0
+	for _, r := range lineText {
+		if n >= runeCol {
+			break
+		}
+		if r == '\t' {
+			col += tabWidth - (col % tabWidth)
+		} else {
+			col++
+		}
+		n++
+	}
+	return col
+}

+ 4 - 4
internal/editor/keyinput.go

@@ -35,10 +35,10 @@ func (m *Model) HandleKeyInput(ev *tcell.EventKey) {
 						for i := range m.AM.CM.Recorded {
 							if m.AM.CM.Recorded[i] == binding.Chord[i] {
 								matching = true
-							} else {
-								matching = false
-								m.AM.CM = NewChordManager()
-								return
+							//} else {
+							//	matching = false
+							//	m.AM.CM = NewChordManager()
+							//	return
 							}
 						}
 

+ 0 - 140
internal/editor/render.go

@@ -1,140 +0,0 @@
-package editor
-
-import (
-	"strings"
-	"strconv"
-	"fmt"
-	"moose/internal/buffer"
-	"github.com/gdamore/tcell/v3/color"
-)
-
-const tabWidth = 4
-
-func expandTabs(s string) string {
-	var b strings.Builder
-	col := 0
-	for _, r := range s {
-		if r == '\t' {
-			spaces := tabWidth - (col % tabWidth)
-			b.WriteString(strings.Repeat(" ", spaces))
-			col += spaces
-		} else {
-			b.WriteRune(r)
-			col++
-		}
-	}
-	return b.String()
-}
-
-func visualCol(lineText string, runeCol int) int {
-	col := 0
-	n := 0
-	for _, r := range lineText {
-		if n >= runeCol {
-			break
-		}
-		if r == '\t' {
-			col += tabWidth - (col % tabWidth)
-		} else {
-			col++
-		}
-		n++
-	}
-	return col
-}
-
-func (m Model) Render() {
-	sWidth, sHeight := m.Screen.Size()
-
-	maxHeight := sHeight - 2 // TODO: saturating sub?
-
-	bLen := len(m.BM.Buffers)
-	bufWidth := sWidth / bLen
-
-	for i := range m.BM.Buffers {
-		buf := &m.BM.Buffers[i]
-
-		primary := buf.CM.Cursors[buf.CM.PrimaryIdx]
-		curLine, _ := buffer.LineCol(buf, primary.Offset)
-		buf.ScrollToShow(curLine, maxHeight)
-
-		startOffset := buffer.OffsetForLine(buf, buf.TopLine)
-		endOffset := buf.Rope.Len()
-		if endLine := buf.TopLine + maxHeight; endLine < buffer.LineCount(buf) {
-			endOffset = buffer.OffsetForLine(buf, endLine)
-		}
-
-		visible := string(buf.Rope.Slice(startOffset, endOffset))
-		table := strings.SplitAfter(visible, "\n")
-		for j, line := range table {
-			if j + 1 > maxHeight { break }
-
-			nums := fmt.Sprintf("%4d ", j + buf.TopLine)
-			r := []rune(nums + expandTabs(line))
-			if len(r) + 1 > bufWidth {
-				r = r[:bufWidth]
-			}
-
-			m.Screen.PutStrStyled(bufWidth*i, j, string(r), m.Style)
-		}
-
-		if i == m.BM.CurrentIdx {
-			for _, cur := range buf.CM.Cursors {
-				line, col := buffer.LineCol(buf, cur.Offset)
-				screenLine := line - buf.TopLine
-				if screenLine < 0 || screenLine + 1 > maxHeight { continue }
-
-				visCol := visualCol(buffer.LineText(buf, line), col)
-				if visCol + 1 > bufWidth { continue }
-
-				ch := buffer.RuneAt(buf, cur.Offset)
-
-				if m.Mode == ModeWrite {
-					m.Screen.SetContent(bufWidth * i + visCol + 5, screenLine, ch, nil, m.Style.Reverse(true))
-				} else {
-					m.Screen.SetContent(bufWidth * i + visCol + 5, screenLine, ch, nil, m.Style.Reverse(true).Foreground(color.Gray))	
-				}
-			}
-		}
-	}
-
-	for col := 0; col < sWidth; col++ {
-		m.Screen.SetContent(col, maxHeight, ' ', nil, m.Style.Background(color.Black))
-	}
-
-	modeStr := m.Mode.String()
-	if m.Mode == ModePalette {
-		if strings.HasPrefix(m.BM.PaletteBuffer.String(), "/") {
-			modeStr += " (command)"
-		} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "?") {
-			modeStr += " (find)"
-		} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "=") {
-			modeStr += " (replace)"
-		}
-	}
-
-	m.Screen.PutStrStyled(sWidth - (len(modeStr) + 1), maxHeight, strings.ToUpper(modeStr), m.Style.Background(color.Black))
-	
-	logStr := m.DebugLog + ", " + strings.Join(m.AM.CM.Recorded, "+") + ", " + strconv.FormatBool(m.AM.CM.Recording)
-	m.Screen.PutStrStyled(1, maxHeight, logStr, m.Style.Background(color.Black))
-
-	if m.Mode == ModePalette {
-		m.Screen.PutStrStyled(0, maxHeight + 1, m.BM.PaletteBuffer.String(), m.Style)
-
-		for _, cur := range m.BM.PaletteBuffer.CM.Cursors {
-			line, col := buffer.LineCol(&m.BM.PaletteBuffer, cur.Offset)
-			if line + maxHeight != maxHeight { continue }
-			if col + 1 > sWidth { continue }
-
-			ch := buffer.RuneAt(&m.BM.PaletteBuffer, cur.Offset)
-
-			m.Screen.SetContent(col, maxHeight + 1, ch, nil, m.Style.Reverse(true))
-		}
-	} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "moose.info:") {
-		m.Screen.PutStrStyled(0, maxHeight + 1, string([]rune(m.BM.PaletteBuffer.String())[11:]), m.Style.Foreground(color.LightGray))
-	} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "moose.warn:") {
-		m.Screen.PutStrStyled(0, maxHeight + 1, string([]rune(m.BM.PaletteBuffer.String())[11:]), m.Style.Foreground(color.Orange))
-	} else if strings.HasPrefix(m.BM.PaletteBuffer.String(), "moose.error:") {
-		m.Screen.PutStrStyled(0, maxHeight + 1, string([]rune(m.BM.PaletteBuffer.String())[12:]), m.Style.Foreground(color.Red))
-	}
-}

+ 4 - 0
internal/layout/layout.go

@@ -53,6 +53,10 @@ func NewContainerEmpty() Container {
 				Buffers: []int{0},
 				ActiveIdx: 0,
 			},
+			ContainerBuffers{
+				Buffers: []int{0},
+				ActiveIdx: 0,
+			},
 		},
 		Split:	  	    SplitVertical,
 		ActiveChildIdx: 0,

+ 10 - 0
internal/util/util.go

@@ -28,3 +28,13 @@ func StandardizeBinding(binding string) string {
 	slices.Sort(arr)
 	return strings.ToLower(strings.Join(arr, "+"))
 }
+
+func NonNilLen[T any](slice []T) int {
+	count := 0
+	for _, item := range slice {
+		if any(item) != nil {
+			count++
+		}
+	}
+	return count
+}