@@ -11,60 +11,6 @@ export def Echowarn(msg: string)
1111 echohl WarningMsg | echom $ ' [markdown_extras] {msg}' | echohl None
1212enddef
1313
14- # TODO it may be limiting to have ' string' only
15- export def KeysFromValue (dict : dict <string> , target_value: string ): list <string>
16- # Given a value, return all the keys associated to it
17- return keys (filter (copy (dict ), $ ' v:val == "{target_value}"' ))
18- enddef
19-
20- export def DictToListOfDicts (d : dict <any> ): list <dict<any> >
21- # Convert a dict in a list of dict .
22- #
23- # For example, {a: ' foo' , b: ' bar' , c : ' baz' } becomes
24- # [{a: ' foo' }, {b: ' bar' }, {c : ' baz' }]
25- #
26- var list_of_dicts = []
27- for [k , v ] in items (d )
28- add (list_of_dicts, {[k ]: v })
29- endfor
30- return list_of_dicts
31- enddef
32-
33- export def ZipLists (l1: list <any> , l2: list <any> ): list <list<any> >
34- # Zip- like function , like in Python
35- var min_len = min ([len (l1), len (l2)])
36- return map (range (min_len), $ ' [{l1}[v:val], {l2}[v:val]]' )
37- enddef
38-
39- export def GetTextObject (textobject: string ): dict <any>
40- # You pass a text object like ' iw' and it returns the text
41- # associated to it along with the start and end positions.
42- #
43- # Note that when you yank some text, the registers ' [' and ' ]' are set , so
44- # after call this function , you can retrieve start and end position of the
45- # text- object by looking at such marks .
46- #
47- # The function also work with motions.
48-
49- # Backup the content of register t (arbitrary choice, YMMV) and marks
50- var oldreg = getreg (" t" )
51- var saved_A = getcharpos (" '[" )
52- var saved_B = getcharpos (" ']" )
53- # silently yank the text covered by whatever text object
54- # was given as argument into register t . Yank also set marks ' [ and ' ]
55- noautocmd execute ' silent normal "ty' .. textobject
56-
57- var text = getreg (" t" )
58- var start_pos = getcharpos (" '[" )
59- var end_pos = getcharpos (" ']" )
60-
61- # restore register t and marks
62- setreg (" t" , oldreg)
63- setcharpos (" '[" , saved_A)
64- setcharpos (" ']" , saved_B)
65-
66- return {text: text, start : start_pos, end : end_pos}
67- enddef
6814
6915export def FormatWithoutMoving (a: number = 0 , b: number = 0 )
7016 # To be used for formatting through autocmds
@@ -92,48 +38,42 @@ export def FormatWithoutMoving(a: number = 0, b: number = 0)
9238enddef
9339
9440export def RemoveSurrounding ()
95- var interval = IsInRange ()
96- if ! empty (interval)
41+ const style_interval = IsInRange ()
42+ if ! empty (style_interval)
43+ const style = keys (style_interval)[0 ]
44+ const interval = values (style_interval)[0 ]
45+
9746 # Remove left delimiter
98- var lA = interval[0 ][1 ]
99- var cA = interval[0 ][2 ]
100- var newline =
101- strcharpart ( getline (lA), 0 , cA - 1 - len (keys (open_delimiter_dict)[ 0 ] ))
102- .. strcharpart (getline (lA), cA - 1 )
47+ const lA = interval[0 ][0 ]
48+ const cA = interval[0 ][1 ]
49+ var newline = strcharpart ( getline (lA), 0 ,
50+ \ cA - 1 - len (constants.TEXT_STYLES_DICT[style].open_delim ))
51+ \ .. strcharpart (getline (lA), cA - 1 )
10352 setline (lA, newline)
10453
10554 # Remove right delimiter
106- var lB = interval[1 ][1 ]
107- var cB = interval[1 ][2 ]
55+ const lB = interval[1 ][0 ]
56+ var cB = interval[1 ][1 ]
10857 # The value of cB may no longer be valid since we shortened the line
10958 if lA == lB
110- cB = cB - len (keys (open_delimiter_dict)[ 0 ] )
59+ cB = cB - len (constants.TEXT_STYLES_DICT[style].open_delim )
11160 endif
11261
113- newline =
114- strcharpart (getline (lB), 0 , cB)
115- .. strcharpart ( getline (lB), cB + len (keys (close_delimiter_dict)[ 0 ] ))
62+ newline = strcharpart ( getline (lB), 0 , cB)
63+ \ .. strcharpart (getline (lB),
64+ \ cB + len (constants.TEXT_STYLES_DICT[style].open_delim ))
11665 setline (lB, newline)
11766 endif
11867enddef
11968
120- export def SurroundSimple (open_delimiter: string ,
121- close_delimiter: string ,
122- open_delimiters_dict: dict <string> ,
123- close_delimiters_dict: dict <string> ,
124- type : string = ' ' )
69+ export def SurroundSimple (style: string , type : string = ' ' )
12570
12671 if getcharpos (" '[" ) == getcharpos (" ']" )
12772 return
12873 endif
12974
130- var open_string = open_delimiter
131- var open_regex = open_delimiters_dict[open_string]
132- var open_delimiter_dict = {open_string: open_regex}
133-
134- var close_string = close_delimiter
135- var close_regex = close_delimiters_dict[close_string]
136- var close_delimiter_dict = {close_string: close_regex}
75+ var open_delim = constants.TEXT_STYLES_DICT[style].open_delim
76+ var close_delim = constants.TEXT_STYLES_DICT[style].close_delim
13777
13878 # line and column of point A
13979 var lA = line (" '[" )
@@ -143,8 +83,8 @@ export def SurroundSimple(open_delimiter: string,
14383 var lB = line (" ']" )
14484 var cB = col (" ']" )
14585
146- var toA = strcharpart (getline (lA), 0 , cA - 1 ) .. open_string
147- var fromB = close_string .. strcharpart (getline (lB), cB)
86+ var toA = strcharpart (getline (lA), 0 , cA - 1 ) .. open_delim
87+ var fromB = close_delim .. strcharpart (getline (lB), cB)
14888
14989 # If on the same line
15090 if lA == lB
@@ -189,9 +129,11 @@ export def SurroundSmart(style: string, type: string = '')
189129 # We don't want to remove links between A and B
190130 var regex_for_removal = keys (constants.TEXT_STYLES_DICT)
191131 - >filter (" v:val !~ '\\ v(markdownLinkText)'" )
132+ # TODO here we should use open_regex and close_regex but then the substitute ()
133+ # will replace also the \S :- (
192134 for k in regex_for_removal
193- add (delimiters_to_remove, constants.TEXT_STYLES_DICT[k ].open_regex )
194- add (delimiters_to_remove, constants.TEXT_STYLES_DICT[k ].close_regex )
135+ add (delimiters_to_remove, constants.TEXT_STYLES_DICT[k ].open_delim )
136+ add (delimiters_to_remove, constants.TEXT_STYLES_DICT[k ].close_delim )
195137 endfor
196138
197139 # line and column of point A
@@ -226,7 +168,6 @@ export def SurroundSmart(style: string, type: string = '')
226168 cursor (lA, cA)
227169 var old_right_delimiter = ' '
228170 var found_interval = IsInRange ()
229- echom found_interval
230171 if ! empty (found_interval)
231172 var found_style = keys (found_interval)[0 ]
232173 old_right_delimiter = constants.TEXT_STYLES_DICT[found_style].open_delim
@@ -294,11 +235,7 @@ export def SurroundSmart(style: string, type: string = '')
294235 var A_to_B = ' '
295236 A_to_B = strcharpart (getline (lA), cA - 1 , cB - cA + 1 )
296237 if style != ' markdownCode'
297- for regex in delimiters_to_remove
298- A_to_B = A_to_B- >substitute (regex, ' ' , ' g' )
299- # echom regex
300- echom " A_to_B: " .. A_to_B
301- endfor
238+ A_to_B = A_to_B- >substitute ($ ' \V{join(delimiters_to_remove, ' \| ' )}' , ' ' , ' g' )
302239 endif
303240 # echom " A_to_B: " .. A_to_B
304241
@@ -314,19 +251,17 @@ export def SurroundSmart(style: string, type: string = '')
314251 # Set line A
315252 var afterA = strcharpart (getline (lA), cA - 1 )
316253 if style != ' markdownCode'
317- for regex in delimiters_to_remove
318- afterA = afterA- >substitute (regex, ' ' , ' g' )
319- endfor
254+ afterA = afterA
255+ - >substitute ($ ' \V{join(delimiters_to_remove, ' \| ' )}' , ' ' , ' g' )
320256 endif
321257 var lineA = toA .. afterA
322258 setline (lA, lineA)
323259
324260 # Set line B
325261 var beforeB = strcharpart (getline (lB), 0 , cB)
326262 if style != ' markdownCode'
327- for regex in delimiters_to_remove
328- beforeB = beforeB- >substitute (regex, ' ' , ' g' )
329- endfor
263+ beforeB = beforeB
264+ - >substitute ($ ' \V{join(delimiters_to_remove, ' \| ' )}' , ' ' , ' g' )
330265 endif
331266 var lineB = beforeB .. fromB
332267 setline (lB, lineB)
@@ -336,9 +271,8 @@ export def SurroundSmart(style: string, type: string = '')
336271 while lA + ii < lB
337272 var middleline = getline (lA + ii)
338273 if style != ' markdownCode'
339- for regex in delimiters_to_remove
340- middleline = middleline- > substitute (regex, ' ' , ' g' )
341- endfor
274+ middleline = middleline
275+ - >substitute ($ ' \V{join(delimiters_to_remove, ' \| ' )}' , ' ' , ' g' )
342276 endif
343277 setline (lA + ii, middleline)
344278 ii += 1
@@ -385,116 +319,6 @@ export def SurroundToggle(open_delimiter: string,
385319 )
386320enddef
387321
388- export def GetTextBetweenMarks (A: string , B: string ): list <string>
389- # Usage: GetTextBetweenMarks (" 'A" , " 'B" ).
390- #
391- # Arguments must be marks called with the back ticks to get the exact
392- # position ('a jump to the marker but places the cursor
393- # at the beginning of the line .)
394- #
395- var [_, l1, c1, _] = getcharpos (A)
396- var [_, l2, c2, _] = getcharpos (B)
397-
398- if l1 == l2
399- # Extract text within a single line
400- return [getline (l1)[c1 - 1 : c2 - 1 ]]
401- else
402- # Extract text across multiple lines
403- var lines = getline (l1, l2)
404- lines [0 ] = lines [0 ][c1 - 1 : ] # Trim the first line from c1
405- lines [-1 ] = lines [-1 ][ : c2 - 1 ] # Trim the last line up to c2
406- return lines
407- endif
408- enddef
409-
410- export def GetDelimitersRanges (
411- open_delimiter_dict: dict <string> ,
412- close_delimiter_dict: dict <string> ,
413- ): list <list<list<number> >>
414- # It returns open - intervals, i .e . the delimiters are excluded.
415- #
416- # Passed delimiters are singleton dicts with key = the delimiter string ,
417- # value = the regex to exactly capture such a delimiter string
418- #
419- # It is assumed that the ranges have no intersections. This happens if
420- # open_delimiter = close_delimiter, as in many languages.
421- #
422- # By contradiction, say that open_delimiter = * and close_delimiter = /. You may
423- # have something like:
424- # ----*---* === /---/ -----
425- # The part in === is an intersection between two ranges .
426- # In these cases, this function will not work.
427- # However, languages where open_delimiter = close_delimiter such intersections
428- # cannot happen and this function apply.
429- #
430- var saved_cursor = getcursorcharpos ()
431- cursor (1 , 1 )
432-
433- var ranges = []
434-
435- var open_regex = values (open_delimiter_dict)[0 ]
436- var open_string = keys (open_delimiter_dict)[0 ]
437- var close_regex = values (close_delimiter_dict)[0 ]
438- var close_string = keys (close_delimiter_dict)[0 ]
439-
440- # 2 D format due to that searchpos () returns a 2 D vector
441- var open_regex_pos_short = [-1 , -1 ]
442- var close_regex_pos_short = [-1 , -1 ]
443- var open_regex_pos_short_final = [-1 , -1 ]
444- var close_regex_pos_short_final = [-1 , -1 ]
445-
446- # 4 D format due to that marks have 4 - coordinates
447- var open_regex_pos = [0 ] + open_regex_pos_short + [0 ]
448- var open_regex_match = ' '
449- var close_regex_pos = [0 ] + close_regex_pos_short + [0 ]
450- var close_regex_length = 0
451- var close_regex_match = ' '
452-
453- while open_regex_pos_short != [0 , 0 ]
454-
455- # A. ------------ open_regex -----------------
456- open_regex_pos_short = searchpos (open_regex, ' W' )
457-
458- # If the open delimiter is the tail of the line ,
459- # then the open - interval starts from the next line , column 1
460- if open_regex_pos_short[1 ] + len (open_string) == col (' $' )
461- open_regex_pos_short_final[0 ] = open_regex_pos_short[0 ] + 1
462- open_regex_pos_short_final[1 ] = 1
463- else
464- # Pick the open - interval
465- open_regex_pos_short_final[0 ] = open_regex_pos_short[0 ]
466- open_regex_pos_short_final[1 ] = open_regex_pos_short[1 ]
467- + len (open_string)
468- endif
469- open_regex_pos = [0 ] + open_regex_pos_short_final + [0 ]
470-
471- # B. ------ Close regex -------
472- close_regex_pos_short = searchpos (close_regex, ' W' )
473- # TODO : if close_regex_pos_short = [0 , 0 ] = > anomaly! One tag has been
474- # opened and never closed!
475-
476- # If the closed delimiter is the lead of the line , then the open - interval
477- # starts from the previous line , last column
478- if close_regex_pos_short[1 ] - 1 == 0
479- close_regex_pos_short_final[0 ] = close_regex_pos_short[0 ] - 1
480- close_regex_pos_short_final[1 ] = len (getline (close_regex_pos_short_final[0 ]))
481- else
482- close_regex_pos_short_final[0 ] = close_regex_pos_short[0 ]
483- close_regex_pos_short_final[1 ] = close_regex_pos_short[1 ] - 1
484- endif
485- close_regex_pos = [0 ] + close_regex_pos_short_final + [0 ]
486-
487- add (ranges , [open_regex_pos, close_regex_pos])
488- endwhile
489- setcursorcharpos (saved_cursor[1 : 2 ])
490-
491- # Remove the last element junky [[0 ,0 ,len (open_delimiter),0 ], [0 ,0 ,-1 ,0 ]]
492- # TODO it does not seems to remove anything...
493- remove (ranges , -1 )
494-
495- return ranges
496- enddef
497-
498322export def IsLess (l1: list <number> , l2: list <number> ): bool
499323 # Lexicographic comparison on common prefix, i .e .for two vectors in N ^n and
500324 # N ^m you compare their projections onto the smaller subspace.
@@ -626,20 +450,6 @@ export def IsInRange(): dict<list<list<number>>>
626450 return return_val
627451enddef
628452
629- # Not used in markdown
630- export def DeleteTextBetweenMarks (A: string , B: string ): string
631- # To jump to the exact position (and not at the beginning of a line ) you
632- # have to call the marker with the backtick ` rather than with ', e .g . `a
633- # instead of 'a
634- # TODO
635- # This implementation most likely modify the jumplist.
636- # Find a solution based on functions instead
637- var exact_A = substitute (A, " '" , " `" , " " )
638- var exact_B = substitute (B, " '" , " `" , " " )
639- execute $ ' norm! {exact_A}v{exact_B}"_d'
640- # This to get rid off E1186
641- return ' '
642- enddef
643453
644454export def SetBlock (open_block: dict <string> ,
645455 close_block: dict <string> ,
0 commit comments