diff options
author | Junegunn Choi <junegunn.c@gmail.com> | 2015-01-12 03:01:24 +0900 |
---|---|---|
committer | Junegunn Choi <junegunn.c@gmail.com> | 2015-01-12 03:18:40 +0900 |
commit | 7a2bc2cada971c7a390d09b0afda34780ff56fb6 (patch) | |
tree | caa19fa8bf404a854c9e2cdf6eb08194e1733a6f /src | |
parent | 9dbf6b02d24b52ae43e36905bbb1e83087e1dfe9 (diff) |
Lint
Diffstat (limited to 'src')
-rw-r--r-- | src/algo.go | 29 | ||||
-rw-r--r-- | src/atomicbool.go | 5 | ||||
-rw-r--r-- | src/cache.go | 6 | ||||
-rw-r--r-- | src/cache_test.go | 2 | ||||
-rw-r--r-- | src/chunklist.go | 20 | ||||
-rw-r--r-- | src/chunklist_test.go | 4 | ||||
-rw-r--r-- | src/constants.go | 19 | ||||
-rw-r--r-- | src/core.go | 43 | ||||
-rw-r--r-- | src/curses/curses.go | 214 | ||||
-rw-r--r-- | src/eventbox.go | 11 | ||||
-rw-r--r-- | src/eventbox_test.go | 14 | ||||
-rw-r--r-- | src/item.go | 16 | ||||
-rw-r--r-- | src/matcher.go | 31 | ||||
-rw-r--r-- | src/merger.go | 10 | ||||
-rw-r--r-- | src/options.go | 43 | ||||
-rw-r--r-- | src/options_test.go | 10 | ||||
-rw-r--r-- | src/pattern.go | 77 | ||||
-rw-r--r-- | src/pattern_test.go | 54 | ||||
-rw-r--r-- | src/reader.go | 10 | ||||
-rw-r--r-- | src/reader_test.go | 18 | ||||
-rw-r--r-- | src/terminal.go | 188 | ||||
-rw-r--r-- | src/tokenizer.go | 47 | ||||
-rw-r--r-- | src/tokenizer_test.go | 4 | ||||
-rw-r--r-- | src/util.go | 4 |
24 files changed, 476 insertions, 403 deletions
diff --git a/src/algo.go b/src/algo.go index e0c173f2..5f15ab3b 100644 --- a/src/algo.go +++ b/src/algo.go @@ -10,6 +10,7 @@ import "strings" * In short: They try to do as little work as possible. */ +// FuzzyMatch performs fuzzy-match func FuzzyMatch(caseSensitive bool, input *string, pattern []rune) (int, int) { runes := []rune(*input) @@ -36,7 +37,7 @@ func FuzzyMatch(caseSensitive bool, input *string, pattern []rune) (int, int) { if sidx < 0 { sidx = index } - if pidx += 1; pidx == len(pattern) { + if pidx++; pidx == len(pattern) { eidx = index + 1 break } @@ -44,14 +45,14 @@ func FuzzyMatch(caseSensitive bool, input *string, pattern []rune) (int, int) { } if sidx >= 0 && eidx >= 0 { - pidx -= 1 + pidx-- for index := eidx - 1; index >= sidx; index-- { char := runes[index] if !caseSensitive && char >= 65 && char <= 90 { char += 32 } if char == pattern[pidx] { - if pidx -= 1; pidx < 0 { + if pidx--; pidx < 0 { sidx = index break } @@ -62,6 +63,8 @@ func FuzzyMatch(caseSensitive bool, input *string, pattern []rune) (int, int) { return -1, -1 } +// ExactMatchStrings performs exact-match using strings package. +// Currently not used. func ExactMatchStrings(caseSensitive bool, input *string, pattern []rune) (int, int) { var str string if caseSensitive { @@ -77,15 +80,13 @@ func ExactMatchStrings(caseSensitive bool, input *string, pattern []rune) (int, return -1, -1 } -/* - * This is a basic string searching algorithm that handles case sensitivity. - * Although naive, it still performs better than the combination of - * strings.ToLower + strings.Index for typical fzf use cases where input - * strings and patterns are not very long. - * - * We might try to implement better algorithms in the future: - * http://en.wikipedia.org/wiki/String_searching_algorithm - */ +// ExactMatchNaive is a basic string searching algorithm that handles case +// sensitivity. Although naive, it still performs better than the combination +// of strings.ToLower + strings.Index for typical fzf use cases where input +// strings and patterns are not very long. +// +// We might try to implement better algorithms in the future: +// http://en.wikipedia.org/wiki/String_searching_algorithm func ExactMatchNaive(caseSensitive bool, input *string, pattern []rune) (int, int) { runes := []rune(*input) numRunes := len(runes) @@ -101,7 +102,7 @@ func ExactMatchNaive(caseSensitive bool, input *string, pattern []rune) (int, in char += 32 } if pattern[pidx] == char { - pidx += 1 + pidx++ if pidx == plen { return index - plen + 1, index + 1 } @@ -113,6 +114,7 @@ func ExactMatchNaive(caseSensitive bool, input *string, pattern []rune) (int, in return -1, -1 } +// PrefixMatch performs prefix-match func PrefixMatch(caseSensitive bool, input *string, pattern []rune) (int, int) { runes := []rune(*input) if len(runes) < len(pattern) { @@ -131,6 +133,7 @@ func PrefixMatch(caseSensitive bool, input *string, pattern []rune) (int, int) { return 0, len(pattern) } +// SuffixMatch performs suffix-match func SuffixMatch(caseSensitive bool, input *string, pattern []rune) (int, int) { runes := []rune(strings.TrimRight(*input, " ")) trimmedLen := len(runes) diff --git a/src/atomicbool.go b/src/atomicbool.go index f2f4894f..b264724c 100644 --- a/src/atomicbool.go +++ b/src/atomicbool.go @@ -2,23 +2,28 @@ package fzf import "sync" +// AtomicBool is a boxed-class that provides synchronized access to the +// underlying boolean value type AtomicBool struct { mutex sync.Mutex state bool } +// NewAtomicBool returns a new AtomicBool func NewAtomicBool(initialState bool) *AtomicBool { return &AtomicBool{ mutex: sync.Mutex{}, state: initialState} } +// Get returns the current boolean value synchronously func (a *AtomicBool) Get() bool { a.mutex.Lock() defer a.mutex.Unlock() return a.state } +// Set updates the boolean value synchronously func (a *AtomicBool) Set(newState bool) bool { a.mutex.Lock() defer a.mutex.Unlock() diff --git a/src/cache.go b/src/cache.go index 340f3258..f2f84a0a 100644 --- a/src/cache.go +++ b/src/cache.go @@ -2,16 +2,21 @@ package fzf import "sync" +// QueryCache associates strings to lists of items type QueryCache map[string][]*Item + +// ChunkCache associates Chunk and query string to lists of items type ChunkCache struct { mutex sync.Mutex cache map[*Chunk]*QueryCache } +// NewChunkCache returns a new ChunkCache func NewChunkCache() ChunkCache { return ChunkCache{sync.Mutex{}, make(map[*Chunk]*QueryCache)} } +// Add adds the list to the cache func (cc *ChunkCache) Add(chunk *Chunk, key string, list []*Item) { if len(key) == 0 || !chunk.IsFull() { return @@ -28,6 +33,7 @@ func (cc *ChunkCache) Add(chunk *Chunk, key string, list []*Item) { (*qc)[key] = list } +// Find is called to lookup ChunkCache func (cc *ChunkCache) Find(chunk *Chunk, key string) ([]*Item, bool) { if len(key) == 0 || !chunk.IsFull() { return nil, false diff --git a/src/cache_test.go b/src/cache_test.go index 2a8b0480..3975eaa3 100644 --- a/src/cache_test.go +++ b/src/cache_test.go @@ -4,7 +4,7 @@ import "testing" func TestChunkCache(t *testing.T) { cache := NewChunkCache() - chunk2 := make(Chunk, CHUNK_SIZE) + chunk2 := make(Chunk, ChunkSize) chunk1p := &Chunk{} chunk2p := &chunk2 items1 := []*Item{&Item{}} diff --git a/src/chunklist.go b/src/chunklist.go index 5bca6da8..73983b1d 100644 --- a/src/chunklist.go +++ b/src/chunklist.go @@ -2,12 +2,17 @@ package fzf import "sync" -const CHUNK_SIZE int = 100 +// Capacity of each chunk +const ChunkSize int = 100 +// Chunk is a list of Item pointers whose size has the upper limit of ChunkSize type Chunk []*Item // >>> []Item +// Transformer is a closure type that builds Item object from a pointer to a +// string and an integer type Transformer func(*string, int) *Item +// ChunkList is a list of Chunks type ChunkList struct { chunks []*Chunk count int @@ -15,6 +20,7 @@ type ChunkList struct { trans Transformer } +// NewChunkList returns a new ChunkList func NewChunkList(trans Transformer) *ChunkList { return &ChunkList{ chunks: []*Chunk{}, @@ -27,34 +33,38 @@ func (c *Chunk) push(trans Transformer, data *string, index int) { *c = append(*c, trans(data, index)) } +// IsFull returns true if the Chunk is full func (c *Chunk) IsFull() bool { - return len(*c) == CHUNK_SIZE + return len(*c) == ChunkSize } func (cl *ChunkList) lastChunk() *Chunk { return cl.chunks[len(cl.chunks)-1] } +// CountItems returns the total number of Items func CountItems(cs []*Chunk) int { if len(cs) == 0 { return 0 } - return CHUNK_SIZE*(len(cs)-1) + len(*(cs[len(cs)-1])) + return ChunkSize*(len(cs)-1) + len(*(cs[len(cs)-1])) } +// Push adds the item to the list func (cl *ChunkList) Push(data string) { cl.mutex.Lock() defer cl.mutex.Unlock() if len(cl.chunks) == 0 || cl.lastChunk().IsFull() { - newChunk := Chunk(make([]*Item, 0, CHUNK_SIZE)) + newChunk := Chunk(make([]*Item, 0, ChunkSize)) cl.chunks = append(cl.chunks, &newChunk) } cl.lastChunk().push(cl.trans, &data, cl.count) - cl.count += 1 + cl.count++ } +// Snapshot returns immutable snapshot of the ChunkList func (cl *ChunkList) Snapshot() ([]*Chunk, int) { cl.mutex.Lock() defer cl.mutex.Unlock() diff --git a/src/chunklist_test.go b/src/chunklist_test.go index 09e4aadd..02288d9f 100644 --- a/src/chunklist_test.go +++ b/src/chunklist_test.go @@ -45,7 +45,7 @@ func TestChunkList(t *testing.T) { } // Add more data - for i := 0; i < CHUNK_SIZE*2; i++ { + for i := 0; i < ChunkSize*2; i++ { cl.Push(fmt.Sprintf("item %d", i)) } @@ -57,7 +57,7 @@ func TestChunkList(t *testing.T) { // New snapshot snapshot, count = cl.Snapshot() if len(snapshot) != 3 || !snapshot[0].IsFull() || - !snapshot[1].IsFull() || snapshot[2].IsFull() || count != CHUNK_SIZE*2+2 { + !snapshot[1].IsFull() || snapshot[2].IsFull() || count != ChunkSize*2+2 { t.Error("Expected two full chunks and one more chunk") } if len(*snapshot[2]) != 2 { diff --git a/src/constants.go b/src/constants.go index b0b64dbb..80eb6345 100644 --- a/src/constants.go +++ b/src/constants.go @@ -1,12 +1,17 @@ package fzf -const VERSION = "0.9.0" +// Current version +const Version = "0.9.0" +// EventType is the type for fzf events +type EventType int + +// fzf events const ( - EVT_READ_NEW EventType = iota - EVT_READ_FIN - EVT_SEARCH_NEW - EVT_SEARCH_PROGRESS - EVT_SEARCH_FIN - EVT_CLOSE + EvtReadNew EventType = iota + EvtReadFin + EvtSearchNew + EvtSearchProgress + EvtSearchFin + EvtClose ) diff --git a/src/core.go b/src/core.go index ab2a48fa..65e641c2 100644 --- a/src/core.go +++ b/src/core.go @@ -32,28 +32,29 @@ import ( "time" ) -const COORDINATOR_DELAY_MAX time.Duration = 100 * time.Millisecond -const COORDINATOR_DELAY_STEP time.Duration = 10 * time.Millisecond +const coordinatorDelayMax time.Duration = 100 * time.Millisecond +const coordinatorDelayStep time.Duration = 10 * time.Millisecond func initProcs() { runtime.GOMAXPROCS(runtime.NumCPU()) } /* -Reader -> EVT_READ_FIN -Reader -> EVT_READ_NEW -> Matcher (restart) -Terminal -> EVT_SEARCH_NEW -> Matcher (restart) -Matcher -> EVT_SEARCH_PROGRESS -> Terminal (update info) -Matcher -> EVT_SEARCH_FIN -> Terminal (update list) +Reader -> EvtReadFin +Reader -> EvtReadNew -> Matcher (restart) +Terminal -> EvtSearchNew -> Matcher (restart) +Matcher -> EvtSearchProgress -> Terminal (update info) +Matcher -> EvtSearchFin -> Terminal (update list) */ +// Run starts fzf func Run(options *Options) { initProcs() opts := ParseOptions() if opts.Version { - fmt.Println(VERSION) + fmt.Println(Version) os.Exit(0) } @@ -108,12 +109,12 @@ func Run(options *Options) { pattern := patternBuilder([]rune(patternString)) looping := true - eventBox.Unwatch(EVT_READ_NEW) + eventBox.Unwatch(EvtReadNew) for looping { eventBox.Wait(func(events *Events) { - for evt, _ := range *events { + for evt := range *events { switch evt { - case EVT_READ_FIN: + case EvtReadFin: looping = false return } @@ -133,7 +134,7 @@ func Run(options *Options) { fmt.Println(patternString) } for i := 0; i < merger.Length(); i++ { - merger.Get(i).Print() + fmt.Println(merger.Get(i).AsString()) } os.Exit(0) } @@ -149,33 +150,33 @@ func Run(options *Options) { // Event coordination reading := true ticks := 0 - eventBox.Watch(EVT_READ_NEW) + eventBox.Watch(EvtReadNew) for { delay := true - ticks += 1 + ticks++ eventBox.Wait(func(events *Events) { defer events.Clear() for evt, value := range *events { switch evt { - case EVT_READ_NEW, EVT_READ_FIN: - reading = reading && evt == EVT_READ_NEW + case EvtReadNew, EvtReadFin: + reading = reading && evt == EvtReadNew snapshot, count := chunkList.Snapshot() terminal.UpdateCount(count, !reading) matcher.Reset(snapshot, terminal.Input(), false) - case EVT_SEARCH_NEW: + case EvtSearchNew: snapshot, _ := chunkList.Snapshot() matcher.Reset(snapshot, terminal.Input(), true) delay = false - case EVT_SEARCH_PROGRESS: + case EvtSearchProgress: switch val := value.(type) { case float32: terminal.UpdateProgress(val) } - case EVT_SEARCH_FIN: + case EvtSearchFin: switch val := value.(type) { case *Merger: terminal.UpdateList(val) @@ -185,8 +186,8 @@ func Run(options *Options) { }) if delay && reading { dur := DurWithin( - time.Duration(ticks)*COORDINATOR_DELAY_STEP, - 0, COORDINATOR_DELAY_MAX) + time.Duration(ticks)*coordinatorDelayStep, + 0, coordinatorDelayMax) time.Sleep(dur) } } diff --git a/src/curses/curses.go b/src/curses/curses.go index 736ccf6b..8ebb5835 100644 --- a/src/curses/curses.go +++ b/src/curses/curses.go @@ -20,66 +20,68 @@ import ( "unicode/utf8" ) +// Types of user action const ( - RUNE = iota - - CTRL_A - CTRL_B - CTRL_C - CTRL_D - CTRL_E - CTRL_F - CTRL_G - CTRL_H - TAB - CTRL_J - CTRL_K - CTRL_L - CTRL_M - CTRL_N - CTRL_O - CTRL_P - CTRL_Q - CTRL_R - CTRL_S - CTRL_T - CTRL_U - CTRL_V - CTRL_W - CTRL_X - CTRL_Y - CTRL_Z + Rune = iota + + CtrlA + CtrlB + CtrlC + CtrlD + CtrlE + CtrlF + CtrlG + CtrlH + Tab + CtrlJ + CtrlK + CtrlL + CtrlM + CtrlN + CtrlO + CtrlP + CtrlQ + CtrlR + CtrlS + CtrlT + CtrlU + CtrlV + CtrlW + CtrlX + CtrlY + CtrlZ ESC - INVALID - MOUSE + Invalid + Mouse - BTAB + BTab - DEL - PGUP - PGDN + Del + PgUp + PgDn - ALT_B - ALT_F - ALT_D - ALT_BS + AltB + AltF + AltD + AltBS ) +// Pallete const ( - COL_NORMAL = iota - COL_PROMPT - COL_MATCH - COL_CURRENT - COL_CURRENT_MATCH - COL_SPINNER - COL_INFO - COL_CURSOR - COL_SELECTED + ColNormal = iota + ColPrompt + ColMatch + ColCurrent + ColCurrentMatch + ColSpinner + ColInfo + ColCursor + ColSelected ) const ( - DOUBLE_CLICK_DURATION = 500 * time.Millisecond + doubleClickDuration = 500 * time.Millisecond ) type Event struct { @@ -112,8 +114,8 @@ func init() { } func attrColored(pair int, bold bool) C.int { - var attr C.int = 0 - if pair > COL_NORMAL { + var attr C.int + if pair > ColNormal { attr = C.COLOR_PAIR(C.int(pair)) } if bold { @@ -123,15 +125,15 @@ func attrColored(pair int, bold bool) C.int { } func attrMono(pair int, bold bool) C.int { - var attr C.int = 0 + var attr C.int switch pair { - case COL_CURRENT: + case ColCurrent: if bold { attr = C.A_REVERSE } - case COL_MATCH: + case ColMatch: attr = C.A_UNDERLINE - case COL_CURRENT_MATCH: + case ColCurrentMatch: attr = C.A_UNDERLINE | C.A_REVERSE } if bold { @@ -198,23 +200,23 @@ func Init(color bool, color256 bool, black bool, mouse bool) { bg = -1 } if color256 { - C.init_pair(COL_PROMPT, 110, bg) - C.init_pair(COL_MATCH, 108, bg) - C.init_pair(COL_CURRENT, 254, 236) - C.init_pair(COL_CURRENT_MATCH, 151, 236) - C.init_pair(COL_SPINNER, 148, bg) - C.init_pair(COL_INFO, 144, bg) - C.init_pair(COL_CURSOR, 161, 236) - C.init_pair(COL_SELECTED, 168, 236) + C.init_pair(ColPrompt, 110, bg) + C.init_pair(ColMatch, 108, bg) + C.init_pair(ColCurrent, 254, 236) + C.init_pair(ColCurrentMatch, 151, 236) + C.init_pair(ColSpinner, 148, bg) + C.init_pair(ColInfo, 144, bg) + C.init_pair(ColCursor, 161, 236) + C.init_pair(ColSelected, 168, 236) } else { - C.init_pair(COL_PROMPT, C.COLOR_BLUE, bg) - C.init_pair(COL_MATCH, C.COLOR_GREEN, bg) - C.init_pair(COL_CURRENT, C.COLOR_YELLOW, C.COLOR_BLACK) - C.init_pair(COL_CURRENT_MATCH, C.COLOR_GREEN, C.COLOR_BLACK) - C.init_pair(COL_SPINNER, C.COLOR_GREEN, bg) - C.init_pair(COL_INFO, C.COLOR_WHITE, bg) - C.init_pair(COL_CURSOR, C.COLOR_RED, C.COLOR_BLACK) - C.init_pair(COL_SELECTED, C.COLOR_MAGENTA, C.COLOR_BLACK) + C.init_pair(ColPrompt, C.COLOR_BLUE, bg) + C.init_pair(ColMatch, C.COLOR_GREEN, bg) + C.init_pair(ColCurrent, C.COLOR_YELLOW, C.COLOR_BLACK) + C.init_pair(ColCurrentMatch, C.COLOR_GREEN, C.COLOR_BLACK) + C.init_pair(ColSpinner, C.COLOR_GREEN, bg) + C.init_pair(ColInfo, C.COLOR_WHITE, bg) + C.init_pair(ColCursor, C.COLOR_RED, C.COLOR_BLACK) + C.init_pair(ColSelected, C.COLOR_MAGENTA, C.COLOR_BLACK) } _color = attrColored } else { @@ -245,7 +247,7 @@ func GetBytes() []byte { // 27 (91 79) 77 type x y func mouseSequence(sz *int) Event { if len(_buf) < 6 { - return Event{INVALID, 0, nil} + return Event{Invalid, 0, nil} } *sz = 6 switch _buf[3] { @@ -258,7 +260,7 @@ func mouseSequence(sz *int) Event { double := false if down { now := time.Now() - if now.Sub(_prevDownTime) < DOUBLE_CLICK_DURATION { + if now.Sub(_prevDownTime) < doubleClickDuration { _clickY = append(_clickY, y) } else { _clickY = []int{y} @@ -266,18 +268,18 @@ func mouseSequence(sz *int) Event { _prevDownTime = now } else { if len(_clickY) > 1 && _clickY[0] == _clickY[1] && - time.Now().Sub(_prevDownTime) < DOUBLE_CLICK_DURATION { + time.Now().Sub(_prevDownTime) < doubleClickDuration { double = true } } - return Event{MOUSE, 0, &MouseEvent{y, x, 0, down, double, mod}} + return Event{Mouse, 0, &MouseEvent{y, x, 0, down, double, mod}} case 96, 100, 104, 112, // scroll-up / shift / cmd / ctrl 97, 101, 105, 113: // scroll-down / shift / cmd / ctrl mod := _buf[3] >= 100 s := 1 - int(_buf[3]%2)*2 - return Event{MOUSE, 0, &MouseEvent{0, 0, s, false, false, mod}} + return Event{Mouse, 0, &MouseEvent{0, 0, s, false, false, mod}} } - return Event{INVALID, 0, nil} + return Event{Invalid, 0, nil} } func escSequence(sz *int) Event { @@ -287,81 +289,81 @@ func escSequence(sz *int) Event { *sz = 2 switch _buf[1] { case 98: - return Event{ALT_B, 0, nil} + return Event{AltB, 0, nil} case 100: - return Event{ALT_D, 0, nil} + return Event{AltD, 0, nil} case 102: - return Event{ALT_F, 0, nil} + return Event{AltF, 0, nil} case 127: - return Event{ALT_BS, 0, nil} + return Event{AltBS, 0, nil} case 91, 79: if len(_buf) < 3 { - return Event{INVALID, 0, nil} + return Event{Invalid, 0, nil} } *sz = 3 switch _buf[2] { case 68: - return Event{CTRL_B, 0, nil} + return Event{CtrlB, 0, nil} case 67: - return Event{CTRL_F, 0, nil} + return Event{CtrlF, 0, nil} case 66: - return Event{CTRL_J, 0, nil} + return Event{CtrlJ, 0, nil} case 65: - return Event{CTRL_K, 0, nil} + return Event{CtrlK, 0, nil} case 90: - return Event{BTAB, 0, nil} + return Event{BTab, 0, nil} case 72: - return Event{CTRL_A, 0, nil} + return Event{CtrlA, 0, nil} case 70: - return Event{CTRL_E, 0, nil} + return Event{CtrlE, 0, nil} case 77: return mouseSequence(sz) case 49, 50, 51, 52, 53, 54: if len(_buf) < 4 { - return Event{INVALID, 0, nil} + return Event{Invalid, 0, nil} } *sz = 4 switch _buf[2] { case 50: - return Event{INVALID, 0, nil} // INS + return Event{Invalid, 0, nil} // INS case 51: - return Event{DEL, 0, nil} + return Event{Del, 0, nil} case 52: - return Event{CTRL_E, 0, nil} + return Event{CtrlE, 0, nil} case 53: - return Event{PGUP, 0, nil} + return Event{PgUp, 0, nil} case 54: - return Event{PGDN, 0, nil} + return Event{PgDn, 0, nil} case 49: switch _buf[3] { case 126: - return Event{CTRL_A, 0, nil} + return Event{CtrlA, 0, nil} case 59: if len(_buf) != 6 { - return Event{INVALID, 0, nil} + return Event{Invalid, 0, nil} } *sz = 6 switch _buf[4] { case 50: switch _buf[5] { case 68: - return Event{CTRL_A, 0, nil} + return Event{CtrlA, 0, nil} case 67: - return Event{CTRL_E, 0, nil} + return Event{CtrlE, 0, nil} } case 53: switch _buf[5] { case 68: - return Event{ALT_B, 0, nil} + return Event{AltB, 0, nil} case 67: - return Event{ALT_F, 0, nil} + return Event{AltF, 0, nil} } } // _buf[4] } // _buf[3] } // _buf[2] } // _buf[2] } // _buf[1] - return Event{INVALID, 0, nil} + return Event{Invalid, 0, nil} } func GetChar() Event { @@ -378,21 +380,21 @@ func GetChar() Event { }() switch _buf[0] { - case CTRL_C, CTRL_G, CTRL_Q: - return Event{CTRL_C, 0, nil} + case CtrlC, CtrlG, CtrlQ: + return Event{CtrlC, 0, nil} case 127: - return Event{CTRL_H, 0, nil} + return Event{CtrlH, 0, nil} case ESC: return escSequence(&sz) } // CTRL-A ~ CTRL-Z - if _buf[0] <= CTRL_Z { + if _buf[0] <= CtrlZ { return Event{int(_buf[0]), 0, nil} } r, rsz := utf8.DecodeRune(_buf) sz = rsz - return Event{RUNE, r, nil} + return Event{Rune, r, nil} } func Move(y int, x int) { diff --git a/src/eventbox.go b/src/eventbox.go index 95126cca..0c8f922a 100644 --- a/src/eventbox.go +++ b/src/eventbox.go @@ -2,16 +2,17 @@ package fzf import "sync" -type EventType int - +// Events is a type that associates EventType to any data type Events map[EventType]interface{} +// EventBox is used for coordinating events type EventBox struct { events Events cond *sync.Cond ignore map[EventType]bool } +// NewEventBox returns a new EventBox func NewEventBox() *EventBox { return &EventBox{ events: make(Events), @@ -19,6 +20,7 @@ func NewEventBox() *EventBox { ignore: make(map[EventType]bool)} } +// Wait blocks the goroutine until signaled func (b *EventBox) Wait(callback func(*Events)) { b.cond.L.Lock() defer b.cond.L.Unlock() @@ -30,6 +32,7 @@ func (b *EventBox) Wait(callback func(*Events)) { callback(&b.events) } +// Set turns on the event type on the box func (b *EventBox) Set(event EventType, value interface{}) { b.cond.L.Lock() defer b.cond.L.Unlock() @@ -39,6 +42,7 @@ func (b *EventBox) Set(event EventType, value interface{}) { } } +// Clear clears the events // Unsynchronized; should be called within Wait routine func (events *Events) Clear() { for event := range *events { @@ -46,6 +50,7 @@ func (events *Events) Clear() { } } +// Peak peaks at the event box if the given event is set func (b *EventBox) Peak(event EventType) bool { b.cond.L.Lock() defer b.cond.L.Unlock() @@ -53,6 +58,7 @@ func (b *EventBox) Peak(event EventType) bool { return ok } +// Watch deletes the events from the ignore list func (b *EventBox) Watch(events ...EventType) { b.cond.L.Lock() defer b.cond.L.Unlock() @@ -61,6 +67,7 @@ func (b *EventBox) Watch(events ...EventType) { } } +// Unwatch adds the events to the ignore list func (b *EventBox) Unwatch(events ...EventType) { b.cond.L.Lock() defer b.cond.L.Unlock() diff --git a/src/eventbox_test.go b/src/eventbox_test.go index fb0ceedf..1cd7f220 100644 --- a/src/eventbox_test.go +++ b/src/eventbox_test.go @@ -9,16 +9,16 @@ func TestEventBox(t *testing.T) { ch := make(chan bool) go func() { - eb.Set(EVT_READ_NEW, 10) + eb.Set(EvtReadNew, 10) ch <- true <-ch - eb.Set(EVT_SEARCH_NEW, 10) - eb.Set(EVT_SEARCH_NEW, 15) - eb.Set(EVT_SEARCH_NEW, 20) - eb.Set(EVT_SEARCH_PROGRESS, 30) + eb.Set(EvtSearchNew, 10) + eb.Set(EvtSearchNew, 15) + eb.Set(EvtSearchNew, 20) + eb.Set(EvtSearchProgress, 30) ch <- true <-ch - eb.Set(EVT_SEARCH_FIN, 40) + eb.Set(EvtSearchFin, 40) ch <- true <-ch }() @@ -39,7 +39,7 @@ func TestEventBox(t *testing.T) { events.Clear() }) ch <- true - count += 1 + count++ } if count != 3 { diff --git a/src/item.go b/src/item.go index 41aa34bd..4cbd3f98 100644 --- a/src/item.go +++ b/src/item.go @@ -1,9 +1,9 @@ package fzf -import "fmt" - +// Offset holds two 32-bit integers denoting the offsets of a matched substring type Offset [2]int32 +// Item represents each input line type Item struct { text *string origText *string @@ -13,12 +13,14 @@ type Item struct { rank Rank } +// Rank is used to sort the search result type Rank struct { matchlen uint16 strlen uint16 index uint32 } +// Rank calculates rank of the Item func (i *Item) Rank(cache bool) Rank { if cache && (i.rank.matchlen > 0 || i.rank.strlen > 0) { return i.rank @@ -45,14 +47,15 @@ func (i *Item) Rank(cache bool) Rank { return rank } -func (i *Item) Print() { +// AsString returns the original string +func (i *Item) AsString() string { if i.origText != nil { - fmt.Println(*i.origText) - } else { - fmt.Println(*i.text) + return *i.origText } + return *i.text } +// ByOrder is for sorting substring offsets type ByOrder []Offset func (a ByOrder) Len() int { @@ -69,6 +72,7 @@ func (a ByOrder) Less(i, j int) bool { return (ioff[0] < joff[0]) || (ioff[0] == joff[0]) && (ioff[1] <= joff[1]) } +// ByRelevance is for sorting Items type ByRelevance []*Item func (a ByRelevance) Len() int { diff --git a/src/matcher.go b/src/matcher.go index 713b4dd6..b8be2870 100644 --- a/src/matcher.go +++ b/src/matcher.go @@ -8,11 +8,13 @@ import ( "time" ) +// MatchRequest represents a search request type MatchRequest struct { chunks []*Chunk pattern *Pattern } +// Matcher is responsible for performing search type Matcher struct { patternBuilder func([]rune) *Pattern sort bool @@ -23,20 +25,15 @@ type Matcher struct { } const ( - REQ_RETRY EventType = iota - REQ_RESET + reqRetry EventType = iota + reqReset ) const ( - STAT_CANCELLED int = iota - STAT_QCH - STAT_CHUNKS -) - -const ( - PROGRESS_MIN_DURATION = 200 * time.Millisecond + progressMinDuration = 200 * time.Millisecond ) +// NewMatcher returns a new Matcher func NewMatcher(patternBuilder func([]rune) *Pattern, sort bool, eventBox *EventBox) *Matcher { return &Matcher{ @@ -48,6 +45,7 @@ func NewMatcher(patternBuilder func([]rune) *Pattern, mergerCache: make(map[string]*Merger)} } +// Loop puts Matcher in action func (m *Matcher) Loop() { prevCount := 0 @@ -91,7 +89,7 @@ func (m *Matcher) Loop() { if !cancelled { m.mergerCache[patternString] = merger - m.eventBox.Set(EVT_SEARCH_FIN, merger) + m.eventBox.Set(EvtSearchFin, merger) |