Explorar o código

Fix very weird rendering issues

Johan Rong hai 1 mes
pai
achega
caf676a64c
Modificáronse 5 ficheiros con 101 adicións e 12 borrados
  1. 23 0
      internal/buffer/buffer.go
  2. 26 0
      internal/editor/action.go
  3. 1 1
      internal/editor/model.go
  4. 50 10
      internal/editor/render.go
  5. 1 1
      main.go

+ 23 - 0
internal/buffer/buffer.go

@@ -304,6 +304,16 @@ func OffsetForLineCol(buf *Buffer, line int, col int) int {
 	return i
 }
 
+func LineText(buf *Buffer, line int) string {
+	start := OffsetForLine(buf, line)
+	end := lineContentEnd(buf, line)
+	if end < start {
+		end = start
+	}
+
+	return string(buf.Rope.Slice(start, end))
+}
+
 func lineContentEnd(buf *Buffer, line int) int {
 	nextStart := OffsetForLine(buf, line+1)
 	if nextStart > 0 && nextStart <= buf.Rope.Len() && buf.Rope.At(nextStart-1) == '\n' {
@@ -380,6 +390,19 @@ func nextRuneEnd(r *rope.Node, offset int) int {
 	return end
 }
 
+func RuneAt(buf *Buffer, offset int) rune {
+	if buf.Rope == nil || offset < 0 || offset >= buf.Rope.Len() {
+		return ' '
+	}
+
+	r, size := utf8.DecodeRune(buf.Rope.Slice(offset, buf.Rope.Len()))
+	if size <= 0 || r == '\n' || r == '\t' {
+		return ' '
+	}
+
+	return r
+}
+
 func (buf Buffer) String() string {
 	if buf.Rope == nil {
 		return ""

+ 26 - 0
internal/editor/action.go

@@ -4,6 +4,7 @@ import(
 	"strings"
 	"strconv"
 	"os"
+	"github.com/zyedidia/rope"
 )
 
 type ActionManager = struct {
@@ -97,6 +98,31 @@ func DefaultActionManager() ActionManager {
 				Command: "s",
 				AskArgs: true,
 			},
+			Action{
+				Binding: "ctrl+Rune[e]",
+				Command: "e",
+				AskArgs: true,
+				Callback: func(m *Model, args []string) {
+					if len(args) < 1 {
+						m.Mode = ModeNormal
+						m.BM.PaletteBuffer.Clear()
+						m.BM.PaletteBuffer.Paste("moose.error:Did not specify path for edit")
+						return
+					}
+
+					content, err := os.ReadFile(args[0])
+					if err != nil {
+						m.Mode = ModeNormal
+						m.BM.PaletteBuffer.Clear()
+						m.BM.PaletteBuffer.Paste("moose.error:Could not edit file \"" + args[0] + "\": " + err.Error())
+						return
+					}
+
+					m.BM.Current().Clear()
+					m.BM.Current().Rope = rope.New(content)
+					m.BM.Current().LI.Rebuild(m.BM.Current().Rope)
+				},
+			},
 		},
 		Normal:  []Action{
 			Action{

+ 1 - 1
internal/editor/model.go

@@ -20,7 +20,7 @@ func NewModel(screen tcell.Screen, style tcell.Style) Model {
 		Style:		   style,
 		Mode:		   ModeNormal,
 		BM:            buffer.BufferManager{
-			Buffers:       []buffer.Buffer{buffer.NewBuffer(), buffer.NewBuffer()},
+			Buffers:       []buffer.Buffer{buffer.NewBuffer()},
 			CurrentIdx:    0,
 			PaletteBuffer: buffer.NewBuffer(),
 		},

+ 50 - 10
internal/editor/render.go

@@ -2,11 +2,46 @@ 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()
 
@@ -33,9 +68,8 @@ func (m Model) Render() {
 		for j, line := range table {
 			if j + 1 > maxHeight { break }
 
-			nums := strconv.Itoa(j + buf.TopLine)
-			nums = strings.Repeat(" ", 4 - len(nums)) + nums
-			r := []rune(nums + " " + line)
+			nums := fmt.Sprintf("%4d ", j + buf.TopLine)
+			r := []rune(nums + expandTabs(line))
 			if len(r) + 1 > bufWidth {
 				r = r[:bufWidth]
 			}
@@ -48,19 +82,23 @@ func (m Model) Render() {
 				line, col := buffer.LineCol(buf, cur.Offset)
 				screenLine := line - buf.TopLine
 				if screenLine < 0 || screenLine + 1 > maxHeight { continue }
-				if col + 1 > bufWidth { 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 + col + 5, screenLine, ' ', nil, m.Style.Reverse(true))
+					m.Screen.SetContent(bufWidth * i + visCol + 5, screenLine, ch, nil, m.Style.Reverse(true))
 				} else {
-					m.Screen.SetContent(bufWidth * i + col + 5, screenLine, ' ', nil, m.Style.Reverse(true).Foreground(color.Gray))	
+					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.Reverse(true))
+		m.Screen.SetContent(col, maxHeight, ' ', nil, m.Style.Background(color.Black))
 	}
 
 	modeStr := m.Mode.String()
@@ -74,7 +112,7 @@ func (m Model) Render() {
 		}
 	}
 
-	m.Screen.PutStrStyled(sWidth - (len(modeStr) + 1), maxHeight, strings.ToUpper(modeStr), m.Style.Reverse(true))
+	m.Screen.PutStrStyled(sWidth - (len(modeStr) + 1), maxHeight, strings.ToUpper(modeStr), m.Style.Background(color.Black))
 
 	if m.Mode == ModePalette {
 		m.Screen.PutStrStyled(0, maxHeight + 1, m.BM.PaletteBuffer.String(), m.Style)
@@ -84,7 +122,9 @@ func (m Model) Render() {
 			if line + maxHeight != maxHeight { continue }
 			if col + 1 > sWidth { continue }
 
-			m.Screen.SetContent(col, maxHeight + 1, ' ', nil, m.Style.Reverse(true))
+			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))

+ 1 - 1
main.go

@@ -59,4 +59,4 @@ func main() {
 
 		s.Show()
 	}
-}
+}