X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=cmd%2Fmicro%2Fview.go;h=b9c901bc4ccebdc8e774d1a086d7ba39c2065c87;hb=c3a73d63b8abe023798e44533e7da0b6c6ef9858;hp=fef81ed461e2c3bef44586bcc4ef0a2371b9301a;hpb=3270acdd000bd453a6c83671485f2e8913f3b2eb;p=micro.git diff --git a/cmd/micro/view.go b/cmd/micro/view.go index fef81ed4..b9c901bc 100644 --- a/cmd/micro/view.go +++ b/cmd/micro/view.go @@ -491,44 +491,51 @@ func (v *View) HandleEvent(event tcell.Event) { case *tcell.EventKey: // Check first if input is a key binding, if it is we 'eat' the input and don't insert a rune isBinding := false - if e.Key() != tcell.KeyRune || e.Modifiers() != 0 { - for key, actions := range bindings { - if e.Key() == key.keyCode { - if e.Key() == tcell.KeyRune { - if e.Rune() != key.r { - continue - } + for key, actions := range bindings { + if e.Key() == key.keyCode { + if e.Key() == tcell.KeyRune { + if e.Rune() != key.r { + continue } - if e.Modifiers() == key.modifiers { + } + if e.Modifiers() == key.modifiers { + for _, c := range v.Buf.cursors { + v.Cursor = c relocate = false isBinding = true - relocate = v.ExecuteActions(actions) - break + relocate = v.ExecuteActions(actions) || relocate } + v.Cursor = &v.Buf.Cursor + break } } } if !isBinding && e.Key() == tcell.KeyRune { // Check viewtype if readonly don't insert a rune (readonly help and log view etc.) if v.Type.readonly == false { - // Insert a character - if v.Cursor.HasSelection() { - v.Cursor.DeleteSelection() - v.Cursor.ResetSelection() - } - v.Buf.Insert(v.Cursor.Loc, string(e.Rune())) - v.Cursor.Right() + for _, c := range v.Buf.cursors { + v.Cursor = c - for pl := range loadedPlugins { - _, err := Call(pl+".onRune", string(e.Rune()), v) - if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") { - TermMessage(err) + // Insert a character + if v.Cursor.HasSelection() { + v.Cursor.DeleteSelection() + v.Cursor.ResetSelection() } - } + v.Buf.Insert(v.Cursor.Loc, string(e.Rune())) + v.Cursor.Right() - if recordingMacro { - curMacro = append(curMacro, e.Rune()) + for pl := range loadedPlugins { + _, err := Call(pl+".onRune", string(e.Rune()), v) + if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") { + TermMessage(err) + } + } + + if recordingMacro { + curMacro = append(curMacro, e.Rune()) + } } + v.Cursor = &v.Buf.Cursor } } case *tcell.EventPaste: @@ -538,14 +545,16 @@ func (v *View) HandleEvent(event tcell.Event) { break } - v.paste(e.Text()) + for _, c := range v.Buf.cursors { + v.Cursor = c + v.paste(e.Text()) + + } + v.Cursor = &v.Buf.Cursor PostActionCall("Paste", v) } case *tcell.EventMouse: - x, y := e.Position() - x -= v.lineNumOffset - v.leftCol + v.x - y += v.Topline - v.y // Don't relocate for mouse events relocate = false @@ -553,7 +562,11 @@ func (v *View) HandleEvent(event tcell.Event) { for key, actions := range bindings { if button == key.buttons { - relocate = v.ExecuteActions(actions) + for _, c := range v.Buf.cursors { + v.Cursor = c + relocate = v.ExecuteActions(actions) || relocate + } + v.Cursor = &v.Buf.Cursor } } @@ -571,6 +584,10 @@ func (v *View) HandleEvent(event tcell.Event) { if !v.mouseReleased { // Mouse was just released + 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 @@ -824,22 +841,20 @@ func (v *View) DisplayView() { } charLoc := char.realLoc - if v.Cursor.HasSelection() && - (charLoc.GreaterEqual(v.Cursor.CurSelection[0]) && charLoc.LessThan(v.Cursor.CurSelection[1]) || - charLoc.LessThan(v.Cursor.CurSelection[0]) && charLoc.GreaterEqual(v.Cursor.CurSelection[1])) { - // The current character is selected - lineStyle = defStyle.Reverse(true) - - if style, ok := colorscheme["selection"]; ok { - lineStyle = style + for _, c := range v.Buf.cursors { + v.Cursor = c + if v.Cursor.HasSelection() && + (charLoc.GreaterEqual(v.Cursor.CurSelection[0]) && charLoc.LessThan(v.Cursor.CurSelection[1]) || + charLoc.LessThan(v.Cursor.CurSelection[0]) && charLoc.GreaterEqual(v.Cursor.CurSelection[1])) { + // The current character is selected + lineStyle = defStyle.Reverse(true) + + if style, ok := colorscheme["selection"]; ok { + lineStyle = style + } } } - - if tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() && - v.Cursor.Y == char.realLoc.Y && v.Cursor.X == char.realLoc.X && !cursorSet { - screen.ShowCursor(xOffset+char.visualLoc.X, yOffset+char.visualLoc.Y) - cursorSet = true - } + v.Cursor = &v.Buf.Cursor if v.Buf.Settings["cursorline"].(bool) && tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() && v.Cursor.Y == realLineN { @@ -850,6 +865,16 @@ func (v *View) DisplayView() { screen.SetContent(xOffset+char.visualLoc.X, yOffset+char.visualLoc.Y, char.drawChar, nil, lineStyle) + for i, c := range v.Buf.cursors { + v.Cursor = c + if tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() && + v.Cursor.Y == char.realLoc.Y && v.Cursor.X == char.realLoc.X && (!cursorSet || i != 0) { + ShowMultiCursor(xOffset+char.visualLoc.X, yOffset+char.visualLoc.Y, i) + cursorSet = true + } + } + v.Cursor = &v.Buf.Cursor + lastChar = char } } @@ -860,19 +885,27 @@ func (v *View) DisplayView() { var cx, cy int if lastChar != nil { lastX = xOffset + lastChar.visualLoc.X + lastChar.width - if tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() && - v.Cursor.Y == lastChar.realLoc.Y && v.Cursor.X == lastChar.realLoc.X+1 { - screen.ShowCursor(lastX, yOffset+lastChar.visualLoc.Y) - cx, cy = lastX, yOffset+lastChar.visualLoc.Y + for i, c := range v.Buf.cursors { + v.Cursor = c + if tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() && + v.Cursor.Y == lastChar.realLoc.Y && v.Cursor.X == lastChar.realLoc.X+1 { + ShowMultiCursor(lastX, yOffset+lastChar.visualLoc.Y, i) + cx, cy = lastX, yOffset+lastChar.visualLoc.Y + } } - realLoc = Loc{lastChar.realLoc.X, realLineN} + v.Cursor = &v.Buf.Cursor + realLoc = Loc{lastChar.realLoc.X + 1, realLineN} visualLoc = Loc{lastX - xOffset, lastChar.visualLoc.Y} } else if len(line) == 0 { - if tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() && - v.Cursor.Y == realLineN { - screen.ShowCursor(xOffset, yOffset+visualLineN) - cx, cy = xOffset, yOffset+visualLineN + for i, c := range v.Buf.cursors { + v.Cursor = c + if tabs[curTab].CurView == v.Num && !v.Cursor.HasSelection() && + v.Cursor.Y == realLineN { + ShowMultiCursor(xOffset, yOffset+visualLineN, i) + cx, cy = xOffset, yOffset+visualLineN + } } + v.Cursor = &v.Buf.Cursor lastX = xOffset realLoc = Loc{0, realLineN} visualLoc = Loc{0, visualLineN} @@ -914,6 +947,18 @@ func (v *View) DisplayView() { } } +// ShowMultiCursor will display a cursor at a location +// If i == 0 then the terminal cursor will be used +// Otherwise a fake cursor will be drawn at the position +func ShowMultiCursor(x, y, i int) { + if i == 0 { + screen.ShowCursor(x, y) + } else { + r, _, _, _ := screen.GetContent(x, y) + screen.SetContent(x, y, r, nil, defStyle.Reverse(true)) + } +} + // Display renders the view, the cursor, and statusline func (v *View) Display() { if globalSettings["termtitle"].(bool) {