add full support for ctrl r in bash, search tweaks, fixes

pull/77/head v2.5.6
Simon Let 6 years ago
parent 1f56260bd0
commit a7d367ed38
  1. 84
      cmd/cli/main.go
  2. 2
      conf/config.toml
  3. 19
      scripts/reshctl.sh
  4. 12
      scripts/widgets.sh

@ -8,7 +8,6 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"math"
"net/http" "net/http"
"os" "os"
"sort" "sort"
@ -60,7 +59,6 @@ func runReshCli() (string, int) {
log.Fatal("Error reading config:", err) log.Fatal("Error reading config:", err)
} }
if config.Debug { if config.Debug {
// Debug = true
log.SetFlags(log.LstdFlags | log.Lmicroseconds) log.SetFlags(log.LstdFlags | log.Lmicroseconds)
} }
@ -96,6 +94,7 @@ func runReshCli() (string, int) {
st := state{ st := state{
// lock sync.Mutex // lock sync.Mutex
fullRecords: resp.FullRecords, fullRecords: resp.FullRecords,
initialQuery: *query,
} }
layout := manager{ layout := manager{
@ -279,24 +278,33 @@ func properMatch(str, term, padChar string) bool {
// 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 // returns error if the query doesn't match the record
func newItemFromRecordForQuery(record records.EnrichedRecord, query query) (item, error) { func newItemFromRecordForQuery(record records.EnrichedRecord, query query, debug bool) (item, error) {
// TODO: use color to highlight matches // TODO: use color to highlight matches
const hitScore = 1.0
const hitScoreConsecutive = 0.1
const properMatchScore = 0.3 const properMatchScore = 0.3
const actualPwdScore = 0.9 const actualPwdScore = 0.9
const actualPwdScoreExtra = 0.2
hits := 0.0 hits := 0.0
if record.ExitCode != 0 {
hits--
}
cmd := record.CmdLine cmd := record.CmdLine
pwdTilde := strings.Replace(record.Pwd, record.Home, "~", 1) pwdTilde := strings.Replace(record.Pwd, record.Home, "~", 1)
pwdDisp := leftCutPadString(pwdTilde, 25) pwdDisp := leftCutPadString(pwdTilde, 25)
pwdRawDisp := leftCutPadString(record.Pwd, 25) pwdRawDisp := leftCutPadString(record.Pwd, 25)
var useRawPwd bool var useRawPwd bool
var dirHit bool
for _, term := range query.terms { for _, term := range query.terms {
alreadyHit := false termHit := false
if strings.Contains(record.CmdLine, term) { if strings.Contains(record.CmdLine, term) {
if alreadyHit == false { if termHit == false {
hits++ hits += hitScore
} else {
hits += hitScoreConsecutive
} }
alreadyHit = true termHit = true
if properMatch(cmd, term, " ") { if properMatch(cmd, term, " ") {
hits += properMatchScore hits += properMatchScore
} }
@ -304,36 +312,48 @@ func newItemFromRecordForQuery(record records.EnrichedRecord, query query) (item
// NO continue // NO continue
} }
if strings.Contains(pwdTilde, term) { if strings.Contains(pwdTilde, term) {
if alreadyHit == false { if termHit == false {
hits++ hits += hitScore
} else {
hits += hitScoreConsecutive
} }
alreadyHit = true termHit = true
if properMatch(pwdTilde, term, " ") { if properMatch(pwdTilde, term, "/") {
hits += properMatchScore hits += properMatchScore
} }
pwdDisp = strings.ReplaceAll(pwdDisp, term, highlightMatch(term)) pwdDisp = strings.ReplaceAll(pwdDisp, term, highlightMatch(term))
useRawPwd = false pwdRawDisp = strings.ReplaceAll(pwdRawDisp, term, highlightMatch(term))
continue // IMPORTANT dirHit = true
} } else if strings.Contains(record.Pwd, term) {
if strings.Contains(record.Pwd, term) { if termHit == false {
if alreadyHit == false { hits += hitScore
hits++ } else {
hits += hitScoreConsecutive
} }
alreadyHit = true termHit = true
if properMatch(pwdTilde, term, " ") { if properMatch(pwdTilde, term, "/") {
hits += properMatchScore hits += properMatchScore
} }
pwdRawDisp = strings.ReplaceAll(pwdRawDisp, term, highlightMatch(term)) pwdRawDisp = strings.ReplaceAll(pwdRawDisp, term, highlightMatch(term))
dirHit = true
useRawPwd = true useRawPwd = true
continue // IMPORTANT
} }
// if strings.Contains(record.GitOriginRemote, term) { // if strings.Contains(record.GitOriginRemote, term) {
// hits++ // hits++
// } // }
} }
// actual pwd matches // actual pwd matches
// only use if there was no directory match on any of the terms
// N terms can only produce:
// -> N matches against the command
// -> N matches against the directory
// -> 1 extra match for the actual directory match
if record.Pwd == query.pwd { if record.Pwd == query.pwd {
if dirHit {
hits += actualPwdScoreExtra
} else {
hits += actualPwdScore hits += actualPwdScore
}
pwdDisp = highlightMatchAlternative(pwdDisp) pwdDisp = highlightMatchAlternative(pwdDisp)
// pwdRawDisp = highlightMatchAlternative(pwdRawDisp) // pwdRawDisp = highlightMatchAlternative(pwdRawDisp)
useRawPwd = false useRawPwd = false
@ -348,8 +368,13 @@ func newItemFromRecordForQuery(record records.EnrichedRecord, query query) (item
} else { } else {
display += pwdDisp display += pwdDisp
} }
hitsDisp := " " + rightCutPadString(strconv.Itoa(int(math.Floor(hits))), 2) if debug {
hitsStr := fmt.Sprintf("%.1f", hits)
hitsDisp := " " + hitsStr + " "
display += hitsDisp display += hitsDisp
} else {
display += " "
}
// cmd := "<" + strings.ReplaceAll(record.CmdLine, "\n", ";") + ">" // cmd := "<" + strings.ReplaceAll(record.CmdLine, "\n", ";") + ">"
cmd = strings.ReplaceAll(cmd, "\n", ";") cmd = strings.ReplaceAll(cmd, "\n", ";")
display += cmd display += cmd
@ -383,6 +408,8 @@ type state struct {
data []item data []item
highlightedItem int highlightedItem int
initialQuery string
output string output string
exitCode int exitCode int
} }
@ -427,7 +454,7 @@ func (m manager) UpdateData(input string) {
m.s.lock.Lock() m.s.lock.Lock()
defer m.s.lock.Unlock() defer m.s.lock.Unlock()
for _, rec := range m.s.fullRecords { for _, rec := range m.s.fullRecords {
itm, err := newItemFromRecordForQuery(rec, query) itm, err := newItemFromRecordForQuery(rec, query, m.config.Debug)
if err != nil { if err != nil {
// records didn't match the query // records didn't match the query
// log.Println(" * continue (no match)", rec.Pwd) // log.Println(" * continue (no match)", rec.Pwd)
@ -482,8 +509,6 @@ func (m manager) Prev(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
// you can have Layout with pointer reciever if you pass the layout function to the setmanger
// I dont think we need that tho
func (m manager) Layout(g *gocui.Gui) error { func (m manager) Layout(g *gocui.Gui) error {
var b byte var b byte
maxX, maxY := g.Size() maxX, maxY := g.Size()
@ -494,12 +519,19 @@ func (m manager) Layout(g *gocui.Gui) error {
} }
v.Editable = true v.Editable = true
// v.Editor = gocui.EditorFunc(m.editor.Edit)
v.Editor = m v.Editor = m
v.Title = "resh cli" v.Title = "resh cli"
g.SetCurrentView("input") g.SetCurrentView("input")
m.s.lock.Lock()
defer m.s.lock.Unlock()
if len(m.s.initialQuery) > 0 {
v.WriteString(m.s.initialQuery)
v.SetCursor(len(m.s.initialQuery), 0)
m.s.initialQuery = ""
}
v, err = g.SetView("body", 0, 2, maxX-1, maxY, b) v, err = g.SetView("body", 0, 2, maxX-1, maxY, b)
if err != nil && gocui.IsUnknownView(err) == false { if err != nil && gocui.IsUnknownView(err) == false {
log.Panicln(err.Error()) log.Panicln(err.Error())
@ -509,8 +541,6 @@ func (m manager) Layout(g *gocui.Gui) error {
v.Clear() v.Clear()
v.Rewind() v.Rewind()
m.s.lock.Lock()
defer m.s.lock.Unlock()
for i, itm := range m.s.data { for i, itm := range m.s.data {
if i == maxY { if i == maxY {
log.Println(maxY) log.Println(maxY)

@ -1,7 +1,7 @@
port = 2627 port = 2627
sesswatchPeriodSeconds = 120 sesswatchPeriodSeconds = 120
sesshistInitHistorySize = 1000 sesshistInitHistorySize = 1000
debug = true debug = false
bindArrowKeysBash = false bindArrowKeysBash = false
bindArrowKeysZsh = true bindArrowKeysZsh = true
bindControlR = false bindControlR = false

@ -25,6 +25,11 @@ __resh_bind_arrows() {
return 0 return 0
} }
__resh_nop() {
# does nothing
true
}
__resh_bind_control_R() { __resh_bind_control_R() {
if [ "${__RESH_control_R_bind_enabled-0}" != 0 ]; then if [ "${__RESH_control_R_bind_enabled-0}" != 0 ]; then
echo "Error: Can't enable control R binding because it is already enabled!" echo "Error: Can't enable control R binding because it is already enabled!"
@ -34,13 +39,15 @@ __resh_bind_control_R() {
__RESH_bindfunc_revert_control_R_bind=$_bindfunc_revert __RESH_bindfunc_revert_control_R_bind=$_bindfunc_revert
__RESH_control_R_bind_enabled=1 __RESH_control_R_bind_enabled=1
if [ -n "${BASH_VERSION-}" ]; then if [ -n "${BASH_VERSION-}" ]; then
echo "BASH is not currently not supported"
return 1
# fuck bash # fuck bash
# TODO set \C-r bind to \impossible1 \impossible2 bind '"\C-r": "\u[31~\u[32~"'
# set \impossible1 to widget bind -x '"\u[31~": __resh_widget_control_R_compat'
# that's it - \impossible2 is set in the widget and revert function is still working
# execute
# bind '"\u[32~": accept-line'
# just paste
# bind -x '"\u[32~": __resh_nop'
true true
fi fi
return 0 return 0
@ -110,6 +117,8 @@ resh() {
elif [ $status_code = 0 ]; then elif [ $status_code = 0 ]; then
# paste # paste
echo "$buffer" echo "$buffer"
elif [ $status_code = 130 ]; then
true
else else
echo "$buffer" > ~/.resh/cli_last_run_out.txt echo "$buffer" > ~/.resh/cli_last_run_out.txt
echo "resh-cli ERROR:" echo "resh-cli ERROR:"

@ -102,18 +102,18 @@ __resh_widget_control_R() {
# zsh # zsh
zle accept-line zle accept-line
elif [ -n "${BASH_VERSION-}" ]; then elif [ -n "${BASH_VERSION-}" ]; then
echo "BASH is not currently not supported for control R binding - sorry"
# bash # bash
# TODO set chained keyseq to accept-line # set chained keyseq to accept-line
true bind '"\u[32~": accept-line'
fi fi
elif [ $status_code = 0 ]; then elif [ $status_code = 0 ]; then
if [ -n "${BASH_VERSION-}" ]; then if [ -n "${BASH_VERSION-}" ]; then
echo "BASH is not currently not supported for control R binding - sorry"
# bash # bash
# TODO set chained keyseq to nothing # set chained keyseq to nothing
true bind -x '"\u[32~": __resh_nop'
fi fi
elif [ $status_code = 130 ]; then
BUFFER="$PREVBUFFER"
else else
echo "$BUFFER" > ~/.resh/cli_last_run_out.txt echo "$BUFFER" > ~/.resh/cli_last_run_out.txt
echo "# RESH cli failed - sorry for the inconvinience (error output was saved to ~/.resh/cli_last_run_out.txt)" echo "# RESH cli failed - sorry for the inconvinience (error output was saved to ~/.resh/cli_last_run_out.txt)"

Loading…
Cancel
Save