mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-20 07:47:15 +09:00
Make cursor movement automatic on insert + remove
This changes the behavior of cursor movement so that all cursors are adjusted when a change is made to the buffer. Cursors don't have to be manually moved after calling Insert or Remove, those functions will move the cursor properly on their own. This should fix issues 1-3 mentioned in the multiple cursors discussion. Ref #5
This commit is contained in:
@@ -554,7 +554,7 @@ func (v *View) InsertSpace(usePlugin bool) bool {
|
||||
v.Cursor.ResetSelection()
|
||||
}
|
||||
v.Buf.Insert(v.Cursor.Loc, " ")
|
||||
v.Cursor.Right()
|
||||
// v.Cursor.Right()
|
||||
|
||||
if usePlugin {
|
||||
return PostActionCall("InsertSpace", v)
|
||||
@@ -574,15 +574,15 @@ func (v *View) InsertNewline(usePlugin bool) bool {
|
||||
v.Cursor.ResetSelection()
|
||||
}
|
||||
|
||||
v.Buf.Insert(v.Cursor.Loc, "\n")
|
||||
ws := GetLeadingWhitespace(v.Buf.Line(v.Cursor.Y))
|
||||
v.Cursor.Right()
|
||||
v.Buf.Insert(v.Cursor.Loc, "\n")
|
||||
// v.Cursor.Right()
|
||||
|
||||
if v.Buf.Settings["autoindent"].(bool) {
|
||||
v.Buf.Insert(v.Cursor.Loc, ws)
|
||||
for i := 0; i < len(ws); i++ {
|
||||
v.Cursor.Right()
|
||||
}
|
||||
// for i := 0; i < len(ws); i++ {
|
||||
// v.Cursor.Right()
|
||||
// }
|
||||
|
||||
// Remove the whitespaces if keepautoindent setting is off
|
||||
if IsSpacesOrTabs(v.Buf.Line(v.Cursor.Y-1)) && !v.Buf.Settings["keepautoindent"].(bool) {
|
||||
@@ -622,18 +622,10 @@ func (v *View) Backspace(usePlugin bool) bool {
|
||||
tabSize := int(v.Buf.Settings["tabsize"].(float64))
|
||||
if v.Buf.Settings["tabstospaces"].(bool) && IsSpaces(lineStart) && len(lineStart) != 0 && len(lineStart)%tabSize == 0 {
|
||||
loc := v.Cursor.Loc
|
||||
v.Cursor.Loc = loc.Move(-tabSize, v.Buf)
|
||||
cx, cy := v.Cursor.X, v.Cursor.Y
|
||||
v.Cursor.Loc = loc
|
||||
v.Buf.Remove(loc.Move(-tabSize, v.Buf), loc)
|
||||
v.Cursor.X, v.Cursor.Y = cx, cy
|
||||
} else {
|
||||
v.Cursor.Left()
|
||||
cx, cy := v.Cursor.X, v.Cursor.Y
|
||||
v.Cursor.Right()
|
||||
loc := v.Cursor.Loc
|
||||
v.Buf.Remove(loc.Move(-1, v.Buf), loc)
|
||||
v.Cursor.X, v.Cursor.Y = cx, cy
|
||||
}
|
||||
}
|
||||
v.Cursor.LastVisualX = v.Cursor.GetVisualX()
|
||||
@@ -753,7 +745,6 @@ func (v *View) OutdentLine(usePlugin bool) bool {
|
||||
break
|
||||
}
|
||||
v.Buf.Remove(Loc{0, v.Cursor.Y}, Loc{1, v.Cursor.Y})
|
||||
v.Cursor.X -= 1
|
||||
}
|
||||
v.Cursor.Relocate()
|
||||
|
||||
@@ -816,9 +807,9 @@ func (v *View) InsertTab(usePlugin bool) bool {
|
||||
tabBytes := len(v.Buf.IndentString())
|
||||
bytesUntilIndent := tabBytes - (v.Cursor.GetVisualX() % tabBytes)
|
||||
v.Buf.Insert(v.Cursor.Loc, v.Buf.IndentString()[:bytesUntilIndent])
|
||||
for i := 0; i < bytesUntilIndent; i++ {
|
||||
v.Cursor.Right()
|
||||
}
|
||||
// for i := 0; i < bytesUntilIndent; i++ {
|
||||
// v.Cursor.Right()
|
||||
// }
|
||||
|
||||
if usePlugin {
|
||||
return PostActionCall("InsertTab", v)
|
||||
@@ -1088,7 +1079,7 @@ func (v *View) DuplicateLine(usePlugin bool) bool {
|
||||
} else {
|
||||
v.Cursor.End()
|
||||
v.Buf.Insert(v.Cursor.Loc, "\n"+v.Buf.Line(v.Cursor.Y))
|
||||
v.Cursor.Right()
|
||||
// v.Cursor.Right()
|
||||
}
|
||||
|
||||
messenger.Message("Duplicated line")
|
||||
@@ -1810,7 +1801,7 @@ func (v *View) PlayMacro(usePlugin bool) bool {
|
||||
v.Cursor.ResetSelection()
|
||||
}
|
||||
v.Buf.Insert(v.Cursor.Loc, string(t))
|
||||
v.Cursor.Right()
|
||||
// v.Cursor.Right()
|
||||
|
||||
for pl := range loadedPlugins {
|
||||
_, err := Call(pl+".onRune", string(t), v)
|
||||
|
||||
@@ -104,6 +104,16 @@ func (eh *EventHandler) Insert(start Loc, text string) {
|
||||
}
|
||||
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
|
||||
@@ -115,6 +125,17 @@ func (eh *EventHandler) Remove(start, end Loc) {
|
||||
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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -522,7 +522,6 @@ func (v *View) HandleEvent(event tcell.Event) {
|
||||
v.Cursor.ResetSelection()
|
||||
}
|
||||
v.Buf.Insert(v.Cursor.Loc, string(e.Rune()))
|
||||
v.Cursor.Right()
|
||||
|
||||
for pl := range loadedPlugins {
|
||||
_, err := Call(pl+".onRune", string(e.Rune()), v)
|
||||
|
||||
Reference in New Issue
Block a user