X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Fview.go;h=c05d83344cea8d37dea84fd00ee24731720699c0;hb=55add69fa01025c37c8a6dbd2014ced24d612e09;hp=59cb3dac5109adfe7a83cf4a2e683fa8dc13bc40;hpb=edd25c68eebe27dd2e2e3b4a6dba378d218a5428;p=micro.git diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 59cb3dac..c05d8334 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -27,15 +27,10 @@ type View struct { Cursor *Cursor // The topmost line, used for vertical scrolling - Topline int - Bottomline int + Topline int // The leftmost column, used for horizontal scrolling leftCol int - // Percentage of the terminal window that this view takes up (from 0 to 100) - widthPercent int - heightPercent int - // Specifies whether or not this view holds a help buffer Type ViewType @@ -133,6 +128,7 @@ func NewViewWidthHeight(buf *Buffer, w, h int) *View { return v } +// ToggleStatusLine creates an extra row for the statusline if necessary func (v *View) ToggleStatusLine() { if v.Buf.Settings["statusline"].(bool) { v.height-- @@ -141,6 +137,7 @@ func (v *View) ToggleStatusLine() { } } +// ToggleTabbar creates an extra row for the tabbar if necessary func (v *View) ToggleTabbar() { if len(tabs) > 1 { if v.y == 0 { @@ -238,6 +235,7 @@ func (v *View) OpenBuffer(buf *Buffer) { v.lastClickTime = time.Time{} } +// Open opens the given file in the view func (v *View) Open(filename string) { home, _ := homedir.Dir() filename = strings.Replace(filename, "~", home, 1) @@ -285,10 +283,80 @@ func (v *View) VSplit(buf *Buffer) bool { return false } +// GetSoftWrapLocation gets the location of a visual click on the screen and converts it to col,line +func (v *View) GetSoftWrapLocation(vx, vy int) (int, int) { + if !v.Buf.Settings["softwrap"].(bool) { + vx = v.Cursor.GetCharPosInLine(vy, vx) + return vx, vy + } + + screenX, screenY := 0, v.Topline + for lineN := v.Topline; lineN < v.Bottomline(); lineN++ { + line := v.Buf.Line(lineN) + + colN := 0 + for _, ch := range line { + if screenX >= v.width-v.lineNumOffset { + screenX = 0 + screenY++ + } + + if screenX == vx && screenY == vy { + return colN, lineN + } + + if ch == '\t' { + screenX += int(v.Buf.Settings["tabsize"].(float64)) - 1 + } + + screenX++ + colN++ + } + if screenY == vy { + return colN, lineN + } + screenX = 0 + screenY++ + } + + return 0, 0 +} + +func (v *View) Bottomline() int { + screenX, screenY := 0, 0 + numLines := 0 + for lineN := v.Topline; lineN < v.Topline+v.height; lineN++ { + line := v.Buf.Line(lineN) + + colN := 0 + for _, ch := range line { + if screenX >= v.width-v.lineNumOffset { + screenX = 0 + screenY++ + } + + if ch == '\t' { + screenX += int(v.Buf.Settings["tabsize"].(float64)) - 1 + } + + screenX++ + colN++ + } + screenX = 0 + screenY++ + numLines++ + + if screenY >= v.height { + break + } + } + return numLines + v.Topline +} + // 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 func (v *View) Relocate() bool { - height := v.Bottomline - v.Topline + height := v.Bottomline() - v.Topline ret := false cy := v.Cursor.Y scrollmargin := int(v.Buf.Settings["scrollmargin"].(float64)) @@ -338,7 +406,8 @@ func (v *View) MoveToMouseClick(x, y int) { x = 0 } - x = v.Cursor.GetCharPosInLine(y, x) + x, y = v.GetSoftWrapLocation(x, y) + // x = v.Cursor.GetCharPosInLine(y, x) if x > Count(v.Buf.Line(y)) { x = Count(v.Buf.Line(y)) } @@ -412,18 +481,7 @@ func (v *View) HandleEvent(event tcell.Event) { break } - leadingWS := GetLeadingWhitespace(v.Buf.Line(v.Cursor.Y)) - - if v.Cursor.HasSelection() { - v.Cursor.DeleteSelection() - v.Cursor.ResetSelection() - } - clip := e.Text() - clip = strings.Replace(clip, "\n", "\n"+leadingWS, -1) - v.Buf.Insert(v.Cursor.Loc, clip) - v.Cursor.Loc = v.Cursor.Loc.Move(Count(clip), v.Buf) - v.freshClip = false - messenger.Message("Pasted clipboard") + v.paste(e.Text()) PostActionCall("Paste", v) case *tcell.EventMouse: @@ -625,7 +683,7 @@ func (v *View) DisplayView() { // This is the current line number of the buffer that we are drawing curLineN = viewLine + v.Topline - if screenY >= v.height { + if screenY-v.y >= v.height { break } @@ -738,7 +796,7 @@ func (v *View) DisplayView() { } if tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN && colN == v.Cursor.X { - v.DisplayCursor(screenX, screenY) + v.DisplayCursor(screenX-v.leftCol, screenY) } lineStyle := defStyle @@ -832,7 +890,7 @@ func (v *View) DisplayView() { // Here we are at a newline if tabs[curTab].curView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == curLineN && colN == v.Cursor.X { - v.DisplayCursor(screenX, screenY) + v.DisplayCursor(screenX-v.leftCol, screenY) } // The newline may be selected, in which case we should draw the selection style @@ -872,10 +930,6 @@ func (v *View) DisplayView() { } } } - v.Bottomline = curLineN - if !v.Buf.Settings["softwrap"].(bool) { - v.Bottomline++ - } } // DisplayCursor draws the current buffer's cursor to the screen