I'm writing a script that does a search like so: normal /needle^M
. This works like I want, except that I want to be able to use n
or N
to repeat the search.
In case it helps, here's the full function:
function! MakeChoices()
let start = line('.')
let choiceStartLine = search('^*choice', 'bW')
let choiceEndLine = search('^\S.*', 'W') "End is first line that starts with non-whitespace
"If above search fails, might be at bottom of buffer
if choiceEndLine == 0
let choiceEndLine = search('^$', 'W') "End is first empty line
endif
"Now go back up to the last *goto
let choiceEndLine = search('*goto', 'bW')
"Get the entire *choice block and put it in gotoBlock
let gotoBlock = getline(choiceStartLine, choiceEndLine)
"Make labelArray (contains all labels to goto)
let labelArray = []
for cur in gotoBlock
if match(cur, '*goto') != -1
"echo 'cur: '.cur
let curParsed = matchlist(cur, '*goto \(\S\+\)')
"echo curParsed
if len(curParsed) > 1
let curLabel = curParsed[1]
else
echo 'ERROR: Bad *goto ('.cur.')'
return -1
endif
call add(labelArray, curLabel)
endif
endfor
"Make newline after choice block if needed
if strlen(getline(choiceEndLine+1)) > 0
echo 'big line: '.getline(choiceEndLine+1)
call cursor(choiceEndLine, 1)
put=''
endif
call cursor(choiceEndLine+1, 1)
"Put the new label blocks
let skippedLabels = ''
let numNewLabels = 0
for cur in labelArray
if !search('*label '.cur, 'wn')
let numNewLabels += 1
put='*label '.cur
put='[This option is yet to be written.]'
put=''
else
let skippedLabels .= cur.' '
endif
endfor
"Remove trailing blank lines (Up to a point)
let nextlines = getline(line('.')+1, line('.')+3)
if len(nextlines) == 3
if nextlines[0] == '' && nextlines[1] == '' && nextlines[2] == ''
normal "_3dd
elseif nextlines[0] == '' && nextlines[1] == ''
normal "_2dd
elseif nextlines[0] == ''
normal "_dd
endif
endif
"Move to first label's text (use ctrl-v ctrl-m to input the <CR> at
"end)
if numNewLabels != 0
call cursor(choiceEndLine, 1)
normal /\[This option is yet to be written.\]
endif
"Print status message
if len(skippedLabels) > 0
echo 'Skipped: '.skippedLabels
else
echo 'New labels created: '.numNewLabels
endif
endfunction
The line in question is near the end, and you can probably just ignore the rest of the code. Basically, this function parses some code (in a language called ChoiceScript) and outputs a set of stock templates based on that code, then jumps (via the vim search command in question) to the first stock template.
For example, let's say I begin with this ChoiceScript code:
*choice
#Option A
*goto optionA
#Option B
*goto optionB
Then, after running the function, the file becomes:
*choice
#Option A
*goto optionA
#Option B
*goto optionB
*label optionA
[This option is yet to be written.]
*label optionB
[This option is yet to be written.]
The cursor will be on the first "[This option is yet to be written.]", and I want to be able to hit n
to jump to the second if that's the option I want to work on first.
n
orN
to repeat the search. Do you have an interfering plugin? Try withvim -Nu NONE
, manually defining the function or action.n
repeated a search earlier in the/
history, but if I typed/
and then hit the up arrow, the latest, function-called search appeared. I hit enter, it worked, and thenn
worked, so this is very odd. Perhaps it's a bug in vim itself? My version is 7.4.692.normal /<Up>^MN
after thenormal /needle^M
line in my function, but the<Up>
didn't work. Is it possible somehow or is there some other workaround?n
by assigning it to the/
register:let @/="needle"
. You don't even need to run a search first for that to work.