Merge pull request #126 from k0kubun/select_mode

Enable selecting by range
This commit is contained in:
lestrrat 2014-07-04 09:22:06 +09:00
commit f7322d6a30
4 changed files with 78 additions and 24 deletions

View file

@ -205,9 +205,11 @@ key item to use Alt/Option key as a mask.
| peco.SelectNext | Selects next line |
| peco.ToggleSelection | Selects the current line, and saves it |
| peco.ToggleSelectionAndSelectNext | Selects the current line, saves it, and proceeds to the next line |
| peco.ToggleSelectMode | Start selecting by range, or append selecting range to selections |
| peco.CancelSelectMode | Finish selecting by range and cancel range selection |
| peco.RotateMatcher | Rotate between matchers (by default, ignore-case/no-ignore-case)|
| peco.Finish | Exits from peco, with success status |
| peco.Cancel | Exits from peco, with failure status |
| peco.Finish | Exits from peco with success status |
| peco.Cancel | Exits from peco with failure status, or cancel select mode |
### Default Keymap

View file

@ -98,6 +98,8 @@ func init() {
)
ActionFunc(doSelectAll).Register("SelectAll")
ActionFunc(doSelectVisible).Register("SelectVisible")
ActionFunc(doToggleSelectMode).Register("ToggleSelectMode")
ActionFunc(doCancelSelectMode).Register("CancelSelectMode")
}
func doRotateMatcher(i *Input, ev termbox.Event) {
@ -119,6 +121,25 @@ func doToggleSelection(i *Input, _ termbox.Event) {
i.selection.Add(i.currentLine)
}
func doToggleSelectMode(i *Input, _ termbox.Event) {
if i.IsSelectMode() {
for _, line := range i.RangeSelection() {
i.selection.Add(line)
}
i.selection.Add(i.currentLine)
i.selectionRangeStart = NoSelectionRange
} else {
i.selectionRangeStart = i.currentLine
}
i.DrawMatches(nil)
}
func doCancelSelectMode(i *Input, _ termbox.Event) {
i.selectionRangeStart = NoSelectionRange
i.DrawMatches(nil)
}
func doSelectNone(i *Input, _ termbox.Event) {
i.selection.Clear()
i.DrawMatches(nil)
@ -145,7 +166,7 @@ func doFinish(i *Input, _ termbox.Event) {
i.selection.Add(i.currentLine)
i.result = []Match{}
for _, lineno := range i.selection {
for _, lineno := range append(i.selection, i.RangeSelection()...) {
if lineno <= len(i.current) {
i.result = append(i.result, i.current[lineno-1])
}
@ -154,6 +175,11 @@ func doFinish(i *Input, _ termbox.Event) {
}
func doCancel(i *Input, ev termbox.Event) {
if i.IsSelectMode() {
doCancelSelectMode(i, ev)
return
}
// peco.Cancel -> end program, exit with failure
i.ExitWith(1)
}

66
ctx.go
View file

@ -66,26 +66,27 @@ func (s Selection) Less(i, j int) bool {
// Ctx contains all the important data. while you can easily access
// data in this struct from anwyehre, only do so via channels
type Ctx struct {
enableSep bool
result []Match
loopCh chan struct{}
queryCh chan string
drawCh chan []Match
statusMsgCh chan string
pagingCh chan PagingRequest
mutex sync.Mutex
query []rune
caretPos int
currentLine int
currentPage struct { index, offset, perPage int }
selection Selection
lines []Match
current []Match
bufferSize int
config *Config
Matchers []Matcher
CurrentMatcher int
ExitStatus int
enableSep bool
result []Match
loopCh chan struct{}
queryCh chan string
drawCh chan []Match
statusMsgCh chan string
pagingCh chan PagingRequest
mutex sync.Mutex
query []rune
caretPos int
currentLine int
currentPage struct { index, offset, perPage int }
selection Selection
lines []Match
current []Match
bufferSize int
config *Config
Matchers []Matcher
CurrentMatcher int
ExitStatus int
selectionRangeStart int
wait *sync.WaitGroup
}
@ -116,10 +117,13 @@ func NewCtx(o CtxOptions) *Ctx {
},
0,
0,
NoSelectionRange,
&sync.WaitGroup{},
}
}
const NoSelectionRange = -1
func (c *Ctx) ReadConfig(file string) error {
if err := c.config.ReadFilename(file); err != nil {
return err
@ -141,6 +145,28 @@ func (c *Ctx) IsBufferOverflowing() bool {
return len(c.lines) > c.bufferSize
}
func (c *Ctx) IsSelectMode() bool {
return c.selectionRangeStart != NoSelectionRange
}
func (c *Ctx) RangeSelection() Selection {
if !c.IsSelectMode() {
return Selection{}
}
selectedLines := []int{}
if c.selectionRangeStart < c.currentLine {
for i := c.selectionRangeStart; i < c.currentLine; i++ {
selectedLines = append(selectedLines, i)
}
} else {
for i := c.selectionRangeStart; i > c.currentLine; i-- {
selectedLines = append(selectedLines, i)
}
}
return Selection(selectedLines)
}
func (c *Ctx) Result() []Match {
return c.result
}

View file

@ -207,7 +207,7 @@ CALCULATE_PAGE:
if n+currentPage.offset == v.currentLine {
fgAttr = v.config.Style.Selected.fg
bgAttr = v.config.Style.Selected.bg
} else if v.selection.Has(n + currentPage.offset) {
} else if v.selection.Has(n + currentPage.offset) || v.RangeSelection().Has(n + currentPage.offset) {
fgAttr = v.config.Style.SavedSelection.fg
bgAttr = v.config.Style.SavedSelection.bg
}