@@ -490,38 +490,92 @@ func (h *BufPane) SelectToEndOfLine() bool {
490490 return true
491491}
492492
493- // ParagraphPrevious moves the cursor to the previous empty line, or beginning of the buffer if there's none
494- func (h * BufPane ) ParagraphPrevious () bool {
493+ func (h * BufPane ) paragraphPrevious () {
495494 var line int
495+ // Skip to the first non-empty line
496496 for line = h .Cursor .Y ; line > 0 ; line -- {
497- if len (h .Buf .LineBytes (line )) == 0 && line != h .Cursor .Y {
497+ if len (h .Buf .LineBytes (line )) != 0 {
498+ break
499+ }
500+ }
501+ // Find the first empty line
502+ for ; line > 0 ; line -- {
503+ if len (h .Buf .LineBytes (line )) == 0 {
498504 h .Cursor .X = 0
499505 h .Cursor .Y = line
500506 break
501507 }
502508 }
503- // If no empty line found. move cursor to end of buffer
509+ // If no empty line was found, move the cursor to the start of the buffer
504510 if line == 0 {
505511 h .Cursor .Loc = h .Buf .Start ()
506512 }
507- h .Relocate ()
508- return true
509513}
510514
511- // ParagraphNext moves the cursor to the next empty line, or end of the buffer if there's none
512- func (h * BufPane ) ParagraphNext () bool {
515+ func (h * BufPane ) paragraphNext () {
513516 var line int
517+ // Skip to the first non-empty line
514518 for line = h .Cursor .Y ; line < h .Buf .LinesNum (); line ++ {
515- if len (h .Buf .LineBytes (line )) == 0 && line != h .Cursor .Y {
519+ if len (h .Buf .LineBytes (line )) != 0 {
520+ break
521+ }
522+ }
523+ // Find the first empty line
524+ for ; line < h .Buf .LinesNum (); line ++ {
525+ if len (h .Buf .LineBytes (line )) == 0 {
516526 h .Cursor .X = 0
517527 h .Cursor .Y = line
518528 break
519529 }
520530 }
521- // If no empty line found. move cursor to end of buffer
531+ // If no empty line was found, move the cursor to the end of the buffer
522532 if line == h .Buf .LinesNum () {
523533 h .Cursor .Loc = h .Buf .End ()
524534 }
535+ }
536+
537+ // ParagraphPrevious moves the cursor to the first empty line that comes before
538+ // the paragraph closest to the cursor, or beginning of the buffer if there
539+ // isn't a paragraph
540+ func (h * BufPane ) ParagraphPrevious () bool {
541+ h .Cursor .Deselect (true )
542+ h .paragraphPrevious ()
543+ h .Relocate ()
544+ return true
545+ }
546+
547+ // ParagraphNext moves the cursor to the first empty line that comes after the
548+ // paragraph closest to the cursor, or end of the buffer if there isn't a
549+ // paragraph
550+ func (h * BufPane ) ParagraphNext () bool {
551+ h .Cursor .Deselect (true )
552+ h .paragraphNext ()
553+ h .Relocate ()
554+ return true
555+ }
556+
557+ // SelectToParagraphPrevious selects to the first empty line that comes before
558+ // the paragraph closest to the cursor, or beginning of the buffer if there
559+ // isn't a paragraph
560+ func (h * BufPane ) SelectToParagraphPrevious () bool {
561+ if ! h .Cursor .HasSelection () {
562+ h .Cursor .OrigSelection [0 ] = h .Cursor .Loc
563+ }
564+ h .paragraphPrevious ()
565+ h .Cursor .SelectTo (h .Cursor .Loc )
566+ h .Relocate ()
567+ return true
568+ }
569+
570+ // SelectToParagraphNext selects to the first empty line that comes after the
571+ // paragraph closest to the cursor, or end of the buffer if there isn't a
572+ // paragraph
573+ func (h * BufPane ) SelectToParagraphNext () bool {
574+ if ! h .Cursor .HasSelection () {
575+ h .Cursor .OrigSelection [0 ] = h .Cursor .Loc
576+ }
577+ h .paragraphNext ()
578+ h .Cursor .SelectTo (h .Cursor .Loc )
525579 h .Relocate ()
526580 return true
527581}
@@ -1068,12 +1122,27 @@ func (h *BufPane) ToggleHighlightSearch() bool {
10681122
10691123// UnhighlightSearch unhighlights all instances of the last used search term
10701124func (h * BufPane ) UnhighlightSearch () bool {
1125+ if ! h .Buf .HighlightSearch {
1126+ return false
1127+ }
10711128 h .Buf .HighlightSearch = false
10721129 return true
10731130}
10741131
1132+ // ResetSearch resets the last used search term
1133+ func (h * BufPane ) ResetSearch () bool {
1134+ if h .Buf .LastSearch != "" {
1135+ h .Buf .LastSearch = ""
1136+ return true
1137+ }
1138+ return false
1139+ }
1140+
10751141// FindNext searches forwards for the last used search term
10761142func (h * BufPane ) FindNext () bool {
1143+ if h .Buf .LastSearch == "" {
1144+ return false
1145+ }
10771146 // If the cursor is at the start of a selection and we search we want
10781147 // to search from the end of the selection in the case that
10791148 // the selection is a search result in which case we wouldn't move at
@@ -1100,6 +1169,9 @@ func (h *BufPane) FindNext() bool {
11001169
11011170// FindPrevious searches backwards for the last used search term
11021171func (h * BufPane ) FindPrevious () bool {
1172+ if h .Buf .LastSearch == "" {
1173+ return false
1174+ }
11031175 // If the cursor is at the end of a selection and we search we want
11041176 // to search from the beginning of the selection in the case that
11051177 // the selection is a search result in which case we wouldn't move at
@@ -1148,15 +1220,19 @@ func (h *BufPane) DiffPrevious() bool {
11481220
11491221// Undo undoes the last action
11501222func (h * BufPane ) Undo () bool {
1151- h .Buf .Undo ()
1223+ if ! h .Buf .Undo () {
1224+ return false
1225+ }
11521226 InfoBar .Message ("Undid action" )
11531227 h .Relocate ()
11541228 return true
11551229}
11561230
11571231// Redo redoes the last action
11581232func (h * BufPane ) Redo () bool {
1159- h .Buf .Redo ()
1233+ if ! h .Buf .Redo () {
1234+ return false
1235+ }
11601236 InfoBar .Message ("Redid action" )
11611237 h .Relocate ()
11621238 return true
@@ -1396,10 +1472,14 @@ func (h *BufPane) paste(clip string) {
13961472func (h * BufPane ) JumpToMatchingBrace () bool {
13971473 matchingBrace , left , found := h .Buf .FindMatchingBrace (h .Cursor .Loc )
13981474 if found {
1399- if left {
1400- h .Cursor .GotoLoc (matchingBrace )
1475+ if h .Buf .Settings ["matchbraceleft" ].(bool ) {
1476+ if left {
1477+ h .Cursor .GotoLoc (matchingBrace )
1478+ } else {
1479+ h .Cursor .GotoLoc (matchingBrace .Move (1 , h .Buf ))
1480+ }
14011481 } else {
1402- h .Cursor .GotoLoc (matchingBrace . Move ( 1 , h . Buf ) )
1482+ h .Cursor .GotoLoc (matchingBrace )
14031483 }
14041484 h .Relocate ()
14051485 return true
@@ -1577,10 +1657,9 @@ func (h *BufPane) ToggleRuler() bool {
15771657 return true
15781658}
15791659
1580- // ClearStatus clears the messenger bar
1660+ // ClearStatus clears the infobar. It is an alias for ClearInfo.
15811661func (h * BufPane ) ClearStatus () bool {
1582- InfoBar .Message ("" )
1583- return true
1662+ return h .ClearInfo ()
15841663}
15851664
15861665// ToggleHelp toggles the help screen
@@ -1635,12 +1714,18 @@ func (h *BufPane) Escape() bool {
16351714
16361715// Deselect deselects on the current cursor
16371716func (h * BufPane ) Deselect () bool {
1717+ if ! h .Cursor .HasSelection () {
1718+ return false
1719+ }
16381720 h .Cursor .Deselect (true )
16391721 return true
16401722}
16411723
16421724// ClearInfo clears the infobar
16431725func (h * BufPane ) ClearInfo () bool {
1726+ if InfoBar .Msg == "" {
1727+ return false
1728+ }
16441729 InfoBar .Message ("" )
16451730 return true
16461731}
@@ -1731,6 +1816,10 @@ func (h *BufPane) AddTab() bool {
17311816// PreviousTab switches to the previous tab in the tab list
17321817func (h * BufPane ) PreviousTab () bool {
17331818 tabsLen := len (Tabs .List )
1819+ if tabsLen == 1 {
1820+ return false
1821+ }
1822+
17341823 a := Tabs .Active () + tabsLen
17351824 Tabs .SetActive ((a - 1 ) % tabsLen )
17361825
@@ -1739,8 +1828,13 @@ func (h *BufPane) PreviousTab() bool {
17391828
17401829// NextTab switches to the next tab in the tab list
17411830func (h * BufPane ) NextTab () bool {
1831+ tabsLen := len (Tabs .List )
1832+ if tabsLen == 1 {
1833+ return false
1834+ }
1835+
17421836 a := Tabs .Active ()
1743- Tabs .SetActive ((a + 1 ) % len ( Tabs . List ) )
1837+ Tabs .SetActive ((a + 1 ) % tabsLen )
17441838
17451839 return true
17461840}
@@ -1776,6 +1870,10 @@ func (h *BufPane) Unsplit() bool {
17761870
17771871// NextSplit changes the view to the next split
17781872func (h * BufPane ) NextSplit () bool {
1873+ if len (h .tab .Panes ) == 1 {
1874+ return false
1875+ }
1876+
17791877 a := h .tab .active
17801878 if a < len (h .tab .Panes )- 1 {
17811879 a ++
@@ -1790,6 +1888,10 @@ func (h *BufPane) NextSplit() bool {
17901888
17911889// PreviousSplit changes the view to the previous split
17921890func (h * BufPane ) PreviousSplit () bool {
1891+ if len (h .tab .Panes ) == 1 {
1892+ return false
1893+ }
1894+
17931895 a := h .tab .active
17941896 if a > 0 {
17951897 a --
@@ -1991,6 +2093,9 @@ func (h *BufPane) MouseMultiCursor(e *tcell.EventMouse) bool {
19912093// SkipMultiCursor moves the current multiple cursor to the next available position
19922094func (h * BufPane ) SkipMultiCursor () bool {
19932095 lastC := h .Buf .GetCursor (h .Buf .NumCursors () - 1 )
2096+ if ! lastC .HasSelection () {
2097+ return false
2098+ }
19942099 sel := lastC .GetSelection ()
19952100 searchStart := lastC .CurSelection [1 ]
19962101
@@ -2026,17 +2131,24 @@ func (h *BufPane) RemoveMultiCursor() bool {
20262131 h .Buf .RemoveCursor (h .Buf .NumCursors () - 1 )
20272132 h .Buf .SetCurCursor (h .Buf .NumCursors () - 1 )
20282133 h .Buf .UpdateCursors ()
2029- } else {
2134+ } else if h . multiWord {
20302135 h .multiWord = false
2136+ h .Cursor .Deselect (true )
2137+ } else {
2138+ return false
20312139 }
20322140 h .Relocate ()
20332141 return true
20342142}
20352143
20362144// RemoveAllMultiCursors removes all cursors except the base cursor
20372145func (h * BufPane ) RemoveAllMultiCursors () bool {
2038- h .Buf .ClearCursors ()
2039- h .multiWord = false
2146+ if h .Buf .NumCursors () > 1 || h .multiWord {
2147+ h .Buf .ClearCursors ()
2148+ h .multiWord = false
2149+ } else {
2150+ return false
2151+ }
20402152 h .Relocate ()
20412153 return true
20422154}
0 commit comments