@@ -8,6 +8,13 @@ const imagePathPattern = new RegExp(
88 "giu"
99)
1010
11+ const treePointerImagePathSource =
12+ String . raw `[^\s"'(<>\[\]{}|\\/][^\s"'(<>\[\]{}|\\]*\.(?:${ extensionAlternation } )`
13+ const treePointerImagePathPattern = new RegExp (
14+ String . raw `(?:^|\s)[└├]\s+(${ treePointerImagePathSource } )(?=$|[\s"')<>\[\]{}|.,;:?!])` ,
15+ "giu"
16+ )
17+
1118const escapeChar = String . fromCodePoint ( 0x1B )
1219const bellChar = String . fromCodePoint ( 0x07 )
1320
@@ -26,22 +33,38 @@ export type TerminalImagePathMatch = {
2633export const stripTerminalAnsi = ( text : string ) : string =>
2734 text . replace ( ansiOscPattern , "" ) . replace ( ansiCsiPattern , "" ) . replace ( ansiOtherEscapePattern , "" )
2835
29- export const detectTerminalImagePathMatches = ( text : string ) : ReadonlyArray < TerminalImagePathMatch > => {
30- const plainText = stripTerminalAnsi ( text )
31- const matches : Array < TerminalImagePathMatch > = [ ]
32- for ( const match of plainText . matchAll ( imagePathPattern ) ) {
36+ const collectPatternMatches = (
37+ plainText : string ,
38+ pattern : RegExp ,
39+ matches : Array < TerminalImagePathMatch > ,
40+ seenStartIndices : Set < number >
41+ ) : void => {
42+ for ( const match of plainText . matchAll ( pattern ) ) {
3343 const candidate = match [ 1 ]
34- if ( candidate !== undefined && candidate . length > 0 ) {
35- const fullMatch = match [ 0 ]
36- const fullStartIndex = match . index
37- const startIndex = fullStartIndex + fullMatch . lastIndexOf ( candidate )
38- matches . push ( {
39- endIndex : startIndex + candidate . length ,
40- path : candidate ,
41- startIndex
42- } )
44+ if ( candidate === undefined || candidate . length === 0 ) {
45+ continue
4346 }
47+ const fullMatch = match [ 0 ]
48+ const fullStartIndex = match . index
49+ const startIndex = fullStartIndex + fullMatch . lastIndexOf ( candidate )
50+ if ( seenStartIndices . has ( startIndex ) ) {
51+ continue
52+ }
53+ seenStartIndices . add ( startIndex )
54+ matches . push ( {
55+ endIndex : startIndex + candidate . length ,
56+ path : candidate ,
57+ startIndex
58+ } )
4459 }
60+ }
61+
62+ export const detectTerminalImagePathMatches = ( text : string ) : ReadonlyArray < TerminalImagePathMatch > => {
63+ const plainText = stripTerminalAnsi ( text )
64+ const matches : Array < TerminalImagePathMatch > = [ ]
65+ const seenStartIndices = new Set < number > ( )
66+ collectPatternMatches ( plainText , imagePathPattern , matches , seenStartIndices )
67+ collectPatternMatches ( plainText , treePointerImagePathPattern , matches , seenStartIndices )
4568 return matches
4669}
4770
0 commit comments