More work on porting hints
This commit is contained in:
parent
5b3f5dd02d
commit
2e1eebd998
@ -124,8 +124,8 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
||||
tui.ReportError(fmt.Errorf("Extra command line arguments present: %s", strings.Join(args, " ")))
|
||||
return 1, nil
|
||||
}
|
||||
text := parse_input(utils.UnsafeBytesToString(stdin))
|
||||
all_marks, index_map, err := find_marks(text, o)
|
||||
input_text := parse_input(utils.UnsafeBytesToString(stdin))
|
||||
text, all_marks, index_map, err := find_marks(input_text, o)
|
||||
if err != nil {
|
||||
tui.ReportError(err)
|
||||
return 1, nil
|
||||
@ -141,7 +141,6 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
||||
alphabet = DEFAULT_HINT_ALPHABET
|
||||
}
|
||||
ignore_mark_indices := utils.NewSet[int](8)
|
||||
_, _, _ = all_marks, index_map, ignore_mark_indices
|
||||
window_title := o.WindowTitle
|
||||
if window_title == "" {
|
||||
switch o.Type {
|
||||
@ -173,30 +172,31 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
||||
hint_style := fctx.SprintFunc(fmt.Sprintf("fg=%s bg=%s bold", o.HintsForegroundColor, o.HintsBackgroundColor))
|
||||
text_style := fctx.SprintFunc(fmt.Sprintf("fg=bright-%s bold", o.HintsTextColor))
|
||||
|
||||
highlight_mark := func(m *Mark) string {
|
||||
highlight_mark := func(m *Mark, mark_text string) string {
|
||||
hint := encode_hint(m.Index, alphabet)
|
||||
if current_input != "" && !strings.HasPrefix(hint, current_input) {
|
||||
return faint(text)
|
||||
return faint(mark_text)
|
||||
}
|
||||
hint = hint[len(current_input):]
|
||||
if hint == "" {
|
||||
hint = " "
|
||||
}
|
||||
text = text[len(hint):]
|
||||
return hint_style(hint) + text_style(text)
|
||||
mark_text = mark_text[len(hint):]
|
||||
return hint_style(hint) + text_style(mark_text)
|
||||
}
|
||||
|
||||
render := func() string {
|
||||
ans := text
|
||||
for i := len(all_marks) - 1; i >= 0; i-- {
|
||||
mark := &all_marks[i]
|
||||
if ignore_mark_indices.Has(mark.Index) {
|
||||
continue
|
||||
}
|
||||
mtext := highlight_mark(mark)
|
||||
text = text[:mark.Start] + mtext + text[mark.End:]
|
||||
mtext := highlight_mark(mark, ans[mark.Start:mark.End])
|
||||
ans = ans[:mark.Start] + mtext + ans[mark.End:]
|
||||
}
|
||||
text = strings.ReplaceAll(text, "\x00", "")
|
||||
return strings.TrimRightFunc(strings.NewReplacer("\r", "\r\n", "\n", "\r\n").Replace(text), unicode.IsSpace)
|
||||
ans = strings.ReplaceAll(ans, "\x00", "")
|
||||
return strings.TrimRightFunc(strings.NewReplacer("\r", "\r\n", "\n", "\r\n").Replace(ans), unicode.IsSpace)
|
||||
}
|
||||
|
||||
draw_screen := func() {
|
||||
@ -208,6 +208,10 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
||||
lp.ClearScreen()
|
||||
lp.QueueWriteString(current_text)
|
||||
}
|
||||
reset := func() {
|
||||
current_input = ""
|
||||
current_text = ""
|
||||
}
|
||||
|
||||
lp.OnInitialize = func() (string, error) {
|
||||
lp.SendOverlayReady()
|
||||
@ -225,7 +229,89 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
||||
draw_screen()
|
||||
return nil
|
||||
}
|
||||
lp.OnText = func(text string, _, _ bool) error {
|
||||
changed := false
|
||||
for _, ch := range text {
|
||||
if strings.ContainsRune(alphabet, ch) {
|
||||
current_input += string(ch)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
matches := []*Mark{}
|
||||
for idx, m := range index_map {
|
||||
if eh := encode_hint(idx, alphabet); strings.HasPrefix(eh, current_input) {
|
||||
matches = append(matches, m)
|
||||
}
|
||||
}
|
||||
if len(matches) == 1 {
|
||||
chosen = append(chosen, matches[0])
|
||||
if o.Multiple {
|
||||
ignore_mark_indices.Add(matches[0].Index)
|
||||
reset()
|
||||
} else {
|
||||
lp.Quit(0)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
current_text = ""
|
||||
draw_screen()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
lp.OnKeyEvent = func(ev *loop.KeyEvent) error {
|
||||
if ev.MatchesPressOrRepeat("backspace") {
|
||||
ev.Handled = true
|
||||
r := []rune(current_input)
|
||||
if len(r) > 0 {
|
||||
r = r[:len(r)-1]
|
||||
current_input = string(r)
|
||||
current_text = ""
|
||||
}
|
||||
draw_screen()
|
||||
} else if ev.MatchesPressOrRepeat("enter") || ev.MatchesPressOrRepeat("space") {
|
||||
ev.Handled = true
|
||||
if current_input != "" {
|
||||
idx := decode_hint(current_input, alphabet)
|
||||
if m := index_map[idx]; m != nil {
|
||||
chosen = append(chosen, m)
|
||||
ignore_mark_indices.Add(idx)
|
||||
if o.Multiple {
|
||||
reset()
|
||||
draw_screen()
|
||||
} else {
|
||||
lp.Quit(0)
|
||||
}
|
||||
} else {
|
||||
current_input = ""
|
||||
current_text = ""
|
||||
draw_screen()
|
||||
}
|
||||
}
|
||||
} else if ev.MatchesPressOrRepeat("esc") {
|
||||
if o.Multiple {
|
||||
lp.Quit(1)
|
||||
} else {
|
||||
lp.Quit(0)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err = lp.Run()
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
ds := lp.DeathSignalName()
|
||||
if ds != "" {
|
||||
fmt.Println("Killed by signal: ", ds)
|
||||
lp.KillIfSignalled()
|
||||
return 1, nil
|
||||
}
|
||||
if lp.ExitCode() != 0 {
|
||||
return lp.ExitCode(), nil
|
||||
}
|
||||
result.Match = make([]string, len(chosen))
|
||||
result.Groupdicts = make([]map[string]string, len(chosen))
|
||||
for i, m := range chosen {
|
||||
|
||||
@ -322,31 +322,32 @@ func (self *ErrNoMatches) Error() string {
|
||||
return fmt.Sprintf("No %s found", none_of)
|
||||
}
|
||||
|
||||
func find_marks(text string, opts *Options) (ans []Mark, index_map map[int]*Mark, err error) {
|
||||
text, hyperlinks := process_escape_codes(text)
|
||||
func find_marks(text string, opts *Options) (sanitized_text string, ans []Mark, index_map map[int]*Mark, err error) {
|
||||
sanitized_text, hyperlinks := process_escape_codes(text)
|
||||
pattern, post_processors, group_processors := functions_for(opts)
|
||||
if opts.Type == "hyperlink" {
|
||||
ans = hyperlinks
|
||||
} else {
|
||||
r, err := regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Failed to compile the regex pattern: %#v with error: %w", pattern, err)
|
||||
return "", nil, nil, fmt.Errorf("Failed to compile the regex pattern: %#v with error: %w", pattern, err)
|
||||
}
|
||||
ans = mark(r, post_processors, group_processors, text, opts)
|
||||
ans = mark(r, post_processors, group_processors, sanitized_text, opts)
|
||||
}
|
||||
if len(ans) == 0 {
|
||||
return nil, nil, &ErrNoMatches{Type: opts.Type}
|
||||
return "", nil, nil, &ErrNoMatches{Type: opts.Type}
|
||||
}
|
||||
largest_index := ans[len(ans)-1].Index
|
||||
offset := utils.Max(0, opts.HintsOffset)
|
||||
index_map = make(map[int]*Mark, len(ans))
|
||||
for _, m := range ans {
|
||||
for i := range ans {
|
||||
m := &ans[i]
|
||||
if opts.Ascending {
|
||||
m.Index += offset
|
||||
} else {
|
||||
m.Index = largest_index - m.Index + offset
|
||||
}
|
||||
index_map[m.Index] = &m
|
||||
index_map[m.Index] = m
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ func TestHintMarking(t *testing.T) {
|
||||
cols := 20
|
||||
r := func(text string, url ...string) {
|
||||
ptext := convert_text(text, cols)
|
||||
marks, _, err := find_marks(ptext, opts)
|
||||
_, marks, _, err := find_marks(ptext, opts)
|
||||
if err != nil {
|
||||
var e *ErrNoMatches
|
||||
if len(url) != 0 || !errors.As(err, &e) {
|
||||
@ -51,7 +51,7 @@ func TestHintMarking(t *testing.T) {
|
||||
opts.Type = "linenum"
|
||||
m := func(text, path string, line int) {
|
||||
ptext := convert_text(text, cols)
|
||||
marks, _, err := find_marks(ptext, opts)
|
||||
_, marks, _, err := find_marks(ptext, opts)
|
||||
if err != nil {
|
||||
t.Fatalf("%#v failed with error: %s", text, err)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user