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, " ")))
|
tui.ReportError(fmt.Errorf("Extra command line arguments present: %s", strings.Join(args, " ")))
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
text := parse_input(utils.UnsafeBytesToString(stdin))
|
input_text := parse_input(utils.UnsafeBytesToString(stdin))
|
||||||
all_marks, index_map, err := find_marks(text, o)
|
text, all_marks, index_map, err := find_marks(input_text, o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tui.ReportError(err)
|
tui.ReportError(err)
|
||||||
return 1, nil
|
return 1, nil
|
||||||
@ -141,7 +141,6 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
|||||||
alphabet = DEFAULT_HINT_ALPHABET
|
alphabet = DEFAULT_HINT_ALPHABET
|
||||||
}
|
}
|
||||||
ignore_mark_indices := utils.NewSet[int](8)
|
ignore_mark_indices := utils.NewSet[int](8)
|
||||||
_, _, _ = all_marks, index_map, ignore_mark_indices
|
|
||||||
window_title := o.WindowTitle
|
window_title := o.WindowTitle
|
||||||
if window_title == "" {
|
if window_title == "" {
|
||||||
switch o.Type {
|
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))
|
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))
|
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)
|
hint := encode_hint(m.Index, alphabet)
|
||||||
if current_input != "" && !strings.HasPrefix(hint, current_input) {
|
if current_input != "" && !strings.HasPrefix(hint, current_input) {
|
||||||
return faint(text)
|
return faint(mark_text)
|
||||||
}
|
}
|
||||||
hint = hint[len(current_input):]
|
hint = hint[len(current_input):]
|
||||||
if hint == "" {
|
if hint == "" {
|
||||||
hint = " "
|
hint = " "
|
||||||
}
|
}
|
||||||
text = text[len(hint):]
|
mark_text = mark_text[len(hint):]
|
||||||
return hint_style(hint) + text_style(text)
|
return hint_style(hint) + text_style(mark_text)
|
||||||
}
|
}
|
||||||
|
|
||||||
render := func() string {
|
render := func() string {
|
||||||
|
ans := text
|
||||||
for i := len(all_marks) - 1; i >= 0; i-- {
|
for i := len(all_marks) - 1; i >= 0; i-- {
|
||||||
mark := &all_marks[i]
|
mark := &all_marks[i]
|
||||||
if ignore_mark_indices.Has(mark.Index) {
|
if ignore_mark_indices.Has(mark.Index) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mtext := highlight_mark(mark)
|
mtext := highlight_mark(mark, ans[mark.Start:mark.End])
|
||||||
text = text[:mark.Start] + mtext + text[mark.End:]
|
ans = ans[:mark.Start] + mtext + ans[mark.End:]
|
||||||
}
|
}
|
||||||
text = strings.ReplaceAll(text, "\x00", "")
|
ans = strings.ReplaceAll(ans, "\x00", "")
|
||||||
return strings.TrimRightFunc(strings.NewReplacer("\r", "\r\n", "\n", "\r\n").Replace(text), unicode.IsSpace)
|
return strings.TrimRightFunc(strings.NewReplacer("\r", "\r\n", "\n", "\r\n").Replace(ans), unicode.IsSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_screen := func() {
|
draw_screen := func() {
|
||||||
@ -208,6 +208,10 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
|||||||
lp.ClearScreen()
|
lp.ClearScreen()
|
||||||
lp.QueueWriteString(current_text)
|
lp.QueueWriteString(current_text)
|
||||||
}
|
}
|
||||||
|
reset := func() {
|
||||||
|
current_input = ""
|
||||||
|
current_text = ""
|
||||||
|
}
|
||||||
|
|
||||||
lp.OnInitialize = func() (string, error) {
|
lp.OnInitialize = func() (string, error) {
|
||||||
lp.SendOverlayReady()
|
lp.SendOverlayReady()
|
||||||
@ -225,7 +229,89 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) {
|
|||||||
draw_screen()
|
draw_screen()
|
||||||
return nil
|
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.Match = make([]string, len(chosen))
|
||||||
result.Groupdicts = make([]map[string]string, len(chosen))
|
result.Groupdicts = make([]map[string]string, len(chosen))
|
||||||
for i, m := range chosen {
|
for i, m := range chosen {
|
||||||
|
|||||||
@ -322,31 +322,32 @@ func (self *ErrNoMatches) Error() string {
|
|||||||
return fmt.Sprintf("No %s found", none_of)
|
return fmt.Sprintf("No %s found", none_of)
|
||||||
}
|
}
|
||||||
|
|
||||||
func find_marks(text string, opts *Options) (ans []Mark, index_map map[int]*Mark, err error) {
|
func find_marks(text string, opts *Options) (sanitized_text string, ans []Mark, index_map map[int]*Mark, err error) {
|
||||||
text, hyperlinks := process_escape_codes(text)
|
sanitized_text, hyperlinks := process_escape_codes(text)
|
||||||
pattern, post_processors, group_processors := functions_for(opts)
|
pattern, post_processors, group_processors := functions_for(opts)
|
||||||
if opts.Type == "hyperlink" {
|
if opts.Type == "hyperlink" {
|
||||||
ans = hyperlinks
|
ans = hyperlinks
|
||||||
} else {
|
} else {
|
||||||
r, err := regexp.Compile(pattern)
|
r, err := regexp.Compile(pattern)
|
||||||
if err != nil {
|
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 {
|
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
|
largest_index := ans[len(ans)-1].Index
|
||||||
offset := utils.Max(0, opts.HintsOffset)
|
offset := utils.Max(0, opts.HintsOffset)
|
||||||
index_map = make(map[int]*Mark, len(ans))
|
index_map = make(map[int]*Mark, len(ans))
|
||||||
for _, m := range ans {
|
for i := range ans {
|
||||||
|
m := &ans[i]
|
||||||
if opts.Ascending {
|
if opts.Ascending {
|
||||||
m.Index += offset
|
m.Index += offset
|
||||||
} else {
|
} else {
|
||||||
m.Index = largest_index - m.Index + offset
|
m.Index = largest_index - m.Index + offset
|
||||||
}
|
}
|
||||||
index_map[m.Index] = &m
|
index_map[m.Index] = m
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ func TestHintMarking(t *testing.T) {
|
|||||||
cols := 20
|
cols := 20
|
||||||
r := func(text string, url ...string) {
|
r := func(text string, url ...string) {
|
||||||
ptext := convert_text(text, cols)
|
ptext := convert_text(text, cols)
|
||||||
marks, _, err := find_marks(ptext, opts)
|
_, marks, _, err := find_marks(ptext, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var e *ErrNoMatches
|
var e *ErrNoMatches
|
||||||
if len(url) != 0 || !errors.As(err, &e) {
|
if len(url) != 0 || !errors.As(err, &e) {
|
||||||
@ -51,7 +51,7 @@ func TestHintMarking(t *testing.T) {
|
|||||||
opts.Type = "linenum"
|
opts.Type = "linenum"
|
||||||
m := func(text, path string, line int) {
|
m := func(text, path string, line int) {
|
||||||
ptext := convert_text(text, cols)
|
ptext := convert_text(text, cols)
|
||||||
marks, _, err := find_marks(ptext, opts)
|
_, marks, _, err := find_marks(ptext, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%#v failed with error: %s", text, err)
|
t.Fatalf("%#v failed with error: %s", text, err)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user