Loading ...
Sorry, an error occurred while loading the content.

Auto-raise existing Vim window on attempt to re-edit?

Expand Messages
  • Gareth McCaughan
    I have a feature request. I expect that either there s a good reason why it s a dumb thing to ask for, or else it s already possible, but I haven t been able
    Message 1 of 9 , Oct 28, 2003
    • 0 Attachment
      I have a feature request. I expect that either there's a good
      reason why it's a dumb thing to ask for, or else it's already
      possible, but I haven't been able to find either a reason why
      it's bad or a way to do it.

      I tend to work with a large number of editor windows open
      at once, and sometimes I forget what I already have open.

      Suppose I type "gvim foo.txt" when I already have a Vim window
      editing foo.txt. Then I get a dialog box offering me the option
      of opening read-only, clobbering the swapfile, recovering the
      swapfile or quitting.

      Generally the Right Thing is to quit and then find the existing
      Vim window and use that instead. Unfortunately, the "find the
      existing window" part of that can be slightly non-trivial when
      there are 10 Vim windows open, several of which have multiple
      files in them, and some of which are hidden behind other Vim
      windows, terminals, web browsers, etc.

      But suppose the new Vim instance, before it dies, could notify
      the old one and ask it to pop up to the top of the window stack?
      That would be much slicker, and I conjecture that it's
      essentially *always* what you want when you quit a new gvim
      instance because there's an old one already editing the file
      you asked to edit.

      I don't know how easy this would be to arrange in Windows,
      but under Unix one fairly painless way to do the communication --
      I think -- would be for the new-but-dying Vim to send the old one
      a SIGWINCH, and for Vim windows to push themselves to the top
      of the stack on receiving a SIGWINCH.

      I've hacked a version of this into my local copy of Vim,
      and it seems to work well. (When I say "hacked", I mean it;
      hence, no patch.)

      So, why is this a silly idea? :-)

      If it's *not* a silly idea, then let me suggest a further
      wrinkle: it should be possible to configure Vim so that
      if it finds an existing swapfile whose process is still
      running it doesn't bother prompting you, but just quits
      and auto-raises. This might be a bit unsatisfactory when
      the already-running process isn't running in GUI mode (since
      we can't auto-raise it then), but on reflection it's still
      what I'd want -- perhaps with a brief message to stderr
      saying what's going on. I repeat that this should be
      optional; some people will doubtless want to be presented
      with the list of options.

      --
      g
    • Bram Moolenaar
      Gareth McCaughan wrote: [see below] When Vim finds a swap file that is owned by the current user, it could indeed contact the process that created the swap
      Message 2 of 9 , Oct 28, 2003
      • 0 Attachment
        Gareth McCaughan wrote:

        [see below]

        When Vim finds a swap file that is owned by the current user, it could
        indeed contact the process that created the swap file. The info is
        there already.

        The SIGWINCH isn't the right signal to use, since it's already being used
        for a window size change. A user signal would be more useful. Except
        that the default is to terminate the process, thus we must be sure the
        other process can handle the signal.

        The client-server communication can be used, but it's not always
        available. And I don't think there currently is a mapping from process
        number to server name. And the swap file doesn't contain the server
        name.

        Note that on MS-Windows it's not very useful, because a process can't
        put itself in front of other windows (you do get a flashing icon).

        > I have a feature request. I expect that either there's a good
        > reason why it's a dumb thing to ask for, or else it's already
        > possible, but I haven't been able to find either a reason why
        > it's bad or a way to do it.
        >
        > I tend to work with a large number of editor windows open
        > at once, and sometimes I forget what I already have open.
        >
        > Suppose I type "gvim foo.txt" when I already have a Vim window
        > editing foo.txt. Then I get a dialog box offering me the option
        > of opening read-only, clobbering the swapfile, recovering the
        > swapfile or quitting.
        >
        > Generally the Right Thing is to quit and then find the existing
        > Vim window and use that instead. Unfortunately, the "find the
        > existing window" part of that can be slightly non-trivial when
        > there are 10 Vim windows open, several of which have multiple
        > files in them, and some of which are hidden behind other Vim
        > windows, terminals, web browsers, etc.
        >
        > But suppose the new Vim instance, before it dies, could notify
        > the old one and ask it to pop up to the top of the window stack?
        > That would be much slicker, and I conjecture that it's
        > essentially *always* what you want when you quit a new gvim
        > instance because there's an old one already editing the file
        > you asked to edit.
        >
        > I don't know how easy this would be to arrange in Windows,
        > but under Unix one fairly painless way to do the communication --
        > I think -- would be for the new-but-dying Vim to send the old one
        > a SIGWINCH, and for Vim windows to push themselves to the top
        > of the stack on receiving a SIGWINCH.
        >
        > I've hacked a version of this into my local copy of Vim,
        > and it seems to work well. (When I say "hacked", I mean it;
        > hence, no patch.)
        >
        > So, why is this a silly idea? :-)
        >
        > If it's *not* a silly idea, then let me suggest a further
        > wrinkle: it should be possible to configure Vim so that
        > if it finds an existing swapfile whose process is still
        > running it doesn't bother prompting you, but just quits
        > and auto-raises. This might be a bit unsatisfactory when
        > the already-running process isn't running in GUI mode (since
        > we can't auto-raise it then), but on reflection it's still
        > what I'd want -- perhaps with a brief message to stderr
        > saying what's going on. I repeat that this should be
        > optional; some people will doubtless want to be presented
        > with the list of options.
      • Gareth McCaughan
        ... Sure. I *said* what I had was a hack! (But see below.) ... I hadn t even known about Vim s client-server mode. Ahem. Another related difficulty occurs to
        Message 3 of 9 , Oct 28, 2003
        • 0 Attachment
          Bram Moolenaar wrote:

          > When Vim finds a swap file that is owned by the current user, it could
          > indeed contact the process that created the swap file. The info is
          > there already.
          >
          > The SIGWINCH isn't the right signal to use, since it's already being used
          > for a window size change. A user signal would be more useful. Except
          > that the default is to terminate the process, thus we must be sure the
          > other process can handle the signal.

          Sure. I *said* what I had was a hack! (But see below.)

          > The client-server communication can be used, but it's not always
          > available. And I don't think there currently is a mapping from process
          > number to server name. And the swap file doesn't contain the server
          > name.

          I hadn't even known about Vim's client-server mode. Ahem.

          Another related difficulty occurs to me: does the swap file
          contain the name of the host on which the process is running?
          If not, then trouble can arise in environments where multiple
          hosts share a filesystem: you can think you've found the right
          process when you haven't. I suppose that's no worse than the
          trouble that can arise even with a single host, if an old
          Vim process has died and a new one happens to have the same
          process ID.

          > Note that on MS-Windows it's not very useful, because a process can't
          > put itself in front of other windows (you do get a flashing icon).

          OK. So:

          - You can't do this very well on Windows, because there's
          no way for a Windows program to force itself to the top
          of the window stack.

          - There's always a theoretical danger of Bad Stuff happening
          when the process-ID isn't enough to identify the Vim instance,
          either because of multiple hosts (if I'm right in guessing
          that the hostname doesn't get stored in the swapfile) or
          because of re-use of the PID of a dead process. Neither of
          these will happen often in practice.

          - On Unix at least, it's possible to communicate via a
          user signal. We are agreed that using SIGWINCH is a hack,
          though I'm not sure I can think of any case where it would
          actually cause trouble.

          - But if the existing process is an older version of Vim
          that doesn't know to raise its window on receiving
          SIGUSR1 or whatever, the process will get killed; that
          would be embarrassing.

          - Presumably it's possible to put enough information in
          the swap file to allow new-enough versions of Vim to
          be identified.

          - This also only works when the existing process is
          (1) on the same machine and (2) owned by the same
          user. That's fair enough; we wouldn't want to be
          raising the window of someone else's Vim process
          anyway :-).

          - There's also the Vim client/server protocol, but that's
          only available when Vim was compiled with support for it;
          and (I'm guessing here, since I'm not familiar with the
          code) only when the already-existing Vim is actually a
          server. Finding the right server may be non-trivial.

          I'm not yet convinced that this is a bad idea. (I'm not sure
          whether I'm supposed to be...) Using the client/server protocol
          doesn't look promising, mostly because it's not always possible.
          Signals seem like a viable approach. The issue with user signals
          terminating the process makes me wonder whether perhaps SIGWINCH
          isn't such a bad idea after all.

          If it's possible to add things to the swap file format without
          backward incompatibility, then we can mitigate the danger of
          identifying the wrong process by making the swap file contain
          not only the process ID but also the hostname and the process's
          start time. The start time is (at least on some Unix systems)
          programmatically accessible by other processes, so the new Vim
          instance can check quite reliably whether it has the right process.
          Or we could just put up with the thing guessing wrong sometimes;
          it's not as if the adverse consequences are very serious. But
          having the extra information in the swap file might conceivably
          be useful for other purposes.

          The other question, of course, is whether this is a useful
          enough feature to be worth putting into Vim even if it is
          possible. That would be a question for Bram :-). (My vote
          is "yes", but you already guessed that.)

          --
          g
        • Bram Moolenaar
          ... Yes. Otherwise we would not know when the process number is valid. ... Actually, since the program you are running is another process, it should be
          Message 4 of 9 , Oct 28, 2003
          • 0 Attachment
            Gareth McCaughan wrote:

            > > The client-server communication can be used, but it's not always
            > > available. And I don't think there currently is a mapping from process
            > > number to server name. And the swap file doesn't contain the server
            > > name.
            >
            > I hadn't even known about Vim's client-server mode. Ahem.
            >
            > Another related difficulty occurs to me: does the swap file
            > contain the name of the host on which the process is running?

            Yes. Otherwise we would not know when the process number is valid.

            > > Note that on MS-Windows it's not very useful, because a process can't
            > > put itself in front of other windows (you do get a flashing icon).
            >
            > OK. So:
            >
            > - You can't do this very well on Windows, because there's
            > no way for a Windows program to force itself to the top
            > of the window stack.

            Actually, since the program you are running is another process, it
            should be possible to bring another gvim to the foreground. The
            remote_foreground() function was added for this.

            > - There's always a theoretical danger of Bad Stuff happening
            > when the process-ID isn't enough to identify the Vim instance,
            > either because of multiple hosts (if I'm right in guessing
            > that the hostname doesn't get stored in the swapfile) or
            > because of re-use of the PID of a dead process. Neither of
            > these will happen often in practice.

            Re-use of a process ID is possible, on many systems they wrap around
            after 65000 or so. But this only happens for swap files that are left
            behind, and that should not happen often.

            > - On Unix at least, it's possible to communicate via a
            > user signal. We are agreed that using SIGWINCH is a hack,
            > though I'm not sure I can think of any case where it would
            > actually cause trouble.
            >
            > - But if the existing process is an older version of Vim
            > that doesn't know to raise its window on receiving
            > SIGUSR1 or whatever, the process will get killed; that
            > would be embarrassing.
            >
            > - Presumably it's possible to put enough information in
            > the swap file to allow new-enough versions of Vim to
            > be identified.

            Yes, but I hesitate to add items to the swap file. We must be very sure
            there are no backwards compatibility problems.

            > - This also only works when the existing process is
            > (1) on the same machine and (2) owned by the same
            > user. That's fair enough; we wouldn't want to be
            > raising the window of someone else's Vim process
            > anyway :-).
            >
            > - There's also the Vim client/server protocol, but that's
            > only available when Vim was compiled with support for it;
            > and (I'm guessing here, since I'm not familiar with the
            > code) only when the already-existing Vim is actually a
            > server. Finding the right server may be non-trivial.

            Most gvim processes running under X11 do support the client-server
            stuff. You can enumerate the servers with serverlist(), but you would
            have to contact each of them to find out which one is editing the file.
            It should work, but it's a bit clumsy.

            > I'm not yet convinced that this is a bad idea. (I'm not sure
            > whether I'm supposed to be...) Using the client/server protocol
            > doesn't look promising, mostly because it's not always possible.
            > Signals seem like a viable approach. The issue with user signals
            > terminating the process makes me wonder whether perhaps SIGWINCH
            > isn't such a bad idea after all.

            I don't like overloading signals. Also, if the buffer is currently
            hidden, the server should probably open a window for it. With a
            SIGWINCH you can't do that, you don't know which buffer to unhide and it
            might actually be a window resize.

            > If it's possible to add things to the swap file format without
            > backward incompatibility, then we can mitigate the danger of
            > identifying the wrong process by making the swap file contain
            > not only the process ID but also the hostname and the process's
            > start time. The start time is (at least on some Unix systems)
            > programmatically accessible by other processes, so the new Vim
            > instance can check quite reliably whether it has the right process.
            > Or we could just put up with the thing guessing wrong sometimes;
            > it's not as if the adverse consequences are very serious. But
            > having the extra information in the swap file might conceivably
            > be useful for other purposes.

            Adding the server name could be useful. Unfortunately, there is no
            extra room in the swap file for this. Only 10 bytes or so are left
            over.

            > The other question, of course, is whether this is a useful
            > enough feature to be worth putting into Vim even if it is
            > possible. That would be a question for Bram :-). (My vote
            > is "yes", but you already guessed that.)

            It's useful. Most people working with several Vims have encountered the
            situation that you get the "file already being edited" warning and
            wondering where that Vim is.

            --
            Proofread carefully to see if you any words out.

            /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
            /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\
            \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
            \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html ///
          • Steve Hall
            ... I m guessing that you still want to be able to maintain multiple instances and merely pop back to the instance that has a file open that you accidentally
            Message 5 of 9 , Oct 28, 2003
            • 0 Attachment
              Gareth McCaughan wrote:
              >
              > [switching to a Vim instance that already has the file open when I
              > try to re-edit it]
              >
              > I hadn't even known about Vim's client-server mode. Ahem.

              I'm guessing that you still want to be able to maintain multiple
              instances and merely pop back to the instance that has a file open
              that you accidentally asked to re-edit. But...

              If you're by chance interested in maintaining only a single instance,
              I use a system that maintains a single instance of gVim in all cases,
              on both Windows and Linux. Below is an (untested) abbreviation of the
              function I use to accomplish this:

              ---------------------------------------------------------------------
              function! Singleserver()
              " always merge a new instance of Vim into a (single) existing one

              " don't use in terminal!
              if !has("gui_running")
              return
              endif

              " if this isn't the primary server
              if v:servername !=? "GVIM"

              " compose command to re-open this file if real
              if bufexists(bufnr("%"))
              " get file name/path
              let myfile = expand("%:p")
              " reverse backslashes (Windows and Unix compatibility)
              let myfile = substitute(myfile, '\\', '/', 'g')
              " escape spaces
              let myfile = escape(myfile, ' ')
              " command to edit current file and maintain position
              let mycmd = '<C-o>:edit +' . line('.') . ' ' . myfile . '<CR>'
              " compose command to open a new buffer
              else
              let mycmd = '<C-o>:enew<CR>'
              endif

              " pass file open/position command to primary server
              call remote_send('GVIM', mycmd)
              " call primary server to foreground
              call remote_foreground('GVIM')
              " quit this server
              confirm qall

              end

              endfunction
              ---------------------------------------------------------------------

              Perhaps a bit off-topic for what you and Bram are discussing and not
              nearly as sophisticated, but (with some overhead) it could probably be
              hacked to pass file info back and forth between instances for what you
              want.


              --
              Steve Hall [ digitect@... ]
            • Valery Kondakoff
              Hello, Steve! Tuesday, October 28, 2003, 11:02:04 PM, you wrote: SH If you re by chance interested in maintaining only a single instance, SH I use a system
              Message 6 of 9 , Nov 4, 2003
              • 0 Attachment
                Hello, Steve!

                Tuesday, October 28, 2003, 11:02:04 PM, you wrote:

                SH> If you're by chance interested in maintaining only a single instance,
                SH> I use a system that maintains a single instance of gVim in all cases,
                SH> on both Windows and Linux. Below is an (untested) abbreviation of the
                SH> function I use to accomplish this:

                SH> ---------------------------------------------------------------------
                SH> function! Singleserver()
                SH> ---------------------------------------------------------------------

                I'm very interested in maintaining a single GVIM instance. Two or
                three weeks ago was asking for help on this topic in a general VIM
                mailing list.

                Now I tryed Singleserver() function and it seems to work pretty well.
                After putting your function in my _vimrc I'm launching GVIM like this:

                gvim.exe "+call Singleserver()" filename

                Is this usage correct or am I missing something? I'm asking this
                because your function seems to work pretty well, except that when I'm
                opening a file using this command (gvim.exe "+call Singleserver()"
                test.txt) I'm receiving 'Swap file test.txt.swp already exists'
                message. The file loads properly if I choose 'Edit anyway' button.
                (I'm using GVIM 6.2, WinXP Pro).

                If there is a way to eliminate 'Swap already exists' message?

                Thank you!


                --
                Best regards,
                Valery mailto:strauss@...

                PGP key: mailto:pgp-public-keys@...?subject=GET%20strauss@...
              • Steve Hall
                From: Valery Kondakoff, Nov 4, 2003 10:17 AM ... You should find that the autocmds I included accomplish the same task without having to pass the function call
                Message 7 of 9 , Nov 4, 2003
                • 0 Attachment
                  From: Valery Kondakoff, Nov 4, 2003 10:17 AM
                  >
                  > Hello, Steve!
                  >
                  > Tuesday, October 28, 2003, 11:02:04 PM, you wrote:
                  >
                  > > If you're by chance interested in maintaining only a single
                  > > instance, I use a system that maintains a single instance of gVim
                  > > in all cases, on both Windows and Linux. Below is an (untested)
                  > > abbreviation of the function I use to accomplish this:
                  > >
                  > > ---------------------------------------------------------------
                  > > function! Singleserver()
                  > > ---------------------------------------------------------------
                  >
                  > I'm very interested in maintaining a single GVIM instance. Two or
                  > three weeks ago was asking for help on this topic in a general VIM
                  > mailing list.
                  >
                  > Now I tryed Singleserver() function and it seems to work pretty well.
                  > After putting your function in my _vimrc I'm launching GVIM like this:
                  >
                  > gvim.exe "+call Singleserver()" filename
                  >
                  > Is this usage correct or am I missing something?

                  You should find that the autocmds I included accomplish the same task
                  without having to pass the function call on startup.


                  > I'm asking this because your function seems to work pretty well,
                  > except that when I'm opening a file using this command (gvim.exe
                  > "+call Singleserver()" test.txt) I'm receiving 'Swap file
                  > test.txt.swp already exists' message. The file loads properly if I
                  > choose 'Edit anyway' button. (I'm using GVIM 6.2, WinXP Pro).
                  >
                  > If there is a way to eliminate 'Swap already exists' message?

                  I've not been able to find a way, other than turning off swap files
                  with :set noswapfile. You could probably derive some very nasty hack
                  where it is only momentarily turned off as the two servers are merged,
                  passing the file info back and forth a few times, but it seems like
                  too much overhead for me.

                  Besides Vim never crashes, so who needs swap files? :)

                  --
                  Steve Hall [ digitect@... ]
                • Valery Kondakoff
                  Hello, Steve! Tuesday, November 4, 2003, 6:43:56 PM, you wrote: SH You should find that the autocmds I included accomplish the same task SH without having to
                  Message 8 of 9 , Nov 5, 2003
                  • 0 Attachment
                    Hello, Steve!

                    Tuesday, November 4, 2003, 6:43:56 PM, you wrote:

                    SH> You should find that the autocmds I included accomplish the same task
                    SH> without having to pass the function call on startup.

                    Sorry, it seems I can't find no autocommands in the function that you
                    post. There is the entire function:

                    -----
                    function! Singleserver()
                    " always merge a new instance of Vim into a (single) existing one

                    " don't use in terminal!
                    if !has("gui_running")
                    return
                    endif

                    " if this isn't the primary server
                    if v:servername !=? "GVIM"

                    " compose command to re-open this file if real
                    if bufexists(bufnr("%"))
                    " get file name/path
                    let myfile = expand("%:p")
                    " reverse backslashes (Windows and Unix compatibility)
                    let myfile = substitute(myfile, '\\', '/', 'g')
                    " escape spaces
                    let myfile = escape(myfile, ' ')
                    " command to edit current file and maintain position
                    let mycmd = '<C-o>:edit +' . line('.') . ' ' . myfile . '<CR>'
                    " compose command to open a new buffer
                    else
                    let mycmd = '<C-o>:enew<CR>'
                    endif

                    " pass file open/position command to primary server
                    call remote_send('GVIM', mycmd)
                    " call primary server to foreground
                    call remote_foreground('GVIM')
                    " quit this server
                    confirm qall

                    end

                    endfunction
                    ----

                    >>
                    >> If there is a way to eliminate 'Swap already exists' message?

                    SH> I've not been able to find a way, other than turning off swap files
                    SH> with :set noswapfile. You could probably derive some very nasty hack
                    SH> where it is only momentarily turned off as the two servers are merged,
                    SH> passing the file info back and forth a few times, but it seems like
                    SH> too much overhead for me.

                    Yes, thank you for an explanation.

                    SH> Besides Vim never crashes, so who needs swap files? :)

                    :)

                    --
                    Best regards,
                    Valery mailto:strauss@...

                    PGP key: mailto:pgp-public-keys@...?subject=GET%20strauss@...

                    np: 01 - Горький Ангел [stopped]
                  • Steve Hall
                    From: Valery Kondakoff, Nov 5, 2003 10:37 AM ... Please refer to my first post: http://groups.yahoo.com/group/vim/message/44631 -- Steve Hall [
                    Message 9 of 9 , Nov 5, 2003
                    • 0 Attachment
                      From: Valery Kondakoff, Nov 5, 2003 10:37 AM
                      > Tuesday, November 4, 2003, 6:43:56 PM, you wrote:
                      > >
                      > > You should find that the autocmds I included accomplish the same
                      > > task without having to pass the function call on startup.
                      >
                      > Sorry, it seems I can't find no autocommands in the function that
                      > you post.

                      Please refer to my first post:

                      http://groups.yahoo.com/group/vim/message/44631


                      --
                      Steve Hall [ digitect@... ]
                    Your message has been successfully submitted and would be delivered to recipients shortly.