diff --git a/cmd/micro/actions.go b/cmd/micro/actions.go index 732459b0..2a6b126e 100644 --- a/cmd/micro/actions.go +++ b/cmd/micro/actions.go @@ -62,54 +62,71 @@ func (v *View) MousePress(usePlugin bool, e *tcell.EventMouse) bool { return false } - x, y := e.Position() - x -= v.lineNumOffset - v.leftCol + v.x - y += v.Topline - v.y + rawX, rawY := e.Position() + + x := rawX - v.lineNumOffset - v.leftCol + v.x + y := rawY + v.Topline - v.y // This is usually bound to left click - v.MoveToMouseClick(x, y) + if !(rawX == v.x+v.Width || rawY == v.y+v.Height || v.resizeX || v.resizeY) { + v.MoveToMouseClick(x, y) + } if v.mouseReleased { - if len(v.Buf.cursors) > 1 { - for i := 1; i < len(v.Buf.cursors); i++ { - v.Buf.cursors[i] = nil - } - v.Buf.cursors = v.Buf.cursors[:1] - v.Buf.UpdateCursors() - v.Cursor.ResetSelection() - v.Relocate() - } - if time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold { - if v.doubleClick { - // Triple click - v.lastClickTime = time.Now() - - v.tripleClick = true - v.doubleClick = false - - v.Cursor.SelectLine() - v.Cursor.CopySelection("primary") - } else { - // Double click - v.lastClickTime = time.Now() - - v.doubleClick = true - v.tripleClick = false - - v.Cursor.SelectWord() - v.Cursor.CopySelection("primary") - } + if rawX == v.x+v.Width { + v.resizeX = true + } else if rawY == v.y+v.Height { + v.resizeY = true } else { - v.doubleClick = false - v.tripleClick = false - v.lastClickTime = time.Now() + if len(v.Buf.cursors) > 1 { + for i := 1; i < len(v.Buf.cursors); i++ { + v.Buf.cursors[i] = nil + } + v.Buf.cursors = v.Buf.cursors[:1] + v.Buf.UpdateCursors() + v.Cursor.ResetSelection() + v.Relocate() + } + if time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold { + if v.doubleClick { + // Triple click + v.lastClickTime = time.Now() - v.Cursor.OrigSelection[0] = v.Cursor.Loc - v.Cursor.CurSelection[0] = v.Cursor.Loc - v.Cursor.CurSelection[1] = v.Cursor.Loc + v.tripleClick = true + v.doubleClick = false + + v.Cursor.SelectLine() + v.Cursor.CopySelection("primary") + } else { + // Double click + v.lastClickTime = time.Now() + + v.doubleClick = true + v.tripleClick = false + + v.Cursor.SelectWord() + v.Cursor.CopySelection("primary") + } + } else { + v.doubleClick = false + v.tripleClick = false + v.lastClickTime = time.Now() + + v.Cursor.OrigSelection[0] = v.Cursor.Loc + v.Cursor.CurSelection[0] = v.Cursor.Loc + v.Cursor.CurSelection[1] = v.Cursor.Loc + } } v.mouseReleased = false } else if !v.mouseReleased { - if v.tripleClick { + if v.resizeX { + v.Width = rawX - v.x + v.LockWidth = true + v.splitNode.parent.ResizeSplits() + } else if v.resizeY { + v.Height = rawY - v.y + v.LockHeight = true + v.splitNode.parent.ResizeSplits() + } else if v.tripleClick { v.Cursor.AddLineToSelection() } else if v.doubleClick { v.Cursor.AddWordToSelection() diff --git a/cmd/micro/cellview.go b/cmd/micro/cellview.go index 2cab7a08..36ab5c03 100644 --- a/cmd/micro/cellview.go +++ b/cmd/micro/cellview.go @@ -112,6 +112,9 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) { // We'll either draw the length of the line, or the width of the screen // whichever is smaller lineLength := min(StringWidth(lineStr, tabsize), width) + if lineLength < 0 { + return + } c.lines = append(c.lines, make([]*Char, lineLength)) wrap := false @@ -133,38 +136,50 @@ func (c *CellView) Draw(buf *Buffer, top, height, left, width int) { char := line[colN] if viewCol >= 0 { - c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle, 1} + if viewCol < len(c.lines[viewLine]) { + c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, char, curStyle, 1} + } } if char == '\t' { charWidth := tabsize - (viewCol+left)%tabsize if viewCol >= 0 { - c.lines[viewLine][viewCol].drawChar = indentchar - c.lines[viewLine][viewCol].width = charWidth + if viewCol < len(c.lines[viewLine]) { + c.lines[viewLine][viewCol].drawChar = indentchar + c.lines[viewLine][viewCol].width = charWidth + } indentStyle := curStyle if group, ok := colorscheme["indent-char"]; ok { indentStyle = group } - c.lines[viewLine][viewCol].style = indentStyle + if viewCol < len(c.lines[viewLine]) { + c.lines[viewLine][viewCol].style = indentStyle + } } for i := 1; i < charWidth; i++ { viewCol++ if viewCol >= 0 && viewCol < lineLength { - c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1} + if viewCol < len(c.lines[viewLine]) { + c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1} + } } } viewCol++ } else if runewidth.RuneWidth(char) > 1 { charWidth := runewidth.RuneWidth(char) if viewCol >= 0 { - c.lines[viewLine][viewCol].width = charWidth + if viewCol < len(c.lines[viewLine]) { + c.lines[viewLine][viewCol].width = charWidth + } } for i := 1; i < charWidth; i++ { viewCol++ if viewCol >= 0 && viewCol < lineLength { - c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1} + if viewCol < len(c.lines[viewLine]) { + c.lines[viewLine][viewCol] = &Char{Loc{viewCol, viewLine}, Loc{colN, lineN}, char, ' ', curStyle, 1} + } } } viewCol++ diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index 46f9f7cf..980fadaf 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -476,7 +476,7 @@ func main() { // We loop through each view in the current tab and make sure the current view // is the one being clicked in for _, v := range tabs[curTab].views { - if x >= v.x && x < v.x+v.Width && y >= v.y && y < v.y+v.Height { + if x > v.x && x <= v.x+v.Width && y > v.y && y <= v.y+v.Height { tabs[curTab].CurView = v.Num } } diff --git a/cmd/micro/view.go b/cmd/micro/view.go index 4560c30e..a5b8c115 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -91,6 +91,9 @@ type View struct { cellview *CellView splitNode *LeafNode + + resizeX bool + resizeY bool } // NewView returns a new fullscreen view @@ -599,21 +602,26 @@ func (v *View) HandleEvent(event tcell.Event) { // Mouse event with no click if !v.mouseReleased { // Mouse was just released + if v.resizeX || v.resizeY { + v.resizeX = false + v.resizeY = false + } else { - x, y := e.Position() - x -= v.lineNumOffset - v.leftCol + v.x - y += v.Topline - v.y + x, y := e.Position() + x -= v.lineNumOffset - v.leftCol + v.x + y += v.Topline - v.y - // Relocating here isn't really necessary because the cursor will - // be in the right place from the last mouse event - // However, if we are running in a terminal that doesn't support mouse motion - // events, this still allows the user to make selections, except only after they - // release the mouse + // Relocating here isn't really necessary because the cursor will + // be in the right place from the last mouse event + // However, if we are running in a terminal that doesn't support mouse motion + // events, this still allows the user to make selections, except only after they + // release the mouse - if !v.doubleClick && !v.tripleClick { - v.MoveToMouseClick(x, y) - v.Cursor.SetSelectionEnd(v.Cursor.Loc) - v.Cursor.CopySelection("primary") + if !v.doubleClick && !v.tripleClick { + v.MoveToMouseClick(x, y) + v.Cursor.SetSelectionEnd(v.Cursor.Loc) + v.Cursor.CopySelection("primary") + } } v.mouseReleased = true }