mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-12-22 10:58:59 +00:00
parent
61d10d8ffa
commit
3b0c86e401
@ -6,6 +6,7 @@ CHANGELOG
|
||||
- Built-in walker improvements
|
||||
- `--walker-root` can take multiple directory arguments. e.g. `--walker-root include src lib`
|
||||
- `--walker-skip` can handle multi-component patterns. e.g. `--walker-skip target/build`
|
||||
- Removed long processing delay when displaying images in the preview window
|
||||
- `FZF_PREVIEW_*` environment variables are exported to all child processes (#4098)
|
||||
- Bug fixes in fish scripts
|
||||
|
||||
|
@ -51,7 +51,8 @@ var placeholder *regexp.Regexp
|
||||
var whiteSuffix *regexp.Regexp
|
||||
var offsetComponentRegex *regexp.Regexp
|
||||
var offsetTrimCharsRegex *regexp.Regexp
|
||||
var passThroughRegex *regexp.Regexp
|
||||
var passThroughBeginRegex *regexp.Regexp
|
||||
var passThroughEndTmuxRegex *regexp.Regexp
|
||||
var ttyin *os.File
|
||||
|
||||
const clearCode string = "\x1b[2J"
|
||||
@ -74,7 +75,15 @@ func init() {
|
||||
// * https://sw.kovidgoyal.net/kitty/graphics-protocol
|
||||
// * https://en.wikipedia.org/wiki/Sixel
|
||||
// * https://iterm2.com/documentation-images.html
|
||||
passThroughRegex = regexp.MustCompile(`\x1bPtmux;\x1b\x1b.*?[^\x1b]\x1b\\|\x1b(_G|P[0-9;]*q).*?\x1b\\\r?|\x1b]1337;.*?(\a|\x1b\\)`)
|
||||
/*
|
||||
passThroughRegex = regexp.MustCompile(`
|
||||
\x1bPtmux;\x1b\x1b .*? [^\x1b]\x1b\\
|
||||
| \x1b(_G|P[0-9;]*q) .*? \x1b\\\r?
|
||||
| \x1b]1337; .*? (\a|\x1b\\)
|
||||
`)
|
||||
*/
|
||||
passThroughBeginRegex = regexp.MustCompile(`\x1bPtmux;\x1b\x1b|\x1b(_G|P[0-9;]*q)|\x1b]1337;`)
|
||||
passThroughEndTmuxRegex = regexp.MustCompile(`[^\x1b]\x1b\\`)
|
||||
}
|
||||
|
||||
type jumpMode int
|
||||
@ -2622,6 +2631,67 @@ func (t *Terminal) makeImageBorder(width int, top bool) string {
|
||||
return v + strings.Repeat(" ", repeat) + v
|
||||
}
|
||||
|
||||
func findPassThrough(line string) []int {
|
||||
loc := passThroughBeginRegex.FindStringIndex(line)
|
||||
if loc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
rest := line[loc[0]:]
|
||||
after := line[loc[1]:]
|
||||
if strings.HasPrefix(rest, "\x1bPtmux") { // Tmux
|
||||
eloc := passThroughEndTmuxRegex.FindStringIndex(after)
|
||||
if eloc == nil {
|
||||
return nil
|
||||
}
|
||||
return []int{loc[0], loc[1] + eloc[1]}
|
||||
} else if strings.HasPrefix(rest, "\x1b]1337;") { // iTerm2
|
||||
index := loc[1]
|
||||
for {
|
||||
after := line[index:]
|
||||
pos := strings.IndexAny(after, "\x1b\a")
|
||||
if pos < 0 {
|
||||
return nil
|
||||
}
|
||||
if after[pos] == '\a' {
|
||||
return []int{loc[0], index + pos + 1}
|
||||
}
|
||||
if pos < len(after)-1 && after[pos+1] == '\\' {
|
||||
return []int{loc[0], index + pos + 2}
|
||||
}
|
||||
index += pos + 1
|
||||
}
|
||||
}
|
||||
// Kitty
|
||||
pos := strings.Index(after, "\x1b\\")
|
||||
if pos < 0 {
|
||||
return nil
|
||||
}
|
||||
if pos < len(after)-2 && after[pos+2] == '\r' {
|
||||
return []int{loc[0], loc[1] + pos + 3}
|
||||
}
|
||||
return []int{loc[0], loc[1] + pos + 2}
|
||||
}
|
||||
|
||||
func extractPassThroughs(line string) ([]string, string) {
|
||||
passThroughs := []string{}
|
||||
transformed := ""
|
||||
index := 0
|
||||
for {
|
||||
rest := line[index:]
|
||||
loc := findPassThrough(rest)
|
||||
if loc == nil {
|
||||
transformed += rest
|
||||
break
|
||||
}
|
||||
passThroughs = append(passThroughs, rest[loc[0]:loc[1]])
|
||||
transformed += line[index : index+loc[0]]
|
||||
index += loc[1]
|
||||
}
|
||||
|
||||
return passThroughs, transformed
|
||||
}
|
||||
|
||||
func (t *Terminal) renderPreviewText(height int, lines []string, lineNo int, unchanged bool) {
|
||||
maxWidth := t.pwindow.Width()
|
||||
var ansi *ansiState
|
||||
@ -2636,10 +2706,7 @@ Loop:
|
||||
ansi.lbg = -1
|
||||
}
|
||||
|
||||
passThroughs := passThroughRegex.FindAllString(line, -1)
|
||||
if passThroughs != nil {
|
||||
line = passThroughRegex.ReplaceAllString(line, "")
|
||||
}
|
||||
passThroughs, line := extractPassThroughs(line)
|
||||
line = strings.TrimLeft(strings.TrimRight(line, "\r\n"), "\r")
|
||||
|
||||
if lineNo >= height || t.pwindow.Y() == height-1 && t.pwindow.X() > 0 {
|
||||
|
@ -507,6 +507,34 @@ func TestParsePlaceholder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractPassthroughs(t *testing.T) {
|
||||
for _, middle := range []string{
|
||||
"\x1bPtmux;\x1b\x1bbar\x1b\\",
|
||||
"\x1bPtmux;\x1b\x1bbar\x1bbar\x1b\\",
|
||||
"\x1b]1337;bar\x1b\\",
|
||||
"\x1b]1337;bar\x1bbar\x1b\\",
|
||||
"\x1b]1337;bar\a",
|
||||
"\x1b_Ga=T,f=32,s=1258,v=1295,c=74,r=35,m=1\x1b\\",
|
||||
"\x1b_Ga=T,f=32,s=1258,v=1295,c=74,r=35,m=1\x1b\\\r",
|
||||
"\x1b_Ga=T,f=32,s=1258,v=1295,c=74,r=35,m=1\x1bbar\x1b\\\r",
|
||||
"\x1b_Gm=1;AAAAAAAAA=\x1b\\",
|
||||
"\x1b_Gm=1;AAAAAAAAA=\x1b\\\r",
|
||||
"\x1b_Gm=1;\x1bAAAAAAAAA=\x1b\\\r",
|
||||
} {
|
||||
line := "foo" + middle + "baz"
|
||||
loc := findPassThrough(line)
|
||||
if loc == nil || line[0:loc[0]] != "foo" || line[loc[1]:] != "baz" {
|
||||
t.Error("failed to find passthrough")
|
||||
}
|
||||
garbage := "\x1bPtmux;\x1b]1337;\x1b_Ga=\x1b]1337;bar\x1b."
|
||||
line = strings.Repeat("foo"+middle+middle+"baz", 3) + garbage
|
||||
passthroughs, result := extractPassThroughs(line)
|
||||
if result != "foobazfoobazfoobaz"+garbage || len(passthroughs) != 6 {
|
||||
t.Error("failed to extract passthroughs")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* utilities section */
|
||||
|
||||
// Item represents one line in fzf UI. Usually it is relative path to files and folders.
|
||||
|
Loading…
Reference in New Issue
Block a user