marshallward / vim-restructuredtext

Syntax file for reStructuredText on Vim.
26 stars 12 forks source link

RstFold.vim conflicts with vim-unimpaired for ]<Space> #32

Closed Naitreey closed 6 years ago

Naitreey commented 6 years ago

In RstFold.vim, folding data is generated by

silent keeppatterns %s/\v^%(%(([=`:.'"~^_*+#-])\1+\n)?.{1,2}\n([=`:.'"~^_*+#-])\2+)|%(%(([=`:.''"~^_*+#-])\3{2,}\n)?.{3,}\n([=`:.''"~^_*+#-])\4{2,})$/\=closure.Process(submatch(0))/gn

After which the [ mark is modified to be at the line of the first title.

However the [ mark is used by vim-unimpaired for restoring cursor position after inserting a new blank line (See line 189, I've pasted relevant lines below):

" Section: Line operations

function! s:BlankUp(count) abort
  put!=repeat(nr2char(10), a:count)
  ']+1
  silent! call repeat#set("\<Plug>unimpairedBlankUp", a:count)
endfunction

function! s:BlankDown(count) abort
  put =repeat(nr2char(10), a:count)
  '[-1
  silent! call repeat#set("\<Plug>unimpairedBlankDown", a:count)
endfunction

nnoremap <silent> <Plug>unimpairedBlankUp   :<C-U>call <SID>BlankUp(v:count1)<CR>
nnoremap <silent> <Plug>unimpairedBlankDown :<C-U>call <SID>BlankDown(v:count1)<CR>

call s:map('n', '[<Space>', '<Plug>unimpairedBlankUp')
call s:map('n', ']<Space>', '<Plug>unimpairedBlankDown')

I'm not sure what's the correct solution for this (VimL newbie here). But anyway, I've proposed a fix that restores [ mark after %s:

     let self.levels[curline] = self.header_types[key]
   endfunction
   let save_cursor = getcurpos()
+  " save [ mark
+  let l:save_mark = ""
+  redir => l:save_mark
+    try
+      silent! marks [
+    catch
+    endtry
+  redir END
+  if l:save_mark != ""
+    let l:save_mark = split(split(l:save_mark, "\n")[1])[1]
+  endif
   silent keeppatterns %s/\v^%(%(([=`:.'"~^_*+#-])\1+\n)?.{1,2}\n([=`:.'"~^_*+#-])\2+)|%(%(([=`:.''"~^_*+#-])\3{2,}\n)?.{3,}\n([=`:.''"~^_*+#-])\4{2,})$/\=closure.Process(submatch(0))/gn
   call setpos('.', save_cursor)
+  " restore [ mark
+  if l:save_mark != ""
+    execute l:save_mark . 'mark ['
+  endif
   let b:RstFoldCache = closure.levels
 endfunction

If this is the way to go, I'll be happy to send a PR.

marshallward commented 6 years ago

@anntzer is probably the best person to weigh in on this. Hopefully he will see this and say if it works alright.

Either way we can do something to ensure that it doesn't break anything.

anntzer commented 6 years ago

I am a bit confused why the position of the [ mark would change, the docs say

                            *'[* *`[*
'[  `[          To the first character of the previously changed
            or yanked text.  {not in Vi}

but no text is being changed or yanked...

I also wonder whether you can save the mark positions more easily with :lockmarks or :keepmarks (dunno).

Naitreey commented 6 years ago

@anntzer Well, I actually tried prepending lockmarks or keepmarks before keeppatterns but neither could have stopped [...

Naitreey commented 6 years ago

By the way, I'm using Vim 8.1:

 $ vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Aug 13 2018 14:59:01)
Included patches: 1-279
Compiled by Arch Linux
Huge version with GTK3 GUI.
# .....
marshallward commented 6 years ago

You're probably using the latest version, I sent the most recent snapshot to Bram earlier this month.

anntzer commented 6 years ago

See the doc of getpos():

        This can be used to save and restore the position of a mark: >
            let save_a_mark = getpos("'a")
            ...
            call setpos("'a", save_a_mark)

Seems simpler than redir?

Naitreey commented 6 years ago

OK, that's much better... :+1: