reorganize search app code, minor fixes

pull/143/head v2.7.5
Simon Let 6 years ago
parent c001500450
commit fe878c57e8
  1. 116
      cmd/cli/main.go
  2. 8
      pkg/searchapp/highlight.go
  3. 231
      pkg/searchapp/item.go
  4. 13
      pkg/searchapp/query.go
  5. 23
      pkg/searchapp/test.go
  6. 2
      pkg/searchapp/time.go
  7. 2
      scripts/reshctl.sh

@ -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)
}

@ -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))
}

@ -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
}

@ -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 + ">")
}

@ -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}
}

@ -1,4 +1,4 @@
package main
package searchapp
import (
"strconv"

@ -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

Loading…
Cancel
Save