mirror of
https://github.com/EnumeratedDev/Typer.git
synced 2025-07-01 07:48:20 +00:00
Render tab characters as 4 spaces
This commit is contained in:
parent
4ca6d9b75b
commit
5d64673519
123
src/window.go
123
src/window.go
@ -4,6 +4,7 @@ import (
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"log"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CursorMode uint8
|
||||
@ -77,49 +78,52 @@ func (window *Window) drawCurrentBuffer() {
|
||||
|
||||
bufferX, bufferY, _, _ := window.GetTextAreaDimensions()
|
||||
|
||||
normalStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color234)
|
||||
selectedStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color243)
|
||||
for i, r := range buffer.Contents + " " {
|
||||
if x-buffer.OffsetX >= bufferX && y-buffer.OffsetY >= bufferY {
|
||||
// Default style
|
||||
style := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color234)
|
||||
|
||||
for i, r := range buffer.Contents {
|
||||
if r == '\n' {
|
||||
x = 0
|
||||
if window.ShowLineIndex {
|
||||
x += bufferX
|
||||
// Change background if under cursor
|
||||
if i == buffer.CursorPos {
|
||||
style = style.Background(tcell.Color243)
|
||||
}
|
||||
y++
|
||||
|
||||
// Change background if selected
|
||||
if buffer.Selection != nil {
|
||||
if buffer.Selection.selectionEnd >= buffer.Selection.selectionStart && i >= buffer.Selection.selectionStart && i <= buffer.Selection.selectionEnd {
|
||||
style = style.Background(tcell.Color243)
|
||||
|
||||
// Show selection on entire tab space
|
||||
if r == '\t' {
|
||||
for j := 0; j < 4; j++ {
|
||||
window.screen.SetContent(x+j-buffer.OffsetX, y-buffer.OffsetY, r, nil, style)
|
||||
}
|
||||
}
|
||||
} else if i <= buffer.Selection.selectionStart && i >= buffer.Selection.selectionEnd {
|
||||
style = style.Background(tcell.Color243)
|
||||
|
||||
// Show selection on entire tab space
|
||||
if r == '\t' {
|
||||
for j := 0; j < 4; j++ {
|
||||
window.screen.SetContent(x+j-buffer.OffsetX, y-buffer.OffsetY, r, nil, style)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.screen.SetContent(x-buffer.OffsetX, y-buffer.OffsetY, r, nil, style)
|
||||
}
|
||||
|
||||
if r != '\n' {
|
||||
// Change position for next character
|
||||
if r == '\n' {
|
||||
x = bufferX
|
||||
y++
|
||||
} else if r == '\t' {
|
||||
x += 4
|
||||
} else {
|
||||
x++
|
||||
}
|
||||
|
||||
if x-buffer.OffsetX-1 < bufferX {
|
||||
continue
|
||||
}
|
||||
if y-buffer.OffsetY < bufferY {
|
||||
continue
|
||||
}
|
||||
|
||||
if buffer.Selection != nil && buffer.Selection.selectionEnd >= buffer.Selection.selectionStart && i >= buffer.Selection.selectionStart && i <= buffer.Selection.selectionEnd {
|
||||
window.screen.SetContent(x-buffer.OffsetX-1, y-buffer.OffsetY, r, nil, selectedStyle)
|
||||
} else if buffer.Selection != nil && i <= buffer.Selection.selectionStart && i >= buffer.Selection.selectionEnd {
|
||||
window.screen.SetContent(x-buffer.OffsetX-1, y-buffer.OffsetY, r, nil, selectedStyle)
|
||||
} else {
|
||||
window.screen.SetContent(x-buffer.OffsetX-1, y-buffer.OffsetY, r, nil, normalStyle)
|
||||
}
|
||||
}
|
||||
|
||||
// Draw cursor
|
||||
cursorX, cursorY := window.GetCursorPos2D()
|
||||
|
||||
cursorX += bufferX
|
||||
cursorY += bufferY
|
||||
|
||||
cursorX -= window.CurrentBuffer.OffsetX
|
||||
cursorY -= window.CurrentBuffer.OffsetY
|
||||
|
||||
r, _, _, _ := window.screen.GetContent(cursorX, cursorY)
|
||||
window.screen.SetContent(cursorX, cursorY, r, nil, selectedStyle)
|
||||
}
|
||||
|
||||
func (window *Window) Draw() {
|
||||
@ -426,24 +430,23 @@ func (window *Window) input(ev *tcell.EventKey) {
|
||||
|
||||
func (window *Window) mouseInput(ev *tcell.EventMouse) {
|
||||
mouseX, mouseY := ev.Position()
|
||||
bufferMouseX, bufferMouseY := window.AbsolutePosToBufferArea(mouseX, mouseY)
|
||||
|
||||
// Left click was pressed
|
||||
if ev.Buttons() == tcell.Button1 {
|
||||
// Ensure click was in buffer area
|
||||
x1, y1, x2, y2 := window.GetTextAreaDimensions()
|
||||
if mouseX >= x1 && mouseY >= y1 && mouseX <= x2 && mouseY <= y2 {
|
||||
|
||||
bufferMouseX, bufferMouseY := window.AbsolutePosToCursorPos2D(mouseX, mouseY)
|
||||
if mouseHeld {
|
||||
// Add to selection
|
||||
if window.CurrentBuffer.Selection == nil {
|
||||
window.CurrentBuffer.Selection = &Selection{
|
||||
selectionStart: window.CurrentBuffer.CursorPos,
|
||||
selectionEnd: window.CursorPos2DToCursorPos(bufferMouseX+window.CurrentBuffer.OffsetX, bufferMouseY+window.CurrentBuffer.OffsetY),
|
||||
selectionEnd: window.CursorPos2DToCursorPos(bufferMouseX, bufferMouseY),
|
||||
}
|
||||
return
|
||||
} else {
|
||||
window.CurrentBuffer.Selection.selectionEnd = window.CursorPos2DToCursorPos(bufferMouseX+window.CurrentBuffer.OffsetX, bufferMouseY+window.CurrentBuffer.OffsetY)
|
||||
window.CurrentBuffer.Selection.selectionEnd = window.CursorPos2DToCursorPos(bufferMouseX, bufferMouseY)
|
||||
}
|
||||
// Prevent selecting dummy character at the end of the buffer
|
||||
if window.CurrentBuffer.Selection.selectionEnd >= len(window.CurrentBuffer.Contents) {
|
||||
@ -456,7 +459,7 @@ func (window *Window) mouseInput(ev *tcell.EventMouse) {
|
||||
}
|
||||
}
|
||||
// Move cursor
|
||||
window.SetCursorPos2D(bufferMouseX+window.CurrentBuffer.OffsetX, bufferMouseY+window.CurrentBuffer.OffsetY)
|
||||
window.SetCursorPos2D(bufferMouseX, bufferMouseY)
|
||||
}
|
||||
mouseHeld = true
|
||||
} else if ev.Buttons() == tcell.ButtonNone {
|
||||
@ -531,12 +534,48 @@ func (window *Window) CursorPos2DToCursorPos(x, y int) int {
|
||||
return lines[y].charIndex + x
|
||||
}
|
||||
|
||||
func (window *Window) AbsolutePosToBufferArea(x, y int) (int, int) {
|
||||
func (window *Window) AbsolutePosToCursorPos2D(x, y int) (int, int) {
|
||||
x1, y1, _, _ := window.GetTextAreaDimensions()
|
||||
|
||||
x -= x1
|
||||
y -= y1
|
||||
|
||||
x += window.CurrentBuffer.OffsetX
|
||||
y += window.CurrentBuffer.OffsetY
|
||||
|
||||
if x < 0 {
|
||||
x = 0
|
||||
}
|
||||
if y < 0 {
|
||||
y = 0
|
||||
}
|
||||
|
||||
split := strings.SplitAfter(window.CurrentBuffer.Contents+" ", "\n")
|
||||
|
||||
if y >= len(split) {
|
||||
y = len(split) - 1
|
||||
}
|
||||
line := split[y]
|
||||
|
||||
posInLine := make([]int, 0)
|
||||
for i, char := range []rune(line) {
|
||||
if char == '\t' {
|
||||
for j := 0; j < 4; j++ {
|
||||
posInLine = append(posInLine, i)
|
||||
}
|
||||
} else {
|
||||
posInLine = append(posInLine, i)
|
||||
}
|
||||
}
|
||||
|
||||
if len(posInLine) == 0 {
|
||||
x = 0
|
||||
} else if x >= len(posInLine) {
|
||||
x = posInLine[len(posInLine)-1]
|
||||
} else {
|
||||
x = posInLine[x]
|
||||
}
|
||||
|
||||
return x, y
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user