Feature: add MoveLinesUp (Alt + Up) and MoveLinesDown (Alt + Down) actions

This commit is contained in:
Saeed Rasooli
2016-10-11 23:05:41 +03:30
parent 0e4f700527
commit c1dd403ab9
3 changed files with 108 additions and 0 deletions

View File

@@ -968,6 +968,85 @@ func (v *View) DeleteLine(usePlugin bool) bool {
return true
}
// MoveLinesUp moves up the current line or selected lines if any
func (v *View) MoveLinesUp(usePlugin bool) bool {
if usePlugin && !PreActionCall("MoveLinesUp", v) {
return false
}
if v.Cursor.HasSelection() {
if v.Cursor.CurSelection[0].Y == 0 {
messenger.Message("Can not move further up")
return true
}
v.Buf.MoveLinesUp(
v.Cursor.CurSelection[0].Y,
v.Cursor.CurSelection[1].Y,
)
v.Cursor.UpN(1)
v.Cursor.CurSelection[0].Y -= 1
v.Cursor.CurSelection[1].Y -= 1
messenger.Message("Moved up selected line(s)")
} else {
if v.Cursor.Loc.Y == 0 {
messenger.Message("Can not move further up")
return true
}
v.Buf.MoveLinesUp(
v.Cursor.Loc.Y,
v.Cursor.Loc.Y + 1,
)
v.Cursor.UpN(1)
messenger.Message("Moved up current line")
}
v.Buf.IsModified = true
if usePlugin {
return PostActionCall("MoveLinesUp", v)
}
return true
}
// MoveLinesDown moves down the current line or selected lines if any
func (v *View) MoveLinesDown(usePlugin bool) bool {
if usePlugin && !PreActionCall("MoveLinesDown", v) {
return false
}
if v.Cursor.HasSelection() {
if v.Cursor.CurSelection[1].Y >= len(v.Buf.lines) {
messenger.Message("Can not move further down")
return true
}
v.Buf.MoveLinesDown(
v.Cursor.CurSelection[0].Y,
v.Cursor.CurSelection[1].Y,
)
v.Cursor.DownN(1)
v.Cursor.CurSelection[0].Y += 1
v.Cursor.CurSelection[1].Y += 1
messenger.Message("Moved down selected line(s)")
} else {
if v.Cursor.Loc.Y >= len(v.Buf.lines)-1 {
messenger.Message("Can not move further down")
return true
}
v.Buf.MoveLinesDown(
v.Cursor.Loc.Y,
v.Cursor.Loc.Y + 1,
)
v.Cursor.DownN(1)
messenger.Message("Moved down current line")
}
v.Buf.IsModified = true
if usePlugin {
return PostActionCall("MoveLinesDown", v)
}
return true
}
// Paste whatever is in the system clipboard into the buffer
// Delete and paste if the user has a selection
func (v *View) Paste(usePlugin bool) bool {

View File

@@ -52,6 +52,8 @@ var bindingActions = map[string]func(*View, bool) bool{
"CutLine": (*View).CutLine,
"DuplicateLine": (*View).DuplicateLine,
"DeleteLine": (*View).DeleteLine,
"MoveLinesUp": (*View).MoveLinesUp,
"MoveLinesDown": (*View).MoveLinesDown,
"IndentSelection": (*View).IndentSelection,
"OutdentSelection": (*View).OutdentSelection,
"Paste": (*View).Paste,
@@ -364,6 +366,8 @@ func DefaultBindings() map[string]string {
"ShiftRight": "SelectRight",
"AltLeft": "WordLeft",
"AltRight": "WordRight",
"AltUp": "MoveLinesUp",
"AltDown": "MoveLinesDown",
"AltShiftRight": "SelectWordRight",
"AltShiftLeft": "SelectWordLeft",
"CtrlLeft": "StartOfLine",

View File

@@ -132,6 +132,31 @@ func (la *LineArray) DeleteByte(pos Loc) {
la.lines[pos.Y] = la.lines[pos.Y][:pos.X+copy(la.lines[pos.Y][pos.X:], la.lines[pos.Y][pos.X+1:])]
}
func (la *LineArray) MoveLinesUp(y0 int, y1 int) {
// 0 < y0 < y1 <= len(la.lines)
if y0 < 1 || y0 >= y1 || y1 > len(la.lines) {
return // what to do? FIXME
}
before := la.lines[y0-1]
for y := y0 ; y < y1 ; y ++ {
la.lines[y-1] = la.lines[y]
}
la.lines[y1-1] = before
}
func (la *LineArray) MoveLinesDown(y0 int, y1 int) {
// 0 <= y0 < y1 < len(la.lines)
if y0 < 0 || y0 >= y1 || y1 >= len(la.lines) {
return // what to do? FIXME
}
after := la.lines[y1]
for y := y1-1 ; y >= y0 ; y -- {
la.lines[y+1] = la.lines[y]
}
la.lines[y0] = after
}
// Substr returns the string representation between two locations
func (la *LineArray) Substr(start, end Loc) string {
startX := runeToByteIndex(start.X, la.lines[start.Y])