1

I am currently setting up my Vim to work with matlab. In matlab, sections are separated by %%, and I am looking for a command to select my current section.

I currently use

nnoremap <Leader>f mf:?%%<CR><Down>v/%%<CR><Up>$:SlimuxREPLSendSelection<CR>`f

to mark the current position as f, search upwards for %%, and select to the next occurrence of %%. The selection is then send to the matlab terminal via Slimux and then I go back to mark f.

However, I would like to extend this to the case when there is no %% before the cursor (then vim should go to the beginning of the file) or when there is no %% after the cursor (then vim should go to the end of the file).

Thank you.

EDIT

The solution by Tumbler41 almost worked for me, I had to change it a tiny bit because the Slimux function call wouldn't work and to make it able to cope when the cursor is on %%.

nnoremap <Leader>f :call SendSection()<CR>:SlimuxREPLSendSelection<CR>`f

function! SendSection()
   normal! mf
   if (search('%%', 'b') <= line("'f"))
      normal! jV
   else
      normal! ggV
   endif
   if (search('%%') > line("'f"))
      normal! k
   else
      normal! G
   endif
endfunction
0

Try this:

nnoremap <Leader>f :call SendSection()<CR>

function! SendSection()
   normal! mf
   let firstLine = search('%%', 'b')
   if (firstLine != 0 && firstLine <= line("'f"))
      normal! jV
   else
      normal! ggV
   endif
   if (search('%%') > line("'f"))
      normal! k
   else
      normal! G
   endif
   '<,'>SlimuxREPLSendSelection
   normal! `f
endfunction

Note: I don't have Slimux and therefore can't test that part.

I'm using search() to find out if there is a %% before and after the mark f.

  • Thank you very much, I had to change the code a tiny bit and have edited my question. – Florian W Jun 23 '16 at 22:32
0

Assuming you are using the slimux you can use :SlimuxREPLSendLine with a line range. \%^ and \%$ mark the start and end of the file respectively. Combine these regex anchors with a pattern alternation (\|), we can search for %% or one of the anchors.

nnoremap <leader>f mf:+?\(%%\n\zs\<bar>\%^\)?,-/\(\zs\n%%\<bar>\%$\)/SlimuxREPLSendLine<cr>`f

Note: Due to how trickiness of the range, this mapping will not work when you are on a %%.

To take this further you may want to may want to look into vim-textobj-user. Here is a quick and dirty text objects:

xnoremap i% :<c-u>call search('\(%%\<bar>\%^\)\_s*\zs.', 'cbW')<cr>m<:call search('.\ze\_s*\(%%\<bar>\%$\)', 'We')<cr>m>gv
onoremap i% :normal vi%<cr>

Now you can use i% text object. Now we can pair it with the a new mapping which uses this text object:

nmap <leader>f mfvi%:SlimuxREPLSendSelection<cr>`m

For more help see:

:h :range
:h /\|
:h /\zs
:h /\%^
:h /\%$
:h search(
  • I'm not great with regular expressions, could you explain what \n\zs\<bar> does? – Florian W Jun 23 '16 at 22:39
  • @FlorianW it matches after a line return. The \zs sets the start of the match after the new line. The \<bar> is an escaped version of \| for regex alternations or branches. Please see the help topics provided in the post. – Peter Rincker Jun 23 '16 at 22:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.