Merge pull request #704 from zyedidia/multiple-cursors
Multiple cursors
This commit is contained in:
commit
7ccec0e3f7
12 changed files with 1035 additions and 733 deletions
File diff suppressed because it is too large
Load diff
|
@ -14,90 +14,95 @@ var mouseBindings map[Key][]func(*View, bool, *tcell.EventMouse) bool
|
|||
var helpBinding string
|
||||
|
||||
var mouseBindingActions = map[string]func(*View, bool, *tcell.EventMouse) bool{
|
||||
"MousePress": (*View).MousePress,
|
||||
"MousePress": (*View).MousePress,
|
||||
"MouseMultiCursor": (*View).MouseMultiCursor,
|
||||
}
|
||||
|
||||
var bindingActions = map[string]func(*View, bool) bool{
|
||||
"CursorUp": (*View).CursorUp,
|
||||
"CursorDown": (*View).CursorDown,
|
||||
"CursorPageUp": (*View).CursorPageUp,
|
||||
"CursorPageDown": (*View).CursorPageDown,
|
||||
"CursorLeft": (*View).CursorLeft,
|
||||
"CursorRight": (*View).CursorRight,
|
||||
"CursorStart": (*View).CursorStart,
|
||||
"CursorEnd": (*View).CursorEnd,
|
||||
"SelectToStart": (*View).SelectToStart,
|
||||
"SelectToEnd": (*View).SelectToEnd,
|
||||
"SelectUp": (*View).SelectUp,
|
||||
"SelectDown": (*View).SelectDown,
|
||||
"SelectLeft": (*View).SelectLeft,
|
||||
"SelectRight": (*View).SelectRight,
|
||||
"WordRight": (*View).WordRight,
|
||||
"WordLeft": (*View).WordLeft,
|
||||
"SelectWordRight": (*View).SelectWordRight,
|
||||
"SelectWordLeft": (*View).SelectWordLeft,
|
||||
"DeleteWordRight": (*View).DeleteWordRight,
|
||||
"DeleteWordLeft": (*View).DeleteWordLeft,
|
||||
"SelectToStartOfLine": (*View).SelectToStartOfLine,
|
||||
"SelectToEndOfLine": (*View).SelectToEndOfLine,
|
||||
"InsertNewline": (*View).InsertNewline,
|
||||
"InsertSpace": (*View).InsertSpace,
|
||||
"Backspace": (*View).Backspace,
|
||||
"Delete": (*View).Delete,
|
||||
"InsertTab": (*View).InsertTab,
|
||||
"Save": (*View).Save,
|
||||
"SaveAll": (*View).SaveAll,
|
||||
"SaveAs": (*View).SaveAs,
|
||||
"Find": (*View).Find,
|
||||
"FindNext": (*View).FindNext,
|
||||
"FindPrevious": (*View).FindPrevious,
|
||||
"Center": (*View).Center,
|
||||
"Undo": (*View).Undo,
|
||||
"Redo": (*View).Redo,
|
||||
"Copy": (*View).Copy,
|
||||
"Cut": (*View).Cut,
|
||||
"CutLine": (*View).CutLine,
|
||||
"DuplicateLine": (*View).DuplicateLine,
|
||||
"DeleteLine": (*View).DeleteLine,
|
||||
"MoveLinesUp": (*View).MoveLinesUp,
|
||||
"MoveLinesDown": (*View).MoveLinesDown,
|
||||
"IndentSelection": (*View).IndentSelection,
|
||||
"OutdentSelection": (*View).OutdentSelection,
|
||||
"OutdentLine": (*View).OutdentLine,
|
||||
"Paste": (*View).Paste,
|
||||
"PastePrimary": (*View).PastePrimary,
|
||||
"SelectAll": (*View).SelectAll,
|
||||
"OpenFile": (*View).OpenFile,
|
||||
"Start": (*View).Start,
|
||||
"End": (*View).End,
|
||||
"PageUp": (*View).PageUp,
|
||||
"PageDown": (*View).PageDown,
|
||||
"HalfPageUp": (*View).HalfPageUp,
|
||||
"HalfPageDown": (*View).HalfPageDown,
|
||||
"StartOfLine": (*View).StartOfLine,
|
||||
"EndOfLine": (*View).EndOfLine,
|
||||
"ToggleHelp": (*View).ToggleHelp,
|
||||
"ToggleRuler": (*View).ToggleRuler,
|
||||
"JumpLine": (*View).JumpLine,
|
||||
"ClearStatus": (*View).ClearStatus,
|
||||
"ShellMode": (*View).ShellMode,
|
||||
"CommandMode": (*View).CommandMode,
|
||||
"Escape": (*View).Escape,
|
||||
"Quit": (*View).Quit,
|
||||
"QuitAll": (*View).QuitAll,
|
||||
"AddTab": (*View).AddTab,
|
||||
"PreviousTab": (*View).PreviousTab,
|
||||
"NextTab": (*View).NextTab,
|
||||
"NextSplit": (*View).NextSplit,
|
||||
"PreviousSplit": (*View).PreviousSplit,
|
||||
"Unsplit": (*View).Unsplit,
|
||||
"VSplit": (*View).VSplitBinding,
|
||||
"HSplit": (*View).HSplitBinding,
|
||||
"ToggleMacro": (*View).ToggleMacro,
|
||||
"PlayMacro": (*View).PlayMacro,
|
||||
"Suspend": (*View).Suspend,
|
||||
"ScrollUp": (*View).ScrollUpAction,
|
||||
"ScrollDown": (*View).ScrollDownAction,
|
||||
"CursorUp": (*View).CursorUp,
|
||||
"CursorDown": (*View).CursorDown,
|
||||
"CursorPageUp": (*View).CursorPageUp,
|
||||
"CursorPageDown": (*View).CursorPageDown,
|
||||
"CursorLeft": (*View).CursorLeft,
|
||||
"CursorRight": (*View).CursorRight,
|
||||
"CursorStart": (*View).CursorStart,
|
||||
"CursorEnd": (*View).CursorEnd,
|
||||
"SelectToStart": (*View).SelectToStart,
|
||||
"SelectToEnd": (*View).SelectToEnd,
|
||||
"SelectUp": (*View).SelectUp,
|
||||
"SelectDown": (*View).SelectDown,
|
||||
"SelectLeft": (*View).SelectLeft,
|
||||
"SelectRight": (*View).SelectRight,
|
||||
"WordRight": (*View).WordRight,
|
||||
"WordLeft": (*View).WordLeft,
|
||||
"SelectWordRight": (*View).SelectWordRight,
|
||||
"SelectWordLeft": (*View).SelectWordLeft,
|
||||
"DeleteWordRight": (*View).DeleteWordRight,
|
||||
"DeleteWordLeft": (*View).DeleteWordLeft,
|
||||
"SelectToStartOfLine": (*View).SelectToStartOfLine,
|
||||
"SelectToEndOfLine": (*View).SelectToEndOfLine,
|
||||
"InsertNewline": (*View).InsertNewline,
|
||||
"InsertSpace": (*View).InsertSpace,
|
||||
"Backspace": (*View).Backspace,
|
||||
"Delete": (*View).Delete,
|
||||
"InsertTab": (*View).InsertTab,
|
||||
"Save": (*View).Save,
|
||||
"SaveAll": (*View).SaveAll,
|
||||
"SaveAs": (*View).SaveAs,
|
||||
"Find": (*View).Find,
|
||||
"FindNext": (*View).FindNext,
|
||||
"FindPrevious": (*View).FindPrevious,
|
||||
"Center": (*View).Center,
|
||||
"Undo": (*View).Undo,
|
||||
"Redo": (*View).Redo,
|
||||
"Copy": (*View).Copy,
|
||||
"Cut": (*View).Cut,
|
||||
"CutLine": (*View).CutLine,
|
||||
"DuplicateLine": (*View).DuplicateLine,
|
||||
"DeleteLine": (*View).DeleteLine,
|
||||
"MoveLinesUp": (*View).MoveLinesUp,
|
||||
"MoveLinesDown": (*View).MoveLinesDown,
|
||||
"IndentSelection": (*View).IndentSelection,
|
||||
"OutdentSelection": (*View).OutdentSelection,
|
||||
"OutdentLine": (*View).OutdentLine,
|
||||
"Paste": (*View).Paste,
|
||||
"PastePrimary": (*View).PastePrimary,
|
||||
"SelectAll": (*View).SelectAll,
|
||||
"OpenFile": (*View).OpenFile,
|
||||
"Start": (*View).Start,
|
||||
"End": (*View).End,
|
||||
"PageUp": (*View).PageUp,
|
||||
"PageDown": (*View).PageDown,
|
||||
"HalfPageUp": (*View).HalfPageUp,
|
||||
"HalfPageDown": (*View).HalfPageDown,
|
||||
"StartOfLine": (*View).StartOfLine,
|
||||
"EndOfLine": (*View).EndOfLine,
|
||||
"ToggleHelp": (*View).ToggleHelp,
|
||||
"ToggleRuler": (*View).ToggleRuler,
|
||||
"JumpLine": (*View).JumpLine,
|
||||
"ClearStatus": (*View).ClearStatus,
|
||||
"ShellMode": (*View).ShellMode,
|
||||
"CommandMode": (*View).CommandMode,
|
||||
"Escape": (*View).Escape,
|
||||
"Quit": (*View).Quit,
|
||||
"QuitAll": (*View).QuitAll,
|
||||
"AddTab": (*View).AddTab,
|
||||
"PreviousTab": (*View).PreviousTab,
|
||||
"NextTab": (*View).NextTab,
|
||||
"NextSplit": (*View).NextSplit,
|
||||
"PreviousSplit": (*View).PreviousSplit,
|
||||
"Unsplit": (*View).Unsplit,
|
||||
"VSplit": (*View).VSplitBinding,
|
||||
"HSplit": (*View).HSplitBinding,
|
||||
"ToggleMacro": (*View).ToggleMacro,
|
||||
"PlayMacro": (*View).PlayMacro,
|
||||
"Suspend": (*View).Suspend,
|
||||
"ScrollUp": (*View).ScrollUpAction,
|
||||
"ScrollDown": (*View).ScrollDownAction,
|
||||
"SpawnMultiCursor": (*View).SpawnMultiCursor,
|
||||
"RemoveMultiCursor": (*View).RemoveMultiCursor,
|
||||
"RemoveAllMultiCursors": (*View).RemoveAllMultiCursors,
|
||||
"SkipMultiCursor": (*View).SkipMultiCursor,
|
||||
|
||||
// This was changed to InsertNewline but I don't want to break backwards compatibility
|
||||
"InsertEnter": (*View).InsertNewline,
|
||||
|
@ -496,8 +501,8 @@ func DefaultBindings() map[string]string {
|
|||
"Alt-b": "WordLeft",
|
||||
"Alt-a": "StartOfLine",
|
||||
"Alt-e": "EndOfLine",
|
||||
"Alt-p": "CursorUp",
|
||||
"Alt-n": "CursorDown",
|
||||
// "Alt-p": "CursorUp",
|
||||
// "Alt-n": "CursorDown",
|
||||
|
||||
// Integration with file managers
|
||||
"F1": "ToggleHelp",
|
||||
|
@ -513,5 +518,11 @@ func DefaultBindings() map[string]string {
|
|||
"MouseWheelDown": "ScrollDown",
|
||||
"MouseLeft": "MousePress",
|
||||
"MouseMiddle": "PastePrimary",
|
||||
"Ctrl-MouseLeft": "MouseMultiCursor",
|
||||
|
||||
"Alt-n": "SpawnMultiCursor",
|
||||
"Alt-p": "RemoveMultiCursor",
|
||||
"Alt-c": "RemoveAllMultiCursors",
|
||||
"Alt-x": "SkipMultiCursor",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@ type Buffer struct {
|
|||
// This stores all the text in the buffer as an array of lines
|
||||
*LineArray
|
||||
|
||||
Cursor Cursor
|
||||
Cursor Cursor
|
||||
cursors []*Cursor // for multiple cursors
|
||||
curCursor int // the current cursor
|
||||
|
||||
// Path to the file on disk
|
||||
Path string
|
||||
|
@ -169,6 +171,8 @@ func NewBuffer(reader io.Reader, size int64, path string) *Buffer {
|
|||
file.Close()
|
||||
}
|
||||
|
||||
b.cursors = []*Cursor{&b.Cursor}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
|
@ -305,6 +309,30 @@ func (b *Buffer) Update() {
|
|||
b.NumLines = len(b.lines)
|
||||
}
|
||||
|
||||
func (b *Buffer) MergeCursors() {
|
||||
var cursors []*Cursor
|
||||
for i := 0; i < len(b.cursors); i++ {
|
||||
c1 := b.cursors[i]
|
||||
if c1 != nil {
|
||||
for j := 0; j < len(b.cursors); j++ {
|
||||
c2 := b.cursors[j]
|
||||
if i != j && c1.Loc == c2.Loc {
|
||||
b.cursors[j] = nil
|
||||
}
|
||||
}
|
||||
cursors = append(cursors, c1)
|
||||
}
|
||||
}
|
||||
|
||||
b.cursors = cursors
|
||||
}
|
||||
|
||||
func (b *Buffer) UpdateCursors() {
|
||||
for i, c := range b.cursors {
|
||||
c.Num = i
|
||||
}
|
||||
}
|
||||
|
||||
// Save saves the buffer to its default path
|
||||
func (b *Buffer) Save() error {
|
||||
return b.SaveAs(b.Path)
|
||||
|
|
|
@ -21,6 +21,9 @@ type Cursor struct {
|
|||
// This is used for line and word selection where it is necessary
|
||||
// to know what the original selection was
|
||||
OrigSelection [2]Loc
|
||||
|
||||
// Which cursor index is this (for multiple cursors)
|
||||
Num int
|
||||
}
|
||||
|
||||
// Goto puts the cursor at the given cursor's location and gives the current cursor its selection too
|
||||
|
|
|
@ -97,30 +97,51 @@ func (eh *EventHandler) ApplyDiff(new string) {
|
|||
// Insert creates an insert text event and executes it
|
||||
func (eh *EventHandler) Insert(start Loc, text string) {
|
||||
e := &TextEvent{
|
||||
C: eh.buf.Cursor,
|
||||
C: *eh.buf.cursors[eh.buf.curCursor],
|
||||
EventType: TextEventInsert,
|
||||
Deltas: []Delta{Delta{text, start, Loc{0, 0}}},
|
||||
Time: time.Now(),
|
||||
}
|
||||
eh.Execute(e)
|
||||
e.Deltas[0].End = start.Move(Count(text), eh.buf)
|
||||
end := e.Deltas[0].End
|
||||
|
||||
for _, c := range eh.buf.cursors {
|
||||
if start.Y != end.Y && c.GreaterThan(start) {
|
||||
c.Loc.Y += end.Y - start.Y
|
||||
} else if c.Y == start.Y && c.GreaterEqual(start) {
|
||||
c.Loc = c.Move(Count(text), eh.buf)
|
||||
}
|
||||
c.LastVisualX = c.GetVisualX()
|
||||
}
|
||||
}
|
||||
|
||||
// Remove creates a remove text event and executes it
|
||||
func (eh *EventHandler) Remove(start, end Loc) {
|
||||
e := &TextEvent{
|
||||
C: eh.buf.Cursor,
|
||||
C: *eh.buf.cursors[eh.buf.curCursor],
|
||||
EventType: TextEventRemove,
|
||||
Deltas: []Delta{Delta{"", start, end}},
|
||||
Time: time.Now(),
|
||||
}
|
||||
eh.Execute(e)
|
||||
|
||||
for _, c := range eh.buf.cursors {
|
||||
if start.Y != end.Y && c.GreaterThan(end) {
|
||||
c.Loc.Y -= end.Y - start.Y
|
||||
} else if c.Y == end.Y && c.GreaterEqual(end) {
|
||||
// TermMessage(start, end)
|
||||
c.Loc = c.Move(-Diff(start, end, eh.buf), eh.buf)
|
||||
// c.Loc = c.Move(ToCharPos(start, eh.buf)-ToCharPos(end, eh.buf), eh.buf)
|
||||
}
|
||||
c.LastVisualX = c.GetVisualX()
|
||||
}
|
||||
}
|
||||
|
||||
// MultipleReplace creates an multiple insertions executes them
|
||||
func (eh *EventHandler) MultipleReplace(deltas []Delta) {
|
||||
e := &TextEvent{
|
||||
C: eh.buf.Cursor,
|
||||
C: *eh.buf.cursors[eh.buf.curCursor],
|
||||
EventType: TextEventReplace,
|
||||
Deltas: deltas,
|
||||
Time: time.Now(),
|
||||
|
@ -195,8 +216,12 @@ func (eh *EventHandler) UndoOneEvent() {
|
|||
|
||||
// Set the cursor in the right place
|
||||
teCursor := t.C
|
||||
t.C = eh.buf.Cursor
|
||||
eh.buf.Cursor.Goto(teCursor)
|
||||
if teCursor.Num >= 0 && teCursor.Num < len(eh.buf.cursors) {
|
||||
t.C = *eh.buf.cursors[teCursor.Num]
|
||||
eh.buf.cursors[teCursor.Num].Goto(teCursor)
|
||||
} else {
|
||||
teCursor.Num = -1
|
||||
}
|
||||
|
||||
// Push it to the redo stack
|
||||
eh.RedoStack.Push(t)
|
||||
|
@ -238,8 +263,12 @@ func (eh *EventHandler) RedoOneEvent() {
|
|||
UndoTextEvent(t, eh.buf)
|
||||
|
||||
teCursor := t.C
|
||||
t.C = eh.buf.Cursor
|
||||
eh.buf.Cursor.Goto(teCursor)
|
||||
if teCursor.Num >= 0 && teCursor.Num < len(eh.buf.cursors) {
|
||||
t.C = *eh.buf.cursors[teCursor.Num]
|
||||
eh.buf.cursors[teCursor.Num].Goto(teCursor)
|
||||
} else {
|
||||
teCursor.Num = -1
|
||||
}
|
||||
|
||||
eh.UndoStack.Push(t)
|
||||
}
|
||||
|
|
|
@ -54,6 +54,28 @@ type Loc struct {
|
|||
X, Y int
|
||||
}
|
||||
|
||||
func Diff(a, b Loc, buf *Buffer) int {
|
||||
if a.Y == b.Y {
|
||||
if a.X > b.X {
|
||||
return a.X - b.X
|
||||
}
|
||||
return b.X - a.X
|
||||
}
|
||||
|
||||
// Make sure a is guaranteed to be less than b
|
||||
if b.LessThan(a) {
|
||||
a, b = b, a
|
||||
}
|
||||
|
||||
loc := 0
|
||||
for i := a.Y + 1; i < b.Y; i++ {
|
||||
// + 1 for the newline
|
||||
loc += Count(buf.Line(i)) + 1
|
||||
}
|
||||
loc += Count(buf.Line(a.Y)) - a.X + b.X + 1
|
||||
return loc
|
||||
}
|
||||
|
||||
// LessThan returns true if b is smaller
|
||||
func (l Loc) LessThan(b Loc) bool {
|
||||
if l.Y < b.Y {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -169,7 +169,7 @@ func (v *View) paste(clip string) {
|
|||
}
|
||||
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.Cursor.Loc = v.Cursor.Loc.Move(Count(clip), v.Buf)
|
||||
v.freshClip = false
|
||||
messenger.Message("Pasted clipboard")
|
||||
}
|
||||
|
@ -479,6 +479,11 @@ func (v *View) ExecuteActions(actions []func(*View, bool) bool) bool {
|
|||
return relocate
|
||||
}
|
||||
|
||||
func (v *View) SetCursor(c *Cursor) {
|
||||
v.Cursor = c
|
||||
v.Buf.curCursor = c.Num
|
||||
}
|
||||
|
||||
// HandleEvent handles an event passed by the main loop
|
||||
func (v *View) HandleEvent(event tcell.Event) {
|
||||
// This bool determines whether the view is relocated at the end of the function
|
||||
|
@ -499,9 +504,14 @@ func (v *View) HandleEvent(event tcell.Event) {
|
|||
}
|
||||
}
|
||||
if e.Modifiers() == key.modifiers {
|
||||
relocate = false
|
||||
isBinding = true
|
||||
relocate = v.ExecuteActions(actions)
|
||||
for _, c := range v.Buf.cursors {
|
||||
v.SetCursor(c)
|
||||
relocate = false
|
||||
isBinding = true
|
||||
relocate = v.ExecuteActions(actions) || relocate
|
||||
}
|
||||
v.SetCursor(&v.Buf.Cursor)
|
||||
v.Buf.MergeCursors()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -509,24 +519,28 @@ func (v *View) HandleEvent(event tcell.Event) {
|
|||
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.SetCursor(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()))
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
if recordingMacro {
|
||||
curMacro = append(curMacro, e.Rune())
|
||||
}
|
||||
v.SetCursor(&v.Buf.Cursor)
|
||||
}
|
||||
}
|
||||
case *tcell.EventPaste:
|
||||
|
@ -536,27 +550,34 @@ func (v *View) HandleEvent(event tcell.Event) {
|
|||
break
|
||||
}
|
||||
|
||||
v.paste(e.Text())
|
||||
for _, c := range v.Buf.cursors {
|
||||
v.SetCursor(c)
|
||||
v.paste(e.Text())
|
||||
|
||||
}
|
||||
v.SetCursor(&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
|
||||
|
||||
button := e.Buttons()
|
||||
|
||||
for key, actions := range bindings {
|
||||
if button == key.buttons {
|
||||
relocate = v.ExecuteActions(actions)
|
||||
if button == key.buttons && e.Modifiers() == key.modifiers {
|
||||
for _, c := range v.Buf.cursors {
|
||||
v.SetCursor(c)
|
||||
relocate = v.ExecuteActions(actions) || relocate
|
||||
}
|
||||
v.SetCursor(&v.Buf.Cursor)
|
||||
v.Buf.MergeCursors()
|
||||
}
|
||||
}
|
||||
|
||||
for key, actions := range mouseBindings {
|
||||
if button == key.buttons {
|
||||
if button == key.buttons && e.Modifiers() == key.modifiers {
|
||||
for _, action := range actions {
|
||||
action(v, true, e)
|
||||
}
|
||||
|
@ -569,6 +590,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
|
||||
|
@ -596,6 +621,10 @@ func (v *View) HandleEvent(event tcell.Event) {
|
|||
}
|
||||
}
|
||||
|
||||
func (v *View) mainCursor() bool {
|
||||
return v.Buf.curCursor == len(v.Buf.cursors)-1
|
||||
}
|
||||
|
||||
// GutterMessage creates a message in this view's gutter
|
||||
func (v *View) GutterMessage(section string, lineN int, msg string, kind int) {
|
||||
lineN--
|
||||
|
@ -822,22 +851,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)
|
||||
for _, c := range v.Buf.cursors {
|
||||
v.SetCursor(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 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.SetCursor(&v.Buf.Cursor)
|
||||
|
||||
if v.Buf.Settings["cursorline"].(bool) && tabs[curTab].CurView == v.Num &&
|
||||
!v.Cursor.HasSelection() && v.Cursor.Y == realLineN {
|
||||
|
@ -848,6 +875,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.SetCursor(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.SetCursor(&v.Buf.Cursor)
|
||||
|
||||
lastChar = char
|
||||
}
|
||||
}
|
||||
|
@ -858,19 +895,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.SetCursor(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
|
||||
}
|
||||
}
|
||||
v.SetCursor(&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.SetCursor(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.SetCursor(&v.Buf.Cursor)
|
||||
lastX = xOffset
|
||||
realLoc = Loc{0, realLineN}
|
||||
visualLoc = Loc{0, visualLineN}
|
||||
|
@ -912,6 +957,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) {
|
||||
|
|
|
@ -1,224 +1,126 @@
|
|||
#Default Keys
|
||||
# Default Keys
|
||||
|
||||
Below are simple charts of the default hotkeys and their functions.
|
||||
For more information about binding custom hotkeys or changing
|
||||
default bindings, please run `>help keybindings`
|
||||
default bindings, please run `> help keybindings`
|
||||
|
||||
Please remember that *all* keys here are rebindable!
|
||||
If you don't like it, you can change it!
|
||||
|
||||
(We are not responsible for you forgetting what you bind keys to.
|
||||
Do not open an issue because you forgot your keybindings.)
|
||||
# Power user
|
||||
|
||||
#Power user
|
||||
+--------+---------------------------------------------------------+
|
||||
| Key | Description of function |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+E | Switch to the micro command prompt to run a command. |
|
||||
| | (See `>help commands` for a list of commands. ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Tab | In command prompt it will auto complete if possible. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+B | Run shell commands in micro's current working directory.|
|
||||
+--------+---------------------------------------------------------+
|
||||
| Key | Description of function |
|
||||
|-------- |-------------------------------------------------------------------------------------------------- |
|
||||
| Ctrl+E | Open a command prompt for running commands (see `> help commands` for a list of valid commands). |
|
||||
| Tab | In command prompt, it will autocomplete if possible. |
|
||||
| Ctrl+B | Run a shell command (this will close micro while your command executes). |
|
||||
|
||||
#Navigation
|
||||
|--------+---------------------------------------------------------+
|
||||
| Arrows | Move the cursor around your current document. |
|
||||
| | (Yes this is rebindable to the vim keys if you want.) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Shift+ | Move and select text. |
|
||||
| Arrows | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Home | |
|
||||
| or | |
|
||||
| Ctrl+ | Move to the beginning of the current line. (Naturally.) |
|
||||
| Left | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| End | |
|
||||
| or | |
|
||||
| Ctrl+ | Move to the end of the current line. |
|
||||
| Right | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+ | |
|
||||
| Left | Move cursor one complete word left. |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+ | |
|
||||
| Right | Move cursor one complete word right. |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| PageUp | Move cursor up lines quickly. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| PageDn | Move cursor down lines quickly. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+ | |
|
||||
| Home | |
|
||||
| or | Move cursor to start of the document |
|
||||
| Ctrl+ | |
|
||||
| Up | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+ | |
|
||||
| End | |
|
||||
| or | Move cursor to end of the document |
|
||||
| Ctrl+ | |
|
||||
| Down | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+L | Jump to line in current file. ( Prompts for line # ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+W | Move between splits open in current tab. |
|
||||
| | (See vsplit and hsplit in `>help commands`) |
|
||||
+--------+---------------------------------------------------------+
|
||||
# Navigation
|
||||
|
||||
#Tabs
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+T | Open a new tab. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+, | Move to the previous tab in the tablist. |
|
||||
| | (This works like moving between file buffers in nano) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+. | Move to the next tab in the tablist. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Key | Description of function |
|
||||
|-------------------------- |------------------------------------------------------------------------------------------ |
|
||||
| Arrows | Move the cursor around |
|
||||
| Shift+arrows | Move and select text |
|
||||
| Home or CtrlLeftArrow | Move to the beginning of the current line |
|
||||
| End or CtrlRightArrow | Move to the end of the current line |
|
||||
| AltLeftArrow | Move cursor one word left |
|
||||
| AltRightArrow | Move cursor one word right |
|
||||
| PageUp | Move cursor up one page |
|
||||
| PageDown | Move cursor down one page |
|
||||
| CtrlHome or CtrlUpArrow | Move cursor to start of document |
|
||||
| CtrlEnd or CtrlDownArrow | Move cursor to end of document |
|
||||
| Ctrl+L | Jump to a line in the file (prompts with #) |
|
||||
| Ctrl+W | Cycle between splits in the current tab (use `> vsplit` or `> hsplit` to create a split) |
|
||||
|
||||
#Find Operations
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+F | Find text in current file. ( Prompts for text to find.) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+N | Find next instance of current search in current file. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+P | Find prev instance of current search in current file. |
|
||||
+--------+---------------------------------------------------------+
|
||||
# Tabs
|
||||
|
||||
#File Operations
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+Q | Close current file. ( Quits micro if last file open. ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+O | Open a file. ( Prompts you to input filename. ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+S | Save current file. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Key | Description of function |
|
||||
|-------- |------------------------- |
|
||||
| Ctrl+T | Open a new tab |
|
||||
| Alt+, | Previous tab |
|
||||
| Alt+. | Next tab |
|
||||
|
||||
#Text operations
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+A | Select all text in current file. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+ | |
|
||||
| Shift+ | Select complete word right. |
|
||||
| Right | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+ | |
|
||||
| Shift+ | Select complete word left. |
|
||||
| Left | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Shift+ | |
|
||||
| Home | |
|
||||
| or | Select from the current cursor position to the |
|
||||
| Ctrl+ | start of the current line. |
|
||||
| Shift+ | |
|
||||
| Left | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Shift+ | |
|
||||
| End | |
|
||||
| or | Select from the current cursor position to the |
|
||||
| Ctrl+ | end of the current line. |
|
||||
| Shift+ | |
|
||||
| Right | |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+ | |
|
||||
| Shift+ | Select from the current cursor position to the |
|
||||
| Up | start of the document. |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+ | |
|
||||
| Shift+ | Select from the current cursor position to the |
|
||||
| Down | end of the document. |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+X | Cut selected text. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+C | Copy selected text. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+V | Paste selected text. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+K | Cut current line. ( Can then be pasted with Ctrl+V) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+D | Duplicate current line. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+Z | Undo actions. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+Y | Redo actions. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+ | |
|
||||
| Up | Move current line or selected lines up. |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+ | |
|
||||
| Down | Move current line or selected lines down. |
|
||||
| Arrow | |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+ | |
|
||||
| Ctrl+H | |
|
||||
| or | Delete complete word left. |
|
||||
| Alt+ | |
|
||||
| Back- | |
|
||||
| space | |
|
||||
+--------+---------------------------------------------------------+
|
||||
# Find Operations
|
||||
|
||||
#Macros
|
||||
+--------+---------------------------------------------------------+
|
||||
| | Toggle ON/OFF macro recording. |
|
||||
| Ctrl+U | Simply press Ctrl+U to begin recording a macro and |
|
||||
| | press Ctrl+U to stop recording macro. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+J | Run your recorded macro. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Key | Description of function |
|
||||
|-------- |------------------------------------------ |
|
||||
| Ctrl+F | Find (opens prompt) |
|
||||
| Ctrl+N | Find next instance of current search |
|
||||
| Ctrl+P | Find previous instance of current search |
|
||||
|
||||
#Other
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+G | Open the help file. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+H | Alternate backspace. |
|
||||
| | (Some old terminals don't support the Backspace key .) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Ctrl+R | Toggle the line number ruler. ( On the lefthand side.) |
|
||||
+--------+---------------------------------------------------------+
|
||||
# File Operations
|
||||
|
||||
#Emacs style actions
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+F | Move to the end of the next word. (To the next space.) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+B | Move to the beginning of the previous word. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+A | Alternate Home key. ( Move to beginning of line. ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+E | Alternate End key. ( Move to the end of line.) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+P | Move cursor up. ( Same as up key. ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Alt+N | Move cursor down. ( Same as down key. ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| Key | Description of function |
|
||||
|-------- |---------------------------------------------------------------- |
|
||||
| Ctrl+Q | Close current file (quits micro if this is the last file open) |
|
||||
| Ctrl+O | Open a file (prompts for filename) |
|
||||
| Ctrl+S | Save current file |
|
||||
|
||||
# Text operations
|
||||
|
||||
| Key | Description of function |
|
||||
|--------------------------------- |------------------------------------------ |
|
||||
| AltShiftRightArrow | Select word right |
|
||||
| AltShiftLeftArrow | Select word left |
|
||||
| ShiftHome or CtrlShiftLeftArrow | Select to start of current line |
|
||||
| ShiftEnd or CtrlShiftRightArrow | Select to end of current line |
|
||||
| CtrlShiftUpArrow | Select to start of file |
|
||||
| CtrlShiftDownArrow | Select to end of file |
|
||||
| Ctrl+X | Cut selected text |
|
||||
| Ctrl+C | Copy selected text |
|
||||
| Ctrl+V | Paste |
|
||||
| Ctrl+K | Cut current line |
|
||||
| Ctrl+D | Duplicate current line |
|
||||
| Ctrl+Z | Undo |
|
||||
| Ctrl+Y | Redo |
|
||||
| AltUpArrow | Move current line or selected lines up |
|
||||
| AltDownArrow | Move current line of selected lines down |
|
||||
| AltBackspace or AltCtrl+H | Delete word left |
|
||||
| Ctrl+A | Select all |
|
||||
|
||||
# Macros
|
||||
|
||||
| Key | Description of function |
|
||||
|-------- |---------------------------------------------------------------------------------- |
|
||||
| Ctrl+U | Toggle macro recording (press Ctrl+U to start recording and press again to stop) |
|
||||
| Ctrl+J | Run latest recorded macro |
|
||||
|
||||
# Multiple cursors
|
||||
|
||||
| Key | Description of function |
|
||||
|---------------- |---------------------------------------------------------------------------------------------- |
|
||||
| Alt+N | Create new multiple cursor from selection (will select current word if no current selection) |
|
||||
| Alt+P | Remove latest multiple cursor |
|
||||
| Alt+C | Remove all multiple cursors (cancel) |
|
||||
| Alt+X | Skip multiple cursor selection |
|
||||
| Ctrl-MouseLeft | Place a multiple cursor at any location |
|
||||
|
||||
# Other
|
||||
|
||||
| Key | Description of function |
|
||||
|-------- |----------------------------------------------------------------------------------- |
|
||||
| Ctrl+G | Open help file |
|
||||
| Ctrl+H | Backspace (old terminals do not support the backspace key and use Ctrl+H instead) |
|
||||
| Ctrl+R | Toggle the line number ruler |
|
||||
|
||||
# Emacs style actions
|
||||
|
||||
| Key | Description of function |
|
||||
|------- |------------------------- |
|
||||
| Alt+F | Next word |
|
||||
| Alt+B | Previous word |
|
||||
| Alt+A | Move to start of line |
|
||||
| Alt+E | Move to end of line |
|
||||
|
||||
# Function keys.
|
||||
|
||||
#Function keys.
|
||||
Warning! The function keys may not work in all terminals!
|
||||
+--------+---------------------------------------------------------+
|
||||
| F1 | Open help. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| F2 | Save current file. |
|
||||
+--------+---------------------------------------------------------+
|
||||
| F3 | Find in current file. ( Same as Ctrl+F ) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| F4 | Close current file. (Quit if only file.) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| F7 | Find in current file. (Same as Ctrl+F) |
|
||||
+--------+---------------------------------------------------------+
|
||||
| F10 | Close current file. |
|
||||
+--------+---------------------------------------------------------+
|
||||
|
||||
| Key | Description of function |
|
||||
|----- |------------------------- |
|
||||
| F1 | Open help |
|
||||
| F2 | Save |
|
||||
| F3 | Find |
|
||||
| F4 | Quit |
|
||||
| F7 | Find |
|
||||
| F10 | Quit |
|
||||
|
|
|
@ -131,9 +131,22 @@ HSplit
|
|||
PreviousSplit
|
||||
ToggleMacro
|
||||
PlayMacro
|
||||
Suspend (Linux only)
|
||||
ScrollUp
|
||||
ScrollDown
|
||||
SpawnMultiCursor
|
||||
RemoveMultiCursor
|
||||
RemoveAllMultiCursors
|
||||
SkipMultiCursor
|
||||
UnbindKey
|
||||
```
|
||||
|
||||
You can also bind some mouse actions (these must be bound to mouse buttons)
|
||||
```
|
||||
MousePress
|
||||
MouseMultiCursor
|
||||
```
|
||||
|
||||
Here is the list of all possible keys you can bind:
|
||||
|
||||
```
|
||||
|
@ -262,6 +275,18 @@ Escape
|
|||
Enter
|
||||
```
|
||||
|
||||
You can also bind some mouse buttons (they may be bound to normal actions or mouse actions)
|
||||
|
||||
```
|
||||
MouseLeft
|
||||
MouseMiddle
|
||||
MouseRight
|
||||
MouseWheelUp
|
||||
MouseWheelDown
|
||||
MouseWheelLeft
|
||||
MouseWheelRight
|
||||
```
|
||||
|
||||
# Default keybinding configuration.
|
||||
|
||||
```json
|
||||
|
@ -276,10 +301,10 @@ Enter
|
|||
"ShiftRight": "SelectRight",
|
||||
"AltLeft": "WordLeft",
|
||||
"AltRight": "WordRight",
|
||||
"AltShiftRight": "SelectWordRight",
|
||||
"AltShiftLeft": "SelectWordLeft",
|
||||
"AltUp": "MoveLinesUp",
|
||||
"AltDown": "MoveLinesDown",
|
||||
"AltShiftRight": "SelectWordRight",
|
||||
"AltShiftLeft": "SelectWordLeft",
|
||||
"CtrlLeft": "StartOfLine",
|
||||
"CtrlRight": "EndOfLine",
|
||||
"CtrlShiftLeft": "SelectToStartOfLine",
|
||||
|
@ -291,13 +316,12 @@ Enter
|
|||
"CtrlShiftUp": "SelectToStart",
|
||||
"CtrlShiftDown": "SelectToEnd",
|
||||
"Enter": "InsertNewline",
|
||||
"Space": "InsertSpace",
|
||||
"CtrlH": "Backspace",
|
||||
"Backspace": "Backspace",
|
||||
"Alt-CtrlH": "DeleteWordLeft",
|
||||
"Alt-Backspace": "DeleteWordLeft",
|
||||
"Tab": "IndentSelection,InsertTab",
|
||||
"Backtab": "OutdentSelection",
|
||||
"Backtab": "OutdentSelection,OutdentLine",
|
||||
"CtrlO": "OpenFile",
|
||||
"CtrlS": "Save",
|
||||
"CtrlF": "Find",
|
||||
|
@ -336,8 +360,6 @@ Enter
|
|||
"Alt-b": "WordLeft",
|
||||
"Alt-a": "StartOfLine",
|
||||
"Alt-e": "EndOfLine",
|
||||
"Alt-p": "CursorUp",
|
||||
"Alt-n": "CursorDown",
|
||||
|
||||
// Integration with file managers
|
||||
"F1": "ToggleHelp",
|
||||
|
@ -347,10 +369,23 @@ Enter
|
|||
"F7": "Find",
|
||||
"F10": "Quit",
|
||||
"Esc": "Escape",
|
||||
|
||||
// Mouse bindings
|
||||
"MouseWheelUp": "ScrollUp",
|
||||
"MouseWheelDown": "ScrollDown",
|
||||
"MouseLeft": "MousePress",
|
||||
"MouseMiddle": "PastePrimary",
|
||||
"Ctrl-MouseLeft": "MouseMultiCursor",
|
||||
|
||||
// Multiple cursors bindings
|
||||
"Alt-n": "SpawnMultiCursor",
|
||||
"Alt-p": "RemoveMultiCursor",
|
||||
"Alt-c": "RemoveAllMultiCursors",
|
||||
"Alt-x": "SkipMultiCursor",
|
||||
}
|
||||
```
|
||||
|
||||
#Final notes
|
||||
# Final notes
|
||||
Note: On some old terminal emulators and on Windows machines, `CtrlH` should be used
|
||||
for backspace.
|
||||
|
||||
|
|
|
@ -21,6 +21,16 @@ This is almost always the current view, which you can get with `CurView()` as we
|
|||
|
||||
All available actions are listed in the keybindings section of the help.
|
||||
|
||||
For callbacks to mouse actions, you are also given the event info:
|
||||
|
||||
```lua
|
||||
function onMousePress(view, event)
|
||||
local x, y = event:Position()
|
||||
|
||||
return false
|
||||
end
|
||||
```
|
||||
|
||||
These functions should also return a boolean specifying whether the view
|
||||
should be relocated to the cursor or not after the action is complete.
|
||||
|
||||
|
@ -156,25 +166,25 @@ See this example to learn how to use `MakeCompletion` and `MakeCommand`
|
|||
|
||||
```lua
|
||||
local function StartsWith(String,Start)
|
||||
String = String:upper()
|
||||
Start = Start:upper()
|
||||
return string.sub(String,1,string.len(Start))==Start
|
||||
String = String:upper()
|
||||
Start = Start:upper()
|
||||
return string.sub(String,1,string.len(Start))==Start
|
||||
end
|
||||
|
||||
function complete(input)
|
||||
local allCompletions = {"Hello", "World", "Foo", "Bar"}
|
||||
local result = {}
|
||||
|
||||
for i,v in pairs(allCompletions) do
|
||||
if StartsWith(v, input) then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
return result
|
||||
local allCompletions = {"Hello", "World", "Foo", "Bar"}
|
||||
local result = {}
|
||||
|
||||
for i,v in pairs(allCompletions) do
|
||||
if StartsWith(v, input) then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function foo(arg)
|
||||
messenger:Message(arg)
|
||||
messenger:Message(arg)
|
||||
end
|
||||
|
||||
MakeCommand("foo", "example.foo", MakeCompletion("example.complete"))
|
||||
|
|
|
@ -1085,6 +1085,7 @@ function onRune(r, v)
|
|||
-- when converting go structs to lua
|
||||
-- It needs to be dereferenced because the function expects a non pointer struct
|
||||
v.Buf:Insert(-v.Cursor.Loc, charAt(autoclosePairs[i], 2))
|
||||
v:CursorLeft(false)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -1107,6 +1108,7 @@ function preInsertNewline(v)
|
|||
v:InsertNewline(false)
|
||||
v:InsertTab(false)
|
||||
v.Buf:Insert(-v.Cursor.Loc, "\n" .. ws)
|
||||
v:CursorLeft(false)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue