Skip to content

Commit

Permalink
Implemented '%' movement command for normal mode
Browse files Browse the repository at this point in the history
  • Loading branch information
driusan committed May 2, 2020
1 parent 9ae5e05 commit 589a288
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 1 deletion.
7 changes: 6 additions & 1 deletion kbmap/normalmode.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,12 @@ func normalMap(e key.Event, buff *demodel.CharBuffer, v demodel.Viewport) (demod
}
return NormalMode, demodel.DirectionNone, nil
case key.Code5:
if e.Modifiers == 0 {
if e.Modifiers&key.ModShift != 0 {
// '%'
actions.MoveCursor(position.MatchingBracket, position.MatchingBracket, buff)
return NormalMode, demodel.DirectionDown, nil

} else if e.Modifiers == 0 {
Repeat = Repeat*10 + 5
}
return NormalMode, demodel.DirectionNone, nil
Expand Down
102 changes: 102 additions & 0 deletions position/positions.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,105 @@ func PrevWordStart(buff demodel.CharBuffer) (uint, error) {
// Got to the start of the buffer, so this must be the start.
return 0, nil
}

func MatchingBracket(buff demodel.CharBuffer) (uint, error) {
if len(buff.Buffer) == 0 || buff.Dot.Start >= uint(len(buff.Buffer)) {
return 0, ErrInvalid
}
cur := buff.Buffer[buff.Dot.Start]

var forwardto, backwardto byte
switch cur {
case '{':
forwardto = '}'
case '}':
backwardto = '{'
case '(':
forwardto = ')'
case ')':
backwardto = '('
case '[':
forwardto = ']'
case ']':
backwardto = '['
case '<':
forwardto = '>'
case '>':
backwardto = '<'
}

if forwardto != 0 {
extralevels := 0
for i := buff.Dot.Start + 1; i < uint(len(buff.Buffer)); i++ {
if buff.Buffer[i] == cur {
extralevels++
}
if buff.Buffer[i] == forwardto {
if extralevels > 0 {
extralevels--
} else {
return i, nil
}
}
}
} else if backwardto != 0 {
extralevels := 0
for i := buff.Dot.Start - 1; i >= 0; i-- {
if buff.Buffer[i] == cur {
extralevels++
}

if buff.Buffer[i] == backwardto {
if extralevels > 0 {
extralevels--
} else {
return i, nil
}
}
}
} else {
// Go backwards to the start of the current block (for some
// definition of block.
extrasquigly := 0
extraround := 0
extrasquare := 0
extraangle := 0
for i := buff.Dot.Start - 1; i >= 0; i-- {
// If there was a block inside this block, skip it
if buff.Buffer[i] == '}' {
extrasquigly++
} else if buff.Buffer[i] == ')' {
extraround++
} else if buff.Buffer[i] == ']' {
extrasquare++
} else if buff.Buffer[i] == '>' {
extraangle++
} else if buff.Buffer[i] == '{' {
if extrasquigly > 0 {
extrasquigly--
} else {
return i, nil
}
} else if buff.Buffer[i] == '(' {
if extraround > 0 {
extraround--
} else {
return i, nil
}
} else if buff.Buffer[i] == '[' {
if extrasquare > 0 {
extrasquare--
} else {
return i, nil
}
} else if buff.Buffer[i] == '<' {
if extraangle > 0 {
extraangle--
} else {
return i, nil
}
}
}
}
return buff.Dot.Start, ErrInvalid
}
2 changes: 2 additions & 0 deletions position/positions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestPositionsDontOverflow(t *testing.T) {
CurTagWordEnd(buff)
NextWordStart(buff)
PrevWordStart(buff)
MatchingBracket(buff)

// Now try with a buffer and dot.End > len(buffer)
buff.Buffer = []byte{'a'}
Expand Down Expand Up @@ -71,5 +72,6 @@ func TestPositionsDontOverflow(t *testing.T) {
CurTagWordEnd(buff)
NextWordStart(buff)
PrevWordStart(buff)
MatchingBracket(buff)

}

0 comments on commit 589a288

Please sign in to comment.