Up to step 154 in Kilo tutorial (chapter 7)
Some checks failed
timw4mail/gilo/pipeline/head There was a failure building this commit
Some checks failed
timw4mail/gilo/pipeline/head There was a failure building this commit
This commit is contained in:
parent
6cdb658d43
commit
f78bbdabb2
@ -106,12 +106,17 @@ func (r *Row) update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Row) updateSyntax() {
|
func (r *Row) updateSyntax() {
|
||||||
for _, ch := range r.render {
|
i := 0
|
||||||
|
|
||||||
|
for i < r.RenderSize() {
|
||||||
|
ch := r.render[i]
|
||||||
if unicode.IsDigit(ch) {
|
if unicode.IsDigit(ch) {
|
||||||
r.Hl = append(r.Hl, highlight.Number)
|
r.Hl = append(r.Hl, highlight.Number)
|
||||||
} else {
|
} else {
|
||||||
r.Hl = append(r.Hl, highlight.Normal)
|
r.Hl = append(r.Hl, highlight.Normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,14 @@ func (e *editor) drawRows(ab *gilo.Buffer) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e.drawFileRow(fileRow, ab)
|
||||||
|
}
|
||||||
|
|
||||||
|
ab.AppendLn(terminal.ClearLine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *editor) drawFileRow(fileRow int, ab *gilo.Buffer) {
|
||||||
currentColor := terminal.DefaultFGColor
|
currentColor := terminal.DefaultFGColor
|
||||||
row := e.document.GetRow(fileRow)
|
row := e.document.GetRow(fileRow)
|
||||||
|
|
||||||
@ -97,10 +105,6 @@ func (e *editor) drawRows(ab *gilo.Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ab.Append(terminal.DefaultFGColor)
|
ab.Append(terminal.DefaultFGColor)
|
||||||
}
|
|
||||||
|
|
||||||
ab.AppendLn(terminal.ClearLine)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *editor) drawPlaceholderRow(y int, ab *gilo.Buffer) {
|
func (e *editor) drawPlaceholderRow(y int, ab *gilo.Buffer) {
|
||||||
|
@ -25,6 +25,7 @@ type editor struct {
|
|||||||
offset *gilo.Point
|
offset *gilo.Point
|
||||||
document *doc.Document
|
document *doc.Document
|
||||||
status *statusMsg
|
status *statusMsg
|
||||||
|
search *search
|
||||||
quitTimes uint8
|
quitTimes uint8
|
||||||
renderX int
|
renderX int
|
||||||
}
|
}
|
||||||
@ -49,6 +50,7 @@ func NewEditor() *editor {
|
|||||||
offset,
|
offset,
|
||||||
document,
|
document,
|
||||||
status,
|
status,
|
||||||
|
newSearch(),
|
||||||
gilo.QuitTimes,
|
gilo.QuitTimes,
|
||||||
0,
|
0,
|
||||||
}
|
}
|
||||||
@ -138,61 +140,6 @@ func (e *editor) prompt(prompt string, callback func(string, string)) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *editor) find() {
|
|
||||||
savedCursor := e.cursor.Clone()
|
|
||||||
savedOffset := e.cursor.Clone()
|
|
||||||
|
|
||||||
lastMatch := -1
|
|
||||||
direction := 1
|
|
||||||
query := e.prompt("Search: %s (Use ESC/Arrows/Enter)", func(query string, ch string) {
|
|
||||||
if ch == string(key.Enter) || ch == string(key.Esc) {
|
|
||||||
lastMatch = -1
|
|
||||||
direction = 1
|
|
||||||
return
|
|
||||||
} else if ch == keyRight || ch == keyDown {
|
|
||||||
direction = 1
|
|
||||||
} else if ch == keyLeft || ch == keyUp {
|
|
||||||
direction = -1
|
|
||||||
} else {
|
|
||||||
lastMatch = -1
|
|
||||||
direction = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if lastMatch == -1 {
|
|
||||||
direction = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
current := lastMatch
|
|
||||||
|
|
||||||
for i := 0; i < e.document.RowCount(); i++ {
|
|
||||||
current += direction
|
|
||||||
if current == -1 {
|
|
||||||
current = e.document.RowCount()
|
|
||||||
} else if current == e.document.RowCount() {
|
|
||||||
current = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
row := e.document.GetRow(current)
|
|
||||||
matchIndex := row.Search(query)
|
|
||||||
if matchIndex != -1 {
|
|
||||||
lastMatch = current
|
|
||||||
e.cursor.Y = current
|
|
||||||
e.cursor.X = row.RenderXtoCursorX(matchIndex)
|
|
||||||
e.offset.Y = e.document.RowCount()
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if query == "" {
|
|
||||||
e.cursor = savedCursor.Clone()
|
|
||||||
e.offset = savedOffset.Clone()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *editor) insertChar(ch rune) {
|
func (e *editor) insertChar(ch rune) {
|
||||||
if e.cursor.Y == e.document.RowCount() {
|
if e.cursor.Y == e.document.RowCount() {
|
||||||
e.document.AppendRow("")
|
e.document.AppendRow("")
|
||||||
|
@ -6,4 +6,5 @@ package highlight
|
|||||||
const (
|
const (
|
||||||
Normal = iota
|
Normal = iota
|
||||||
Number
|
Number
|
||||||
|
Match
|
||||||
)
|
)
|
||||||
|
@ -2,11 +2,19 @@ package highlight
|
|||||||
|
|
||||||
import "timshome.page/gilo/terminal"
|
import "timshome.page/gilo/terminal"
|
||||||
|
|
||||||
func SyntaxToColor(hl int) string {
|
var syntaxColorMap = map[int]string{
|
||||||
switch hl {
|
Number: terminal.FGRed,
|
||||||
case Number:
|
Match: terminal.FGBlue,
|
||||||
return terminal.FGRed
|
Normal: terminal.DefaultFGColor,
|
||||||
default:
|
}
|
||||||
return terminal.DefaultFGColor
|
|
||||||
}
|
// Take a highlighting type and map it to
|
||||||
|
// an ANSI color escape code for display
|
||||||
|
func SyntaxToColor(hl int) string {
|
||||||
|
color := syntaxColorMap[hl]
|
||||||
|
if len(color) == 0 {
|
||||||
|
color = terminal.DefaultFGColor
|
||||||
|
}
|
||||||
|
|
||||||
|
return color
|
||||||
}
|
}
|
||||||
|
112
editor/search.go
Normal file
112
editor/search.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package editor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"timshome.page/gilo/editor/highlight"
|
||||||
|
"timshome.page/gilo/gilo"
|
||||||
|
"timshome.page/gilo/key"
|
||||||
|
)
|
||||||
|
|
||||||
|
type search struct {
|
||||||
|
cursor *gilo.Point
|
||||||
|
offset *gilo.Point
|
||||||
|
hlLine int
|
||||||
|
hl []int
|
||||||
|
direction int
|
||||||
|
lastMatch int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSearch() *search {
|
||||||
|
return &search{
|
||||||
|
cursor: gilo.DefaultPoint(),
|
||||||
|
offset: gilo.DefaultPoint(),
|
||||||
|
hlLine: -1,
|
||||||
|
hl: []int{},
|
||||||
|
lastMatch: -1,
|
||||||
|
direction: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *editor) find() {
|
||||||
|
e.search.cursor.X = e.cursor.X
|
||||||
|
e.search.cursor.Y = e.cursor.Y
|
||||||
|
e.search.offset.X = e.offset.X
|
||||||
|
e.search.offset.Y = e.offset.Y
|
||||||
|
|
||||||
|
query := e.prompt("Search: %s (Use ESC/Arrows/Enter)", e.findCallback)
|
||||||
|
|
||||||
|
if query == "" {
|
||||||
|
e.cursor.X = e.search.cursor.X
|
||||||
|
e.cursor.Y = e.search.cursor.Y
|
||||||
|
e.offset.X = e.search.offset.X
|
||||||
|
e.offset.Y = e.search.offset.Y
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *editor) findCallback(query string, ch string) {
|
||||||
|
if e.search.hlLine != -1 && e.search.hl != nil {
|
||||||
|
staleRow := e.document.GetRow(e.search.hlLine)
|
||||||
|
for i, val := range e.search.hl {
|
||||||
|
staleRow.Hl[i] = val
|
||||||
|
}
|
||||||
|
e.search.hl = nil
|
||||||
|
e.search.hlLine = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ch == string(key.Enter) || ch == string(key.Esc) {
|
||||||
|
e.search.lastMatch = -1
|
||||||
|
e.search.direction = 1
|
||||||
|
return
|
||||||
|
} else if ch == keyRight || ch == keyDown {
|
||||||
|
e.search.direction = 1
|
||||||
|
} else if ch == keyLeft || ch == keyUp {
|
||||||
|
e.search.direction = -1
|
||||||
|
} else {
|
||||||
|
e.search.lastMatch = -1
|
||||||
|
e.search.direction = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.search.lastMatch == -1 {
|
||||||
|
e.search.direction = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(query) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
current := e.search.lastMatch
|
||||||
|
|
||||||
|
for i := 0; i < e.document.RowCount(); i++ {
|
||||||
|
current += e.search.direction
|
||||||
|
|
||||||
|
if current == -1 {
|
||||||
|
current = e.document.RowCount() - 1
|
||||||
|
} else if current == e.document.RowCount() {
|
||||||
|
current = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
row := e.document.GetRow(current)
|
||||||
|
matchIndex := row.Search(query)
|
||||||
|
if matchIndex == -1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
e.search.lastMatch = current
|
||||||
|
e.cursor.Y = current
|
||||||
|
e.cursor.X = row.RenderXtoCursorX(matchIndex)
|
||||||
|
e.offset.Y = e.document.RowCount()
|
||||||
|
|
||||||
|
// Update highlighting of search result
|
||||||
|
e.search.hlLine = current
|
||||||
|
e.search.hl = make([]int, row.RenderSize())
|
||||||
|
for i, val := range row.Hl {
|
||||||
|
e.search.hl[i] = val
|
||||||
|
}
|
||||||
|
for x := matchIndex; x < matchIndex+len(query); x++ {
|
||||||
|
row.Hl[x] = highlight.Match
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
1
gilo.go
1
gilo.go
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
"os"
|
"os"
|
||||||
"timshome.page/gilo/editor"
|
"timshome.page/gilo/editor"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package key
|
package key
|
||||||
|
|
||||||
|
import "unicode"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// !Terminal Input Escape Code Sequences
|
// !Terminal Input Escape Code Sequences
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -12,7 +14,7 @@ const (
|
|||||||
|
|
||||||
// Is this an ASCII character?
|
// Is this an ASCII character?
|
||||||
func IsAscii(char rune) bool {
|
func IsAscii(char rune) bool {
|
||||||
return char < 0x80
|
return char <= unicode.MaxASCII
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this an ASCII ctrl character?
|
// Is this an ASCII ctrl character?
|
||||||
@ -34,3 +36,8 @@ func Ctrl(char rune) rune {
|
|||||||
|
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is the character a general token separator type?
|
||||||
|
func IsSeparator(char rune) bool {
|
||||||
|
return unicode.IsPunct(char) || unicode.IsSpace(char)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user