Ran go fmt *.go
on all sources
This commit is contained in:
parent
e115855491
commit
3982628653
22
main.go
22
main.go
@ -4,9 +4,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
@ -186,7 +186,7 @@ func main() {
|
|||||||
tabContainer.AddTab("noname", textEdit)
|
tabContainer.AddTab("noname", textEdit)
|
||||||
|
|
||||||
changeFocus(tabContainer)
|
changeFocus(tabContainer)
|
||||||
tabContainer.FocusTab(tabContainer.GetTabCount()-1)
|
tabContainer.FocusTab(tabContainer.GetTabCount() - 1)
|
||||||
}}, &ui.ItemEntry{Name: "Open...", Shortcut: "Ctrl+O", Callback: func() {
|
}}, &ui.ItemEntry{Name: "Open...", Shortcut: "Ctrl+O", Callback: func() {
|
||||||
callback := func(filePaths []string) {
|
callback := func(filePaths []string) {
|
||||||
var errOccurred bool
|
var errOccurred bool
|
||||||
@ -214,7 +214,7 @@ func main() {
|
|||||||
dialog = nil // Hide the file selector
|
dialog = nil // Hide the file selector
|
||||||
changeFocus(tabContainer)
|
changeFocus(tabContainer)
|
||||||
if tabContainer.GetTabCount() > 0 {
|
if tabContainer.GetTabCount() > 0 {
|
||||||
tabContainer.FocusTab(tabContainer.GetTabCount()-1)
|
tabContainer.FocusTab(tabContainer.GetTabCount() - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,13 +254,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}, &ui.ItemEntry{Name: "Save As...", QuickChar: 5, Callback: saveAs}, &ui.ItemSeparator{},
|
}}, &ui.ItemEntry{Name: "Save As...", QuickChar: 5, Callback: saveAs}, &ui.ItemSeparator{},
|
||||||
&ui.ItemEntry{Name: "Close", Shortcut: "Ctrl+Q", Callback: func() {
|
&ui.ItemEntry{Name: "Close", Shortcut: "Ctrl+Q", Callback: func() {
|
||||||
if tabContainer.GetTabCount() > 0 {
|
if tabContainer.GetTabCount() > 0 {
|
||||||
tabContainer.RemoveTab(tabContainer.GetSelectedTabIdx())
|
tabContainer.RemoveTab(tabContainer.GetSelectedTabIdx())
|
||||||
} else { // No tabs open; close the editor
|
} else { // No tabs open; close the editor
|
||||||
closing = true
|
closing = true
|
||||||
}
|
}
|
||||||
}}})
|
}}})
|
||||||
|
|
||||||
panelMenu := ui.NewMenu("Panel", 0, &theme)
|
panelMenu := ui.NewMenu("Panel", 0, &theme)
|
||||||
|
|
||||||
@ -426,7 +426,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ev.Modifiers() & tcell.ModCtrl != 0 {
|
if ev.Modifiers()&tcell.ModCtrl != 0 {
|
||||||
handled := menuBar.HandleEvent(ev)
|
handled := menuBar.HandleEvent(ev)
|
||||||
if handled {
|
if handled {
|
||||||
continue // Avoid passing the event to the focusedComponent
|
continue // Avoid passing the event to the focusedComponent
|
||||||
|
@ -62,7 +62,6 @@ type Buffer interface {
|
|||||||
// the last rune before the line delimiter.
|
// the last rune before the line delimiter.
|
||||||
ClampLineCol(line, col int) (int, int)
|
ClampLineCol(line, col int) (int, int)
|
||||||
|
|
||||||
|
|
||||||
// LineColToPos returns the index of the byte at line, col. If line is less than
|
// LineColToPos returns the index of the byte at line, col. If line is less than
|
||||||
// zero, or more than the number of available lines, the function will panic. If
|
// zero, or more than the number of available lines, the function will panic. If
|
||||||
// col is less than zero, the function will panic. If col is greater than the
|
// col is less than zero, the function will panic. If col is greater than the
|
||||||
|
@ -23,14 +23,14 @@ func (c *Colorscheme) GetStyle(s Syntax) tcell.Style {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tcell.StyleDefault; // No value for Default; use default style.
|
return tcell.StyleDefault // No value for Default; use default style.
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegexpRegion struct {
|
type RegexpRegion struct {
|
||||||
Start *regexp.Regexp
|
Start *regexp.Regexp
|
||||||
End *regexp.Regexp // Should be "$" by default
|
End *regexp.Regexp // Should be "$" by default
|
||||||
Skip *regexp.Regexp // Optional
|
Skip *regexp.Regexp // Optional
|
||||||
Error *regexp.Regexp // Optional
|
Error *regexp.Regexp // Optional
|
||||||
Specials []*regexp.Regexp // Optional (nil or zero len)
|
Specials []*regexp.Regexp // Optional (nil or zero len)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,9 +97,9 @@ func (h *Highlighter) updateLines(startLine, endLine int) {
|
|||||||
bytes := h.Buffer.Slice(startLine, 0, endLine, endCol)
|
bytes := h.Buffer.Slice(startLine, 0, endLine, endCol)
|
||||||
|
|
||||||
for k, v := range h.Language.Rules {
|
for k, v := range h.Language.Rules {
|
||||||
var indexes [][]int // [][2]int
|
var indexes [][]int // [][2]int
|
||||||
if k.End != nil && k.End.String() != "$" { // If this range might be a multiline range...
|
if k.End != nil && k.End.String() != "$" { // If this range might be a multiline range...
|
||||||
endIndexes := k.End.FindAllIndex(bytes, -1) // Attempt to find every ending match
|
endIndexes := k.End.FindAllIndex(bytes, -1) // Attempt to find every ending match
|
||||||
startIndexes := k.Start.FindAllIndex(bytes, -1) // Attempt to find every starting match
|
startIndexes := k.Start.FindAllIndex(bytes, -1) // Attempt to find every starting match
|
||||||
// ...
|
// ...
|
||||||
_ = endIndexes
|
_ = endIndexes
|
||||||
@ -111,9 +111,9 @@ func (h *Highlighter) updateLines(startLine, endLine int) {
|
|||||||
if indexes != nil {
|
if indexes != nil {
|
||||||
for i := range indexes {
|
for i := range indexes {
|
||||||
startLine, startCol := h.Buffer.PosToLineCol(indexes[i][0] + startPos)
|
startLine, startCol := h.Buffer.PosToLineCol(indexes[i][0] + startPos)
|
||||||
endLine, endCol := h.Buffer.PosToLineCol(indexes[i][1]-1 + startPos)
|
endLine, endCol := h.Buffer.PosToLineCol(indexes[i][1] - 1 + startPos)
|
||||||
|
|
||||||
match := Match { startCol, endLine, endCol, v }
|
match := Match{startCol, endLine, endCol, v}
|
||||||
|
|
||||||
h.lineMatches[startLine] = append(h.lineMatches[startLine], match) // Unsorted
|
h.lineMatches[startLine] = append(h.lineMatches[startLine], match) // Unsorted
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ func (h *Highlighter) UpdateInvalidatedLines(startLine, endLine int) {
|
|||||||
|
|
||||||
// Keep endLine clamped
|
// Keep endLine clamped
|
||||||
if endLine >= len(h.lineMatches) {
|
if endLine >= len(h.lineMatches) {
|
||||||
endLine = len(h.lineMatches)-1
|
endLine = len(h.lineMatches) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move endLine back to first line at or before endLine with invalidated changes
|
// Move endLine back to first line at or before endLine with invalidated changes
|
||||||
|
@ -57,7 +57,7 @@ func (b *RopeBuffer) LineColToPos(line, col int) int {
|
|||||||
// delimiter. line starts from zero. Data returned may or may not be a copy: do not
|
// delimiter. line starts from zero. Data returned may or may not be a copy: do not
|
||||||
// write it.
|
// write it.
|
||||||
func (b *RopeBuffer) Line(line int) []byte {
|
func (b *RopeBuffer) Line(line int) []byte {
|
||||||
pos := b.getLineStartPos(line)
|
pos := b.getLineStartPos(line)
|
||||||
bytes := 0
|
bytes := 0
|
||||||
|
|
||||||
_rope := (*rope.Node)(b)
|
_rope := (*rope.Node)(b)
|
||||||
@ -99,7 +99,7 @@ func (b *RopeBuffer) Line(line int) []byte {
|
|||||||
func (b *RopeBuffer) Slice(startLine, startCol, endLine, endCol int) []byte {
|
func (b *RopeBuffer) Slice(startLine, startCol, endLine, endCol int) []byte {
|
||||||
endPos := b.LineColToPos(endLine, endCol)
|
endPos := b.LineColToPos(endLine, endCol)
|
||||||
if length := (*rope.Node)(b).Len(); endPos >= length {
|
if length := (*rope.Node)(b).Len(); endPos >= length {
|
||||||
endPos = length-1
|
endPos = length - 1
|
||||||
}
|
}
|
||||||
return (*rope.Node)(b).Slice(b.LineColToPos(startLine, startCol), endPos+1)
|
return (*rope.Node)(b).Slice(b.LineColToPos(startLine, startCol), endPos+1)
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ func (b *RopeBuffer) getLineStartPos(line int) int {
|
|||||||
if line > 0 {
|
if line > 0 {
|
||||||
_rope.IndexAllFunc(0, _rope.Len(), []byte{'\n'}, func(idx int) bool {
|
_rope.IndexAllFunc(0, _rope.Len(), []byte{'\n'}, func(idx int) bool {
|
||||||
line--
|
line--
|
||||||
pos = idx + 1 // idx+1 = start of line after delimiter
|
pos = idx + 1 // idx+1 = start of line after delimiter
|
||||||
if line <= 0 { // If pos is now the start of the line we're searching for...
|
if line <= 0 { // If pos is now the start of the line we're searching for...
|
||||||
return true // Stop indexing
|
return true // Stop indexing
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ func (b *RopeBuffer) RunesInLineWithDelim(line int) int {
|
|||||||
count++ // Add the '\r' we previously thought was part of the delim.
|
count++ // Add the '\r' we previously thought was part of the delim.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respect Utf-8 codepoint boundaries
|
// Respect Utf-8 codepoint boundaries
|
||||||
_, size := utf8.DecodeRune(data[i:])
|
_, size := utf8.DecodeRune(data[i:])
|
||||||
i += size
|
i += size
|
||||||
@ -257,7 +257,7 @@ func (b *RopeBuffer) RunesInLine(line int) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
count++
|
count++
|
||||||
|
|
||||||
// Respect Utf-8 codepoint boundaries
|
// Respect Utf-8 codepoint boundaries
|
||||||
_, size := utf8.DecodeRune(data[i:])
|
_, size := utf8.DecodeRune(data[i:])
|
||||||
i += size
|
i += size
|
||||||
@ -275,8 +275,8 @@ func (b *RopeBuffer) RunesInLine(line int) int {
|
|||||||
func (b *RopeBuffer) ClampLineCol(line, col int) (int, int) {
|
func (b *RopeBuffer) ClampLineCol(line, col int) (int, int) {
|
||||||
if line < 0 {
|
if line < 0 {
|
||||||
line = 0
|
line = 0
|
||||||
} else if lines := b.Lines()-1; line > lines {
|
} else if lines := b.Lines() - 1; line > lines {
|
||||||
line = lines
|
line = lines
|
||||||
}
|
}
|
||||||
|
|
||||||
if col < 0 {
|
if col < 0 {
|
||||||
|
@ -19,7 +19,7 @@ func TestRopePosToLineCol(t *testing.T) {
|
|||||||
t.Errorf("Expected startCol == 0, got %v", startCol)
|
t.Errorf("Expected startCol == 0, got %v", startCol)
|
||||||
}
|
}
|
||||||
|
|
||||||
endPos := buf.Len()-1
|
endPos := buf.Len() - 1
|
||||||
endLine, endCol := buf.PosToLineCol(endPos)
|
endLine, endCol := buf.PosToLineCol(endPos)
|
||||||
t.Logf("endPos = %v", endPos)
|
t.Logf("endPos = %v", endPos)
|
||||||
if endLine != 3 {
|
if endLine != 3 {
|
||||||
|
@ -47,7 +47,7 @@ func DrawQuickCharStr(s tcell.Screen, x, y int, str string, quickCharIdx int, st
|
|||||||
|
|
||||||
sty := style
|
sty := style
|
||||||
if runeIdx == quickCharIdx {
|
if runeIdx == quickCharIdx {
|
||||||
sty = style.Underline(true)
|
sty = style.Underline(true)
|
||||||
}
|
}
|
||||||
s.SetContent(x+col, y, r, nil, sty)
|
s.SetContent(x+col, y, r, nil, sty)
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ func DrawRectOutlineDefault(s tcell.Screen, x, y, width, height int, style tcell
|
|||||||
func DrawWindow(s tcell.Screen, x, y, width, height int, title string, theme *Theme) {
|
func DrawWindow(s tcell.Screen, x, y, width, height int, title string, theme *Theme) {
|
||||||
headerStyle := theme.GetOrDefault("WindowHeader")
|
headerStyle := theme.GetOrDefault("WindowHeader")
|
||||||
|
|
||||||
DrawRect(s, x, y, width, 1, ' ', headerStyle) // Draw header background
|
DrawRect(s, x, y, width, 1, ' ', headerStyle) // Draw header background
|
||||||
DrawStr(s, x + width/2 - len(title)/2, y, title, headerStyle) // Draw header title
|
DrawStr(s, x+width/2-len(title)/2, y, title, headerStyle) // Draw header title
|
||||||
|
|
||||||
DrawRect(s, x, y+1, width, height-1, ' ', theme.GetOrDefault("Window")) // Draw body
|
DrawRect(s, x, y+1, width, height-1, ' ', theme.GetOrDefault("Window")) // Draw body
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
type FileSelectorDialog struct {
|
type FileSelectorDialog struct {
|
||||||
MustExist bool // Whether the dialog should have a user select an existing file.
|
MustExist bool // Whether the dialog should have a user select an existing file.
|
||||||
FilesChosenCallback func([]string) // Returns slice of filenames selected. nil if user canceled.
|
FilesChosenCallback func([]string) // Returns slice of filenames selected. nil if user canceled.
|
||||||
Theme *Theme
|
Theme *Theme
|
||||||
|
|
||||||
title string
|
title string
|
||||||
x, y int
|
x, y int
|
||||||
@ -31,7 +31,7 @@ func NewFileSelectorDialog(screen *tcell.Screen, title string, mustExist bool, t
|
|||||||
MustExist: mustExist,
|
MustExist: mustExist,
|
||||||
FilesChosenCallback: filesChosenCallback,
|
FilesChosenCallback: filesChosenCallback,
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
title: title,
|
title: title,
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog.inputField = NewInputField(screen, []byte{}, theme.GetOrDefault("Window")) // Use window's theme for InputField
|
dialog.inputField = NewInputField(screen, []byte{}, theme.GetOrDefault("Window")) // Use window's theme for InputField
|
||||||
|
@ -81,7 +81,7 @@ func (f *InputField) insert(dst []byte, at int, src ...byte) []byte {
|
|||||||
copy(dstn[at:], src)
|
copy(dstn[at:], src)
|
||||||
return dstn
|
return dstn
|
||||||
}
|
}
|
||||||
dstn := make([]byte, len(dst) + len(src))
|
dstn := make([]byte, len(dst)+len(src))
|
||||||
copy(dstn, dst[:at])
|
copy(dstn, dst[:at])
|
||||||
copy(dstn[at:], src)
|
copy(dstn[at:], src)
|
||||||
copy(dstn[at+len(src):], dst[at:])
|
copy(dstn[at+len(src):], dst[at:])
|
||||||
|
24
ui/menu.go
24
ui/menu.go
@ -77,7 +77,7 @@ type MenuBar struct {
|
|||||||
x, y int
|
x, y int
|
||||||
width, height int
|
width, height int
|
||||||
focused bool
|
focused bool
|
||||||
selected int // Index of selection in MenuBar
|
selected int // Index of selection in MenuBar
|
||||||
menusVisible bool // Whether to draw the selected menu
|
menusVisible bool // Whether to draw the selected menu
|
||||||
|
|
||||||
Theme *Theme
|
Theme *Theme
|
||||||
@ -115,7 +115,7 @@ func (b *MenuBar) ActivateMenuUnderCursor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *MenuBar) CursorLeft() {
|
func (b *MenuBar) CursorLeft() {
|
||||||
if b.menusVisible {
|
if b.menusVisible {
|
||||||
b.menus[b.selected].SetFocused(false) // Unfocus current menu
|
b.menus[b.selected].SetFocused(false) // Unfocus current menu
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ func (b *MenuBar) Draw(s tcell.Screen) {
|
|||||||
DrawRect(s, b.x, b.y, b.width, 1, ' ', normalStyle)
|
DrawRect(s, b.x, b.y, b.width, 1, ' ', normalStyle)
|
||||||
col := b.x + 1
|
col := b.x + 1
|
||||||
for i, item := range b.menus {
|
for i, item := range b.menus {
|
||||||
sty := normalStyle
|
sty := normalStyle
|
||||||
if b.focused && b.selected == i {
|
if b.focused && b.selected == i {
|
||||||
sty = b.Theme.GetOrDefault("MenuBarSelected") // Use special style for selected item
|
sty = b.Theme.GetOrDefault("MenuBarSelected") // Use special style for selected item
|
||||||
}
|
}
|
||||||
@ -242,7 +242,7 @@ func (b *MenuBar) HandleEvent(event tcell.Event) bool {
|
|||||||
if !b.menusVisible { // If menus are not visible...
|
if !b.menusVisible { // If menus are not visible...
|
||||||
b.ActivateMenuUnderCursor()
|
b.ActivateMenuUnderCursor()
|
||||||
} else { // The selected Menu is visible, send the event to it
|
} else { // The selected Menu is visible, send the event to it
|
||||||
return b.menus[b.selected].HandleEvent(event)
|
return b.menus[b.selected].HandleEvent(event)
|
||||||
}
|
}
|
||||||
case tcell.KeyLeft:
|
case tcell.KeyLeft:
|
||||||
b.CursorLeft()
|
b.CursorLeft()
|
||||||
@ -261,14 +261,14 @@ func (b *MenuBar) HandleEvent(event tcell.Event) bool {
|
|||||||
for i, m := range b.menus {
|
for i, m := range b.menus {
|
||||||
r := QuickCharInString(m.Name, m.QuickChar)
|
r := QuickCharInString(m.Name, m.QuickChar)
|
||||||
if r != 0 && r == ev.Rune() {
|
if r != 0 && r == ev.Rune() {
|
||||||
b.selected = i // Select menu at i
|
b.selected = i // Select menu at i
|
||||||
b.ActivateMenuUnderCursor() // Show menu
|
b.ActivateMenuUnderCursor() // Show menu
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return b.menus[b.selected].HandleEvent(event) // Have menu handle quick char event
|
return b.menus[b.selected].HandleEvent(event) // Have menu handle quick char event
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if b.menusVisible {
|
if b.menusVisible {
|
||||||
@ -299,10 +299,10 @@ type Menu struct {
|
|||||||
// New creates a new Menu. `items` can be `nil`.
|
// New creates a new Menu. `items` can be `nil`.
|
||||||
func NewMenu(name string, quickChar int, theme *Theme) *Menu {
|
func NewMenu(name string, quickChar int, theme *Theme) *Menu {
|
||||||
return &Menu{
|
return &Menu{
|
||||||
Name: name,
|
Name: name,
|
||||||
QuickChar: quickChar,
|
QuickChar: quickChar,
|
||||||
Items: make([]Item, 0, 6),
|
Items: make([]Item, 0, 6),
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ func (m *Menu) ActivateItemUnderCursor() {
|
|||||||
m.itemSelectedCallback()
|
m.itemSelectedCallback()
|
||||||
case *Menu:
|
case *Menu:
|
||||||
// TODO: implement sub-menus ...
|
// TODO: implement sub-menus ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Menu) CursorUp() {
|
func (m *Menu) CursorUp() {
|
||||||
@ -379,7 +379,7 @@ func (m *Menu) Draw(s tcell.Screen) {
|
|||||||
} else {
|
} else {
|
||||||
sty = defaultStyle
|
sty = defaultStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
nameCols := DrawQuickCharStr(s, m.x+1, m.y+1+i, item.GetName(), item.GetQuickCharIdx(), sty)
|
nameCols := DrawQuickCharStr(s, m.x+1, m.y+1+i, item.GetName(), item.GetQuickCharIdx(), sty)
|
||||||
|
|
||||||
str := strings.Repeat(" ", m.width-2-nameCols) // Fill space after menu names to border
|
str := strings.Repeat(" ", m.width-2-nameCols) // Fill space after menu names to border
|
||||||
@ -437,7 +437,7 @@ func (m *Menu) GetSize() (int, int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.width = 1 + maxNameLen + shortcutsWidth + 1 // Add two for padding
|
m.width = 1 + maxNameLen + shortcutsWidth + 1 // Add two for padding
|
||||||
m.height = 1 + len(m.Items) + 1 // And another two for the same reason ...
|
m.height = 1 + len(m.Items) + 1 // And another two for the same reason ...
|
||||||
return m.width, m.height
|
return m.width, m.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ func NewMessageDialog(title string, message string, kind MessageDialogKind, opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
dialog := MessageDialog{
|
dialog := MessageDialog{
|
||||||
Title: title,
|
Title: title,
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Callback: callback,
|
Callback: callback,
|
||||||
|
|
||||||
theme: theme,
|
theme: theme,
|
||||||
@ -117,8 +117,8 @@ func (d *MessageDialog) SetPos(x, y int) {
|
|||||||
|
|
||||||
func (d *MessageDialog) GetMinSize() (int, int) {
|
func (d *MessageDialog) GetMinSize() (int, int) {
|
||||||
lines := strings.Count(d.messageWrapped, "\n") + 1
|
lines := strings.Count(d.messageWrapped, "\n") + 1
|
||||||
|
|
||||||
return Max(len(d.Title)+2, 30), 2+lines+2
|
return Max(len(d.Title)+2, 30), 2 + lines + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *MessageDialog) GetSize() (int, int) {
|
func (d *MessageDialog) GetSize() (int, int) {
|
||||||
|
@ -9,9 +9,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/mattn/go-runewidth"
|
|
||||||
"github.com/fivemoreminix/qedit/ui/buffer"
|
"github.com/fivemoreminix/qedit/ui/buffer"
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
|
"github.com/mattn/go-runewidth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Selection represents a region of the buffer to be selected for text editing
|
// A Selection represents a region of the buffer to be selected for text editing
|
||||||
@ -91,12 +91,12 @@ loop:
|
|||||||
t.Buffer = buffer.NewRopeBuffer(contents)
|
t.Buffer = buffer.NewRopeBuffer(contents)
|
||||||
|
|
||||||
// TODO: replace with automatic determination of language via filetype
|
// TODO: replace with automatic determination of language via filetype
|
||||||
lang := &buffer.Language {
|
lang := &buffer.Language{
|
||||||
Name: "Go",
|
Name: "Go",
|
||||||
Filetypes: []string{".go"},
|
Filetypes: []string{".go"},
|
||||||
Rules: map[*buffer.RegexpRegion]buffer.Syntax {
|
Rules: map[*buffer.RegexpRegion]buffer.Syntax{
|
||||||
&buffer.RegexpRegion{Start: regexp.MustCompile("\\/\\/.*")}: buffer.Comment,
|
&buffer.RegexpRegion{Start: regexp.MustCompile("\\/\\/.*")}: buffer.Comment,
|
||||||
&buffer.RegexpRegion{Start: regexp.MustCompile("\".*?\"")}: buffer.String,
|
&buffer.RegexpRegion{Start: regexp.MustCompile("\".*?\"")}: buffer.String,
|
||||||
&buffer.RegexpRegion{
|
&buffer.RegexpRegion{
|
||||||
Start: regexp.MustCompile("\\b(var|const|if|else|range|for|switch|fallthrough|case|default|break|continue|go|func|return|defer|import|type|package)\\b"),
|
Start: regexp.MustCompile("\\b(var|const|if|else|range|for|switch|fallthrough|case|default|break|continue|go|func|return|defer|import|type|package)\\b"),
|
||||||
}: buffer.Keyword,
|
}: buffer.Keyword,
|
||||||
@ -115,7 +115,7 @@ loop:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
colorscheme := &buffer.Colorscheme {
|
colorscheme := &buffer.Colorscheme{
|
||||||
buffer.Default: tcell.Style{}.Foreground(tcell.ColorLightGray).Background(tcell.ColorBlack),
|
buffer.Default: tcell.Style{}.Foreground(tcell.ColorLightGray).Background(tcell.ColorBlack),
|
||||||
buffer.Comment: tcell.Style{}.Foreground(tcell.ColorGray).Background(tcell.ColorBlack),
|
buffer.Comment: tcell.Style{}.Foreground(tcell.ColorGray).Background(tcell.ColorBlack),
|
||||||
buffer.String: tcell.Style{}.Foreground(tcell.ColorOlive).Background(tcell.ColorBlack),
|
buffer.String: tcell.Style{}.Foreground(tcell.ColorOlive).Background(tcell.ColorBlack),
|
||||||
@ -275,7 +275,7 @@ func (t *TextEdit) SetLineCol(line, col int) {
|
|||||||
line, col = t.Buffer.ClampLineCol(line, col)
|
line, col = t.Buffer.ClampLineCol(line, col)
|
||||||
|
|
||||||
// Handle hard tabs
|
// Handle hard tabs
|
||||||
tabOffset := t.getTabCountInLineAtCol(line, col) * (t.TabSize-1) // Offset for the current line from hard tabs (temporary; purely visual)
|
tabOffset := t.getTabCountInLineAtCol(line, col) * (t.TabSize - 1) // Offset for the current line from hard tabs (temporary; purely visual)
|
||||||
|
|
||||||
// Scroll the screen when going to lines out of view
|
// Scroll the screen when going to lines out of view
|
||||||
if line >= t.scrolly+t.height-1 { // If the new line is below view...
|
if line >= t.scrolly+t.height-1 { // If the new line is below view...
|
||||||
@ -386,7 +386,7 @@ func (t *TextEdit) Draw(s tcell.Screen) {
|
|||||||
selectedStyle := t.Theme.GetOrDefault("TextEditSelected")
|
selectedStyle := t.Theme.GetOrDefault("TextEditSelected")
|
||||||
columnStyle := t.Theme.GetOrDefault("TextEditColumn")
|
columnStyle := t.Theme.GetOrDefault("TextEditColumn")
|
||||||
|
|
||||||
t.Highlighter.UpdateInvalidatedLines(t.scrolly, t.scrolly + (t.height-1))
|
t.Highlighter.UpdateInvalidatedLines(t.scrolly, t.scrolly+(t.height-1))
|
||||||
|
|
||||||
var tabBytes []byte
|
var tabBytes []byte
|
||||||
if t.UseHardTabs {
|
if t.UseHardTabs {
|
||||||
@ -410,30 +410,30 @@ func (t *TextEdit) Draw(s tcell.Screen) {
|
|||||||
|
|
||||||
// When iterating lineTabs: the value at i is
|
// When iterating lineTabs: the value at i is
|
||||||
// the rune index the tab was found at.
|
// the rune index the tab was found at.
|
||||||
// var lineTabs [128]int // Rune index for each hard tab '\t' in lineBytes
|
// var lineTabs [128]int // Rune index for each hard tab '\t' in lineBytes
|
||||||
// var tabs int // Length of lineTabs (number of hard tabs)
|
// var tabs int // Length of lineTabs (number of hard tabs)
|
||||||
if t.UseHardTabs {
|
if t.UseHardTabs {
|
||||||
// var ri int // rune index
|
// var ri int // rune index
|
||||||
// var i int
|
// var i int
|
||||||
// for i < len(lineBytes) {
|
// for i < len(lineBytes) {
|
||||||
// r, size := utf8.DecodeRune(lineBytes[i:])
|
// r, size := utf8.DecodeRune(lineBytes[i:])
|
||||||
// if r == '\t' {
|
// if r == '\t' {
|
||||||
// lineTabs[tabs] = ri
|
// lineTabs[tabs] = ri
|
||||||
// tabs++
|
// tabs++
|
||||||
// }
|
// }
|
||||||
// i += size
|
// i += size
|
||||||
// ri++
|
// ri++
|
||||||
// }
|
// }
|
||||||
lineBytes = bytes.ReplaceAll(lineBytes, []byte{'\t'}, tabBytes)
|
lineBytes = bytes.ReplaceAll(lineBytes, []byte{'\t'}, tabBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineHighlightData := t.Highlighter.GetLineMatches(line)
|
lineHighlightData := t.Highlighter.GetLineMatches(line)
|
||||||
var lineHighlightDataIdx int
|
var lineHighlightDataIdx int
|
||||||
|
|
||||||
var byteIdx int // Byte index of lineStr
|
var byteIdx int // Byte index of lineStr
|
||||||
// X offset we draw the next rune at (some runes can be 2 cols wide)
|
// X offset we draw the next rune at (some runes can be 2 cols wide)
|
||||||
col := t.x + columnWidth
|
col := t.x + columnWidth
|
||||||
var runeIdx int // Index into lineStr (as runes) we draw the next character at
|
var runeIdx int // Index into lineStr (as runes) we draw the next character at
|
||||||
|
|
||||||
// REWRITE OF SCROLL FUNC:
|
// REWRITE OF SCROLL FUNC:
|
||||||
for runeIdx < t.scrollx && byteIdx < len(lineBytes) {
|
for runeIdx < t.scrollx && byteIdx < len(lineBytes) {
|
||||||
@ -444,7 +444,7 @@ func (t *TextEdit) Draw(s tcell.Screen) {
|
|||||||
|
|
||||||
tabOffsetAtRuneIdx := func(idx int) int {
|
tabOffsetAtRuneIdx := func(idx int) int {
|
||||||
var count int
|
var count int
|
||||||
var i int
|
var i int
|
||||||
for i < len(origLineBytes) {
|
for i < len(origLineBytes) {
|
||||||
r, size := utf8.DecodeRune(origLineBytes[i:])
|
r, size := utf8.DecodeRune(origLineBytes[i:])
|
||||||
if r == '\t' {
|
if r == '\t' {
|
||||||
@ -459,7 +459,7 @@ func (t *TextEdit) Draw(s tcell.Screen) {
|
|||||||
// not affected by the hard tabs becoming 4 or 8 spaces.
|
// not affected by the hard tabs becoming 4 or 8 spaces.
|
||||||
origRuneIdx := func(idx int) int { // returns the idx that is not mutated by hard tabs
|
origRuneIdx := func(idx int) int { // returns the idx that is not mutated by hard tabs
|
||||||
var ridx int // new rune idx
|
var ridx int // new rune idx
|
||||||
var i int // byte index
|
var i int // byte index
|
||||||
for idx > 0 {
|
for idx > 0 {
|
||||||
r, size := utf8.DecodeRune(origLineBytes[i:])
|
r, size := utf8.DecodeRune(origLineBytes[i:])
|
||||||
if r == '\t' {
|
if r == '\t' {
|
||||||
@ -475,9 +475,9 @@ func (t *TextEdit) Draw(s tcell.Screen) {
|
|||||||
return ridx
|
return ridx
|
||||||
}
|
}
|
||||||
|
|
||||||
for col < t.x + t.width { // For each column in view...
|
for col < t.x+t.width { // For each column in view...
|
||||||
var r rune = ' ' // Rune to draw this iteration
|
var r rune = ' ' // Rune to draw this iteration
|
||||||
var size int = 1 // Size of the rune (in bytes)
|
var size int = 1 // Size of the rune (in bytes)
|
||||||
var selected bool // Whether this rune should be styled as selected
|
var selected bool // Whether this rune should be styled as selected
|
||||||
|
|
||||||
tabOffsetAtRuneIdx := tabOffsetAtRuneIdx(runeIdx)
|
tabOffsetAtRuneIdx := tabOffsetAtRuneIdx(runeIdx)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user