creating a “:KeepCursor” command The Next CEO of Stack OverflowHow to undo last command in command line?How can I repeat last Ex-mode command in normal mode?Copy text based on delimiting stringsHow to simulate Return and Escape for global command without using Control-V?Use pattern of global ex command found on a line to substitute in another lineHow to pipe *characters* to cmd ( `:!` )Search pattern for an if statement that isn't followed by curly brace on the next lineSetting the search pattern to just a portion of a regex patternIs there a setting that hides the last colon-command entered?':norm dtxdty' works different than '0dtxdty', what's happening?

Robert Sheckley short story about vacation spots being overwhelmed

How to be diplomatic in refusing to write code that breaches the privacy of our users

Clustering points and summing up attributes per cluster in QGIS

How easy is it to start Magic from scratch?

If/When UK leaves the EU, can a future goverment do a referendum to join EU

What flight has the highest ratio of time difference to flight time?

How to start emacs in "nothing" mode (`fundamental-mode`)

Why do we use the plural of movies in this phrase "We went to the movies last night."?

Why doesn't a table tennis ball float on a surface of steel balls? How do we calculate buoyancy here?

Can I equip Skullclamp on a creature I am sacrificing?

What was the first Unix version to run on a microcomputer?

Why did we only see the N-1 starfighters in one film?

How do I construct this japanese bowl?

Should I tutor a student who I know has cheated on their homework?

Shade part of a Venn diagram

How do I go from 300 unfinished/half written blog posts, to published posts?

How can I get through very long and very dry, but also very useful technical documents when learning a new tool?

Extracting names from filename in bash

Is HostGator storing my password in plaintext?

What does "Its cash flow is deeply negative" mean?

Was a professor correct to chastise me for writing "Prof. X" rather than "Professor X"?

Why do airplanes bank sharply to the right after air-to-air refueling?

Hindi speaking tourist to UK from India

Apart from "berlinern", do any other German dialects have a corresponding verb?



creating a “:KeepCursor” command



The Next CEO of Stack OverflowHow to undo last command in command line?How can I repeat last Ex-mode command in normal mode?Copy text based on delimiting stringsHow to simulate Return and Escape for global command without using Control-V?Use pattern of global ex command found on a line to substitute in another lineHow to pipe *characters* to cmd ( `:!` )Search pattern for an if statement that isn't followed by curly brace on the next lineSetting the search pattern to just a portion of a regex patternIs there a setting that hides the last colon-command entered?':norm dtxdty' works different than '0dtxdty', what's happening?










2















I'd like to make a command that works like this: :KeepCursor cmd will the given execute ex command string, then restore the cursor's position. A primary example is:



:KeepCursor normal! *


which would perform a keyword search without jumping to the next match. This can of course be accomplished in other ways, but it's a good demonstration of the functionality I'm looking for, which I want to work in every possible case.



This is my attempt so far. I'm using feedkeys+imtx because I'd like the command to behave exactly as though I typed it. I put the cursor restoration in a finally so it works even if the command encounters an error.



function! s:keepcursor(qargs)
let l:view = winsaveview()
let l:winid = win_getid()
try
call feedkeys(':'.a:qargs."<cr>", 'imtx')
finally
if win_getid() != l:winid
if !win_id2win(l:winid)
return
endif
call win_gotoid(l:winid)
endif
call winrestview(l:view)
endtry
endfunction

command! -nargs=* KeepCursor call s:keepcursor(<q-args>)


However, it does not seem to work. Using :KeepCursor normal! * prints the search string but does not highlight anything. Running :hlsearch afterwards highlights the wrong thing.



My questions are a) can it be explained why this doesn't work and b) can such a :KeepCursor command be written?










share|improve this question


























    2















    I'd like to make a command that works like this: :KeepCursor cmd will the given execute ex command string, then restore the cursor's position. A primary example is:



    :KeepCursor normal! *


    which would perform a keyword search without jumping to the next match. This can of course be accomplished in other ways, but it's a good demonstration of the functionality I'm looking for, which I want to work in every possible case.



    This is my attempt so far. I'm using feedkeys+imtx because I'd like the command to behave exactly as though I typed it. I put the cursor restoration in a finally so it works even if the command encounters an error.



    function! s:keepcursor(qargs)
    let l:view = winsaveview()
    let l:winid = win_getid()
    try
    call feedkeys(':'.a:qargs."<cr>", 'imtx')
    finally
    if win_getid() != l:winid
    if !win_id2win(l:winid)
    return
    endif
    call win_gotoid(l:winid)
    endif
    call winrestview(l:view)
    endtry
    endfunction

    command! -nargs=* KeepCursor call s:keepcursor(<q-args>)


    However, it does not seem to work. Using :KeepCursor normal! * prints the search string but does not highlight anything. Running :hlsearch afterwards highlights the wrong thing.



    My questions are a) can it be explained why this doesn't work and b) can such a :KeepCursor command be written?










    share|improve this question
























      2












      2








      2








      I'd like to make a command that works like this: :KeepCursor cmd will the given execute ex command string, then restore the cursor's position. A primary example is:



      :KeepCursor normal! *


      which would perform a keyword search without jumping to the next match. This can of course be accomplished in other ways, but it's a good demonstration of the functionality I'm looking for, which I want to work in every possible case.



      This is my attempt so far. I'm using feedkeys+imtx because I'd like the command to behave exactly as though I typed it. I put the cursor restoration in a finally so it works even if the command encounters an error.



      function! s:keepcursor(qargs)
      let l:view = winsaveview()
      let l:winid = win_getid()
      try
      call feedkeys(':'.a:qargs."<cr>", 'imtx')
      finally
      if win_getid() != l:winid
      if !win_id2win(l:winid)
      return
      endif
      call win_gotoid(l:winid)
      endif
      call winrestview(l:view)
      endtry
      endfunction

      command! -nargs=* KeepCursor call s:keepcursor(<q-args>)


      However, it does not seem to work. Using :KeepCursor normal! * prints the search string but does not highlight anything. Running :hlsearch afterwards highlights the wrong thing.



      My questions are a) can it be explained why this doesn't work and b) can such a :KeepCursor command be written?










      share|improve this question














      I'd like to make a command that works like this: :KeepCursor cmd will the given execute ex command string, then restore the cursor's position. A primary example is:



      :KeepCursor normal! *


      which would perform a keyword search without jumping to the next match. This can of course be accomplished in other ways, but it's a good demonstration of the functionality I'm looking for, which I want to work in every possible case.



      This is my attempt so far. I'm using feedkeys+imtx because I'd like the command to behave exactly as though I typed it. I put the cursor restoration in a finally so it works even if the command encounters an error.



      function! s:keepcursor(qargs)
      let l:view = winsaveview()
      let l:winid = win_getid()
      try
      call feedkeys(':'.a:qargs."<cr>", 'imtx')
      finally
      if win_getid() != l:winid
      if !win_id2win(l:winid)
      return
      endif
      call win_gotoid(l:winid)
      endif
      call winrestview(l:view)
      endtry
      endfunction

      command! -nargs=* KeepCursor call s:keepcursor(<q-args>)


      However, it does not seem to work. Using :KeepCursor normal! * prints the search string but does not highlight anything. Running :hlsearch afterwards highlights the wrong thing.



      My questions are a) can it be explained why this doesn't work and b) can such a :KeepCursor command be written?







      search command-line cursor command






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 22 at 18:18









      MassMass

      6,4101420




      6,4101420




















          2 Answers
          2






          active

          oldest

          votes


















          5















          Can it be written?




          Yup.



          command! -nargs=* -complete=command KeepCursor
          let [s:view, s:win] = [winsaveview(), win_getid()] |
          try |
          execute <q-args> |
          finally |
          if win_id2win(s:win) |
          call win_gotoid(s:win) |
          endif |
          keepjumps call winrestview(s:view) |
          endtry



          Can it be explained why this doesn't work




          There is a lot going on here. I haven't debugged anything, but my guess is feedkeys() is part of your problem. I typically avoid feedkeys() as it is often easier to debug other methods.






          share|improve this answer

























          • Originally I used feedkeys because hlsearch doesn't work when using execute from a function. So basically the difference is putting execute inside the command, not inside a function?

            – Mass
            Mar 23 at 0:55











          • I have tried this a few ways. Inside a function, outside a function, w/ feedkeys(), w/ :execute, w/ call execute(). From what I can tell you can use feedkeys() , :execute, execute(), it doesn't matter. For some reason it is the function that seems to be the problem here. I only kept it out of the function so that the errors would look "native", so I stumbled on the solution by accident. This might be a a bug, but I am not on the latest version of Vim. I am on Vim 8.1 patches 1-950.

            – Peter Rincker
            Mar 24 at 1:44


















          2















          Can it be written?




          Possibly, but it might be a lot harder than expected. Because, what do you do with commands that close the current window? Or commands, that add lines above the current cursor position?



          One problem you are running into is described unter :h function-search-undo.



          The last used search pattern and the redo command "."
          will not be changed by the function. This also
          implies that the effect of :nohlsearch is undone
          when the function returns.


          The only way I know to circumvent this is to make use of using feedkeys(), but apparently, this does not work with the x flag, you have given to the feedkeys command (and I am not actually sure this is needed here). So using



          call feedkeys(':'.a:qargs."<cr>", 'imt')


          and your example starts to work (well, almost). However, if you start using this, you'll notice the cursor position will be off, despite the fact, that winrestview() should have restored the cursor position. I think this happens, because the feedkeys() call will insert the command after the current command is executed, e.g. after the function s:keepcursor() returns. I dont' know a way around this (well, perhaps a workaround would be to try to make use of timers, but I consider this ugly).



          Note, there is also this script that implements a :KeepView command.






          share|improve this answer























            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "599"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fvi.stackexchange.com%2fquestions%2f19277%2fcreating-a-keepcursor-command%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            5















            Can it be written?




            Yup.



            command! -nargs=* -complete=command KeepCursor
            let [s:view, s:win] = [winsaveview(), win_getid()] |
            try |
            execute <q-args> |
            finally |
            if win_id2win(s:win) |
            call win_gotoid(s:win) |
            endif |
            keepjumps call winrestview(s:view) |
            endtry



            Can it be explained why this doesn't work




            There is a lot going on here. I haven't debugged anything, but my guess is feedkeys() is part of your problem. I typically avoid feedkeys() as it is often easier to debug other methods.






            share|improve this answer

























            • Originally I used feedkeys because hlsearch doesn't work when using execute from a function. So basically the difference is putting execute inside the command, not inside a function?

              – Mass
              Mar 23 at 0:55











            • I have tried this a few ways. Inside a function, outside a function, w/ feedkeys(), w/ :execute, w/ call execute(). From what I can tell you can use feedkeys() , :execute, execute(), it doesn't matter. For some reason it is the function that seems to be the problem here. I only kept it out of the function so that the errors would look "native", so I stumbled on the solution by accident. This might be a a bug, but I am not on the latest version of Vim. I am on Vim 8.1 patches 1-950.

              – Peter Rincker
              Mar 24 at 1:44















            5















            Can it be written?




            Yup.



            command! -nargs=* -complete=command KeepCursor
            let [s:view, s:win] = [winsaveview(), win_getid()] |
            try |
            execute <q-args> |
            finally |
            if win_id2win(s:win) |
            call win_gotoid(s:win) |
            endif |
            keepjumps call winrestview(s:view) |
            endtry



            Can it be explained why this doesn't work




            There is a lot going on here. I haven't debugged anything, but my guess is feedkeys() is part of your problem. I typically avoid feedkeys() as it is often easier to debug other methods.






            share|improve this answer

























            • Originally I used feedkeys because hlsearch doesn't work when using execute from a function. So basically the difference is putting execute inside the command, not inside a function?

              – Mass
              Mar 23 at 0:55











            • I have tried this a few ways. Inside a function, outside a function, w/ feedkeys(), w/ :execute, w/ call execute(). From what I can tell you can use feedkeys() , :execute, execute(), it doesn't matter. For some reason it is the function that seems to be the problem here. I only kept it out of the function so that the errors would look "native", so I stumbled on the solution by accident. This might be a a bug, but I am not on the latest version of Vim. I am on Vim 8.1 patches 1-950.

              – Peter Rincker
              Mar 24 at 1:44













            5












            5








            5








            Can it be written?




            Yup.



            command! -nargs=* -complete=command KeepCursor
            let [s:view, s:win] = [winsaveview(), win_getid()] |
            try |
            execute <q-args> |
            finally |
            if win_id2win(s:win) |
            call win_gotoid(s:win) |
            endif |
            keepjumps call winrestview(s:view) |
            endtry



            Can it be explained why this doesn't work




            There is a lot going on here. I haven't debugged anything, but my guess is feedkeys() is part of your problem. I typically avoid feedkeys() as it is often easier to debug other methods.






            share|improve this answer
















            Can it be written?




            Yup.



            command! -nargs=* -complete=command KeepCursor
            let [s:view, s:win] = [winsaveview(), win_getid()] |
            try |
            execute <q-args> |
            finally |
            if win_id2win(s:win) |
            call win_gotoid(s:win) |
            endif |
            keepjumps call winrestview(s:view) |
            endtry



            Can it be explained why this doesn't work




            There is a lot going on here. I haven't debugged anything, but my guess is feedkeys() is part of your problem. I typically avoid feedkeys() as it is often easier to debug other methods.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 22 at 21:05

























            answered Mar 22 at 19:02









            Peter RinckerPeter Rincker

            10.5k11828




            10.5k11828












            • Originally I used feedkeys because hlsearch doesn't work when using execute from a function. So basically the difference is putting execute inside the command, not inside a function?

              – Mass
              Mar 23 at 0:55











            • I have tried this a few ways. Inside a function, outside a function, w/ feedkeys(), w/ :execute, w/ call execute(). From what I can tell you can use feedkeys() , :execute, execute(), it doesn't matter. For some reason it is the function that seems to be the problem here. I only kept it out of the function so that the errors would look "native", so I stumbled on the solution by accident. This might be a a bug, but I am not on the latest version of Vim. I am on Vim 8.1 patches 1-950.

              – Peter Rincker
              Mar 24 at 1:44

















            • Originally I used feedkeys because hlsearch doesn't work when using execute from a function. So basically the difference is putting execute inside the command, not inside a function?

              – Mass
              Mar 23 at 0:55











            • I have tried this a few ways. Inside a function, outside a function, w/ feedkeys(), w/ :execute, w/ call execute(). From what I can tell you can use feedkeys() , :execute, execute(), it doesn't matter. For some reason it is the function that seems to be the problem here. I only kept it out of the function so that the errors would look "native", so I stumbled on the solution by accident. This might be a a bug, but I am not on the latest version of Vim. I am on Vim 8.1 patches 1-950.

              – Peter Rincker
              Mar 24 at 1:44
















            Originally I used feedkeys because hlsearch doesn't work when using execute from a function. So basically the difference is putting execute inside the command, not inside a function?

            – Mass
            Mar 23 at 0:55





            Originally I used feedkeys because hlsearch doesn't work when using execute from a function. So basically the difference is putting execute inside the command, not inside a function?

            – Mass
            Mar 23 at 0:55













            I have tried this a few ways. Inside a function, outside a function, w/ feedkeys(), w/ :execute, w/ call execute(). From what I can tell you can use feedkeys() , :execute, execute(), it doesn't matter. For some reason it is the function that seems to be the problem here. I only kept it out of the function so that the errors would look "native", so I stumbled on the solution by accident. This might be a a bug, but I am not on the latest version of Vim. I am on Vim 8.1 patches 1-950.

            – Peter Rincker
            Mar 24 at 1:44





            I have tried this a few ways. Inside a function, outside a function, w/ feedkeys(), w/ :execute, w/ call execute(). From what I can tell you can use feedkeys() , :execute, execute(), it doesn't matter. For some reason it is the function that seems to be the problem here. I only kept it out of the function so that the errors would look "native", so I stumbled on the solution by accident. This might be a a bug, but I am not on the latest version of Vim. I am on Vim 8.1 patches 1-950.

            – Peter Rincker
            Mar 24 at 1:44











            2















            Can it be written?




            Possibly, but it might be a lot harder than expected. Because, what do you do with commands that close the current window? Or commands, that add lines above the current cursor position?



            One problem you are running into is described unter :h function-search-undo.



            The last used search pattern and the redo command "."
            will not be changed by the function. This also
            implies that the effect of :nohlsearch is undone
            when the function returns.


            The only way I know to circumvent this is to make use of using feedkeys(), but apparently, this does not work with the x flag, you have given to the feedkeys command (and I am not actually sure this is needed here). So using



            call feedkeys(':'.a:qargs."<cr>", 'imt')


            and your example starts to work (well, almost). However, if you start using this, you'll notice the cursor position will be off, despite the fact, that winrestview() should have restored the cursor position. I think this happens, because the feedkeys() call will insert the command after the current command is executed, e.g. after the function s:keepcursor() returns. I dont' know a way around this (well, perhaps a workaround would be to try to make use of timers, but I consider this ugly).



            Note, there is also this script that implements a :KeepView command.






            share|improve this answer



























              2















              Can it be written?




              Possibly, but it might be a lot harder than expected. Because, what do you do with commands that close the current window? Or commands, that add lines above the current cursor position?



              One problem you are running into is described unter :h function-search-undo.



              The last used search pattern and the redo command "."
              will not be changed by the function. This also
              implies that the effect of :nohlsearch is undone
              when the function returns.


              The only way I know to circumvent this is to make use of using feedkeys(), but apparently, this does not work with the x flag, you have given to the feedkeys command (and I am not actually sure this is needed here). So using



              call feedkeys(':'.a:qargs."<cr>", 'imt')


              and your example starts to work (well, almost). However, if you start using this, you'll notice the cursor position will be off, despite the fact, that winrestview() should have restored the cursor position. I think this happens, because the feedkeys() call will insert the command after the current command is executed, e.g. after the function s:keepcursor() returns. I dont' know a way around this (well, perhaps a workaround would be to try to make use of timers, but I consider this ugly).



              Note, there is also this script that implements a :KeepView command.






              share|improve this answer

























                2












                2








                2








                Can it be written?




                Possibly, but it might be a lot harder than expected. Because, what do you do with commands that close the current window? Or commands, that add lines above the current cursor position?



                One problem you are running into is described unter :h function-search-undo.



                The last used search pattern and the redo command "."
                will not be changed by the function. This also
                implies that the effect of :nohlsearch is undone
                when the function returns.


                The only way I know to circumvent this is to make use of using feedkeys(), but apparently, this does not work with the x flag, you have given to the feedkeys command (and I am not actually sure this is needed here). So using



                call feedkeys(':'.a:qargs."<cr>", 'imt')


                and your example starts to work (well, almost). However, if you start using this, you'll notice the cursor position will be off, despite the fact, that winrestview() should have restored the cursor position. I think this happens, because the feedkeys() call will insert the command after the current command is executed, e.g. after the function s:keepcursor() returns. I dont' know a way around this (well, perhaps a workaround would be to try to make use of timers, but I consider this ugly).



                Note, there is also this script that implements a :KeepView command.






                share|improve this answer














                Can it be written?




                Possibly, but it might be a lot harder than expected. Because, what do you do with commands that close the current window? Or commands, that add lines above the current cursor position?



                One problem you are running into is described unter :h function-search-undo.



                The last used search pattern and the redo command "."
                will not be changed by the function. This also
                implies that the effect of :nohlsearch is undone
                when the function returns.


                The only way I know to circumvent this is to make use of using feedkeys(), but apparently, this does not work with the x flag, you have given to the feedkeys command (and I am not actually sure this is needed here). So using



                call feedkeys(':'.a:qargs."<cr>", 'imt')


                and your example starts to work (well, almost). However, if you start using this, you'll notice the cursor position will be off, despite the fact, that winrestview() should have restored the cursor position. I think this happens, because the feedkeys() call will insert the command after the current command is executed, e.g. after the function s:keepcursor() returns. I dont' know a way around this (well, perhaps a workaround would be to try to make use of timers, but I consider this ugly).



                Note, there is also this script that implements a :KeepView command.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 25 at 7:58









                Christian BrabandtChristian Brabandt

                16k2646




                16k2646



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Vi and Vim Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fvi.stackexchange.com%2fquestions%2f19277%2fcreating-a-keepcursor-command%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Adding axes to figuresAdding axes labels to LaTeX figuresLaTeX equivalent of ConTeXt buffersRotate a node but not its content: the case of the ellipse decorationHow to define the default vertical distance between nodes?TikZ scaling graphic and adjust node position and keep font sizeNumerical conditional within tikz keys?adding axes to shapesAlign axes across subfiguresAdding figures with a certain orderLine up nested tikz enviroments or how to get rid of themAdding axes labels to LaTeX figures

                    Tähtien Talli Jäsenet | Lähteet | NavigointivalikkoSuomen Hippos – Tähtien Talli

                    Do these cracks on my tires look bad? The Next CEO of Stack OverflowDry rot tire should I replace?Having to replace tiresFishtailed so easily? Bad tires? ABS?Filling the tires with something other than air, to avoid puncture hassles?Used Michelin tires safe to install?Do these tyre cracks necessitate replacement?Rumbling noise: tires or mechanicalIs it possible to fix noisy feathered tires?Are bad winter tires still better than summer tires in winter?Torque converter failure - Related to replacing only 2 tires?Why use snow tires on all 4 wheels on 2-wheel-drive cars?