diff --git a/README.md b/README.md index 156da18..45be296 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,7 @@ Some keys just... don't map correctly / too easily for various reasons. Here, we | peco.DeleteBackwardChar | Delete one character backward | | peco.DeleteForwardWord | Delete one word forward | | peco.DeleteBackwardWord | Delete one word backward | +| peco.InvertSelection | Inverts the selected lines | | peco.KillEndOfLine | Delete the characters under the cursor until the end of the line | | peco.DeleteAll | Delete all entered characters | | peco.RefreshScreen | Redraws the screen. Note that this effectively re-runs your query | diff --git a/action.go b/action.go index edd5c39..7d063f4 100644 --- a/action.go +++ b/action.go @@ -1,9 +1,10 @@ package peco import ( + "unicode" + "github.com/nsf/termbox-go" "github.com/peco/peco/keyseq" - "unicode" ) // Action describes an action that can be executed upon receiving user @@ -51,6 +52,7 @@ func init() { nameToActions = map[string]Action{} defaultKeyBinding = map[string]Action{} + ActionFunc(doInvertSelection).Register("InvertSelection") ActionFunc(doBeginningOfLine).Register("BeginningOfLine", termbox.KeyCtrlA) ActionFunc(doBackwardChar).Register("BackwardChar", termbox.KeyCtrlB) ActionFunc(doBackwardWord).Register("BackwardWord") @@ -285,6 +287,32 @@ func doToggleSelectionAndSelectNext(i *Input, ev termbox.Event) { }) } +func doInvertSelection(i *Input, _ termbox.Event) { + lines := i.selection.GetSelection() + if lines == nil { + lines = []int{} + } + lines = append(lines, i.SelectedRange().GetSelection()...) + total := i.GetLinesCount() + newSelection := make([]int, total-len(lines)) + + checkIdx := 0 + newIdx := 0 + linesLen := len(lines) + for x := range make([]struct{}, total) { + if linesLen > checkIdx && lines[checkIdx] == x+1 { + // skip + checkIdx++ + } else { + newSelection[newIdx] = x + 1 + newIdx++ + } + } + + i.selection.SetSelection(newSelection) + i.DrawMatches(nil) +} + func doDeleteBackwardWord(i *Input, _ termbox.Event) { if i.CaretPos() == 0 { return diff --git a/selection.go b/selection.go index f91a2a4..a8c73be 100644 --- a/selection.go +++ b/selection.go @@ -17,6 +17,12 @@ func NewSelection() *Selection { return &Selection{nil, newMutex()} } +func (s *Selection) SetSelection(x []int) { + s.mutex.Lock() + defer s.mutex.Unlock() + s.selection = x +} + func (s *Selection) GetSelection() []int { s.mutex.Lock() defer s.mutex.Unlock()