mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-30 06:37:14 +09:00
More actions and view relocation
This commit is contained in:
@@ -2,8 +2,10 @@ package action
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/zyedidia/clipboard"
|
||||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
"github.com/zyedidia/micro/cmd/micro/screen"
|
"github.com/zyedidia/micro/cmd/micro/screen"
|
||||||
"github.com/zyedidia/micro/cmd/micro/util"
|
"github.com/zyedidia/micro/cmd/micro/util"
|
||||||
@@ -18,11 +20,21 @@ func (h *BufHandler) MousePress(e *tcell.EventMouse) bool {
|
|||||||
|
|
||||||
// ScrollUpAction scrolls the view up
|
// ScrollUpAction scrolls the view up
|
||||||
func (h *BufHandler) ScrollUpAction() bool {
|
func (h *BufHandler) ScrollUpAction() bool {
|
||||||
|
b := h.Buf
|
||||||
|
sspeed := b.Settings["scrollspeed"].(int)
|
||||||
|
if h.Win.StartLine >= sspeed {
|
||||||
|
h.Win.StartLine -= sspeed
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScrollDownAction scrolls the view up
|
// ScrollDownAction scrolls the view up
|
||||||
func (h *BufHandler) ScrollDownAction() bool {
|
func (h *BufHandler) ScrollDownAction() bool {
|
||||||
|
b := h.Buf
|
||||||
|
sspeed := b.Settings["scrollspeed"].(int)
|
||||||
|
if h.Win.StartLine <= h.Buf.LinesNum()-1-sspeed {
|
||||||
|
h.Win.StartLine += sspeed
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,12 +370,12 @@ func (h *BufHandler) IndentSelection() bool {
|
|||||||
tabsize := int(h.Buf.Settings["tabsize"].(float64))
|
tabsize := int(h.Buf.Settings["tabsize"].(float64))
|
||||||
indentsize := len(h.Buf.IndentString(tabsize))
|
indentsize := len(h.Buf.IndentString(tabsize))
|
||||||
for y := startY; y <= endY; y++ {
|
for y := startY; y <= endY; y++ {
|
||||||
h.Buf.Insert(buffer.Loc{0, y}, h.Buf.IndentString(tabsize))
|
h.Buf.Insert(buffer.Loc{X: 0, Y: y}, h.Buf.IndentString(tabsize))
|
||||||
if y == startY && start.X > 0 {
|
if y == startY && start.X > 0 {
|
||||||
h.Cursor.SetSelectionStart(start.Move(indentsize, h.Buf))
|
h.Cursor.SetSelectionStart(start.Move(indentsize, h.Buf))
|
||||||
}
|
}
|
||||||
if y == endY {
|
if y == endY {
|
||||||
h.Cursor.SetSelectionEnd(buffer.Loc{endX + indentsize + 1, endY})
|
h.Cursor.SetSelectionEnd(buffer.Loc{X: endX + indentsize + 1, Y: endY})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.Cursor.Relocate()
|
h.Cursor.Relocate()
|
||||||
@@ -371,21 +383,58 @@ func (h *BufHandler) IndentSelection() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OutdentLine moves the current line back one indentation
|
// OutdentLine moves the current line back one indentation
|
||||||
func (h *BufHandler) OutdentLine() bool {
|
func (h *BufHandler) OutdentLine() bool {
|
||||||
|
if h.Cursor.HasSelection() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for x := 0; x < len(h.Buf.IndentString(h.Buf.Settings["tabsize"].(int))); x++ {
|
||||||
|
if len(util.GetLeadingWhitespace(h.Buf.LineBytes(h.Cursor.Y))) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
h.Buf.Remove(buffer.Loc{X: 0, Y: h.Cursor.Y}, buffer.Loc{X: 1, Y: h.Cursor.Y})
|
||||||
|
}
|
||||||
|
h.Cursor.Relocate()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// OutdentSelection takes the current selection and moves it back one indent level
|
// OutdentSelection takes the current selection and moves it back one indent level
|
||||||
func (h *BufHandler) OutdentSelection() bool {
|
func (h *BufHandler) OutdentSelection() bool {
|
||||||
return true
|
if h.Cursor.HasSelection() {
|
||||||
|
start := h.Cursor.CurSelection[0]
|
||||||
|
end := h.Cursor.CurSelection[1]
|
||||||
|
if end.Y < start.Y {
|
||||||
|
start, end = end, start
|
||||||
|
h.Cursor.SetSelectionStart(start)
|
||||||
|
h.Cursor.SetSelectionEnd(end)
|
||||||
|
}
|
||||||
|
|
||||||
|
startY := start.Y
|
||||||
|
endY := end.Move(-1, h.Buf).Y
|
||||||
|
for y := startY; y <= endY; y++ {
|
||||||
|
for x := 0; x < len(h.Buf.IndentString(h.Buf.Settings["tabsize"].(int))); x++ {
|
||||||
|
if len(util.GetLeadingWhitespace(h.Buf.LineBytes(y))) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
h.Buf.Remove(buffer.Loc{X: 0, Y: y}, buffer.Loc{X: 1, Y: y})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h.Cursor.Relocate()
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertTab inserts a tab or spaces
|
// InsertTab inserts a tab or spaces
|
||||||
func (h *BufHandler) InsertTab() bool {
|
func (h *BufHandler) InsertTab() bool {
|
||||||
|
indent := h.Buf.IndentString(h.Buf.Settings["tabsize"].(int))
|
||||||
|
tabBytes := len(indent)
|
||||||
|
bytesUntilIndent := tabBytes - (h.Cursor.GetVisualX() % tabBytes)
|
||||||
|
h.Buf.Insert(h.Cursor.Loc, indent[:bytesUntilIndent])
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,36 +471,91 @@ func (h *BufHandler) FindPrevious() bool {
|
|||||||
|
|
||||||
// Undo undoes the last action
|
// Undo undoes the last action
|
||||||
func (h *BufHandler) Undo() bool {
|
func (h *BufHandler) Undo() bool {
|
||||||
|
// TODO: clear cursors and message
|
||||||
|
h.Buf.Undo()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redo redoes the last action
|
// Redo redoes the last action
|
||||||
func (h *BufHandler) Redo() bool {
|
func (h *BufHandler) Redo() bool {
|
||||||
|
// TODO: clear cursors and message
|
||||||
|
h.Buf.Redo()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the selection to the system clipboard
|
// Copy the selection to the system clipboard
|
||||||
func (h *BufHandler) Copy() bool {
|
func (h *BufHandler) Copy() bool {
|
||||||
|
if h.Cursor.HasSelection() {
|
||||||
|
h.Cursor.CopySelection("clipboard")
|
||||||
|
h.freshClip = true
|
||||||
|
// TODO: message
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// CutLine cuts the current line to the clipboard
|
// CutLine cuts the current line to the clipboard
|
||||||
func (h *BufHandler) CutLine() bool {
|
func (h *BufHandler) CutLine() bool {
|
||||||
|
h.Cursor.SelectLine()
|
||||||
|
if !h.Cursor.HasSelection() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if h.freshClip == true {
|
||||||
|
if h.Cursor.HasSelection() {
|
||||||
|
if clip, err := clipboard.ReadAll("clipboard"); err != nil {
|
||||||
|
// messenger.Error(err)
|
||||||
|
} else {
|
||||||
|
clipboard.WriteAll(clip+string(h.Cursor.GetSelection()), "clipboard")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if time.Since(h.lastCutTime)/time.Second > 10*time.Second || h.freshClip == false {
|
||||||
|
h.Copy()
|
||||||
|
}
|
||||||
|
h.freshClip = true
|
||||||
|
h.lastCutTime = time.Now()
|
||||||
|
h.Cursor.DeleteSelection()
|
||||||
|
h.Cursor.ResetSelection()
|
||||||
|
// messenger.Message("Cut line")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cut the selection to the system clipboard
|
// Cut the selection to the system clipboard
|
||||||
func (h *BufHandler) Cut() bool {
|
func (h *BufHandler) Cut() bool {
|
||||||
return true
|
if h.Cursor.HasSelection() {
|
||||||
|
h.Cursor.CopySelection("clipboard")
|
||||||
|
h.Cursor.DeleteSelection()
|
||||||
|
h.Cursor.ResetSelection()
|
||||||
|
h.freshClip = true
|
||||||
|
// messenger.Message("Cut selection")
|
||||||
|
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return h.CutLine()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DuplicateLine duplicates the current line or selection
|
// DuplicateLine duplicates the current line or selection
|
||||||
func (h *BufHandler) DuplicateLine() bool {
|
func (h *BufHandler) DuplicateLine() bool {
|
||||||
|
if h.Cursor.HasSelection() {
|
||||||
|
h.Buf.Insert(h.Cursor.CurSelection[1], string(h.Cursor.GetSelection()))
|
||||||
|
} else {
|
||||||
|
h.Cursor.End()
|
||||||
|
h.Buf.Insert(h.Cursor.Loc, "\n"+string(h.Buf.LineBytes(h.Cursor.Y)))
|
||||||
|
// h.Cursor.Right()
|
||||||
|
}
|
||||||
|
|
||||||
|
// messenger.Message("Duplicated line")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteLine deletes the current line
|
// DeleteLine deletes the current line
|
||||||
func (h *BufHandler) DeleteLine() bool {
|
func (h *BufHandler) DeleteLine() bool {
|
||||||
|
h.Cursor.SelectLine()
|
||||||
|
if !h.Cursor.HasSelection() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
h.Cursor.DeleteSelection()
|
||||||
|
h.Cursor.ResetSelection()
|
||||||
|
// messenger.Message("Deleted line")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,6 +588,11 @@ func (h *BufHandler) JumpToMatchingBrace() bool {
|
|||||||
|
|
||||||
// SelectAll selects the entire buffer
|
// SelectAll selects the entire buffer
|
||||||
func (h *BufHandler) SelectAll() bool {
|
func (h *BufHandler) SelectAll() bool {
|
||||||
|
h.Cursor.SetSelectionStart(h.Buf.Start())
|
||||||
|
h.Cursor.SetSelectionEnd(h.Buf.End())
|
||||||
|
// Put the cursor at the beginning
|
||||||
|
h.Cursor.X = 0
|
||||||
|
h.Cursor.Y = 0
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,11 +603,18 @@ func (h *BufHandler) OpenFile() bool {
|
|||||||
|
|
||||||
// Start moves the viewport to the start of the buffer
|
// Start moves the viewport to the start of the buffer
|
||||||
func (h *BufHandler) Start() bool {
|
func (h *BufHandler) Start() bool {
|
||||||
|
h.Win.StartLine = 0
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// End moves the viewport to the end of the buffer
|
// End moves the viewport to the end of the buffer
|
||||||
func (h *BufHandler) End() bool {
|
func (h *BufHandler) End() bool {
|
||||||
|
// TODO: softwrap problems?
|
||||||
|
if h.Win.Height > h.Buf.LinesNum() {
|
||||||
|
h.Win.StartLine = 0
|
||||||
|
} else {
|
||||||
|
h.StartLine = h.Buf.LinesNum() - h.Win.Height
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,6 +660,13 @@ func (h *BufHandler) HalfPageDown() bool {
|
|||||||
|
|
||||||
// ToggleRuler turns line numbers off and on
|
// ToggleRuler turns line numbers off and on
|
||||||
func (h *BufHandler) ToggleRuler() bool {
|
func (h *BufHandler) ToggleRuler() bool {
|
||||||
|
if !h.Buf.Settings["ruler"].(bool) {
|
||||||
|
h.Buf.Settings["ruler"] = true
|
||||||
|
// messenger.Message("Enabled ruler")
|
||||||
|
} else {
|
||||||
|
h.Buf.Settings["ruler"] = false
|
||||||
|
// messenger.Message("Disabled ruler")
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
|
"github.com/zyedidia/micro/cmd/micro/display"
|
||||||
"github.com/zyedidia/micro/cmd/micro/util"
|
"github.com/zyedidia/micro/cmd/micro/util"
|
||||||
"github.com/zyedidia/tcell"
|
"github.com/zyedidia/tcell"
|
||||||
)
|
)
|
||||||
@@ -46,6 +47,7 @@ func BufMapMouse(k MouseEvent, action string) {
|
|||||||
// visual positions for mouse clicks and scrolling
|
// visual positions for mouse clicks and scrolling
|
||||||
type BufHandler struct {
|
type BufHandler struct {
|
||||||
Buf *buffer.Buffer
|
Buf *buffer.Buffer
|
||||||
|
Win *display.BufWindow
|
||||||
|
|
||||||
cursors []*buffer.Cursor
|
cursors []*buffer.Cursor
|
||||||
Cursor *buffer.Cursor // the active cursor
|
Cursor *buffer.Cursor // the active cursor
|
||||||
@@ -81,9 +83,10 @@ type BufHandler struct {
|
|||||||
tripleClick bool
|
tripleClick bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBufHandler(buf *buffer.Buffer) *BufHandler {
|
func NewBufHandler(buf *buffer.Buffer, win *display.BufWindow) *BufHandler {
|
||||||
h := new(BufHandler)
|
h := new(BufHandler)
|
||||||
h.Buf = buf
|
h.Buf = buf
|
||||||
|
h.Win = win
|
||||||
|
|
||||||
h.cursors = []*buffer.Cursor{buffer.NewCursor(buf, buf.StartCursor)}
|
h.cursors = []*buffer.Cursor{buffer.NewCursor(buf, buf.StartCursor)}
|
||||||
h.Cursor = h.cursors[0]
|
h.Cursor = h.cursors[0]
|
||||||
@@ -117,7 +120,9 @@ func (h *BufHandler) HandleEvent(event tcell.Event) {
|
|||||||
|
|
||||||
func (h *BufHandler) DoKeyEvent(e KeyEvent) bool {
|
func (h *BufHandler) DoKeyEvent(e KeyEvent) bool {
|
||||||
if action, ok := BufKeyBindings[e]; ok {
|
if action, ok := BufKeyBindings[e]; ok {
|
||||||
action(h)
|
if action(h) {
|
||||||
|
h.Win.Relocate()
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@@ -125,7 +130,9 @@ func (h *BufHandler) DoKeyEvent(e KeyEvent) bool {
|
|||||||
|
|
||||||
func (h *BufHandler) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
|
func (h *BufHandler) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
|
||||||
if action, ok := BufMouseBindings[e]; ok {
|
if action, ok := BufMouseBindings[e]; ok {
|
||||||
action(h, te)
|
if action(h, te) {
|
||||||
|
h.Win.Relocate()
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/action"
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
"github.com/zyedidia/micro/cmd/micro/config"
|
"github.com/zyedidia/micro/cmd/micro/config"
|
||||||
"github.com/zyedidia/micro/cmd/micro/screen"
|
"github.com/zyedidia/micro/cmd/micro/screen"
|
||||||
@@ -84,12 +83,13 @@ func (s *StatusLine) Display() {
|
|||||||
option := name[4:]
|
option := name[4:]
|
||||||
return []byte(fmt.Sprint(s.FindOpt(string(option))))
|
return []byte(fmt.Sprint(s.FindOpt(string(option))))
|
||||||
} else if bytes.HasPrefix(name, []byte("bind")) {
|
} else if bytes.HasPrefix(name, []byte("bind")) {
|
||||||
binding := string(name[5:])
|
// binding := string(name[5:])
|
||||||
for k, v := range action.Bindings {
|
// TODO: search bindings
|
||||||
if v == binding {
|
// for k, v := range action.Bindings {
|
||||||
return []byte(k)
|
// if v == binding {
|
||||||
}
|
// return []byte(k)
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
return []byte("null")
|
return []byte("null")
|
||||||
} else {
|
} else {
|
||||||
return []byte(s.Info[string(name)](s.win.Buf))
|
return []byte(s.Info[string(name)](s.win.Buf))
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package display
|
package display
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@@ -37,12 +38,15 @@ type BufWindow struct {
|
|||||||
Buf *buffer.Buffer
|
Buf *buffer.Buffer
|
||||||
|
|
||||||
sline *StatusLine
|
sline *StatusLine
|
||||||
|
|
||||||
|
lineHeight []int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBufWindow creates a new window at a location in the screen with a width and height
|
// NewBufWindow creates a new window at a location in the screen with a width and height
|
||||||
func NewBufWindow(x, y, width, height int, buf *buffer.Buffer) *BufWindow {
|
func NewBufWindow(x, y, width, height int, buf *buffer.Buffer) *BufWindow {
|
||||||
w := new(BufWindow)
|
w := new(BufWindow)
|
||||||
w.X, w.Y, w.Width, w.Height, w.Buf = x, y, width, height, buf
|
w.X, w.Y, w.Width, w.Height, w.Buf = x, y, width, height, buf
|
||||||
|
w.lineHeight = make([]int, height)
|
||||||
|
|
||||||
w.sline = NewStatusLine(w)
|
w.sline = NewStatusLine(w)
|
||||||
|
|
||||||
@@ -58,6 +62,71 @@ 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 {
|
||||||
|
// b := w.Buf
|
||||||
|
|
||||||
|
// if !b.Settings["softwrap"].(bool) {
|
||||||
|
// return w.StartLine + w.Height
|
||||||
|
// }
|
||||||
|
|
||||||
|
prev := 0
|
||||||
|
for i, l := range w.lineHeight {
|
||||||
|
if l >= prev {
|
||||||
|
log.Println("lineHeight[", i, "] = ", l)
|
||||||
|
prev = l
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prev
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
height := w.Bottomline() + 1 - w.StartLine
|
||||||
|
log.Println("Height: ", 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
|
||||||
|
ret = true
|
||||||
|
} else if cy < w.StartLine {
|
||||||
|
w.StartLine = cy
|
||||||
|
ret = true
|
||||||
|
}
|
||||||
|
if cy > w.StartLine+height-1-scrollmargin && cy < b.LinesNum()-scrollmargin {
|
||||||
|
w.StartLine = cy - height + 1 + scrollmargin
|
||||||
|
ret = true
|
||||||
|
} else if cy >= b.LinesNum()-scrollmargin && cy >= height {
|
||||||
|
w.StartLine = b.LinesNum() - height
|
||||||
|
log.Println(w.StartLine)
|
||||||
|
ret = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: horizontal scroll
|
||||||
|
// if !b.Settings["softwrap"].(bool) {
|
||||||
|
// cx := activeC.GetVisualX()
|
||||||
|
// if cx < w.StartCol {
|
||||||
|
// w.StartCol = cx
|
||||||
|
// ret = true
|
||||||
|
// }
|
||||||
|
// if cx+v.lineNumOffset+1 > v.leftCol+v.Width {
|
||||||
|
// v.leftCol = cx - v.Width + v.lineNumOffset + 1
|
||||||
|
// ret = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxLineNumLength int, vloc *buffer.Loc, bloc *buffer.Loc) {
|
func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxLineNumLength int, vloc *buffer.Loc, bloc *buffer.Loc) {
|
||||||
lineNum := strconv.Itoa(bloc.Y + 1)
|
lineNum := strconv.Itoa(bloc.Y + 1)
|
||||||
|
|
||||||
@@ -173,6 +242,8 @@ func (w *BufWindow) displayBuffer() {
|
|||||||
nColsBeforeStart--
|
nColsBeforeStart--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.lineHeight[vloc.Y] = bloc.Y
|
||||||
|
|
||||||
totalwidth := bloc.X - nColsBeforeStart
|
totalwidth := bloc.X - nColsBeforeStart
|
||||||
for len(line) > 0 {
|
for len(line) > 0 {
|
||||||
if activeC.X == bloc.X && activeC.Y == bloc.Y {
|
if activeC.X == bloc.X && activeC.Y == bloc.Y {
|
||||||
@@ -217,6 +288,7 @@ func (w *BufWindow) displayBuffer() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
vloc.X = 0
|
vloc.X = 0
|
||||||
|
w.lineHeight[vloc.Y] = bloc.Y
|
||||||
// This will draw an empty line number because the current line is wrapped
|
// This will draw an empty line number because the current line is wrapped
|
||||||
w.drawLineNum(lineNumStyle, true, maxLineNumLength, &vloc, &bloc)
|
w.drawLineNum(lineNumStyle, true, maxLineNumLength, &vloc, &bloc)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ type EditPane struct {
|
|||||||
|
|
||||||
func NewBufEditPane(x, y, width, height int, b *buffer.Buffer) *EditPane {
|
func NewBufEditPane(x, y, width, height int, b *buffer.Buffer) *EditPane {
|
||||||
e := new(EditPane)
|
e := new(EditPane)
|
||||||
e.Window = display.NewBufWindow(x, y, width, height, b)
|
// TODO: can probably replace editpane with bufhandler entirely
|
||||||
e.Handler = action.NewBufHandler(b)
|
w := display.NewBufWindow(x, y, width, height, b)
|
||||||
|
e.Window = w
|
||||||
|
e.Handler = action.NewBufHandler(b, w)
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,3 +231,19 @@ func EscapePath(path string) string {
|
|||||||
path = filepath.ToSlash(path)
|
path = filepath.ToSlash(path)
|
||||||
return strings.Replace(path, "/", "%", -1)
|
return strings.Replace(path, "/", "%", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLeadingWhitespace returns the leading whitespace of the given byte array
|
||||||
|
func GetLeadingWhitespace(b []byte) []byte {
|
||||||
|
ws := []byte{}
|
||||||
|
for len(b) > 0 {
|
||||||
|
r, size := utf8.DecodeRune(b)
|
||||||
|
if r == ' ' || r == '\t' {
|
||||||
|
ws = append(ws, byte(r))
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
b = b[size:]
|
||||||
|
}
|
||||||
|
return ws
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user