From fe878c57e804948d3e8d0b1ec95ea9bb448f9245 Mon Sep 17 00:00:00 2001 From: Simon Let Date: Sun, 17 May 2020 14:35:14 +0200 Subject: [PATCH] reorganize search app code, minor fixes --- cmd/cli/main.go | 116 ++++++------ {cmd/cli => pkg/searchapp}/highlight.go | 8 +- {cmd/cli => pkg/searchapp}/item.go | 231 ++++++++++++++---------- {cmd/cli => pkg/searchapp}/query.go | 13 +- pkg/searchapp/test.go | 23 +++ {cmd/cli => pkg/searchapp}/time.go | 2 +- scripts/reshctl.sh | 2 +- 7 files changed, 220 insertions(+), 175 deletions(-) rename {cmd/cli => pkg/searchapp}/highlight.go (92%) rename {cmd/cli => pkg/searchapp}/item.go (66%) rename {cmd/cli => pkg/searchapp}/query.go (81%) create mode 100644 pkg/searchapp/test.go rename {cmd/cli => pkg/searchapp}/time.go (99%) diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 33bbb95..6870c46 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -18,6 +18,7 @@ import ( "github.com/curusarn/resh/pkg/cfg" "github.com/curusarn/resh/pkg/msg" "github.com/curusarn/resh/pkg/records" + "github.com/curusarn/resh/pkg/searchapp" "os/user" "path/filepath" @@ -70,6 +71,8 @@ func runReshCli() (string, int) { pwd := flag.String("pwd", "", "present working directory") gitOriginRemote := flag.String("gitOriginRemote", "DEFAULT", "git origin remote") query := flag.String("query", "", "search query") + testHistory := flag.String("test-history", "", "load history from a file instead from the daemon (for testing purposes only!)") + testHistoryLines := flag.Int("test-lines", 0, "the number of lines to load from a file passed with --test-history (for testing purposes only!)") flag.Parse() if *sessionID == "" { @@ -96,11 +99,16 @@ func runReshCli() (string, int) { // g.SelBgColor = gocui.ColorGreen g.Highlight = true - mess := msg.CliMsg{ - SessionID: *sessionID, - PWD: *pwd, + var resp msg.CliResponse + if *testHistory == "" { + mess := msg.CliMsg{ + SessionID: *sessionID, + PWD: *pwd, + } + resp = SendCliMsg(mess, strconv.Itoa(config.Port)) + } else { + resp = searchapp.LoadHistoryFromFile(*testHistory, *testHistoryLines) } - resp := SendCliMsg(mess, strconv.Itoa(config.Port)) st := state{ // lock sync.Mutex @@ -166,8 +174,8 @@ func runReshCli() (string, int) { type state struct { lock sync.Mutex cliRecords []records.CliRecord - data []item - rawData []rawItem + data []searchapp.Item + rawData []searchapp.RawItem highlightedItem int displayedItemsCount int @@ -193,7 +201,7 @@ func (m manager) SelectExecute(g *gocui.Gui, v *gocui.View) error { m.s.lock.Lock() defer m.s.lock.Unlock() if m.s.highlightedItem < len(m.s.data) { - m.s.output = m.s.data[m.s.highlightedItem].cmdLine + m.s.output = m.s.data[m.s.highlightedItem].CmdLine m.s.exitCode = exitCodeExecute return gocui.ErrQuit } @@ -204,7 +212,7 @@ func (m manager) SelectPaste(g *gocui.Gui, v *gocui.View) error { m.s.lock.Lock() defer m.s.lock.Unlock() if m.s.highlightedItem < len(m.s.data) { - m.s.output = m.s.data[m.s.highlightedItem].cmdLine + m.s.output = m.s.data[m.s.highlightedItem].CmdLine m.s.exitCode = 0 // success return gocui.ErrQuit } @@ -233,21 +241,21 @@ func (m manager) UpdateData(input string) { log.Println("len(fullRecords) =", len(m.s.cliRecords)) log.Println("len(data) =", len(m.s.data)) } - query := newQueryFromString(input, m.host, m.pwd, m.gitOriginRemote) - var data []item + query := searchapp.NewQueryFromString(input, m.host, m.pwd, m.gitOriginRemote, m.config.Debug) + var data []searchapp.Item itemSet := make(map[string]int) m.s.lock.Lock() defer m.s.lock.Unlock() for _, rec := range m.s.cliRecords { - itm, err := newItemFromRecordForQuery(rec, query, m.config.Debug) + itm, err := searchapp.NewItemFromRecordForQuery(rec, query, m.config.Debug) if err != nil { // records didn't match the query // log.Println(" * continue (no match)", rec.Pwd) continue } - if idx, ok := itemSet[itm.key]; ok { + if idx, ok := itemSet[itm.Key]; ok { // duplicate found - if data[idx].score >= itm.score { + if data[idx].Score >= itm.Score { // skip duplicate item continue } @@ -256,14 +264,14 @@ func (m manager) UpdateData(input string) { continue } // add new item - itemSet[itm.key] = len(data) + itemSet[itm.Key] = len(data) data = append(data, itm) } if debug { log.Println("len(tmpdata) =", len(data)) } sort.SliceStable(data, func(p, q int) bool { - return data[p].score > data[q].score + return data[p].Score > data[q].Score }) m.s.data = nil for _, itm := range data { @@ -281,28 +289,28 @@ func (m manager) UpdateData(input string) { } func (m manager) UpdateRawData(input string) { - if debug { + if m.config.Debug { log.Println("EDIT start") log.Println("len(fullRecords) =", len(m.s.cliRecords)) log.Println("len(data) =", len(m.s.data)) } - query := getRawTermsFromString(input) - var data []rawItem + query := searchapp.GetRawTermsFromString(input, m.config.Debug) + var data []searchapp.RawItem itemSet := make(map[string]bool) m.s.lock.Lock() defer m.s.lock.Unlock() for _, rec := range m.s.cliRecords { - itm, err := newRawItemFromRecordForQuery(rec, query, m.config.Debug) + itm, err := searchapp.NewRawItemFromRecordForQuery(rec, query, m.config.Debug) if err != nil { // records didn't match the query // log.Println(" * continue (no match)", rec.Pwd) continue } - if itemSet[itm.key] { + if itemSet[itm.Key] { // log.Println(" * continue (already present)", itm.key(), itm.pwd) continue } - itemSet[itm.key] = true + itemSet[itm.Key] = true data = append(data, itm) // log.Println("DATA =", itm.display) } @@ -310,7 +318,7 @@ func (m manager) UpdateRawData(input string) { log.Println("len(tmpdata) =", len(data)) } sort.SliceStable(data, func(p, q int) bool { - return data[p].hits > data[q].hits + return data[p].Score > data[q].Score }) m.s.rawData = nil for _, itm := range data { @@ -412,31 +420,6 @@ func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit } -func getHeader(compactRendering bool) itemColumns { - date := "TIME " - host := "HOST:" - dir := "DIRECTORY" - if compactRendering { - dir = "DIR" - } - flags := " FLAGS" - cmdLine := "COMMAND-LINE" - return itemColumns{ - date: date, - dateWithColor: date, - host: host, - hostWithColor: host, - pwdTilde: dir, - samePwd: false, - flags: flags, - flagsWithColor: flags, - cmdLine: cmdLine, - cmdLineWithColor: cmdLine, - // score: i.score, - key: "_HEADERS_", - } -} - const smallTerminalTresholdWidth = 110 func (m manager) normalMode(g *gocui.Gui, v *gocui.View) error { @@ -447,31 +430,31 @@ func (m manager) normalMode(g *gocui.Gui, v *gocui.View) error { compactRenderingMode = true } - data := []itemColumns{} + data := []searchapp.ItemColumns{} - header := getHeader(compactRenderingMode) - longestDateLen := len(header.date) - longestLocationLen := len(header.host) + len(header.pwdTilde) + header := searchapp.GetHeader(compactRenderingMode) + longestDateLen := len(header.Date) + longestLocationLen := len(header.Host) + len(header.PwdTilde) longestFlagsLen := 2 maxPossibleMainViewHeight := maxY - 3 - 1 - 1 - 1 // - top box - header - status - help for i, itm := range m.s.data { if i == maxY { break } - ic := itm.drawItemColumns(compactRenderingMode) + ic := itm.DrawItemColumns(compactRenderingMode, debug) data = append(data, ic) if i > maxPossibleMainViewHeight { // do not stretch columns because of results that will end up outside of the page continue } - if len(ic.date) > longestDateLen { - longestDateLen = len(ic.date) + if len(ic.Date) > longestDateLen { + longestDateLen = len(ic.Date) } - if len(ic.host)+len(ic.pwdTilde) > longestLocationLen { - longestLocationLen = len(ic.host) + len(ic.pwdTilde) + if len(ic.Host)+len(ic.PwdTilde) > longestLocationLen { + longestLocationLen = len(ic.Host) + len(ic.PwdTilde) } - if len(ic.flags) > longestFlagsLen { - longestFlagsLen = len(ic.flags) + if len(ic.Flags) > longestFlagsLen { + longestFlagsLen = len(ic.Flags) } } maxLocationLen := maxX/7 + 8 @@ -487,7 +470,10 @@ func (m manager) normalMode(g *gocui.Gui, v *gocui.View) error { topBoxHeight++ // headers realLineLength := maxX - 2 printedLineLength := maxX - 4 - statusLine := m.s.data[m.s.highlightedItem].drawStatusLine(compactRenderingMode, printedLineLength, realLineLength) + statusLine := searchapp.GetEmptyStatusLine(printedLineLength, realLineLength) + if m.s.highlightedItem != -1 && m.s.highlightedItem < len(m.s.data) { + statusLine = m.s.data[m.s.highlightedItem].DrawStatusLine(compactRenderingMode, printedLineLength, realLineLength) + } var statusLineHeight int = len(statusLine) helpLineHeight := 1 @@ -500,8 +486,8 @@ func (m manager) normalMode(g *gocui.Gui, v *gocui.View) error { // header // header := getHeader() - dispStr, _ := header.produceLine(longestDateLen, longestLocationLen, longestFlagsLen, true, true) - dispStr = doHighlightHeader(dispStr, maxX*2) + dispStr, _ := header.ProduceLine(longestDateLen, longestLocationLen, longestFlagsLen, true, true) + dispStr = searchapp.DoHighlightHeader(dispStr, maxX*2) v.WriteString(dispStr + "\n") var index int @@ -512,10 +498,10 @@ func (m manager) normalMode(g *gocui.Gui, v *gocui.View) error { break } - displayStr, _ := itm.produceLine(longestDateLen, longestLocationLen, longestFlagsLen, false, true) + displayStr, _ := itm.ProduceLine(longestDateLen, longestLocationLen, longestFlagsLen, false, true) if m.s.highlightedItem == index { // maxX * 2 because there are escape sequences that make it hard to tell the real string lenght - displayStr = doHighlightString(displayStr, maxX*3) + displayStr = searchapp.DoHighlightString(displayStr, maxX*3) if debug { log.Println("### HightlightedItem string :", displayStr) } @@ -560,10 +546,10 @@ func (m manager) rawMode(g *gocui.Gui, v *gocui.View) error { } break } - displayStr := itm.cmdLineWithColor + displayStr := itm.CmdLineWithColor if m.s.highlightedItem == i { // use actual min requried length instead of 420 constant - displayStr = doHighlightString(displayStr, maxX*2) + displayStr = searchapp.DoHighlightString(displayStr, maxX*2) if debug { log.Println("### HightlightedItem string :", displayStr) } diff --git a/cmd/cli/highlight.go b/pkg/searchapp/highlight.go similarity index 92% rename from cmd/cli/highlight.go rename to pkg/searchapp/highlight.go index a121dc9..3b6f973 100644 --- a/cmd/cli/highlight.go +++ b/pkg/searchapp/highlight.go @@ -1,4 +1,4 @@ -package main +package searchapp import ( "strconv" @@ -91,14 +91,16 @@ func highlightGit(str string) string { return greenBold + cleanHighlight(str) + end } -func doHighlightHeader(str string, minLength int) string { +// DoHighlightHeader . +func DoHighlightHeader(str string, minLength int) string { if len(str) < minLength { str = str + strings.Repeat(" ", minLength-len(str)) } return highlightHeader(str) } -func doHighlightString(str string, minLength int) string { +// DoHighlightString . +func DoHighlightString(str string, minLength int) string { if len(str) < minLength { str = str + strings.Repeat(" ", minLength-len(str)) } diff --git a/cmd/cli/item.go b/pkg/searchapp/item.go similarity index 66% rename from cmd/cli/item.go rename to pkg/searchapp/item.go index 56cd763..af3b685 100644 --- a/cmd/cli/item.go +++ b/pkg/searchapp/item.go @@ -1,7 +1,6 @@ -package main +package searchapp import ( - "errors" "fmt" "log" "strconv" @@ -13,7 +12,8 @@ import ( const itemLocationLenght = 30 -type item struct { +// Item holds item info for normal mode +type Item struct { isRaw bool realtimeBefore float64 @@ -29,43 +29,44 @@ type item struct { sameGitRepo bool exitCode int - cmdLineWithColor string - cmdLine string + CmdLineWithColor string + CmdLine string - score float64 + Score float64 - key string + Key string // cmdLineRaw string } -type itemColumns struct { - dateWithColor string - date string +// ItemColumns holds rendered columns +type ItemColumns struct { + DateWithColor string + Date string // [host:]pwd - hostWithColor string - host string - pwdTilde string + HostWithColor string + Host string + PwdTilde string samePwd bool //locationWithColor string //location string // [G] [E#] - flagsWithColor string - flags string + FlagsWithColor string + Flags string - cmdLineWithColor string - cmdLine string + CmdLineWithColor string + CmdLine string // score float64 - key string + Key string // cmdLineRaw string } -func (i item) less(i2 item) bool { +func (i Item) less(i2 Item) bool { // reversed order - return i.score > i2.score + return i.Score > i2.Score } func splitStatusLineToLines(statusLine string, printedLineLength, realLineLength int) []string { @@ -97,9 +98,10 @@ func splitStatusLineToLines(statusLine string, printedLineLength, realLineLength return statusLineSlice } -func (i item) drawStatusLine(compactRendering bool, printedLineLength, realLineLength int) []string { +// DrawStatusLine ... +func (i Item) DrawStatusLine(compactRendering bool, printedLineLength, realLineLength int) []string { if i.isRaw { - return splitStatusLineToLines(i.cmdLine, printedLineLength, realLineLength) + return splitStatusLineToLines(i.CmdLine, printedLineLength, realLineLength) } secs := int64(i.realtimeBefore) nsecs := int64((i.realtimeBefore - float64(secs)) * 1e9) @@ -110,24 +112,30 @@ func (i item) drawStatusLine(compactRendering bool, printedLineLength, realLineL pwdTilde := strings.Replace(i.pwd, i.home, "~", 1) separator := " " - stLine := timeString + separator + i.host + ":" + pwdTilde + separator + i.cmdLine + stLine := timeString + separator + i.host + ":" + pwdTilde + separator + i.CmdLine return splitStatusLineToLines(stLine, printedLineLength, realLineLength) } -func (i item) drawItemColumns(compactRendering bool) itemColumns { +// GetEmptyStatusLine . +func GetEmptyStatusLine(printedLineLength, realLineLength int) []string { + return splitStatusLineToLines("- no result selected -", printedLineLength, realLineLength) +} + +// DrawItemColumns ... +func (i Item) DrawItemColumns(compactRendering bool, debug bool) ItemColumns { if i.isRaw { notAvailable := "n/a" - return itemColumns{ - date: notAvailable + " ", - dateWithColor: notAvailable + " ", + return ItemColumns{ + Date: notAvailable + " ", + DateWithColor: notAvailable + " ", // dateWithColor: highlightDate(notAvailable) + " ", - host: "", - hostWithColor: "", - pwdTilde: notAvailable, - cmdLine: i.cmdLine, - cmdLineWithColor: i.cmdLineWithColor, + Host: "", + HostWithColor: "", + PwdTilde: notAvailable, + CmdLine: i.CmdLine, + CmdLineWithColor: i.CmdLineWithColor, // score: i.score, - key: i.key, + Key: i.Key, } } @@ -159,7 +167,7 @@ func (i item) drawItemColumns(compactRendering bool) itemColumns { flags := "" flagsWithColor := "" if debug { - hitsStr := fmt.Sprintf("%.1f", i.score) + hitsStr := fmt.Sprintf("%.1f", i.Score) flags += " S" + hitsStr flagsWithColor += " S" + hitsStr } @@ -174,46 +182,47 @@ func (i item) drawItemColumns(compactRendering bool) itemColumns { // NOTE: you can debug arbitrary metadata like this // flags += " <" + record.GitOriginRemote + ">" // flagsWithColor += " <" + record.GitOriginRemote + ">" - return itemColumns{ - date: date, - dateWithColor: dateWithColor, - host: host, - hostWithColor: hostWithColor, - pwdTilde: pwdTilde, + return ItemColumns{ + Date: date, + DateWithColor: dateWithColor, + Host: host, + HostWithColor: hostWithColor, + PwdTilde: pwdTilde, samePwd: i.samePwd, - flags: flags, - flagsWithColor: flagsWithColor, - cmdLine: i.cmdLine, - cmdLineWithColor: i.cmdLineWithColor, + Flags: flags, + FlagsWithColor: flagsWithColor, + CmdLine: i.CmdLine, + CmdLineWithColor: i.CmdLineWithColor, // score: i.score, - key: i.key, + Key: i.Key, } } -func (ic itemColumns) produceLine(dateLength int, locationLength int, flagLength int, header bool, showDate bool) (string, int) { +// ProduceLine ... +func (ic ItemColumns) ProduceLine(dateLength int, locationLength int, flagLength int, header bool, showDate bool) (string, int) { line := "" if showDate { - date := ic.date + date := ic.Date for len(date) < dateLength { line += " " date += " " } // TODO: use strings.Repeat - line += ic.dateWithColor + line += ic.DateWithColor } // LOCATION - locationWithColor := ic.hostWithColor - pwdLength := locationLength - len(ic.host) + locationWithColor := ic.HostWithColor + pwdLength := locationLength - len(ic.Host) if ic.samePwd { - locationWithColor += highlightPwd(leftCutPadString(ic.pwdTilde, pwdLength)) + locationWithColor += highlightPwd(leftCutPadString(ic.PwdTilde, pwdLength)) } else { - locationWithColor += leftCutPadString(ic.pwdTilde, pwdLength) + locationWithColor += leftCutPadString(ic.PwdTilde, pwdLength) } line += locationWithColor - line += ic.flagsWithColor - flags := ic.flags - if flagLength < len(ic.flags) { - log.Printf("produceLine can't specify line w/ flags shorter than the actual size. - len(flags) %v, requested %v\n", len(ic.flags), flagLength) + line += ic.FlagsWithColor + flags := ic.Flags + if flagLength < len(ic.Flags) { + log.Printf("produceLine can't specify line w/ flags shorter than the actual size. - len(flags) %v, requested %v\n", len(ic.Flags), flagLength) } for len(flags) < flagLength { line += " " @@ -225,9 +234,9 @@ func (ic itemColumns) produceLine(dateLength int, locationLength int, flagLength // because there is likely a long flag like E130 in the view spacer = " " } - line += spacer + ic.cmdLineWithColor + line += spacer + ic.CmdLineWithColor - length := dateLength + locationLength + flagLength + len(spacer) + len(ic.cmdLine) + length := dateLength + locationLength + flagLength + len(spacer) + len(ic.CmdLine) return line, length } @@ -262,9 +271,9 @@ func properMatch(str, term, padChar string) bool { return false } -// newItemFromRecordForQuery creates new item from record based on given query +// NewItemFromRecordForQuery creates new item from record based on given query // returns error if the query doesn't match the record -func newItemFromRecordForQuery(record records.CliRecord, query query, debug bool) (item, error) { +func NewItemFromRecordForQuery(record records.CliRecord, query Query, debug bool) (Item, error) { // Use numbers that won't add up to same score for any number of query words // query score weigth 1.51 const hitScore = 1.517 // 1 * 1.51 @@ -319,13 +328,13 @@ func newItemFromRecordForQuery(record records.CliRecord, query query, debug bool record.GitOriginRemote + unlikelySeparator + record.Host */ if record.IsRaw { - return item{ + return Item{ isRaw: true, - cmdLine: cmdLine, - cmdLineWithColor: cmdLineWithColor, - score: score, - key: key, + CmdLine: cmdLine, + CmdLineWithColor: cmdLineWithColor, + Score: score, + Key: key, }, nil } // actual pwd matches @@ -357,12 +366,13 @@ func newItemFromRecordForQuery(record records.CliRecord, query query, debug bool // errorExitStatus = true score -= nonZeroExitCodeScorePenalty } - if score <= 0 && !anyHit { - return item{}, errors.New("no match for given record and query") - } + _ = anyHit + // if score <= 0 && !anyHit { + // return Item{}, errors.New("no match for given record and query") + // } score += record.RealtimeBefore * timeScoreCoef - it := item{ + it := Item{ realtimeBefore: record.RealtimeBefore, differentHost: differentHost, @@ -373,52 +383,73 @@ func newItemFromRecordForQuery(record records.CliRecord, query query, debug bool sameGitRepo: sameGitRepo, exitCode: record.ExitCode, - cmdLine: cmdLine, - cmdLineWithColor: cmdLineWithColor, - score: score, - key: key, + CmdLine: cmdLine, + CmdLineWithColor: cmdLineWithColor, + Score: score, + Key: key, } return it, nil } -type rawItem struct { - cmdLineWithColor string - cmdLine string +// GetHeader returns header columns +func GetHeader(compactRendering bool) ItemColumns { + date := "TIME " + host := "HOST:" + dir := "DIRECTORY" + if compactRendering { + dir = "DIR" + } + flags := " FLAGS" + cmdLine := "COMMAND-LINE" + return ItemColumns{ + Date: date, + DateWithColor: date, + Host: host, + HostWithColor: host, + PwdTilde: dir, + samePwd: false, + Flags: flags, + FlagsWithColor: flags, + CmdLine: cmdLine, + CmdLineWithColor: cmdLine, + // score: i.score, + Key: "_HEADERS_", + } +} + +// RawItem is item for raw mode +type RawItem struct { + CmdLineWithColor string + CmdLine string - hits float64 + Score float64 - key string + Key string // cmdLineRaw string } -// newRawItemFromRecordForQuery creates new item from record based on given query +// NewRawItemFromRecordForQuery creates new item from record based on given query // returns error if the query doesn't match the record -func newRawItemFromRecordForQuery(record records.CliRecord, terms []string, debug bool) (rawItem, error) { +func NewRawItemFromRecordForQuery(record records.CliRecord, terms []string, debug bool) (RawItem, error) { const hitScore = 1.0 - const hitScoreConsecutive = 0.1 + const hitScoreConsecutive = 0.01 const properMatchScore = 0.3 - hits := 0.0 - anyHit := false + const timeScoreCoef = 1e-13 + + score := 0.0 cmd := record.CmdLine for _, term := range terms { - termHit := false - if strings.Contains(record.CmdLine, term) { - anyHit = true - if termHit == false { - hits += hitScore - } else { - hits += hitScoreConsecutive - } - termHit = true + c := strings.Count(record.CmdLine, term) + if c > 0 { + score += hitScore + hitScoreConsecutive*float64(c) if properMatch(cmd, term, " ") { - hits += properMatchScore + score += properMatchScore } cmd = strings.ReplaceAll(cmd, term, highlightMatch(term)) - // NO continue } } - _ = anyHit + score += record.RealtimeBefore * timeScoreCoef // KEY for deduplication key := record.CmdLine @@ -428,11 +459,11 @@ func newRawItemFromRecordForQuery(record records.CliRecord, terms []string, debu cmdLine := strings.ReplaceAll(record.CmdLine, "\n", ";") cmdLineWithColor := strings.ReplaceAll(cmd, "\n", ";") - it := rawItem{ - cmdLine: cmdLine, - cmdLineWithColor: cmdLineWithColor, - hits: hits, - key: key, + it := RawItem{ + CmdLine: cmdLine, + CmdLineWithColor: cmdLineWithColor, + Score: score, + Key: key, } return it, nil } diff --git a/cmd/cli/query.go b/pkg/searchapp/query.go similarity index 81% rename from cmd/cli/query.go rename to pkg/searchapp/query.go index 7fd8d4f..2b8227d 100644 --- a/cmd/cli/query.go +++ b/pkg/searchapp/query.go @@ -1,4 +1,4 @@ -package main +package searchapp import ( "log" @@ -6,7 +6,8 @@ import ( "strings" ) -type query struct { +// Query holds information that is used for result scoring +type Query struct { terms []string host string pwd string @@ -34,7 +35,8 @@ func filterTerms(terms []string) []string { return newTerms } -func newQueryFromString(queryInput string, host string, pwd string, gitOriginRemote string) query { +// NewQueryFromString . +func NewQueryFromString(queryInput string, host string, pwd string, gitOriginRemote string, debug bool) Query { if debug { log.Println("QUERY input = <" + queryInput + ">") } @@ -56,7 +58,7 @@ func newQueryFromString(queryInput string, host string, pwd string, gitOriginRem log.Println("QUERY pwd =" + pwd) } sort.SliceStable(terms, func(i, j int) bool { return len(terms[i]) < len(terms[j]) }) - return query{ + return Query{ terms: terms, host: host, pwd: pwd, @@ -64,7 +66,8 @@ func newQueryFromString(queryInput string, host string, pwd string, gitOriginRem } } -func getRawTermsFromString(queryInput string) []string { +// GetRawTermsFromString . +func GetRawTermsFromString(queryInput string, debug bool) []string { if debug { log.Println("QUERY input = <" + queryInput + ">") } diff --git a/pkg/searchapp/test.go b/pkg/searchapp/test.go new file mode 100644 index 0000000..e33e2f7 --- /dev/null +++ b/pkg/searchapp/test.go @@ -0,0 +1,23 @@ +package searchapp + +import ( + "math" + + "github.com/curusarn/resh/pkg/histcli" + "github.com/curusarn/resh/pkg/msg" + "github.com/curusarn/resh/pkg/records" +) + +// LoadHistoryFromFile ... +func LoadHistoryFromFile(historyPath string, numLines int) msg.CliResponse { + recs := records.LoadFromFile(historyPath, math.MaxInt32) + if numLines != 0 && numLines < len(recs) { + recs = recs[:numLines] + } + cliRecords := histcli.New() + for i := len(recs) - 1; i >= 0; i-- { + rec := recs[i] + cliRecords.AddRecord(rec) + } + return msg.CliResponse{CliRecords: cliRecords.List} +} diff --git a/cmd/cli/time.go b/pkg/searchapp/time.go similarity index 99% rename from cmd/cli/time.go rename to pkg/searchapp/time.go index 77ca367..5de6d20 100644 --- a/cmd/cli/time.go +++ b/pkg/searchapp/time.go @@ -1,4 +1,4 @@ -package main +package searchapp import ( "strconv" diff --git a/scripts/reshctl.sh b/scripts/reshctl.sh index a9bca77..44200b0 100644 --- a/scripts/reshctl.sh +++ b/scripts/reshctl.sh @@ -109,7 +109,7 @@ __resh_unbind_all() { resh() { local buffer local git_remote; git_remote="$(git remote get-url origin 2>/dev/null)" - buffer=$(resh-cli --sessionID "$__RESH_SESSION_ID" --host "$__RESH_HOST" --pwd "$PWD" --gitOriginRemote "$git_remote") + buffer=$(resh-cli --sessionID "$__RESH_SESSION_ID" --host "$__RESH_HOST" --pwd "$PWD" --gitOriginRemote "$git_remote" $@) status_code=$? if [ $status_code = 111 ]; then # execute