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

Bug/Patch : quickfix should set v:swapcommand to allow dispatching of the command to a remote server. Plus a remote command dispatching script.

Expand Messages
  • Neighbour
    Currently a quickfix jump that triggers SwapExistsEvent always has the v:swapcommand 1G . The following patch sets it to the jump destination. ... +++
    Message 1 of 7 , Sep 13, 2009
    • 0 Attachment
      Currently a quickfix jump that triggers SwapExistsEvent always has the
      v:swapcommand '1G'. The following patch sets it to the jump destination.


      --- a/src/quickfix.c
      +++ b/src/quickfix.c
      @@ -1519,6 +1519,20 @@ qf_jump(qi, dir, errornr, forceit)
      }
      }

      + /*
      + * Set the v:swapcommand to have the possibility to direct a remote
      vim-server
      + * that owns the buffer, to the right location within the file
      + */
      +
      + if ( qf_ptr ) {
      + const int long_enough_to_hold_two_numbers = 100 ;
      + char_u swap_command_buffer[ long_enough_to_hold_two_numbers ] ;
      +
      + snprintf( swap_command_buffer ,
      long_enough_to_hold_two_numbers , "%ldG%i|" , qf_ptr->qf_lnum ,
      qf_ptr->qf_col ) ;
      +
      + set_vim_var_string(VV_SWAPCOMMAND, swap_command_buffer , -1);
      + }
      +
      #ifdef FEAT_WINDOWS
      qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
      if (qf_win_pos_update(qi, old_qf_index))



      This patch is against version 7.2.238

      As it appears v:swapcommand is a somewhat unused mechanism, as only ':tag'
      seems to set it. Well, together with quickfix it would cover the majority of
      my use-cases.


      The script is strongly related but not that important, so I place it in an
      answer to this post.

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Neighbour
      Have there been considerations about shared buffers? Is that possible already? I have read the most part of the manuals and did not find anything... With the
      Message 2 of 7 , Sep 13, 2009
      • 0 Attachment
        Have there been considerations about shared buffers? Is that possible already?
        I have read the most part of the manuals and did not find anything...

        With the help of SwapExistsEvent, v:swapcommand and remote_expr() I managed to
        have basic interaction between multiple gvim-instances.

        My use case:
        - multiple gvim instances to represent different parts of a project,
        with a pertinent titlestring and a familiar tab-layout.
        - registered buffers for a session, to easily clean foreign buffers.
        - SwapExistsEvent handling to iterate over existing vim-servers and
        dispatch the corresponding command. That applies to everything
        quickfix and ':tag' related.


        Now, I'm a very young vim-scriptor and this script is ... somewhat fragile.
        And the style and design could be improved, too.
        This is actually my first script that exceeds one screen-page -
        my practicing ground so to speak. It is clearly just a prototype.
        It currently works for me - not without frowns but it works for me - and I
        have spent too much time on it already distracting me from my actual project.
        I will continue to improve my vim-scripting and hopefully contribute something
        more mature then.

        However, I desperately needed this functionality and maybe others do, too. So
        please forgive me that I kind of just ... put it here, because of the
        distraction-point I made above. Maybe someone who needs it, too, finds it
        improves it, generalizes it...

        Advices are welcome, of course.

        Or maybe see this as a xxx lines strong wishlist entry for shared buffers.
        Separate bufferlist have its advantages too (more manageable, better overview)
        but not having the quickfix buffer in the remote session is a major drawback
        (that was the intention for the unused "Swap-Command-Context" in the script).

        Obvious problems and pecularities are:
        - I don't know how to prevent an already remotely edited buffer from
        being added to the bufferlist
        - If the remote command triggers a prompt (like ':tag'), one cannot
        enter digits
        - the remote acceptor function does not search the tab for the buffer
        but always uses the last tab, which is some sort of rummaging tab in
        each of my sessions.
        - :bufdo closes the quickfix window if it is the current window while
        executing MarkAllNonRegisteredBuffersToBeDeleted()
        - and more...


        The next answer is the script...

        --~--~---------~--~----~------------~-------~--~----~
        You received this message from the "vim_dev" maillist.
        For more information, visit http://www.vim.org/maillist.php
        -~----------~----~----~----~------~----~------~--~---
      • Neighbour
        --------------- Buffer Registration Interface --------------------------------------------------------
        Message 3 of 7 , Sep 13, 2009
        • 0 Attachment
          "--------------- Buffer Registration Interface --------------------------------------------------------
          "--------------------------------------------------------------------------------------

          " Function:
          " "RegisterAllValidBuffersForSession()"
          " Collect the basenames of all suitable buffers and save them in a file
          " that is named after the session-file with a special suffix

          " Function:
          " "MarkAllNonRegisteredBuffersToBeDeleted()"
          " The correpsonding buffer numbers are collected in a list for later deletion

          " Function:
          " "GetBufferDeletionCommandIfAppropriateAndConcatCommand( concatCommand )"
          " I best give a mapping as an example to show how it can be used.
          " :map <F8> :call MarkAllNonRegisteredBuffersToBeDeleted()<CR>:ls<CR>:<C-R>=GetBufferDeletionCommandIfAppropriateAndConcatCommand("Mks")<CR>
          " - call MarkAllNonRegisteredBuffersToBeDeleted()
          " - :ls
          " - Use this function to get something like this ":bd 28 29 | mks" on
          " the commandline and be able to inspect it
          " ... I tryed to simplify it but, I think buffer deletion is not possible
          " when pulling the expressions register.




          "--------------- Remote Instance Interaction Interface --------------------------------------------------------
          "--------------------------------------------------------------------------------------

          " Command:
          " "TurnOnForeignBufferAutoHandling()"
          " This sets the autocommand for the SwapExistsEvent. From then on every attempt to
          " open an already edited file, will record a remote command, and unless interrupted when
          " prompted, will TryToDispatchPendingRemoteCommand()

          " Command:
          " "TryToDispatchPendingRemoteCommand()"
          " Normally done automatically, but can also be done manually with this function

          " Command:
          " "ReturnToTheSourceServerOfTheLastRemoteCommand()"
          " Exactly!


          " Command:
          " "ShowRegisteredCommand()"
          " "ShowBuffersEditedByAnotherSession()"
          " "ShowLastRemoteCommandSourceServer()"
          " "ShowLastReceivedRemoteCommand()"
          " Display information only


          " Command:
          " "SetRemoteInteractionContext( contextSpecifier )"
          " The intention for a context was to clone the quickfix buffer remotely.
          " Currently it's not interpreted.


          " Command:
          " "SetPendingRemoteCommand(RemoteBuffer,RemoteCommand,Context)"
          " Needed only if you want to issue remote commands yourself.
          " RemoteCommand is :executed with "normal " prepended. Notes relating to the
          " corresponding manual entry:
          " - The opening angle-bracket of vim-keycodes eg <ESC> must be escpaped "\<ESC>"
          " - Mappings will be used. Executed without '!' (If the [!] is given, mappings will not be used.) TODO???
          " - (The display isn't updated while ":normal" is busy.) The {cmd} is aborted automatically
          " if not completed, but that does not happen until you do something else (press a key, ...)
          " - A ":" command must be completed as well.



          "---------------------------------------------------------------------------------------------------------
          "--------------- Tools ----------------------------------------------------------------
          "---------------------------------------------------------------------------------------------------------



          fun! GetBasenameOfPath( path )
          let s:lastPathSepIdx = strridx( a:path , "/" )
          if s:lastPathSepIdx == -1
          return a:path
          else
          return strpart( a:path , s:lastPathSepIdx + 1 )
          endif
          endfun


          fun! ColorMessageOutput( putItThatWay )
          echohl WarningMsg | echomsg a:putItThatWay | echohl None
          endfun

          fun! ColorMessageOutputConfirm( putItThatWay )
          echohl WarningMsg | call input( a:putItThatWay ) | echohl None
          endfun


          "---------------------------------------------------------------------------------------------------------
          "--------------- Buffer Registration Impl ----------------------------------------------------------------
          "---------------------------------------------------------------------------------------------------------


          " This is appended to 'v:this_session' to form the filename for the registered
          " buffers
          let s:BufferListFilenameExtension = ".RegisteredBuffers"


          if ! exists("g:RegisteredBuffersForSession")
          let g:RegisteredBuffersForSession = []
          endif

          if ! exists("g:ToBeDeletedBufferKludge")
          " had some problems with deletion. Maybe
          " iteration-list manipulation, or similar. Anyway, this is used to
          " aggregate the buffernumbers to be deleted by ':bd' with one call.
          let g:ToBeDeletedBufferKludge= []
          endif


          fun! s:OneBuffer_RegisterCurrentBufferForSession()

          " Skipping some buffer types
          let l:AlwaysSkippedBufferTypes = [ "nofile" , "nowrite" , "quickfix" , "help" ]
          if strlen( &buftype ) != 0
          if index( l:AlwaysSkippedBufferTypes , &buftype ) != -1
          call ColorMessageOutput( "Skipping buffer-type for session : " . expand("%") . " type:" . &buftype )
          return
          endif
          endif

          " Skipping readonly buffers
          if &readonly == 1
          call ColorMessageOutput( "Skipping readonly buffer for session : " . expand("%") )
          return
          endif

          " Truncating the path so that it is only the filename
          let l:FileNamePartOfBufferPath = GetBasenameOfPath( expand("%") )

          if strlen( l:FileNamePartOfBufferPath ) == 0
          " can happen: new buffers do not have the type "nofile"
          call ColorMessageOutput( "Empty Name bufnum:" . bufnr("%") )
          return
          endif

          " Registering
          call add( g:RegisteredBuffersForSession , l:FileNamePartOfBufferPath )
          endfun


          fun! s:GetBufferListFileName()
          if strlen( v:this_session ) == 0
          throw "no session, need a session"
          endif

          return v:this_session . s:BufferListFilenameExtension
          endfun




          fun! s:WriteBufferListToFile()
          let s:BufferListFileName = s:GetBufferListFileName()

          call writefile( g:RegisteredBuffersForSession , s:BufferListFileName )
          endfun


          fun! s:ReadBufferListFromFile()

          let s:BufferListFileName = s:GetBufferListFileName()

          if ! filereadable( s:BufferListFileName )
          throw "RegisteredBuffers filename not readable : " . s:BufferListFileName
          endif

          let g:RegisteredBuffersForSession = readfile( s:BufferListFileName )

          echo "Did restore these : "
          echo g:RegisteredBuffersForSession
          endfun




          fun! s:InsertThisBufferIntoTheToBeDeletedListIfUnmodified()

          if &modified != 0
          throw "Buffer is modified"
          endif

          call add( g:ToBeDeletedBufferKludge , bufnr("%") )
          endfun


          fun! s:MarkCurrentBufferToBeDeletedIfNotRegisteredAndUnmodified()

          let s:AlwaysKeptBufferTypes = [ "quickfix" ]
          if strlen( &buftype ) != 0

          if index( s:AlwaysKeptBufferTypes , &buftype ) != -1

          call ColorMessageOutput( "Keeping buffer-type : " . expand("%") . " type:" . &buftype )
          return
          endif
          endif

          let s:FileNamePartOfBufferPath = GetBasenameOfPath( expand("%") )

          if strlen( s:FileNamePartOfBufferPath ) == 0
          " can happen: new buffers do not have the type "nofile"
          " bufnr("%") failed once,
          call ColorMessageOutput( "Empty Name bufnum:" . expand("%") )
          call s:InsertThisBufferIntoTheToBeDeletedListIfUnmodified()
          return
          " TODO does that work correctly together with exceptions?
          " a return?
          endif

          if index( g:RegisteredBuffersForSession , s:FileNamePartOfBufferPath ) == -1
          call ColorMessageOutput( "Unregisterd Buffer bufname:" . s:FileNamePartOfBufferPath . " bufnr:" . bufnr("%") )
          call s:InsertThisBufferIntoTheToBeDeletedListIfUnmodified()
          endif
          endfun


          fun! RegisterAllValidBuffersForSession()

          " Can not be part of ':bufdo' iteration, as they are inaccessible
          call EmptyOutTheAggregationOfBuffersEditedWithinAnotherSession()

          let g:RegisteredBuffersForSession = []

          let l:CurrentBufNum = bufnr("%")
          try
          bufdo call s:OneBuffer_RegisterCurrentBufferForSession()
          finally
          if bufexists( l:CurrentBufNum )
          execute "bu " . l:CurrentBufNum
          else
          call ColorMessageOutput( "Warning : buffer disappeared while registering buffers"
          endif
          endtry

          call s:WriteBufferListToFile()

          echo "Registered these : "
          echo g:RegisteredBuffersForSession

          endfun


          fun! MarkAllNonRegisteredBuffersToBeDeleted()

          " Can not be part of ':bufdo' iteration, as they are inaccessible
          call EmptyOutTheAggregationOfBuffersEditedWithinAnotherSession()

          " I don't know why ':bufdo' closes quickfix-window if it is the current buffer...
          let l:QuickFixGetsClosedIfCurrentWorkaround = 0
          if &buftype == "quickfix"
          let l:QuickFixGetsClosedIfCurrentWorkaround = 1
          execute 0 . "tabnext"
          endif

          let g:ToBeDeletedBufferKludge = []

          call s:ReadBufferListFromFile()

          let l:CurrentBufNum = bufnr("%")
          try
          bufdo call s:MarkCurrentBufferToBeDeletedIfNotRegisteredAndUnmodified()
          finally
          if l:QuickFixGetsClosedIfCurrentWorkaround == 1
          tabl
          else
          if bufexists( l:CurrentBufNum )
          execute "bu " . l:CurrentBufNum
          endif
          endif
          endtry

          endfun


          " This can be used to get something like ":bd 1 2 3 | mks" on the commandline
          " and inspect it prior to executing
          :fun! GetBufferDeletionCommandIfAppropriateAndConcatCommand( concatCommand )

          " Causes " E523: Not allowed here: bu 4 " when executed through pulling the
          " expression-register
          "call MarkAllNonRegisteredBuffersToBeDeleted()
          "ls

          let l:concat = ""
          if strlen( a:concatCommand ) > 0
          let l:concat = "|" . a:concatCommand
          endif

          if empty( g:ToBeDeletedBufferKludge )
          return a:concatCommand
          else
          let l:BufferNumbersToBeDeleted = join(g:ToBeDeletedBufferKludge," ")
          let g:ToBeDeletedBufferKludge = []
          return "bd " . l:BufferNumbersToBeDeleted . l:concat
          endif

          :endfun



          "---------------------------------------------------------------------------------------------------------
          "--------------- Remote Instance Interaction Impl --------------------------------------------------------
          "---------------------------------------------------------------------------------------------------------



          "---------------
          " Command Buffer
          "---------------

          " Note : 'v:servername' envvar that hold the current instance's servername
          " The command's data isjust a list with predefined indizes:
          let s:BufferIdx = 0
          let s:CommandIdx = 1
          let s:ContextIdx = 2
          let s:RemoteAcceptorFunName = "AcceptRemoteCommandFromClient"
          let s:UnhandledRetval = "unhandled"
          let s:HandledRetval = "successfullyHandled"

          if ! exists("s:RemoteInteractionCommand")
          let s:RemoteInteractionCommand = []
          endif


          if ! exists("s:SourceServerOfLastRemoteCommand")
          let s:SourceServerOfLastRemoteCommand = ""
          endif

          if ! exists("s:LastReceivedRemoteCommand")
          let s:LastReceivedRemoteCommand = ""
          endif

          if ! exists("s:RemoteInteractionContextSpecifier")
          let s:RemoteInteractionContextSpecifier = ""
          endif

          if ! exists('s:AggregationOfBuffersEditedWithinAnotherSession')
          let s:AggregationOfBuffersEditedWithinAnotherSession = {}
          endif

          " Yet unused, but for future use, clients would set the context with this
          " function prior to executing a command that could reveal buffers within
          " another session (make, tags, ...)
          fun! SetRemoteInteractionContext( contextSpecifier )
          let s:RemoteInteractionContextSpecifier = a:contextSpecifier
          endfun

          "--------------------------------------------------------------------------------------
          " Accept Commands from a client
          "--------------------------------------------------------------------------------------

          fun! {s:RemoteAcceptorFunName}(SourceServer,WantedBuffer,WantedCommand,ContextOfCommand)

          " Check if this session has the requested buffer.
          let l:RelevantBuffer = bufnr( a:WantedBuffer )
          if l:RelevantBuffer == -1
          return s:UnhandledRetval
          endif

          " inform
          call ColorMessageOutput( printf( "Accepting a remote command. SourceServer(%s) WantedBuffer(%s) WantedCommand(%s) Context(%s)", a:SourceServer , a:WantedBuffer , a:WantedCommand , a:Context )

          " record the source server and the command
          let s:SourceServerOfLastRemoteCommand = a:SourceServer
          let s:LastReceivedRemoteCommand = printf( "SourceServer(%s) Buffer(%s) Command(%s) Context(%s)" , a:SourceServer , a:WantedBuffer , strtrans( a:WantedCommand ) , a:ContextOfCommand )

          " this is an utility to jump to/from the last tab page which is kind of a rummaging tab.
          " MAILTODO : remove this.
          call SetLastTabSwitchTabPageNumber()

          " go to last tab, top left-window , visualize the buffer, and present it
          tabl
          wincmd t
          execute ":buffer " . l:RelevantBuffer
          call foreground()

          " Assert we are in the right buffer
          if bufnr("%") != bufnr( l:RelevantBuffer )
          throw "Assertion of being in the right buffer immediately before command execution failed"
          endif

          " do what must be done
          call ColorMessageOutput( "executing '" . strtrans(a:WantedCommand). "'" )
          call ColorMessageOutput( "strlen is (want to know if special chars are converted) : " . strlen(a:WantedCommand) )

          let v:errormsg = ""

          " As it appears ':normal xyz' executed in insert mode (from remote) does not
          " insert these chars but executes them in normal mode (hey, now I get the name, I though it would mean 'unimpressed').
          " It seems that you can't even leave insert mode by prepending "\<C-\>\<C-N>"
          " Anyway, the former renders the latter unnecessary.

          " double escape would not hurt, would it? It ensures the command is terminated.
          " Necessary for example for the ':ta' swapcommands

          execute ":normal " . expand(a:WantedCommand) . "\e"

          if strlen( v:errormsg ) != 0
          echo "(TODO: duplicated output of errormsg?)" . v:errormsg
          endif

          return s:HandledRetval
          endfun

          "--------------------------------------------------------------------------------------
          " Server Focus
          "--------------------------------------------------------------------------------------

          fun! ReturnToTheSourceServerOfTheLastRemoteCommand()

          if strlen(s:SourceServerOfLastRemoteCommand) == 0
          call ColorMessageOutput( "Cannot return, no source server recorded" )
          return
          endif

          try
          call remote_expr( s:SourceServerOfLastRemoteCommand , "foreground()" )
          catch /E241/
          call ColorMessageOutput( s:SourceServerOfLastRemoteCommand . ": no such server. Giving focus to that server failed." )
          endtry

          endfun

          "--------------------------------------------------------------------------------------
          " Sending a Command Request
          "--------------------------------------------------------------------------------------

          fun! GimmeListOfTheServersWithoutCurrentServerAsAnActualList()

          let l:WholeList = split( serverlist() )

          let l:ThisServersIndex = index( l:WholeList , v:servername )
          if ( l:ThisServersIndex == -1 )
          throw "serverlist without v:servername - unexpected"
          endif

          call remove( l:WholeList , l:ThisServersIndex )

          if index( l:WholeList , v:servername ) != -1
          throw "Failed to remove v:servername from serverlist() - unexpected, should really work"
          endif

          return l:WholeList
          endfun


          " TODO ELIGIBLE ELLIGIBLE?
          fun! GetPendingRemoteCommandAsAnExpressionEligibleForSending()

          " empty return-string means no command pending.

          if empty( s:RemoteInteractionCommand ) == 1
          return ""
          endif

          if len( s:RemoteInteractionCommand ) != 3
          throw "Invalid len(s:RemoteInteractionCommand) : " . string( s:RemoteInteractionCommand )
          endif

          let l:BufferBase = GetBasenameOfPath( s:RemoteInteractionCommand[ s:BufferIdx ] )
          let l:RemCommand = s:RemoteInteractionCommand[ s:CommandIdx ]
          let l:Context = s:RemoteInteractionCommand[ s:ContextIdx ]

          let l:RequestedRemoteCommand = printf( "%s('%s','%s','%s','%s')" , s:RemoteAcceptorFunName , v:servername , l:BufferBase , l:RemCommand , l:Context )

          return l:RequestedRemoteCommand

          endfun


          fun! SetPendingRemoteCommand(RemoteBuffer,RemoteCommand,Context)
          let s:RemoteInteractionCommand = [ a:RemoteBuffer , a:RemoteCommand , a:Context]
          endfun


          fun! TryToDispatchPendingRemoteCommand()

          let l:RemoteCommandToBeDispatched = GetPendingRemoteCommandAsAnExpressionEligibleForSending()

          if strlen( l:RemoteCommandToBeDispatched ) == 0
          call ColorMessageOutput( "No remote command pending" )
          return
          endif

          call ColorMessageOutput( "Trying to dispatch this : " . strtrans( l:RemoteCommandToBeDispatched ) )

          let l:HasCommandBeenHandled = ""
          for l:CandidateServer in GimmeListOfTheServersWithoutCurrentServerAsAnActualList()

          try
          let l:HasCommandBeenHandled = remote_expr( l:CandidateServer , l:RemoteCommandToBeDispatched )

          if l:HasCommandBeenHandled == s:HandledRetval

          call ColorMessageOutput( printf( "server(%s) accepted the command" , l:CandidateServer ) )
          break
          endif

          catch /E241/
          throw "Impossible? A server from the serverlist() disappeared"
          endtry
          endfor

          if l:HasCommandBeenHandled != s:HandledRetval
          call ColorMessageOutput( "No server accepted the command" )
          endif

          endfun


          "--------------------------------------------------------------------------------------
          " SwapExistsEvent handling, and recording/deleting the buffers which are added but not loaded
          "--------------------------------------------------------------------------------------

          fun! EmptyOutTheAggregationOfBuffersEditedWithinAnotherSession()

          for l:BuffernameToDelete in keys(s:AggregationOfBuffersEditedWithinAnotherSession)

          let l:ToBeDeletedBufNumber = bufnr( l:BuffernameToDelete )

          if l:ToBeDeletedBufNumber == -1

          call ColorMessageOutput( "Buffer does not exist : " . l:BuffernameToDelete )
          continue

          elseif bufloaded( l:ToBeDeletedBufNumber )

          call ColorMessageOutput( "Buffer is now loaded. keeping it : " . l:BuffernameToDelete )

          elseif ! buflisted( l:ToBeDeletedBufNumber )

          call ColorMessageOutput( "Buffer is now missing - unexpected: " . l:BuffernameToDelete )

          else
          " is not loaded can't be modified, will produce error otherwise (no '!' after 'bd')
          call ColorMessageOutput( "Deleting foreign buffer : " . l:BuffernameToDelete )
          execute( "bd " . l:ToBeDeletedBufNumber )
          endif
          endfor

          let s:AggregationOfBuffersEditedWithinAnotherSession = {}
          endfun


          fun! HandleSwapExistsEventAndRecordRemoteCommand( BufferBeingEditedAlready )

          let l:BufferBeingEditedAlreadyBasename = GetBasenameOfPath( a:BufferBeingEditedAlready )

          " Don't know how to prevent the remote buffers from being recorded in the
          " local bufferlist Can't delete them right here (probably sandbox)
          let s:AggregationOfBuffersEditedWithinAnotherSession[ BufferBeingEditedAlreadyBasename ] = 0

          call SetPendingRemoteCommand( BufferBeingEditedAlreadyBasename , v:swapcommand , s:RemoteInteractionContextSpecifier )

          " a-bort (alternative would be q-uit). Both add the buffer to the bufferlist.
          let v:swapchoice = 'a'

          call ColorMessageOutputConfirm( printf("Buffer edited by another session. Recorded remote command : buffer(%s) command(%s). Going to dispatch..." , BufferBeingEditedAlreadyBasename , strtrans(v:swapcommand) ) )

          call TryToDispatchPendingRemoteCommand()
          endfun


          fun! TurnOnForeignBufferAutoHandling()
          au! SwapExists * call HandleSwapExistsEventAndRecordRemoteCommand( expand('<afile>') )
          endfun


          "--------------------------------------------------------------------------------------
          " Info
          "--------------------------------------------------------------------------------------

          fun! ShowRegisteredCommand()
          echo "Remote Command is (strtrans converted): " . strtrans( GetPendingRemoteCommandAsAnExpressionEligibleForSending() )
          endfun

          fun! ShowLastRemoteCommandSourceServer()
          echo "Last Remote Command Source Server is : " . s:SourceServerOfLastRemoteCommand
          endfun

          fun! ShowLastReceivedRemoteCommand()
          echo "Last Received Remote Command is : " . s:LastReceivedRemoteCommand
          endfun

          fun! ShowBuffersEditedByAnotherSession()
          echo "Buffers edited by another session : " . string(keys(s:AggregationOfBuffersEditedWithinAnotherSession))
          endfun


          --~--~---------~--~----~------------~-------~--~----~
          You received this message from the "vim_dev" maillist.
          For more information, visit http://www.vim.org/maillist.php
          -~----------~----~----~----~------~----~------~--~---
        • Neighbour
          The same patch applyable. ... +++ b/src/quickfix.c @@ -1519,6 +1519,20 @@ qf_jump(qi, dir, errornr, forceit) } } + /* + * Set the v:swapcommand to have
          Message 4 of 7 , Sep 13, 2009
          • 0 Attachment
            The same patch applyable.

            --- a/src/quickfix.c
            +++ b/src/quickfix.c
            @@ -1519,6 +1519,20 @@ qf_jump(qi, dir, errornr, forceit)
            }
            }

            + /*
            + * Set the v:swapcommand to have the possibility to direct a remote vim-server
            + * that owns the buffer, to the right location within the file
            + */
            +
            + if ( qf_ptr ) {
            + const int long_enough_to_hold_two_numbers = 100 ;
            + char_u swap_command_buffer[ long_enough_to_hold_two_numbers ] ;
            +
            + snprintf( swap_command_buffer , long_enough_to_hold_two_numbers , "%ldG%i|" , qf_ptr->qf_lnum , qf_ptr->qf_col ) ;
            +
            + set_vim_var_string(VV_SWAPCOMMAND, swap_command_buffer , -1);
            + }
            +
            #ifdef FEAT_WINDOWS
            qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
            if (qf_win_pos_update(qi, old_qf_index))

            --~--~---------~--~----~------------~-------~--~----~
            You received this message from the "vim_dev" maillist.
            For more information, visit http://www.vim.org/maillist.php
            -~----------~----~----~----~------~----~------~--~---
          • Bram Moolenaar
            ... I won t look at patches that add new code without knowing your full name. It s a copyright thing. Politeness too. -- Married is a three ring circus:
            Message 5 of 7 , Sep 13, 2009
            • 0 Attachment
              Neighbour wrote:

              > Currently a quickfix jump that triggers SwapExistsEvent always has the
              > v:swapcommand '1G'. The following patch sets it to the jump destination.

              I won't look at patches that add new code without knowing your full
              name. It's a copyright thing. Politeness too.

              --
              Married is a three ring circus:
              First comes the engagement ring.
              Then comes the wedding ring.
              Then comes the suffering.

              /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
              /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
              \\\ download, build and distribute -- http://www.A-A-P.org ///
              \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

              --~--~---------~--~----~------------~-------~--~----~
              You received this message from the "vim_dev" maillist.
              For more information, visit http://www.vim.org/maillist.php
              -~----------~----~----~----~------~----~------~--~---
            • Neighbour
              ... Awww, of course. It ended up being this address because failure to be able post to vim.org (and not to googlegroups.com) had me wildly testing.
              Message 6 of 7 , Sep 15, 2009
              • 0 Attachment
                On Sunday 13 September 2009 20:56:17 Bram Moolenaar wrote:

                > I won't look at patches that add new code without knowing your full
                > name. It's a copyright thing. Politeness too.

                Awww, of course. It ended up being this address because failure to be able post to vim.org (and
                not to googlegroups.com) had me wildly testing. (http://www.vim.org/maillist.php).
                I ridiculed myself with this (now defunct) address in the past, and I can't make the link that obvious.

                It's not that important anyway, but if it helps, "I hereby give up any rights concerning this thread".


                --~--~---------~--~----~------------~-------~--~----~
                You received this message from the "vim_dev" maillist.
                For more information, visit http://www.vim.org/maillist.php
                -~----------~----~----~----~------~----~------~--~---
              • Bram Moolenaar
                ... I still don t see your full name. -- Marriage is when a man and woman become as one; the trouble starts when they try to decide which one /// Bram
                Message 7 of 7 , Sep 15, 2009
                • 0 Attachment
                  > On Sunday 13 September 2009 20:56:17 Bram Moolenaar wrote:
                  >
                  > > I won't look at patches that add new code without knowing your full
                  > > name. It's a copyright thing. Politeness too.
                  >
                  > Awww, of course. It ended up being this address because failure to be able post to vim.org (and
                  > not to googlegroups.com) had me wildly testing. (http://www.vim.org/maillist.php).
                  > I ridiculed myself with this (now defunct) address in the past, and I can't make the link that obvious.
                  >
                  > It's not that important anyway, but if it helps, "I hereby give up any rights concerning this thread".

                  I still don't see your full name.

                  --
                  "Marriage is when a man and woman become as one; the trouble starts
                  when they try to decide which one"

                  /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                  /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                  \\\ download, build and distribute -- http://www.A-A-P.org ///
                  \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

                  --~--~---------~--~----~------------~-------~--~----~
                  You received this message from the "vim_dev" maillist.
                  For more information, visit http://www.vim.org/maillist.php
                  -~----------~----~----~----~------~----~------~--~---
                Your message has been successfully submitted and would be delivered to recipients shortly.