Fixed bug in key event handling between vim modes, where the same key event could get interpreted repeatedly. Also some rewrites/improvements of the code. Key mappings can now contain control characters and meta keys with a vim-like notation. There's a hard insert mode, which disables all of browsh's shortcuts and requires 4 hits on ESC to leave. There's a new multiple link opening feature analogous to vimium, that's still incomplete.
This commit is contained in:
parent
935983725c
commit
b2ade39223
|
@ -75,50 +75,64 @@ func setDefaults() {
|
|||
viper.SetDefault("tty.keys.next-tab", []string{"\u001c", "28", "2"})
|
||||
|
||||
// Vim commands
|
||||
vimCommandsBindings["gg"] = "scrollToTop"
|
||||
vimCommandsBindings["G"] = "scrollToBottom"
|
||||
vimCommandsBindings["j"] = "scrollDown"
|
||||
vimCommandsBindings["k"] = "scrollUp"
|
||||
vimCommandsBindings["h"] = "scrollLeft"
|
||||
vimCommandsBindings["l"] = "scrollRight"
|
||||
vimCommandsBindings["d"] = "scrollHalfPageDown"
|
||||
vimCommandsBindings["u"] = "scrollHalfPageUp"
|
||||
vimCommandsBindings["e"] = "editURL"
|
||||
vimCommandsBindings["ge"] = "editURL"
|
||||
vimCommandsBindings["gE"] = "editURLInNewTab"
|
||||
vimCommandsBindings["H"] = "historyBack"
|
||||
vimCommandsBindings["L"] = "historyForward"
|
||||
vimCommandsBindings["J"] = "prevTab"
|
||||
vimCommandsBindings["K"] = "nextTab"
|
||||
vimCommandsBindings["r"] = "reload"
|
||||
vimCommandsBindings["xx"] = "removeTab"
|
||||
vimCommandsBindings["X"] = "restoreTab"
|
||||
vimCommandsBindings["t"] = "newTab"
|
||||
vimCommandsBindings["/"] = "findMode"
|
||||
vimCommandsBindings["n"] = "findNext"
|
||||
vimCommandsBindings["N"] = "findPrevious"
|
||||
vimCommandsBindings["g0"] = "firstTab"
|
||||
vimCommandsBindings["g$"] = "lastTab"
|
||||
vimCommandsBindings["gu"] = "urlUp"
|
||||
vimCommandsBindings["gU"] = "urlRoot"
|
||||
vimCommandsBindings["<<"] = "moveTabLeft"
|
||||
vimCommandsBindings[">>"] = "moveTabRight"
|
||||
vimCommandsBindings["^"] = "previouslyVisitedTab"
|
||||
vimCommandsBindings["m"] = "makeMark"
|
||||
vimCommandsBindings["'"] = "gotoMark"
|
||||
vimCommandsBindings["i"] = "insertMode"
|
||||
vimCommandsBindings["yy"] = "copyURL"
|
||||
vimCommandsBindings["p"] = "openClipboardURL"
|
||||
vimCommandsBindings["P"] = "openClipboardURLInNewTab"
|
||||
vimCommandsBindings["gi"] = "focusFirstTextInput"
|
||||
vimCommandsBindings["f"] = "openLinkInCurrentTab"
|
||||
vimCommandsBindings["F"] = "openLinkInNewTab"
|
||||
vimCommandsBindings["yf"] = "copyLinkURL"
|
||||
vimCommandsBindings["[["] = "followLinkLabeledPrevious"
|
||||
vimCommandsBindings["]]"] = "followLinkLabeledNext"
|
||||
vimCommandsBindings["yt"] = "duplicateTab"
|
||||
vimCommandsBindings["v"] = "visualMode"
|
||||
vimCommandsBindings["?"] = "viewHelp"
|
||||
vimKeyMap["normal gg"] = "scrollToTop"
|
||||
vimKeyMap["normal G"] = "scrollToBottom"
|
||||
vimKeyMap["normal j"] = "scrollDown"
|
||||
vimKeyMap["normal k"] = "scrollUp"
|
||||
vimKeyMap["normal h"] = "scrollLeft"
|
||||
vimKeyMap["normal l"] = "scrollRight"
|
||||
vimKeyMap["normal d"] = "scrollHalfPageDown"
|
||||
vimKeyMap["normal <C-d>"] = "scrollHalfPageDown"
|
||||
vimKeyMap["normal u"] = "scrollHalfPageUp"
|
||||
vimKeyMap["normal <C-u>"] = "scrollHalfPageUp"
|
||||
vimKeyMap["normal e"] = "editURL"
|
||||
vimKeyMap["normal ge"] = "editURL"
|
||||
vimKeyMap["normal gE"] = "editURLInNewTab"
|
||||
vimKeyMap["normal H"] = "historyBack"
|
||||
vimKeyMap["normal L"] = "historyForward"
|
||||
vimKeyMap["normal J"] = "prevTab"
|
||||
vimKeyMap["normal K"] = "nextTab"
|
||||
vimKeyMap["normal r"] = "reload"
|
||||
vimKeyMap["normal xx"] = "removeTab"
|
||||
vimKeyMap["normal X"] = "restoreTab"
|
||||
vimKeyMap["normal t"] = "newTab"
|
||||
vimKeyMap["normal T"] = "searchForTab"
|
||||
vimKeyMap["normal /"] = "findMode"
|
||||
vimKeyMap["normal n"] = "findNext"
|
||||
vimKeyMap["normal N"] = "findPrevious"
|
||||
vimKeyMap["normal g0"] = "firstTab"
|
||||
vimKeyMap["normal g$"] = "lastTab"
|
||||
vimKeyMap["normal gu"] = "urlUp"
|
||||
vimKeyMap["normal gU"] = "urlRoot"
|
||||
vimKeyMap["normal <<"] = "moveTabLeft"
|
||||
vimKeyMap["normal >>"] = "moveTabRight"
|
||||
vimKeyMap["normal ^"] = "previouslyVisitedTab"
|
||||
vimKeyMap["normal m"] = "makeMark"
|
||||
vimKeyMap["normal '"] = "gotoMark"
|
||||
vimKeyMap["normal i"] = "insertMode"
|
||||
vimKeyMap["normal I"] = "insertModeHard"
|
||||
vimKeyMap["normal yy"] = "copyURL"
|
||||
vimKeyMap["normal p"] = "openClipboardURL"
|
||||
vimKeyMap["normal P"] = "openClipboardURLInNewTab"
|
||||
vimKeyMap["normal gi"] = "focusFirstTextInput"
|
||||
vimKeyMap["normal f"] = "openLinkInCurrentTab"
|
||||
vimKeyMap["normal F"] = "openLinkInNewTab"
|
||||
vimKeyMap["normal <M-f>"] = "openMultipleLinksInNewTab"
|
||||
vimKeyMap["normal yf"] = "copyLinkURL"
|
||||
vimKeyMap["normal [["] = "followLinkLabeledPrevious"
|
||||
vimKeyMap["normal ]]"] = "followLinkLabeledNext"
|
||||
vimKeyMap["normal yt"] = "duplicateTab"
|
||||
vimKeyMap["normal v"] = "visualMode"
|
||||
vimKeyMap["normal ?"] = "viewHelp"
|
||||
vimKeyMap["caret v"] = "visualMode"
|
||||
vimKeyMap["caret h"] = "moveCaretLeft"
|
||||
vimKeyMap["caret l"] = "moveCaretRight"
|
||||
vimKeyMap["caret j"] = "moveCaretDown"
|
||||
vimKeyMap["caret k"] = "moveCaretUp"
|
||||
vimKeyMap["caret <Enter>"] = "clickAtCaretPosition"
|
||||
vimKeyMap["visual c"] = "caretMode"
|
||||
vimKeyMap["visual o"] = "swapVisualModeCursorPosition"
|
||||
vimKeyMap["visual y"] = "copyVisualModeSelection"
|
||||
}
|
||||
|
||||
func loadConfig() {
|
||||
|
|
|
@ -57,7 +57,7 @@ func readStdin() {
|
|||
}
|
||||
}
|
||||
|
||||
func handleUserKeyPress(ev *tcell.EventKey) {
|
||||
func handleShortcuts(ev *tcell.EventKey) {
|
||||
if CurrentTab == nil {
|
||||
if ev.Key() == tcell.KeyCtrlQ {
|
||||
quitBrowsh()
|
||||
|
@ -88,6 +88,12 @@ func handleUserKeyPress(ev *tcell.EventKey) {
|
|||
if isKey("tty.keys.next-tab", ev) {
|
||||
nextTab()
|
||||
}
|
||||
}
|
||||
|
||||
func handleUserKeyPress(ev *tcell.EventKey) {
|
||||
if currentVimMode != insertModeHard {
|
||||
handleShortcuts(ev)
|
||||
}
|
||||
if !urlInputBox.isActive {
|
||||
forwardKeyPress(ev)
|
||||
}
|
||||
|
|
|
@ -115,10 +115,14 @@ func overlayVimMode() {
|
|||
switch currentVimMode {
|
||||
case insertMode:
|
||||
writeString(0, height-1, "ins", tcell.StyleDefault)
|
||||
case insertModeHard:
|
||||
writeString(0, height-1, "INS", tcell.StyleDefault)
|
||||
case linkMode:
|
||||
writeString(0, height-1, "lnk", tcell.StyleDefault)
|
||||
case linkModeNewTab:
|
||||
writeString(0, height-1, "LNK", tcell.StyleDefault)
|
||||
case linkModeMultipleNewTab:
|
||||
writeString(0, height-1, "*LNK", tcell.StyleDefault)
|
||||
case linkModeCopy:
|
||||
writeString(0, height-1, "cp", tcell.StyleDefault)
|
||||
case visualMode:
|
||||
|
@ -128,14 +132,14 @@ func overlayVimMode() {
|
|||
writeString(caretPos.X, caretPos.Y, "#", tcell.StyleDefault)
|
||||
case findMode:
|
||||
writeString(0, height-1, "/"+findText, tcell.StyleDefault)
|
||||
case makeMarkMode:
|
||||
case markModeMake:
|
||||
writeString(0, height-1, "mark", tcell.StyleDefault)
|
||||
case gotoMarkMode:
|
||||
case markModeGoto:
|
||||
writeString(0, height-1, "goto", tcell.StyleDefault)
|
||||
}
|
||||
|
||||
switch currentVimMode {
|
||||
case linkMode, linkModeNewTab, linkModeCopy:
|
||||
case linkMode, linkModeNewTab, linkModeMultipleNewTab, linkModeCopy:
|
||||
if !linkModeWithHints {
|
||||
findAndHighlightTextOnScreen(linkText)
|
||||
}
|
||||
|
|
|
@ -19,15 +19,17 @@ type vimMode int
|
|||
const (
|
||||
normalMode vimMode = iota + 1
|
||||
insertMode
|
||||
insertModeHard
|
||||
findMode
|
||||
linkMode
|
||||
linkModeNewTab
|
||||
linkModeMultipleNewTab
|
||||
linkModeCopy
|
||||
waitMode
|
||||
visualMode
|
||||
caretMode
|
||||
makeMarkMode
|
||||
gotoMarkMode
|
||||
markModeMake
|
||||
markModeGoto
|
||||
)
|
||||
|
||||
// TODO: What's a mark?
|
||||
|
@ -49,11 +51,13 @@ type hintRect struct {
|
|||
}
|
||||
|
||||
var (
|
||||
currentVimMode = normalMode
|
||||
vimCommandsBindings = make(map[string]string)
|
||||
keyEvents = make([]*tcell.EventKey, 0, 11)
|
||||
waitModeStartTime time.Time
|
||||
findText string
|
||||
currentVimMode = normalMode
|
||||
vimKeyMap = make(map[string]string)
|
||||
keyEvents = make([]*tcell.EventKey, 0, 11)
|
||||
waitModeStartTime time.Time
|
||||
waitModeMaxMilliseconds = 1000
|
||||
findText string
|
||||
latestKeyCombination string
|
||||
// Marks
|
||||
globalMarkMap = make(map[rune]*mark)
|
||||
localMarkMap = make(map[int]map[rune]*mark)
|
||||
|
@ -156,7 +160,7 @@ func makeMark() *mark {
|
|||
}
|
||||
|
||||
func goIntoWaitMode() {
|
||||
currentVimMode = waitMode
|
||||
changeVimMode(waitMode)
|
||||
waitModeStartTime = time.Now()
|
||||
}
|
||||
|
||||
|
@ -219,96 +223,111 @@ func eraseLinkHints() {
|
|||
linkHintRects = nil
|
||||
}
|
||||
|
||||
func resetLinkHints() {
|
||||
linkText = ""
|
||||
updateLinkHintDisplay()
|
||||
}
|
||||
|
||||
func isNormalModeKey(ev *tcell.EventKey) bool {
|
||||
if ev.Key() == tcell.KeyESC {
|
||||
if ev != nil && ev.Key() == tcell.KeyESC {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func handleVimControl(ev *tcell.EventKey) {
|
||||
var lastRune rune
|
||||
command := ""
|
||||
|
||||
if len(keyEvents) > 0 && keyEvents[0] != nil {
|
||||
lastRune = keyEvents[len(keyEvents)-1].Rune()
|
||||
func keyEventToString(ev *tcell.EventKey) string {
|
||||
if ev == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
r := string(ev.Rune())
|
||||
if ev.Modifiers()&tcell.ModAlt != 0 && ev.Modifiers()&tcell.ModCtrl != 0 {
|
||||
return "<C-M-" + r + ">"
|
||||
} else if ev.Modifiers()&tcell.ModAlt != 0 {
|
||||
return "<M-" + r + ">"
|
||||
} else if ev.Modifiers()&tcell.ModCtrl != 0 {
|
||||
return "<C-" + strings.ToLower(ev.Name()[5:]) + ">"
|
||||
}
|
||||
|
||||
switch ev.Key() {
|
||||
case tcell.KeyEnter:
|
||||
return "<Enter>"
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
func getNLastKeyEvent(n int) *tcell.EventKey {
|
||||
if n < 0 || keyEvents == nil {
|
||||
return nil
|
||||
}
|
||||
if len(keyEvents) > n {
|
||||
return keyEvents[len(keyEvents)-n-1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func mapVimKeyEvents(ev *tcell.EventKey, mapMode string) string {
|
||||
var lastEvent *tcell.EventKey
|
||||
command := ""
|
||||
|
||||
keyEvents = append(keyEvents, ev)
|
||||
if len(keyEvents) > 10 {
|
||||
keyEvents = keyEvents[1:]
|
||||
}
|
||||
|
||||
keyCombination := string(lastRune) + string(ev.Rune())
|
||||
lastEvent = getNLastKeyEvent(1)
|
||||
|
||||
latestKeyCombination = keyEventToString(lastEvent) + keyEventToString(ev)
|
||||
|
||||
command = vimKeyMap[mapMode+" "+latestKeyCombination]
|
||||
if len(command) == 0 {
|
||||
latestKeyCombination = keyEventToString(ev)
|
||||
command = vimKeyMap[mapMode+" "+latestKeyCombination]
|
||||
}
|
||||
if len(command) <= 0 {
|
||||
latestKeyCombination = ""
|
||||
} else {
|
||||
// Since len(command) must be greather than 0 here,
|
||||
// a key mapping did match, therefore we reset keyEvents
|
||||
keyEvents = nil
|
||||
}
|
||||
return command
|
||||
}
|
||||
|
||||
func handleVimMode(ev *tcell.EventKey, mode string) string {
|
||||
if isNormalModeKey(ev) {
|
||||
return "normalMode"
|
||||
} else {
|
||||
return mapVimKeyEvents(ev, mode)
|
||||
}
|
||||
}
|
||||
|
||||
func handleVimControl(ev *tcell.EventKey) {
|
||||
var command string
|
||||
switch currentVimMode {
|
||||
case waitMode:
|
||||
if time.Since(waitModeStartTime) < time.Millisecond*1000 {
|
||||
if time.Since(waitModeStartTime) < time.Millisecond*time.Duration(waitModeMaxMilliseconds) {
|
||||
return
|
||||
}
|
||||
currentVimMode = normalMode
|
||||
changeVimMode(normalMode)
|
||||
fallthrough
|
||||
case normalMode:
|
||||
command = vimCommandsBindings[keyCombination]
|
||||
if len(command) == 0 {
|
||||
keyCombination := string(ev.Rune())
|
||||
command = vimCommandsBindings[keyCombination]
|
||||
}
|
||||
command = mapVimKeyEvents(ev, "normal")
|
||||
case insertMode:
|
||||
if isNormalModeKey(ev) {
|
||||
command = handleVimMode(ev, "insert")
|
||||
case insertModeHard:
|
||||
if isNormalModeKey(ev) && isNormalModeKey(getNLastKeyEvent(0)) && isNormalModeKey(getNLastKeyEvent(1)) && isNormalModeKey(getNLastKeyEvent(2)) {
|
||||
command = "normalMode"
|
||||
} else {
|
||||
command = mapVimKeyEvents(ev, "insertHard")
|
||||
}
|
||||
case visualMode:
|
||||
if isNormalModeKey(ev) {
|
||||
command = "normalMode"
|
||||
} else {
|
||||
if ev.Rune() == 'c' {
|
||||
command = "caretMode"
|
||||
}
|
||||
if ev.Rune() == 'o' {
|
||||
//swap cursor position begin->end or end->begin
|
||||
}
|
||||
if ev.Rune() == 'y' {
|
||||
//clipboard
|
||||
}
|
||||
}
|
||||
command = handleVimMode(ev, "visual")
|
||||
case caretMode:
|
||||
if isNormalModeKey(ev) {
|
||||
command = "normalMode"
|
||||
} else {
|
||||
switch ev.Key() {
|
||||
case tcell.KeyEnter:
|
||||
generateLeftClick(caretPos.X, caretPos.Y-uiHeight)
|
||||
}
|
||||
switch ev.Rune() {
|
||||
case 'v':
|
||||
command = "visualMode"
|
||||
case 'h':
|
||||
moveVimCaret(func() bool { return caretPos.X > 0 }, &caretPos.X, -1)
|
||||
case 'l':
|
||||
width, _ := screen.Size()
|
||||
moveVimCaret(func() bool { return caretPos.X < width }, &caretPos.X, 1)
|
||||
case 'k':
|
||||
_, height := screen.Size()
|
||||
moveVimCaret(func() bool { return caretPos.Y >= uiHeight }, &caretPos.Y, -1)
|
||||
if caretPos.Y < uiHeight {
|
||||
command = "scrollHalfPageUp"
|
||||
if CurrentTab.frame.yScroll == 0 {
|
||||
caretPos.Y = uiHeight
|
||||
} else {
|
||||
caretPos.Y += (height - uiHeight) / 2
|
||||
}
|
||||
}
|
||||
case 'j':
|
||||
_, height := screen.Size()
|
||||
moveVimCaret(func() bool { return caretPos.Y <= height-uiHeight }, &caretPos.Y, 1)
|
||||
if caretPos.Y > height-uiHeight {
|
||||
command = "scrollHalfPageDown"
|
||||
caretPos.Y -= (height - uiHeight) / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
case makeMarkMode:
|
||||
command = handleVimMode(ev, "caret")
|
||||
case markModeMake:
|
||||
if unicode.IsLower(ev.Rune()) {
|
||||
if localMarkMap[CurrentTab.ID] == nil {
|
||||
localMarkMap[CurrentTab.ID] = make(map[rune]*mark)
|
||||
|
@ -319,7 +338,7 @@ func handleVimControl(ev *tcell.EventKey) {
|
|||
}
|
||||
|
||||
command = "normalMode"
|
||||
case gotoMarkMode:
|
||||
case markModeGoto:
|
||||
if mark, ok := globalMarkMap[ev.Rune()]; ok {
|
||||
gotoMark(mark)
|
||||
} else if m, ok := localMarkMap[CurrentTab.ID]; unicode.IsLower(ev.Rune()) && ok {
|
||||
|
@ -335,7 +354,7 @@ func handleVimControl(ev *tcell.EventKey) {
|
|||
findText = ""
|
||||
} else {
|
||||
if ev.Key() == tcell.KeyEnter {
|
||||
currentVimMode = normalMode
|
||||
changeVimMode(normalMode)
|
||||
command = "findText"
|
||||
break
|
||||
}
|
||||
|
@ -347,7 +366,7 @@ func handleVimControl(ev *tcell.EventKey) {
|
|||
findText += string(ev.Rune())
|
||||
}
|
||||
}
|
||||
case linkMode, linkModeNewTab, linkModeCopy:
|
||||
case linkMode, linkModeNewTab, linkModeMultipleNewTab, linkModeCopy:
|
||||
if isNormalModeKey(ev) {
|
||||
command = "normalMode"
|
||||
eraseLinkHints()
|
||||
|
@ -366,6 +385,9 @@ func handleVimControl(ev *tcell.EventKey) {
|
|||
}
|
||||
case linkModeNewTab:
|
||||
sendMessageToWebExtension("/new_tab," + r.Href)
|
||||
case linkModeMultipleNewTab:
|
||||
resetLinkHints()
|
||||
return
|
||||
case linkModeCopy:
|
||||
clipboard.WriteAll(r.Href)
|
||||
}
|
||||
|
@ -386,7 +408,7 @@ func handleVimControl(ev *tcell.EventKey) {
|
|||
linkText = ""
|
||||
return
|
||||
} else if len(coords) == 0 {
|
||||
currentVimMode = normalMode
|
||||
changeVimMode(normalMode)
|
||||
linkText = ""
|
||||
return
|
||||
}
|
||||
|
@ -394,13 +416,17 @@ func handleVimControl(ev *tcell.EventKey) {
|
|||
}
|
||||
}
|
||||
|
||||
if len(command) > 0 {
|
||||
executeVimCommand(command)
|
||||
}
|
||||
executeVimCommand(command)
|
||||
}
|
||||
|
||||
func executeVimCommand(command string) {
|
||||
switch command {
|
||||
if len(command) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
currentCommand := command
|
||||
command = ""
|
||||
switch currentCommand {
|
||||
case "urlUp":
|
||||
sendMessageToWebExtension("/tab_command,/url_up")
|
||||
case "urlRoot":
|
||||
|
@ -472,15 +498,19 @@ func executeVimCommand(command string) {
|
|||
case "viewHelp":
|
||||
sendMessageToWebExtension("/new_tab,https://www.brow.sh/docs/keybindings/")
|
||||
case "openLinkInCurrentTab":
|
||||
currentVimMode = linkMode
|
||||
changeVimMode(linkMode)
|
||||
sendMessageToWebExtension("/tab_command,/get_clickable_hints")
|
||||
eraseLinkHints()
|
||||
case "openLinkInNewTab":
|
||||
currentVimMode = linkModeNewTab
|
||||
changeVimMode(linkModeNewTab)
|
||||
sendMessageToWebExtension("/tab_command,/get_link_hints")
|
||||
eraseLinkHints()
|
||||
case "openMultipleLinksInNewTab":
|
||||
changeVimMode(linkModeMultipleNewTab)
|
||||
sendMessageToWebExtension("/tab_command,/get_link_hints")
|
||||
eraseLinkHints()
|
||||
case "copyLinkURL":
|
||||
currentVimMode = linkModeCopy
|
||||
changeVimMode(linkModeCopy)
|
||||
sendMessageToWebExtension("/tab_command,/get_link_hints")
|
||||
eraseLinkHints()
|
||||
case "findText":
|
||||
|
@ -490,22 +520,68 @@ func executeVimCommand(command string) {
|
|||
case "findPrevious":
|
||||
sendMessageToWebExtension("/tab_command,/find_previous," + findText)
|
||||
case "makeMark":
|
||||
currentVimMode = makeMarkMode
|
||||
changeVimMode(markModeMake)
|
||||
case "gotoMark":
|
||||
currentVimMode = gotoMarkMode
|
||||
changeVimMode(markModeGoto)
|
||||
case "insertMode":
|
||||
currentVimMode = insertMode
|
||||
changeVimMode(insertMode)
|
||||
case "insertModeHard":
|
||||
changeVimMode(insertModeHard)
|
||||
case "findMode":
|
||||
currentVimMode = findMode
|
||||
changeVimMode(findMode)
|
||||
case "normalMode":
|
||||
currentVimMode = normalMode
|
||||
changeVimMode(normalMode)
|
||||
// Visual mode
|
||||
case "visualMode":
|
||||
currentVimMode = visualMode
|
||||
changeVimMode(visualMode)
|
||||
case "swapVisualModeCursorPosition":
|
||||
// Stub
|
||||
case "copyVisualModeSelection":
|
||||
// Caret mode
|
||||
case "caretMode":
|
||||
currentVimMode = caretMode
|
||||
changeVimMode(caretMode)
|
||||
width, height := screen.Size()
|
||||
caretPos.X, caretPos.Y = width/2, height/2
|
||||
case "clickAtCaretPosition":
|
||||
generateLeftClick(caretPos.X, caretPos.Y-uiHeight)
|
||||
case "moveCaretLeft":
|
||||
moveVimCaret(func() bool { return caretPos.X > 0 }, &caretPos.X, -1)
|
||||
case "moveCaretRight":
|
||||
width, _ := screen.Size()
|
||||
moveVimCaret(func() bool { return caretPos.X < width }, &caretPos.X, 1)
|
||||
case "moveCaretUp":
|
||||
_, height := screen.Size()
|
||||
moveVimCaret(func() bool { return caretPos.Y >= uiHeight }, &caretPos.Y, -1)
|
||||
if caretPos.Y < uiHeight {
|
||||
command = "scrollHalfPageUp"
|
||||
if CurrentTab.frame.yScroll == 0 {
|
||||
caretPos.Y = uiHeight
|
||||
} else {
|
||||
caretPos.Y += (height - uiHeight) / 2
|
||||
}
|
||||
}
|
||||
case "moveCaretDown":
|
||||
_, height := screen.Size()
|
||||
moveVimCaret(func() bool { return caretPos.Y <= height-uiHeight }, &caretPos.Y, 1)
|
||||
if caretPos.Y > height-uiHeight {
|
||||
command = "scrollHalfPageDown"
|
||||
caretPos.Y -= (height - uiHeight) / 2
|
||||
}
|
||||
}
|
||||
|
||||
// A command can spawn another
|
||||
executeVimCommand(command)
|
||||
}
|
||||
|
||||
func changeVimMode(mode vimMode) {
|
||||
if currentVimMode == mode {
|
||||
// No change
|
||||
return
|
||||
}
|
||||
|
||||
currentVimMode = mode
|
||||
// Reset keyEvents
|
||||
keyEvents = nil
|
||||
}
|
||||
|
||||
func searchVisibleScreenForText(text string) []Coordinate {
|
||||
|
|
Loading…
Reference in New Issue