tommcdo / vim-ninja-feet

Strike from the cursor to either end of a text object
MIT License
80 stars 7 forks source link

Make it work in Normal mode #3

Open tommcdo opened 10 years ago

tommcdo commented 10 years ago

That would be super nice. Current problem is that the natural mappings would involve [i, ]i, [a, and ]a -- some of which step on other plugins' feet (notably unimpaired.vim).

kiryph commented 7 years ago

Just for the record:

[i and ]i step on the feet of vim itself

                            *[i*
[i          Display the first line that contains the keyword
            under the cursor.  The search starts at the beginning
            of the file.  Lines that look like a comment are
            ignored (see 'comments' option).  If a count is given,
            the count'th matching line is displayed, and comment
            lines are not ignored.  {not in Vi}

                            *]i*
]i          like "[i", but start at the current cursor position.
            {not in Vi}

[a and ]a step on the feet of vim-unimpaired:

*[a*     |:previous|
*]a*     |:next|

Reconsider use of z[ and z]

Consider following tex file

\documentclass{article}

\begin{document}

\paragraph{Paragraph}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. <CURSOR> At
vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,
no sea takimata sanctus est.

\end{document}

I am using the plugin vimtex which defines the text objects iP and aP.

When I want to insert text before Lorem ipsum, I could combine ninja-feet and vimtex to z[iP. However, ninja-feet inserts a new line which I might not want.

I would propose to leave the decision to the user and use z[<text object> as a normal mode and visual motion (#2) which you apparently also want to add to this plugin.

I would consider this more important than jumping directly into insert mode. This can serve the purpose of navigation and not only having a superintelligent switch into insert mode which decides for you if a newline is inserted. And they are also still available in visual mode and can therefore be consistent between normal and visual mode.

You could use Z[<text object> for the current behavior.

And of course the mappings should be configurable, so a user can return to the previous behavior for z[ and z].

Just another thought: or one could define that z[ z] add never a newline (i and a) and Z[ and Z] always add newline (o and O).

tommcdo commented 7 years ago

The [i and ]i mappings are only defined in Operator-pending mode, meaning they only activate after an operator is invoked. At least, that's the intention -- are you finding that these clobber the default Vim commands?

kiryph commented 7 years ago

Mmmh. I am not sure if you got me right here.

Your plugin works just fine for me. I just miss additional functionality and was wondering what mappings could be good choices for

  1. movement in normal mode
  2. movement in visual mode
  3. customization of jump into Insert mode
tommcdo commented 7 years ago

Ah, gotcha. Yeah, choosing the mappings is tricky, but there's a much more challenging problem ahead of it, which is getting it to work in Normal mode without actually being an operator.

It's easy to make an operator that does nothing but move the cursor. This gives us free compatibility with all motions (built-in and user-defined), but it has an unacceptable side-effect: as all operators are repeatable, it overrides the previous operation to be repeated by .. This would be quite jarring to a user.

I've yet to think of a way to get that compatibility without killing repeatability. It might actually require a feature request to Vim itself.

sudo-nice commented 6 years ago

When I want to insert text before Lorem ipsum, I could combine ninja-feet and vimtex to z[iP. However, ninja-feet inserts a new line which I might not want.

@kiryph I believe, you can tweak the plugin to archive the desired behavior:

diff --git a/plugin/ninja-feet.vim b/plugin/ninja-feet.vim
index 661a641..f317b5e 100644
--- a/plugin/ninja-feet.vim
+++ b/plugin/ninja-feet.vim
@@ -28,12 +28,12 @@ function! s:ninja_strike(mode)
endfunction

function! s:ninja_insert(mode)
-   let op = a:mode == 'line' ? 'O' : 'i'
+   let op = a:mode == 'line' ? 'I' : 'i'
call feedkeys('`['.op, 'n')
endfunction

function! s:ninja_append(mode)
-   let op = a:mode == 'line' ? 'o' : 'a'
+   let op = a:mode == 'line' ? 'A' : 'a'
call feedkeys('`]'.op, 'n')
endfunction

Also you can add new mappings Z[ and Z] and bind original (unchanged) functions to that mappings.

simlei commented 6 years ago

I would also find it way nicer for z[ to be a motion in normal/visual mode.

kiryph commented 1 year ago

Workaround: add Esc to feedkeys():

diff --git a/plugin/ninja-feet.vim b/plugin/ninja-feet.vim
index 7a5fc32..e80c0e5 100644
--- a/plugin/ninja-feet.vim
+++ b/plugin/ninja-feet.vim
@@ -28,12 +28,12 @@ endfunction

 function! s:ninja_insert(mode)
        let op = a:mode == 'line' ? 'O' : 'i'
-       call feedkeys('`['.op, 'n')
+       call feedkeys('`['.op."\<Esc>", 'n')
 endfunction

 function! s:ninja_append(mode)
        let op = a:mode == 'line' ? 'o' : 'a'
-       call feedkeys('`]'.op, 'n')
+       call feedkeys('`]'.op."\<Esc>", 'n')
 endfunction

 function! s:map_expr(sid, type, direction, count)
tommcdo commented 1 year ago

Workaround: add Esc to feedkeys():

That would work, but as I pointed out before, implementing it as an operator would have the unintended side effect of overwriting the most recent operation (i.e., it breaks . repeating). To me, that's a side effect I'm not willing to accept.

Say, for example, you wanted to delete the first and last word within parentheses:

(extra words are fun really)
                ^

Move cursor to beginning using ninja-feet: [i)

(extra words are fun really)
 ^

Delete word: daw

(words are fun really)
 ^

Move cursor to end using ninja-feet: ]i)

(words are fun really)
                    ^

Delete word (using repeat): .

(words are fun really)
                    ^

That last step didn't actually delete: it repeated the ]i) command, since it was implemented as an operator.

kiryph commented 1 year ago

That would work, but as I pointed out before, implementing it as an operator would have the unintended side effect of overwriting the most recent operation (i.e., it breaks . repeating).

Yeah. That is not good.

I have added the word 'workaround' to make clear that this is not a proper solution (no PR).

But pointing out the problem with dot-repeat explicitly is certainly helpful for other users coming along to understand why the workaround is not a good fit for the vim world.

I guess there is no real solution. That is unfortunate. I am really missing it.

kaddkaka commented 1 week ago

@tommcdo is there no way around this? Like

If a feature is needed in vim, maybe someone with a bit more insight can create an isssue https://github.com/vim/vim/issues to start a discussion there :)