mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-23 01:07:16 +09:00
Merge
This commit is contained in:
@@ -118,6 +118,9 @@ func luaImportMicroBuffer() *lua.LTable {
|
||||
ulua.L.SetField(pkg, "Loc", luar.New(ulua.L, func(x, y int) buffer.Loc {
|
||||
return buffer.Loc{x, y}
|
||||
}))
|
||||
ulua.L.SetField(pkg, "SLoc", luar.New(ulua.L, func(line, row int) display.SLoc {
|
||||
return display.SLoc{line, row}
|
||||
}))
|
||||
ulua.L.SetField(pkg, "BTDefault", luar.New(ulua.L, buffer.BTDefault.Kind))
|
||||
ulua.L.SetField(pkg, "BTHelp", luar.New(ulua.L, buffer.BTHelp.Kind))
|
||||
ulua.L.SetField(pkg, "BTLog", luar.New(ulua.L, buffer.BTLog.Kind))
|
||||
|
||||
2
go.mod
2
go.mod
@@ -27,6 +27,6 @@ require (
|
||||
|
||||
replace github.com/kballard/go-shellquote => github.com/zyedidia/go-shellquote v0.0.0-20200613203517-eccd813c0655
|
||||
|
||||
replace github.com/mattn/go-runewidth => github.com/p-e-w/go-runewidth v0.0.10-0.20200613030200-3e1705c5c059
|
||||
replace github.com/mattn/go-runewidth => github.com/zyedidia/go-runewidth v0.0.12
|
||||
|
||||
go 1.11
|
||||
|
||||
4
go.sum
4
go.sum
@@ -27,6 +27,8 @@ github.com/p-e-w/go-runewidth v0.0.10-0.20200613030200-3e1705c5c059 h1:/+h2b6i15
|
||||
github.com/p-e-w/go-runewidth v0.0.10-0.20200613030200-3e1705c5c059/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA=
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
@@ -44,6 +46,8 @@ github.com/zyedidia/clipboard v1.0.3 h1:F/nCDVYMdbDWTmY8s8cJl0tnwX32q96IF09JHM14
|
||||
github.com/zyedidia/clipboard v1.0.3/go.mod h1:zykFnZUXX0ErxqvYLUFEq7QDJKId8rmh2FgD0/Y8cjA=
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3 h1:oMHjjTLfGXVuyOQBYj5/td9WC0mw4g1xDBPovIqmHew=
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3/go.mod h1:YKbIYP//Eln8eDgAJGI3IDvR3s4Tv9Z9TGIOumiyQ5c=
|
||||
github.com/zyedidia/go-runewidth v0.0.12 h1:aHWj8qL3aH7caRzoPBJXe1pEaZBXHpKtfTuiBo5p74Q=
|
||||
github.com/zyedidia/go-runewidth v0.0.12/go.mod h1:vF8djYdLmG8BJaUZ4CznFYCJ3pFR8m4B4VinTvTTarU=
|
||||
github.com/zyedidia/go-shellquote v0.0.0-20200613203517-eccd813c0655 h1:Z3RhH6hvcSx7eX6Q/pP6YVsgea/1eMDG99vtWwi3nK4=
|
||||
github.com/zyedidia/go-shellquote v0.0.0-20200613203517-eccd813c0655/go.mod h1:1sTqqO+kcYzZp43M5VsJe1tns9IzlSeC9jB6c2+o/5Y=
|
||||
github.com/zyedidia/highlight v0.0.0-20170330143449-201131ce5cf5 h1:Zs6mpwXvlqpF9zHl5XaN0p5V4J9XvP+WBuiuXyIgqvc=
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
@@ -19,21 +20,26 @@ import (
|
||||
// ScrollUp is not an action
|
||||
func (h *BufPane) ScrollUp(n int) {
|
||||
v := h.GetView()
|
||||
if v.StartLine >= n {
|
||||
v.StartLine -= n
|
||||
h.SetView(v)
|
||||
} else {
|
||||
v.StartLine = 0
|
||||
}
|
||||
v.StartLine = h.Scroll(v.StartLine, -n)
|
||||
h.SetView(v)
|
||||
}
|
||||
|
||||
// ScrollDown is not an action
|
||||
func (h *BufPane) ScrollDown(n int) {
|
||||
v := h.GetView()
|
||||
if v.StartLine <= h.Buf.LinesNum()-1-n {
|
||||
v.StartLine += n
|
||||
h.SetView(v)
|
||||
v.StartLine = h.Scroll(v.StartLine, n)
|
||||
h.SetView(v)
|
||||
}
|
||||
|
||||
// If the user has scrolled past the last line, ScrollAdjust can be used
|
||||
// to shift the view so that the last line is at the bottom
|
||||
func (h *BufPane) ScrollAdjust() {
|
||||
v := h.GetView()
|
||||
end := h.SLocFromLoc(h.Buf.End())
|
||||
if h.Diff(v.StartLine, end) < v.Height-1 {
|
||||
v.StartLine = h.Scroll(end, -v.Height+1)
|
||||
}
|
||||
h.SetView(v)
|
||||
}
|
||||
|
||||
// MousePress is the event that should happen when a normal click happens
|
||||
@@ -111,15 +117,9 @@ func (h *BufPane) ScrollDownAction() bool {
|
||||
// Center centers the view on the cursor
|
||||
func (h *BufPane) Center() bool {
|
||||
v := h.GetView()
|
||||
v.StartLine = h.Cursor.Y - v.Height/2
|
||||
if v.StartLine+v.Height > h.Buf.LinesNum() {
|
||||
v.StartLine = h.Buf.LinesNum() - v.Height
|
||||
}
|
||||
if v.StartLine < 0 {
|
||||
v.StartLine = 0
|
||||
}
|
||||
v.StartLine = h.Scroll(h.SLocFromLoc(h.Cursor.Loc), -v.Height/2)
|
||||
h.SetView(v)
|
||||
h.Relocate()
|
||||
h.ScrollAdjust()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1243,45 +1243,31 @@ func (h *BufPane) JumpLine() bool {
|
||||
// Start moves the viewport to the start of the buffer
|
||||
func (h *BufPane) Start() bool {
|
||||
v := h.GetView()
|
||||
v.StartLine = 0
|
||||
v.StartLine = display.SLoc{0, 0}
|
||||
h.SetView(v)
|
||||
return true
|
||||
}
|
||||
|
||||
// End moves the viewport to the end of the buffer
|
||||
func (h *BufPane) End() bool {
|
||||
// TODO: softwrap problems?
|
||||
v := h.GetView()
|
||||
if v.Height > h.Buf.LinesNum() {
|
||||
v.StartLine = 0
|
||||
h.SetView(v)
|
||||
} else {
|
||||
v.StartLine = h.Buf.LinesNum() - v.Height
|
||||
h.SetView(v)
|
||||
}
|
||||
v.StartLine = h.Scroll(h.SLocFromLoc(h.Buf.End()), -v.Height+1)
|
||||
h.SetView(v)
|
||||
return true
|
||||
}
|
||||
|
||||
// PageUp scrolls the view up a page
|
||||
func (h *BufPane) PageUp() bool {
|
||||
v := h.GetView()
|
||||
if v.StartLine > v.Height {
|
||||
h.ScrollUp(v.Height)
|
||||
} else {
|
||||
v.StartLine = 0
|
||||
}
|
||||
h.SetView(v)
|
||||
h.ScrollUp(v.Height)
|
||||
return true
|
||||
}
|
||||
|
||||
// PageDown scrolls the view down a page
|
||||
func (h *BufPane) PageDown() bool {
|
||||
v := h.GetView()
|
||||
if h.Buf.LinesNum()-(v.StartLine+v.Height) > v.Height {
|
||||
h.ScrollDown(v.Height)
|
||||
} else if h.Buf.LinesNum() >= v.Height {
|
||||
v.StartLine = h.Buf.LinesNum() - v.Height
|
||||
}
|
||||
h.ScrollDown(v.Height)
|
||||
h.ScrollAdjust()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1338,24 +1324,15 @@ func (h *BufPane) CursorPageDown() bool {
|
||||
// HalfPageUp scrolls the view up half a page
|
||||
func (h *BufPane) HalfPageUp() bool {
|
||||
v := h.GetView()
|
||||
if v.StartLine > v.Height/2 {
|
||||
h.ScrollUp(v.Height / 2)
|
||||
} else {
|
||||
v.StartLine = 0
|
||||
}
|
||||
h.SetView(v)
|
||||
h.ScrollUp(v.Height / 2)
|
||||
return true
|
||||
}
|
||||
|
||||
// HalfPageDown scrolls the view down half a page
|
||||
func (h *BufPane) HalfPageDown() bool {
|
||||
v := h.GetView()
|
||||
if h.Buf.LinesNum()-(v.StartLine+v.Height) > v.Height/2 {
|
||||
h.ScrollDown(v.Height / 2)
|
||||
} else if h.Buf.LinesNum() >= v.Height {
|
||||
v.StartLine = h.Buf.LinesNum() - v.Height
|
||||
}
|
||||
h.SetView(v)
|
||||
h.ScrollDown(v.Height / 2)
|
||||
h.ScrollAdjust()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,6 @@ func WriteLog(s string) {
|
||||
buffer.WriteLog(s)
|
||||
if LogBufPane != nil {
|
||||
LogBufPane.CursorEnd()
|
||||
v := LogBufPane.GetView()
|
||||
endY := buffer.LogBuf.End().Y
|
||||
|
||||
if endY > v.StartLine+v.Height {
|
||||
v.StartLine = buffer.LogBuf.End().Y - v.Height + 2
|
||||
LogBufPane.SetView(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +30,4 @@ func WriteLog(s string) {
|
||||
func (h *BufPane) OpenLogBuf() {
|
||||
LogBufPane = h.HSplitBuf(buffer.LogBuf)
|
||||
LogBufPane.CursorEnd()
|
||||
|
||||
v := LogBufPane.GetView()
|
||||
endY := buffer.LogBuf.End().Y
|
||||
|
||||
if endY > v.StartLine+v.Height {
|
||||
v.StartLine = buffer.LogBuf.End().Y - v.Height + 2
|
||||
LogBufPane.SetView(v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,6 +545,27 @@ func (b *Buffer) RuneAt(loc Loc) rune {
|
||||
return '\n'
|
||||
}
|
||||
|
||||
// WordAt returns the word around a given location in the buffer
|
||||
func (b *Buffer) WordAt(loc Loc) []byte {
|
||||
if len(b.LineBytes(loc.Y)) == 0 || !util.IsWordChar(b.RuneAt(loc)) {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
start := loc
|
||||
end := loc.Move(1, b)
|
||||
|
||||
for start.X > 0 && util.IsWordChar(b.RuneAt(start.Move(-1, b))) {
|
||||
start.X--
|
||||
}
|
||||
|
||||
lineLen := util.CharacterCount(b.LineBytes(loc.Y))
|
||||
for end.X < lineLen && util.IsWordChar(b.RuneAt(end)) {
|
||||
end.X++
|
||||
}
|
||||
|
||||
return b.Substr(start, end)
|
||||
}
|
||||
|
||||
// Modified returns if this buffer has been modified since
|
||||
// being opened
|
||||
func (b *Buffer) Modified() bool {
|
||||
|
||||
@@ -106,51 +106,35 @@ func (w *BufWindow) Clear() {
|
||||
}
|
||||
}
|
||||
|
||||
// Bottomline returns the line number of the lowest line in the view
|
||||
// You might think that this is obviously just v.StartLine + v.Height
|
||||
// but if softwrap is enabled things get complicated since one buffer
|
||||
// line can take up multiple lines in the view
|
||||
func (w *BufWindow) Bottomline() int {
|
||||
if !w.Buf.Settings["softwrap"].(bool) {
|
||||
h := w.StartLine + w.Height - 1
|
||||
if w.drawStatus {
|
||||
h--
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
l := w.LocFromVisual(buffer.Loc{0, w.Y + w.Height})
|
||||
|
||||
return l.Y
|
||||
}
|
||||
|
||||
// Relocate moves the view window so that the cursor is in view
|
||||
// This is useful if the user has scrolled far away, and then starts typing
|
||||
// Returns true if the window location is moved
|
||||
func (w *BufWindow) Relocate() bool {
|
||||
b := w.Buf
|
||||
// how many buffer lines are in the view
|
||||
height := w.Bottomline() + 1 - w.StartLine
|
||||
h := w.Height
|
||||
height := w.Height
|
||||
if w.drawStatus {
|
||||
h--
|
||||
height--
|
||||
}
|
||||
ret := false
|
||||
activeC := w.Buf.GetActiveCursor()
|
||||
cy := activeC.Y
|
||||
scrollmargin := int(b.Settings["scrollmargin"].(float64))
|
||||
if cy < w.StartLine+scrollmargin && cy > scrollmargin-1 {
|
||||
w.StartLine = cy - scrollmargin
|
||||
|
||||
c := w.SLocFromLoc(activeC.Loc)
|
||||
bStart := SLoc{0, 0}
|
||||
bEnd := w.SLocFromLoc(b.End())
|
||||
|
||||
if c.LessThan(w.Scroll(w.StartLine, scrollmargin)) && c.GreaterThan(w.Scroll(bStart, scrollmargin-1)) {
|
||||
w.StartLine = w.Scroll(c, -scrollmargin)
|
||||
ret = true
|
||||
} else if cy < w.StartLine {
|
||||
w.StartLine = cy
|
||||
} else if c.LessThan(w.StartLine) {
|
||||
w.StartLine = c
|
||||
ret = true
|
||||
}
|
||||
if cy > w.StartLine+height-1-scrollmargin && cy < b.LinesNum()-scrollmargin {
|
||||
w.StartLine = cy - height + 1 + scrollmargin
|
||||
if c.GreaterThan(w.Scroll(w.StartLine, height-1-scrollmargin)) && c.LessThan(w.Scroll(bEnd, -scrollmargin+1)) {
|
||||
w.StartLine = w.Scroll(c, -height+1+scrollmargin)
|
||||
ret = true
|
||||
} else if cy >= b.LinesNum()-scrollmargin && cy >= height {
|
||||
w.StartLine = b.LinesNum() - height
|
||||
} else if c.GreaterThan(w.Scroll(bEnd, -scrollmargin)) && c.GreaterThan(w.Scroll(w.StartLine, height-1)) {
|
||||
w.StartLine = w.Scroll(bEnd, -height+1)
|
||||
ret = true
|
||||
}
|
||||
|
||||
@@ -199,11 +183,15 @@ func (w *BufWindow) LocFromVisual(svloc buffer.Loc) buffer.Loc {
|
||||
// this represents the current draw position
|
||||
// within the current window
|
||||
vloc := buffer.Loc{X: 0, Y: 0}
|
||||
if softwrap {
|
||||
// the start line may be partially out of the current window
|
||||
vloc.Y = -w.StartLine.Row
|
||||
}
|
||||
|
||||
// this represents the current draw position in the buffer (char positions)
|
||||
bloc := buffer.Loc{X: -1, Y: w.StartLine}
|
||||
bloc := buffer.Loc{X: -1, Y: w.StartLine.Line}
|
||||
|
||||
for vloc.Y = 0; vloc.Y < bufHeight; vloc.Y++ {
|
||||
for ; vloc.Y < bufHeight; vloc.Y++ {
|
||||
vloc.X = 0
|
||||
if hasMessage {
|
||||
vloc.X += 2
|
||||
@@ -473,14 +461,18 @@ func (w *BufWindow) displayBuffer() {
|
||||
// this represents the current draw position
|
||||
// within the current window
|
||||
vloc := buffer.Loc{X: 0, Y: 0}
|
||||
if softwrap {
|
||||
// the start line may be partially out of the current window
|
||||
vloc.Y = -w.StartLine.Row
|
||||
}
|
||||
|
||||
// this represents the current draw position in the buffer (char positions)
|
||||
bloc := buffer.Loc{X: -1, Y: w.StartLine}
|
||||
bloc := buffer.Loc{X: -1, Y: w.StartLine.Line}
|
||||
|
||||
cursors := b.GetCursors()
|
||||
|
||||
curStyle := config.DefStyle
|
||||
for vloc.Y = 0; vloc.Y < bufHeight; vloc.Y++ {
|
||||
for ; vloc.Y < bufHeight; vloc.Y++ {
|
||||
vloc.X = 0
|
||||
|
||||
currentLine := false
|
||||
@@ -496,16 +488,28 @@ func (w *BufWindow) displayBuffer() {
|
||||
s = curNumStyle
|
||||
}
|
||||
|
||||
if hasMessage {
|
||||
w.drawGutter(&vloc, &bloc)
|
||||
}
|
||||
if vloc.Y >= 0 {
|
||||
if hasMessage {
|
||||
w.drawGutter(&vloc, &bloc)
|
||||
}
|
||||
|
||||
if b.Settings["diffgutter"].(bool) {
|
||||
w.drawDiffGutter(s, false, &vloc, &bloc)
|
||||
}
|
||||
if b.Settings["diffgutter"].(bool) {
|
||||
w.drawDiffGutter(s, false, &vloc, &bloc)
|
||||
}
|
||||
|
||||
if b.Settings["ruler"].(bool) {
|
||||
w.drawLineNum(s, false, maxLineNumLength, &vloc, &bloc)
|
||||
if b.Settings["ruler"].(bool) {
|
||||
w.drawLineNum(s, false, maxLineNumLength, &vloc, &bloc)
|
||||
}
|
||||
} else {
|
||||
if hasMessage {
|
||||
vloc.X += 2
|
||||
}
|
||||
if b.Settings["diffgutter"].(bool) {
|
||||
vloc.X++
|
||||
}
|
||||
if b.Settings["ruler"].(bool) {
|
||||
vloc.X += maxLineNumLength + 1
|
||||
}
|
||||
}
|
||||
|
||||
w.gutterOffset = vloc.X
|
||||
@@ -517,7 +521,7 @@ func (w *BufWindow) displayBuffer() {
|
||||
bloc.X = bslice
|
||||
|
||||
draw := func(r rune, combc []rune, style tcell.Style, showcursor bool) {
|
||||
if nColsBeforeStart <= 0 {
|
||||
if nColsBeforeStart <= 0 && vloc.Y >= 0 {
|
||||
_, origBg, _ := style.Decompose()
|
||||
_, defBg, _ := config.DefStyle.Decompose()
|
||||
|
||||
@@ -590,6 +594,8 @@ func (w *BufWindow) displayBuffer() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if nColsBeforeStart <= 0 {
|
||||
vloc.X++
|
||||
}
|
||||
nColsBeforeStart--
|
||||
@@ -735,7 +741,7 @@ func (w *BufWindow) displayScrollBar() {
|
||||
if barsize < 1 {
|
||||
barsize = 1
|
||||
}
|
||||
barstart := w.Y + int(float64(w.StartLine)/float64(w.Buf.LinesNum())*float64(w.Height))
|
||||
barstart := w.Y + int(float64(w.StartLine.Line)/float64(w.Buf.LinesNum())*float64(w.Height))
|
||||
|
||||
scrollBarStyle := config.DefStyle.Reverse(true)
|
||||
if style, ok := config.Colorscheme["scrollbar"]; ok {
|
||||
|
||||
@@ -72,6 +72,10 @@ func (i *InfoWindow) LocFromVisual(vloc buffer.Loc) buffer.Loc {
|
||||
return buffer.Loc{c.GetCharPosInLine(l, vloc.X-n), 0}
|
||||
}
|
||||
|
||||
func (i *InfoWindow) Scroll(s SLoc, n int) SLoc { return s }
|
||||
func (i *InfoWindow) Diff(s1, s2 SLoc) int { return 0 }
|
||||
func (i *InfoWindow) SLocFromLoc(loc buffer.Loc) SLoc { return SLoc{0, 0} }
|
||||
|
||||
func (i *InfoWindow) Clear() {
|
||||
for x := 0; x < i.Width; x++ {
|
||||
screen.SetContent(x, i.Y, ' ', nil, i.defStyle())
|
||||
|
||||
149
internal/display/softwrap.go
Normal file
149
internal/display/softwrap.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package display
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
// SLoc represents a vertical scrolling location, i.e. a location of a visual line
|
||||
// in the buffer. When softwrap is enabled, a buffer line may be displayed as
|
||||
// multiple visual lines (rows). So SLoc stores a number of a line in the buffer
|
||||
// and a number of a row within this line.
|
||||
type SLoc struct {
|
||||
Line, Row int
|
||||
}
|
||||
|
||||
// LessThan returns true if s is less b
|
||||
func (s SLoc) LessThan(b SLoc) bool {
|
||||
if s.Line < b.Line {
|
||||
return true
|
||||
}
|
||||
return s.Line == b.Line && s.Row < b.Row
|
||||
}
|
||||
|
||||
// GreaterThan returns true if s is bigger than b
|
||||
func (s SLoc) GreaterThan(b SLoc) bool {
|
||||
if s.Line > b.Line {
|
||||
return true
|
||||
}
|
||||
return s.Line == b.Line && s.Row > b.Row
|
||||
}
|
||||
|
||||
type SoftWrap interface {
|
||||
Scroll(s SLoc, n int) SLoc
|
||||
Diff(s1, s2 SLoc) int
|
||||
SLocFromLoc(loc buffer.Loc) SLoc
|
||||
}
|
||||
|
||||
func (w *BufWindow) getRow(loc buffer.Loc) int {
|
||||
width := w.Width - w.gutterOffset
|
||||
if w.Buf.Settings["scrollbar"].(bool) && w.Buf.LinesNum() > w.Height {
|
||||
width--
|
||||
}
|
||||
if width <= 0 {
|
||||
return 0
|
||||
}
|
||||
// TODO: this doesn't work quite correctly if there is an incomplete tab
|
||||
// or wide character at the end of a row. See also issue #1979
|
||||
x := util.StringWidth(w.Buf.LineBytes(loc.Y), loc.X, util.IntOpt(w.Buf.Settings["tabsize"]))
|
||||
return x / width
|
||||
}
|
||||
|
||||
func (w *BufWindow) getRowCount(line int) int {
|
||||
return w.getRow(buffer.Loc{X: util.CharacterCount(w.Buf.LineBytes(line)), Y: line}) + 1
|
||||
}
|
||||
|
||||
func (w *BufWindow) scrollUp(s SLoc, n int) SLoc {
|
||||
for n > 0 {
|
||||
if n <= s.Row {
|
||||
s.Row -= n
|
||||
n = 0
|
||||
} else if s.Line > 0 {
|
||||
s.Line--
|
||||
n -= s.Row + 1
|
||||
s.Row = w.getRowCount(s.Line) - 1
|
||||
} else {
|
||||
s.Row = 0
|
||||
break
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (w *BufWindow) scrollDown(s SLoc, n int) SLoc {
|
||||
for n > 0 {
|
||||
rc := w.getRowCount(s.Line)
|
||||
if n < rc-s.Row {
|
||||
s.Row += n
|
||||
n = 0
|
||||
} else if s.Line < w.Buf.LinesNum()-1 {
|
||||
s.Line++
|
||||
n -= rc - s.Row
|
||||
s.Row = 0
|
||||
} else {
|
||||
s.Row = rc - 1
|
||||
break
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (w *BufWindow) scroll(s SLoc, n int) SLoc {
|
||||
if n < 0 {
|
||||
return w.scrollUp(s, -n)
|
||||
}
|
||||
return w.scrollDown(s, n)
|
||||
}
|
||||
|
||||
func (w *BufWindow) diff(s1, s2 SLoc) int {
|
||||
n := 0
|
||||
for s1.LessThan(s2) {
|
||||
if s1.Line < s2.Line {
|
||||
n += w.getRowCount(s1.Line) - s1.Row
|
||||
s1.Line++
|
||||
s1.Row = 0
|
||||
} else {
|
||||
n += s2.Row - s1.Row
|
||||
s1.Row = s2.Row
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Scroll returns the location which is n visual lines below the location s
|
||||
// i.e. the result of scrolling n lines down. n can be negative,
|
||||
// which means scrolling up. The returned location is guaranteed to be
|
||||
// within the buffer boundaries.
|
||||
func (w *BufWindow) Scroll(s SLoc, n int) SLoc {
|
||||
if !w.Buf.Settings["softwrap"].(bool) {
|
||||
s.Line += n
|
||||
if s.Line < 0 {
|
||||
s.Line = 0
|
||||
}
|
||||
if s.Line > w.Buf.LinesNum()-1 {
|
||||
s.Line = w.Buf.LinesNum() - 1
|
||||
}
|
||||
return s
|
||||
}
|
||||
return w.scroll(s, n)
|
||||
}
|
||||
|
||||
// Diff returns the difference (the vertical distance) between two SLocs.
|
||||
func (w *BufWindow) Diff(s1, s2 SLoc) int {
|
||||
if !w.Buf.Settings["softwrap"].(bool) {
|
||||
return s2.Line - s1.Line
|
||||
}
|
||||
if s1.GreaterThan(s2) {
|
||||
return -w.diff(s2, s1)
|
||||
}
|
||||
return w.diff(s1, s2)
|
||||
}
|
||||
|
||||
// SLocFromLoc takes a position in the buffer and returns the location
|
||||
// of the visual line containing this position.
|
||||
func (w *BufWindow) SLocFromLoc(loc buffer.Loc) SLoc {
|
||||
if !w.Buf.Settings["softwrap"].(bool) {
|
||||
return SLoc{loc.Y, 0}
|
||||
}
|
||||
return SLoc{loc.Y, w.getRow(loc)}
|
||||
}
|
||||
@@ -8,10 +8,13 @@ type View struct {
|
||||
X, Y int // X,Y location of the view
|
||||
Width, Height int // Width and height of the view
|
||||
|
||||
// Start line and start column of the view (vertical/horizontal scroll)
|
||||
// Start line of the view (for vertical scroll)
|
||||
StartLine SLoc
|
||||
|
||||
// Start column of the view (for horizontal scroll)
|
||||
// note that since the starting column of every line is different if the view
|
||||
// is scrolled, StartCol is a visual index (will be the same for every line)
|
||||
StartLine, StartCol int
|
||||
StartCol int
|
||||
}
|
||||
|
||||
type Window interface {
|
||||
@@ -28,5 +31,6 @@ type Window interface {
|
||||
|
||||
type BWindow interface {
|
||||
Window
|
||||
SoftWrap
|
||||
SetBuffer(b *buffer.Buffer)
|
||||
}
|
||||
|
||||
@@ -259,6 +259,7 @@ The packages and functions are listed below (in Go type signatures):
|
||||
- `MTError` error message.
|
||||
|
||||
- `Loc(x, y int) Loc`: creates a new location struct.
|
||||
- `SLoc(line, row int) display.SLoc`: creates a new scrolling location struct.
|
||||
|
||||
- `BTDefault`: default buffer type.
|
||||
- `BTLog`: log buffer type.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
filetype: patch
|
||||
|
||||
detect:
|
||||
detect:
|
||||
filename: "\\.(patch|diff)$"
|
||||
header: "^diff"
|
||||
|
||||
rules:
|
||||
- brightgreen: "^\\+.*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
filetype: perl6
|
||||
filetype: raku
|
||||
|
||||
detect:
|
||||
filename: "(\\.p6$|\\.pl6$|\\.pm6$)"
|
||||
filename: "(\\.p6$|\\.pl6$|\\.pm6$|\\.raku$|\\.rakumod$|\\.rakudoc$)"
|
||||
|
||||
rules:
|
||||
- type: "\\b(accept|alarm|atan2|bin(d|mode)|c(aller|h(dir|mod|op|own|root)|lose(dir)?|onnect|os|rypt)|d(bm(close|open)|efined|elete|ie|o|ump)|e(ach|of|val|x(ec|ists|it|p))|f(cntl|ileno|lock|ork)|get(c|login|peername|pgrp|ppid|priority|pwnam|(host|net|proto|serv)byname|pwuid|grgid|(host|net)byaddr|protobynumber|servbyport)|([gs]et|end)(pw|gr|host|net|proto|serv)ent|getsock(name|opt)|gmtime|goto|grep|hex|index|int|ioctl|join|keys|kill|last|length|link|listen|local(time)?|log|lstat|m|mkdir|msg(ctl|get|snd|rcv)|next|oct|open(dir)?|ord|pack|pipe|pop|printf?|push|q|qq|qx|rand|re(ad(dir|link)?|cv|do|name|quire|set|turn|verse|winddir)|rindex|rmdir|s|scalar|seek|seekdir|se(lect|mctl|mget|mop|nd|tpgrp|tpriority|tsockopt)|shift|shm(ctl|get|read|write)|shutdown|sin|sleep|socket(pair)?|sort|spli(ce|t)|sprintf|sqrt|srand|stat|study|substr|symlink|sys(call|read|tem|write)|tell(dir)?|time|tr|y|truncate|umask|un(def|link|pack|shift)|utime|values|vec|wait(pid)?|wantarray|warn|write)\\b"
|
||||
Reference in New Issue
Block a user