Skip to content

Commit 40a6a9a

Browse files
committed
Marks 'Added block surrounding
1 parent 5bb146c commit 40a6a9a

File tree

3 files changed

+139
-161
lines changed

3 files changed

+139
-161
lines changed

lib/funcs.vim

Lines changed: 0 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
vim9script
22

3-
43
export def ToggleMark()
54
# Toggle checkbox marks in todo lists
65
#
@@ -71,157 +70,3 @@ export def ContinueList()
7170
startinsert
7271

7372
enddef
74-
75-
# ----------------------------
76-
# Set-unset code-blocks
77-
# ----------------------------
78-
def SetBlockStartEndLines(start_line: number = -1,
79-
\ end_line: number = -1): list<number>
80-
# Check if the passed lines are valid, or ask for user input
81-
# If any of the lines has a negative number, it returns an empty list
82-
83-
var range_str = ''
84-
var l0 = -1
85-
var l1 = -1
86-
87-
# UBA
88-
if start_line == -1 || end_line == -1
89-
range_str = input('Enter range of the code-block: ')
90-
if empty(range_str)
91-
return []
92-
endif
93-
l0 = str2nr(split(range_str, ',')[0])
94-
l1 = str2nr(split(range_str, ',')[1])
95-
# Lines must be positive
96-
if l0 < 1 || l1 < 1
97-
return []
98-
endif
99-
else
100-
l0 = start_line
101-
l1 = end_line
102-
endif
103-
104-
return [l0, l1]
105-
enddef
106-
107-
108-
109-
def SetBlock(tag: string, start_line: number = -1,
110-
\ end_line: number = -1, fence: string = '')
111-
# This is redundant, the check already happens in ToggleCodeBlock
112-
if IsInsideBlock(tag) || getline(line('.')) =~ $'^{tag}'
113-
return
114-
endif
115-
116-
# Get actual first and last line of the block
117-
var block_range = SetBlockStartEndLines(start_line, end_line)
118-
if empty(block_range)
119-
return
120-
endif
121-
122-
# TODO Will never happen...
123-
var user_fence = 'kbvasLvkbdfkb'
124-
125-
# If you don't want any language, just set
126-
# g:markdown_extras_config['code_block_language'] = ''
127-
#
128-
if exists('g:markdown_extras_config') != 0
129-
&& has_key(g:markdown_extras_config, 'code_block_language')
130-
user_fence = g:markdown_extras_config['code_block_language']
131-
endif
132-
133-
if user_fence == 'kbvasLvkbdfkb'
134-
user_fence = input('Enter code-block language: ')
135-
endif
136-
137-
var l0 = block_range[0]
138-
var l1 = block_range[1]
139-
140-
# Create block (indenting included)
141-
# append(l0 - 1, $'{tag}{user_fence}')
142-
append(l0, $'{tag}{user_fence}')
143-
# cursor(l0 + 1, 1)
144-
145-
silent! execute $':{l0 + 1},{l1}s/^\s\+//'
146-
silent! execute $':{l0 + 2},{l1}>'
147-
append(l1, tag)
148-
enddef
149-
150-
def UnsetBlock(tag: string)
151-
if !IsInsideBlock(tag) || getline(line('.')) =~ $'^{tag}'
152-
return
153-
else
154-
var l0 = search(tag, 'cnb')
155-
var l1 = search(tag, 'cn')
156-
157-
# Remove indent
158-
silent! execute $':{l0 + 1},{l1 + 1}s/^\s\+//'
159-
160-
# Remove tags
161-
deletebufline(bufnr('%'), l0)
162-
deletebufline(bufnr('%'), l1 - 1)
163-
endif
164-
enddef
165-
166-
167-
def GetBlocksRanges(tag: string): list<list<number>>
168-
# Return a list of lists, where each element delimits a block in the current buffer.
169-
# E.g. [[38, 33], [46 89]] => two blocks with their range in current buffer
170-
# Initialize an empty list to store ranges
171-
var ranges = []
172-
173-
# Initialize a variable to keep track of the start line
174-
var start_line = -1
175-
176-
# Loop through each line in the buffer
177-
for ii in range(1, line('$'))
178-
# Get the current line content
179-
var line_content = getline(ii)
180-
181-
# Check if the line contains the delimiter
182-
if line_content =~ tag
183-
# If start_line is -1, this is the start of a block
184-
if start_line == -1
185-
start_line = ii
186-
else
187-
# Extremes are excluded
188-
# This is the end of a block, add the range to the list
189-
add(ranges, [start_line, ii])
190-
start_line = -1
191-
endif
192-
endif
193-
endfor
194-
return ranges
195-
enddef
196-
197-
# ciai aii aiaia XXX#
198-
def IsInsideBlock(tag: string): bool
199-
var is_inside_block = false
200-
var ranges = GetBlocksRanges(tag)
201-
var current_line = line('.')
202-
203-
# Check if inside a block
204-
for range in ranges
205-
if current_line >= range[0] && current_line <= range[1]
206-
is_inside_block = true
207-
break
208-
endif
209-
endfor
210-
211-
return is_inside_block
212-
enddef
213-
214-
215-
export def ToggleBlock(tag: string, line_start: number = -1,
216-
\ line_end: number = -1, fence: string = '')
217-
# Set or unset
218-
if getline(line('.')) =~ $'^{tag}'
219-
return
220-
endif
221-
222-
if !IsInsideBlock(tag)
223-
SetBlock(tag, line_start, line_end, fence)
224-
else
225-
UnsetBlock(tag)
226-
endif
227-
enddef

lib/utils.vim

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,6 @@ export def IsInRange(
570570

571571
# OBS! Ranges are open-intervals!
572572
var ranges = GetDelimitersRanges(open_delimiter_dict, close_delimiter_dict)
573-
echom open_delimiter_dict
574-
echom ranges
575573

576574
var saved_mark_a = getcharpos("'a")
577575
var saved_mark_b = getcharpos("'b")
@@ -606,3 +604,68 @@ export def DeleteTextBetweenMarks(A: string, B: string): string
606604
# This to get rid off E1186
607605
return ''
608606
enddef
607+
608+
609+
export def SetBlock(open_block: dict<string>,
610+
close_block: dict<string>,
611+
motion: string = '')
612+
# Put the selected text between open_block and close_block.
613+
var label = ''
614+
if exists('g:markdown_extras_config') != 0
615+
&& has_key(g:markdown_extras_config, 'block_label')
616+
label = g:markdown_extras_config['block_label']
617+
else
618+
label = input('Enter code-block language: ')
619+
endif
620+
echom label
621+
622+
# TODO return or remove surrounding?
623+
if !empty(IsInRange(open_block, close_block))
624+
|| getline('.') == $'{keys(open_block)[0] .. label}'
625+
|| getline('.') == $'{keys(close_block)[0]}'
626+
return
627+
endif
628+
629+
# Set marks
630+
var A = getcharpos("'<")
631+
var B = getcharpos("'>")
632+
if !empty(motion)
633+
# GetTextObject is called for setting '[ and '] marks through a yank.
634+
var motion_dict = GetTextObject(motion)
635+
A = motion_dict.start
636+
B = motion_dict.end
637+
endif
638+
639+
# line and column of point A
640+
var lA = A[1]
641+
var cA = A[2]
642+
643+
# line and column of point B
644+
var lB = B[1]
645+
var cB = B[2]
646+
647+
# TODO: may be not needed
648+
if A == B
649+
return
650+
endif
651+
652+
var firstline = getline(lA)
653+
var lastline = getline(lB)
654+
# Set first part
655+
setline(lA, strcharpart(getline(lA), 0, cA - 1))
656+
append(lA, [$'{keys(open_block)[0] .. label}',
657+
" " .. strcharpart(firstline, cA - 1)])
658+
lA += 2
659+
lB += 2
660+
661+
# Set intermediate part
662+
var ii = 1
663+
while lA + ii <= lB
664+
setline(lA + ii, " " .. getline(lA + ii)->substitute('^\s*', '', ''))
665+
ii += 1
666+
endwhile
667+
668+
# Set last part
669+
setline(lB, " " .. strcharpart(lastline, 0, cB))
670+
append(lB, [$'{keys(close_block)[0]}', strcharpart(lastline, cB)])
671+
enddef

test/test_utils.vim

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,10 @@ def g:Test_SurroundSimple_one_line()
431431
]
432432
utils.SurroundSimple('**', '**', text_style_dict, text_style_dict)
433433
actual_value = getline(20, 22)
434-
echom actual_value
435-
echom assert_equal(expected_value, actual_value)
434+
assert_equal(expected_value, actual_value)
436435

436+
cursor(19, 53)
437+
utils.SurroundSimple('*', '*', text_style_dict, text_style_dict, 'iw')
437438
:%bw!
438439
Cleanup_testfile(src_name_2)
439440
enddef
@@ -496,6 +497,20 @@ def g:Test_SurroundSmart_one_line()
496497
]
497498
cursor(15, 13)
498499
utils.SurroundSmart('**', '**', text_style_dict, text_style_dict, 'a(')
500+
# Do the same operation, nothing should change
501+
utils.SurroundSmart('**', '**', text_style_dict, text_style_dict, 'a(')
502+
actual_value = getline(14, 16)
503+
assert_equal(expected_value, actual_value)
504+
505+
# Prolong delimiter
506+
expected_value = [
507+
'Quis autem vel eum iure reprehenderit qui in ea **voluptate velit esse**',
508+
'quam nihil **(molestiae consequatur), vel** illum qui dolorem eum fugiat quo',
509+
'voluptas nulla pariatur?',
510+
]
511+
cursor(15, 32)
512+
exe "norm! veee\<esc>"
513+
utils.SurroundSmart('**', '**', text_style_dict, text_style_dict)
499514
actual_value = getline(14, 16)
500515
assert_equal(expected_value, actual_value)
501516

@@ -640,7 +655,7 @@ def g:Test_RemoveSurrounding_multi_line()
640655
cursor(28, 25)
641656
utils.RemoveSurrounding(code_dict, code_dict)
642657
var actual_value = getline(28, 30)
643-
echom assert_equal(expected_value, actual_value)
658+
assert_equal(expected_value, actual_value)
644659

645660
# Test 2: preserve inner surrounding
646661
expected_value = [
@@ -650,7 +665,62 @@ def g:Test_RemoveSurrounding_multi_line()
650665
cursor(32, 28)
651666
utils.RemoveSurrounding(italic_dict, italic_dict)
652667
actual_value = getline(32, 33)
653-
echom assert_equal(expected_value, actual_value)
668+
assert_equal(expected_value, actual_value)
669+
670+
:%bw!
671+
Cleanup_testfile(src_name_2)
672+
enddef
673+
674+
675+
def g:Test_code_block()
676+
vnew
677+
Generate_testfile(lines_2, src_name_2)
678+
exe $"edit {src_name_2}"
679+
680+
g:markdown_extras_config = {}
681+
g:markdown_extras_config['block_label'] = ''
682+
683+
var expected_value = [
684+
'ab illo inventore veritatis ',
685+
'```',
686+
' et quasi architecto beatae vitae dicta',
687+
' sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit',
688+
' aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos',
689+
' qui ratione voluptatem sequi ',
690+
'```',
691+
'nesciunt.',
692+
]
693+
cursor(3, 29)
694+
exe "norm! v3j\<esc>"
695+
utils.SetBlock(codeblock_dict, codeblock_dict)
696+
var actual_value = getline(3, 10)
697+
assert_equal(expected_value, actual_value)
698+
699+
# Check that it won't undo
700+
cursor(6, 10)
701+
utils.SetBlock(codeblock_dict, codeblock_dict)
702+
assert_equal(expected_value, actual_value)
703+
704+
# Check that it won't undo when on the border
705+
cursor(4, 2)
706+
utils.SetBlock(codeblock_dict, codeblock_dict)
707+
assert_equal(expected_value, actual_value)
708+
709+
# check with motion
710+
expected_value = [
711+
'```',
712+
' Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,',
713+
' consectetur, adipisci velit, sed quia non numquam eius modi tempora',
714+
' incidunt ut (labore et ~~dolore magnam) aliquam quaerat~~ voluptatem. Ut',
715+
' enim ad `minima [veniam`, quis no~~strum] exercitationem~~ ullam corporis',
716+
'```',
717+
]
718+
cursor(12, 1)
719+
utils.SetBlock(codeblock_dict, codeblock_dict, '3j')
720+
actual_value = getline(13, 18)
721+
assert_equal(expected_value, actual_value)
722+
723+
unlet g:markdown_extras_config
654724

655725
:%bw!
656726
Cleanup_testfile(src_name_2)

0 commit comments

Comments
 (0)