Timer to automatically go back to normal mode

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Timer to automatically go back to normal mode

gmguyx

Often times I want to enter insert mode just for a quick edit and then
go back to normal mode so that I can use the normal mode commands to
navigate to the next text that I want to edit. For example I might do
"cw" and then type the text and then hit <Esc>, then navigate to the
next text that I want to change, do something similar, etc. If I'm
doing many of these quick edits, it gets annoying to constantly have
to hit the <Esc> key after each one.

So I'm wondering if there is a way to set up a timer so that I can
type "cw", then type the text, then have vim automatically go back to
normal mode after a specified time (eg: 200 ms or whatever I configure
it to) after my last keystroke in insert mode. Obviously I wouldn't
want vim to always work this way so I could just set some global
variable in vim to turn this timer behavior on or off.


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

RE: Timer to automatically go back to normal mode

Larson, David

> -----Original Message-----
>
> Often times I want to enter insert mode just for a quick edit and then
> go back to normal mode so that I can use the normal mode commands to
> navigate to the next text that I want to edit. For example I might do
> "cw" and then type the text and then hit <Esc>, then navigate to the
> next text that I want to change, do something similar, etc. If I'm
> doing many of these quick edits, it gets annoying to constantly have
> to hit the <Esc> key after each one.
>
> So I'm wondering if there is a way to set up a timer so that I can
> type "cw", then type the text, then have vim automatically go back to
> normal mode after a specified time (eg: 200 ms or whatever I configure
> it to) after my last keystroke in insert mode. Obviously I wouldn't
> want vim to always work this way so I could just set some global
> variable in vim to turn this timer behavior on or off.

I think that you'll benefit from the recording feature (:help
recording). It is a more elegant solution.

David

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Timer to automatically go back to normal mode

fREW Schmidt

> I think that you'll benefit from the recording feature (:help
> recording). It is a more elegant solution.

I disagree.  Macros only really help if he wants to do the same thing
over and over.  I kinda wanted to hear an answer to his original
question as it would be nice to be able to do what he had said.

--
-fREW

Q: Why is this email 5 sentences or less?
A: http://five.sentenc.es

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

RE: Timer to automatically go back to normal mode

Larson, David

> > I think that you'll benefit from the recording feature (:help
> > recording). It is a more elegant solution.
>
> I disagree.  Macros only really help if he wants to do the same thing
> over and over.  I kinda wanted to hear an answer to his original
> question as it would be nice to be able to do what he had said.

In that case, I'd recommend using the CursorHoldI autocommand and
setting the 'updatetime' to 200, to fit "gmguyx"'s example. These
settings can be set up and torn down in a simple script (untested):

function SetUp()
   autocommand CursorHoldI * <esc>
   let s:saveupdatetime = &updatetime
   let &updatetime = 200
endfunction

function TearDown()
   autocommand! CursorHoldI * <esc>
   let &updatetime = s:saveupdatetime
endfunction

nmap <whatever> :call SetUp()<cr>
nmap <somethingelse> :call Teardown()<cr>

David

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Timer to automatically go back to normal mode

gmguyx

> In that case, I'd recommend using the CursorHoldI autocommand and
> setting the 'updatetime' to 200, to fit "gmguyx"'s example. These
> settings can be set up and torn down in a simple script (untested):
>
> function SetUp()
>    autocommand CursorHoldI * <esc>
>    let s:saveupdatetime = &updatetime
>    let &updatetime = 200
> endfunction

Thanks David - this looks promising. BTW, I tried using your script
but it didn't work. So I tried the following:

au! CursorHoldI * execute "normal \<Esc>"

but it didn't work, so then I tried:

au! CursorHoldI * stopinsert

but that didn't work either. Any suggestions for what I could be doing
wrong?


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

RE: Timer to automatically go back to normal mode

Larson, David

> Thanks David - this looks promising. BTW, I tried using your script
> but it didn't work. So I tried the following:
>
> au! CursorHoldI * execute "normal \<Esc>"
>
> but it didn't work, so then I tried:
>
> au! CursorHoldI * stopinsert
>
> but that didn't work either. Any suggestions for what I could be doing
> wrong?

The au! command removes the defined autocommand, while au defines it. I
think you've been playing around with the au!, not the au.

After testing it, it turns out that stopinsert is the right solution.
Use this (I changed it to toggle setup and teardown, to make it easier
to use):

let s:on = 0

function ToggleSetUp()
   let cmd = "CursorHoldI * stopinsert"
   if !s:on
      exec "au" cmd
      let s:saveupdatetime = &updatetime
      let &updatetime = 200
   else
      exec "au!" cmd
      let &updatetime = s:saveupdatetime
   endif
   let s:on = !s:on
endfunction

nmap ,s :call ToggleSetUp()<cr>


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

RE: Timer to automatically go back to normal mode

Larson, David

>       exec "au!" cmd

Oops. I was using au! incorrectly. Placing the cmd in the au! command
tells au to use that cmd instead of the previously defined one. This
should work better:

let s:on = 0

function ToggleSetUp()
   let &updatetime = 200
   let s:on = !s:on
   exec "au".((s:on)?"":"!") "CursorHoldI *" ((s:on)?"stopinsert":"")
endfunction

nmap ,s :call ToggleSetUp()<cr>


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Timer to automatically go back to normal mode

Tony Mechelynck
In reply to this post by Larson, David

Larson, David wrote:

>> Thanks David - this looks promising. BTW, I tried using your script
>> but it didn't work. So I tried the following:
>>
>> au! CursorHoldI * execute "normal \<Esc>"
>>
>> but it didn't work, so then I tried:
>>
>> au! CursorHoldI * stopinsert
>>
>> but that didn't work either. Any suggestions for what I could be doing
>> wrong?
>
> The au! command removes the defined autocommand, while au defines it. I
> think you've been playing around with the au!, not the au.
>
> After testing it, it turns out that stopinsert is the right solution.
> Use this (I changed it to toggle setup and teardown, to make it easier
> to use):
>
> let s:on = 0
>
> function ToggleSetUp()
>    let cmd = "CursorHoldI * stopinsert"
>    if !s:on
>       exec "au" cmd
>       let s:saveupdatetime = &updatetime
>       let &updatetime = 200
>    else
>       exec "au!" cmd

this removes the autocommand immediately re-adds it

>       let &updatetime = s:saveupdatetime
>    endif
>    let s:on = !s:on
> endfunction
>
> nmap ,s :call ToggleSetUp()<cr>


function ToggleAutoStopInsert()
        if !exists("s:stopinsert")
                let s:stopinsert = 0
                let s:updatetime = &updatetime
        endif
        if !exists g:toggleinsert_time
                let g:toggleinsert_time = 1000
        endif
        if g:toggleinsert_time <= 0
                return 0
        endif
        if s:stopinsert
                au! togglestopinsert CursorHoldI
                let &updatetime = s:updatetime
        else
                let &updatetime = g:toggleinsert_time
                augroup togglestopinsert
                        au CursorHoldI * stopinsert
                augroup END
        endif
        let s:stopinsert = !s:stopinsert
        return &updatetime
endfunction
nmap <F12> :call ToggleAutoStopInsert()<CR>


Best regards,
Tony.
--
"If you understand what you're doing, you're not learning anything."
                -- A. L.

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Timer to automatically go back to normal mode

gmguyx
In reply to this post by Larson, David

On Aug 3, 9:57 am, "Larson, David" <[hidden email]> wrote:
> >       exec "au!" cmd
>
> Oops. I was using au! incorrectly. Placing the cmd in the au! command
> tells au to use that cmd instead of the previously defined one. This
> should work better:
>
> let s:on = 0
> ...

Or you could just do "au! CursorHoldI" instead of "exec "au!" cmd",
because your second example does not restore the &updatetime.

Now there is just one final thing that would make this perfect for me.
I noticed that if I use insert mode completion (ie: <C-N>/<C-P>), then
I still have to press <Esc> (or move the cursor) to allow the
&updatetime timer to continue and then invoke the autocmd. So now I'm
wondering if there is a way to make commands (in this case insert mode
completion) timeout also.

Thanks,
Addison


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

RE: Timer to automatically go back to normal mode

Larson, David

Addison,

> Or you could just do "au! CursorHoldI" instead of "exec "au!" cmd",
> because your second example does not restore the &updatetime.

My second example did not restore the updatetime because I wasn't sure
that it was important to do so - it depends on whether you use
updatetime for anything else, I don't.

I moved the autocommand into one line so that we might avoid confusion
about which au command to update and to prevent the two au commands from
not matching.

"au! CursorHoldI" will remove all the autocommands defined for that
event. I wanted to just remove the one we defined, to prevent stomping
on other scripts that you may have in your environment. Tony
Mechelynck's idea of using the augroup may be the best way to do this.

> Now there is just one final thing that would make this perfect for me.
> I noticed that if I use insert mode completion (ie: <C-N>/<C-P>), then
> I still have to press <Esc> (or move the cursor) to allow the
> &updatetime timer to continue and then invoke the autocmd. So now I'm
> wondering if there is a way to make commands (in this case insert mode
> completion) timeout also.

:help timeout

may also work for insert completion, though I'm not sure. You'll have to
experiment. You may also want to read through :help ins-completion for
ideas (if any).

Hope that helps,
David


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Timer to automatically go back to normal mode

gmguyx

David,

> "au! CursorHoldI" will remove all the autocommands defined for that
> event. I wanted to just remove the one we defined, to prevent stomping
> on other scripts that you may have in your environment. Tony
> Mechelynck's idea of using the augroup may be the best way to do this.

I agree.

> > Now there is just one final thing that would make this perfect for me.
> > I noticed that if I use insert mode completion (ie: <C-N>/<C-P>), then
> > I still have to press <Esc> (or move the cursor) to allow the
> > &updatetime timer to continue and then invoke the autocmd. So now I'm
> > wondering if there is a way to make commands (in this case insert mode
> > completion) timeout also.
>
> :help timeout
>
> may also work for insert completion, though I'm not sure. You'll have to
> experiment. You may also want to read through :help ins-completion for
> ideas (if any).

None of these seem to provide what I'm looking for. I supposed what is
really needed is a new autocmd-event similar to CursorHoldI but for
commands. Maybe "CommandHold" and "CommandHoldI". Maybe I should
donate some money to vim so that I can vote for this feature :-)

Thanks,
Addison


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Timer to automatically go back to normal mode

Michael F. Lamb


> None of these seem to provide what I'm looking for. I supposed what is
> really needed is a new autocmd-event similar to CursorHoldI but for
> commands. Maybe "CommandHold" and "CommandHoldI". Maybe I should
> donate some money to vim so that I can vote for this feature :-)

Maybe you could achieve the kind of editing style you want not with a
timeout, but with something less annoying than <esc>. Typically when I
use 'cw', it is to make a local modification. Rarely will I want to
insert a newline. So, how about a clever mapping that causes <cr> after
'cw' to return to normal mode?

I haven't been able to come up with the right commands to accomplish
this yet, though.

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Timer to automatically go back to normal mode

gmguyx

> Maybe you could achieve the kind of editing style you want not with a
> timeout, but with something less annoying than <esc>. Typically when I
> use 'cw', it is to make a local modification. Rarely will I want to
> insert a newline. So, how about a clever mapping that causes <cr> after
> 'cw' to return to normal mode?
>
> I haven't been able to come up with the right commands to accomplish
> this yet, though.

This might be achieved by mapping <CR> to a function which returns to
normal mode only if the "stopinsertmode" var from the
ToggleStopInsertMode() function is set to 1. However, my point is that
I don't want to have to press ANY key (even if <CR> is easier to press
than <Esc>). I just want it to automatically go back to normal mode
without pressing anything.


--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---