def _HandleFixitResponse(self): if not len(self._response['fixits']): vimsupport.PostVimMessage('No fixits found for current line', warning=False) else: try: fixit_index = 0 # When there are multiple fixit suggestions, present them as a list to # the user hand have her choose which one to apply. fixits = self._response['fixits'] if len(fixits) > 1: fixit_index = vimsupport.SelectFromList( "Multiple FixIt suggestions are available at this location. " "Which one would you like to apply?", [fixit['text'] for fixit in fixits]) chosen_fixit = fixits[fixit_index] if chosen_fixit['resolve']: self._request_data.update({'fixit': chosen_fixit}) response = self.PostDataToHandler(self._request_data, 'resolve_fixit') fixits = response['fixits'] assert len(fixits) == 1 chosen_fixit = fixits[0] vimsupport.ReplaceChunks(chosen_fixit['chunks'], silent=self._command == 'Format') except RuntimeError as e: vimsupport.PostVimMessage(str(e))
def _HandleFixitResponse(self): if not len(self._response['fixits']): vimsupport.PostVimMessage('No fixits found for current line', warning=False) else: try: fixit_index = 0 # If there is more than one fixit, we need to ask the user which one # should be applied. # # If there's only one, triggered by the FixIt subcommand (as opposed to # `RefactorRename`, for example) and whose `kind` is not `quicfix`, we # still need to as the user for confirmation. fixits = self._response['fixits'] if (len(fixits) > 1 or (len(fixits) == 1 and self._command == 'FixIt' and fixits[0].get('kind') != 'quickfix')): fixit_index = vimsupport.SelectFromList( "FixIt suggestion(s) available at this location. " "Which one would you like to apply?", [fixit['text'] for fixit in fixits]) chosen_fixit = fixits[fixit_index] if chosen_fixit['resolve']: self._request_data.update({'fixit': chosen_fixit}) response = self.PostDataToHandler(self._request_data, 'resolve_fixit') fixits = response['fixits'] assert len(fixits) == 1 chosen_fixit = fixits[0] vimsupport.ReplaceChunks(chosen_fixit['chunks'], silent=self._command == 'Format') except RuntimeError as e: vimsupport.PostVimMessage(str(e))
def ReplaceChunks_SingleFile_Open_test(vim_command, vim_eval, echo_text_vim_width, open_filename, buffer_is_visible, get_buffer_number_for_filename): chunks = [_BuildChunk(1, 1, 2, 1, 'replacement', 'single_file')] result_buffer = MockBuffer([ 'line1', 'line2', 'line3', ], 'single_file', 1) with patch('vim.buffers', [None, result_buffer, None]): vimsupport.ReplaceChunks(chunks) # Ensure that we applied the replacement correctly eq_(result_buffer.lines, [ 'replacementline2', 'line3', ]) # GetBufferNumberForFilename is called twice: # - once to the check if we would require opening the file (so that we can # raise a warning) # - once whilst applying the changes get_buffer_number_for_filename.assert_has_exact_calls([ call('single_file', False), call('single_file', False), ]) # BufferIsVisible is called twice for the same reasons as above buffer_is_visible.assert_has_exact_calls([ call(1), call(1), ]) # we don't attempt to open any files open_filename.assert_not_called() # But we do set the quickfix list vim_eval.assert_has_exact_calls([ call('setqflist( {0} )'.format( json.dumps([{ 'bufnr': 1, 'filename': 'single_file', 'lnum': 1, 'col': 1, 'text': 'replacement', 'type': 'F' }]))), ]) vim_command.assert_has_calls([call('copen 1')]) # And it is ReplaceChunks that prints the message showing the number of # changes echo_text_vim_width.assert_has_exact_calls([ call('Applied 1 changes'), ])
def _HandleFixitResponse(self): if not len(self._response['fixits']): vimsupport.EchoText("No fixits found for current line") else: chunks = self._response['fixits'][0]['chunks'] try: vimsupport.ReplaceChunks(chunks) except RuntimeError as e: vimsupport.PostMultiLineNotice(e.message)
def _OnCompleteDone_FixIt(self, completion_extra_data): fixits = completion_extra_data.get('fixits', []) for fixit in fixits: cursor_position = 'end' if fixit.get('is_completion', False) else None vimsupport.ReplaceChunks(fixit['chunks'], silent=True, cursor_position=cursor_position)
def ReplaceChunks_User_Declines_To_Open_File_test( vim_command, vim_eval, confirm, echo_text_vim_width, open_filename, buffer_is_visible, get_buffer_number_for_filename ): # Same as above, except the user selects Cancel when asked if they should # allow us to open lots of (ahem, 1) file. chunks = [ _BuildChunk( 1, 1, 2, 1, 'replacement', 'single_file' ) ] result_buffer = MockBuffer( [ 'line1', 'line2', 'line3', ], 'single_file', 1 ) with patch( 'vim.buffers', [ None, result_buffer, None ] ): vimsupport.ReplaceChunks( chunks ) # We checked if it was OK to open the file confirm.assert_has_exact_calls( [ call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) ) ] ) # Ensure that buffer is not changed eq_( result_buffer.GetLines(), [ 'line1', 'line2', 'line3', ] ) # GetBufferNumberForFilename is called once. The return values are set in # the @patch call above: # - once to the check if we would require opening the file (so that we can # raise a warning) (-1 return) get_buffer_number_for_filename.assert_has_exact_calls( [ call( 'single_file', False ), ] ) # BufferIsVisible is called once for the above file, which wasn't visible. buffer_is_visible.assert_has_exact_calls( [ call( -1 ), ] ) # We don't attempt to open any files or update any quickfix list or anything # like that open_filename.assert_not_called() vim_eval.assert_not_called() vim_command.assert_not_called() echo_text_vim_width.assert_not_called()
def _OnCompleteDone_Java(self): completions = self._GetCompletionsUserMayHaveCompleted() fixit_completions = [_GetFixItCompletion(c) for c in completions] fixit_completions = [f for f in fixit_completions if f] if not fixit_completions: return # If we have user_data in completions (8.0.1493 or later), then we would # only ever return max. 1 completion here. However, if we had to guess, it # is possible that we matched multiple completion items (e.g. for overloads, # or similar classes in multiple packages). In any case, rather than # prompting the user and disturbing her workflow, we just apply the first # one. This might be wrong, but the solution is to use a (very) new version # of Vim which supports user_data on completion items fixit_completion = fixit_completions[0] for fixit in fixit_completion: vimsupport.ReplaceChunks(fixit['chunks'], silent=True)
def _HandleFixitResponse(self): if not len(self._response['fixits']): vimsupport.EchoText("No fixits found for current line") else: try: fixit_index = 0 # When there are multiple fixit suggestions, present them as a list to # the user hand have her choose which one to apply. if len(self._response['fixits']) > 1: fixit_index = vimsupport.SelectFromList( "Multiple FixIt suggestions are available at this location. " "Which one would you like to apply?", [fixit['text'] for fixit in self._response['fixits']]) vimsupport.ReplaceChunks( self._response['fixits'][fixit_index]['chunks']) except RuntimeError as e: vimsupport.PostMultiLineNotice(str(e))
def ReplaceChunks_SingleFile_NotOpen_test( vim_command, vim_eval, confirm, echo_text_vim_width, open_filename, buffer_is_visible, get_buffer_number_for_filename ): chunks = [ _BuildChunk( 1, 1, 2, 1, 'replacement', 'single_file' ) ] result_buffer = MockBuffer( [ 'line1', 'line2', 'line3', ], 'single_file', 1 ) with patch( 'vim.buffers', [ None, result_buffer, None ] ): vimsupport.ReplaceChunks( chunks ) # We checked if it was OK to open the file confirm.assert_has_exact_calls( [ call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) ) ] ) # Ensure that we applied the replacement correctly eq_( result_buffer.GetLines(), [ 'replacementline2', 'line3', ] ) # GetBufferNumberForFilename is called 3 times. The return values are set in # the @patch call above: # - once to the check if we would require opening the file (so that we can # raise a warning) (-1 return) # - once whilst applying the changes (-1 return) # - finally after calling OpenFilename (1 return) get_buffer_number_for_filename.assert_has_exact_calls( [ call( 'single_file', False ), call( 'single_file', False ), call( 'single_file', False ), ] ) # BufferIsVisible is called 3 times for the same reasons as above, with the # return of each one buffer_is_visible.assert_has_exact_calls( [ call( -1 ), call( -1 ), call( 1 ), ] ) # We open 'single_file' as expected. open_filename.assert_called_with( 'single_file', { 'focus': True, 'fix': True, 'size': 10 } ) # And close it again, then show the preview window (note, we don't check exact # calls because there are other calls which are checked elsewhere) vim_command.assert_has_calls( [ call( 'lclose' ), call( 'hide' ), call( 'copen 1' ), ] ) # And update the quickfix list vim_eval.assert_has_exact_calls( [ call( '&previewheight' ), call( 'setqflist( {0} )'.format( json.dumps( [ { 'bufnr': 1, 'filename': 'single_file', 'lnum': 1, 'col': 1, 'text': 'replacement', 'type': 'F' } ] ) ) ), ] ) # And it is ReplaceChunks that prints the message showing the number of # changes echo_text_vim_width.assert_has_exact_calls( [ call( 'Applied 1 changes' ), ] )
def ReplaceChunks_MultiFile_Open_test( vim_command, vim_eval, confirm, echo_text_vim_width, open_filename, buffer_is_visible, get_buffer_number_for_filename ): # Chunks are split across 2 files, one is already open, one isn't chunks = [ _BuildChunk( 1, 1, 2, 1, 'first_file_replacement ', '1_first_file' ), _BuildChunk( 2, 1, 2, 1, 'second_file_replacement ', '2_another_file' ), ] first_file = MockBuffer( [ 'line1', 'line2', 'line3', ], '1_first_file', 22 ) another_file = MockBuffer( [ 'another line1', 'ACME line2', ], '2_another_file', 19 ) vim_buffers = [ None ] * 23 vim_buffers[ 22 ] = first_file vim_buffers[ 19 ] = another_file with patch( 'vim.buffers', vim_buffers ): vimsupport.ReplaceChunks( chunks ) # We checked for the right file names get_buffer_number_for_filename.assert_has_exact_calls( [ call( '1_first_file', False ), call( '2_another_file', False ), call( '1_first_file', False ), call( '2_another_file', False ), call( '2_another_file', False ), ] ) # We checked if it was OK to open the file confirm.assert_has_exact_calls( [ call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) ) ] ) # Ensure that buffers are updated eq_( another_file.GetLines(), [ 'another line1', 'second_file_replacement ACME line2', ] ) eq_( first_file.GetLines(), [ 'first_file_replacement line2', 'line3', ] ) # We open '2_another_file' as expected. open_filename.assert_called_with( '2_another_file', { 'focus': True, 'fix': True, 'size': 10 } ) # And close it again, then show the preview window (note, we don't check exact # calls because there are other calls which are checked elsewhere) vim_command.assert_has_calls( [ call( 'lclose' ), call( 'hide' ), call( 'copen 2' ), ] ) # And update the quickfix list with each entry vim_eval.assert_has_exact_calls( [ call( '&previewheight' ), call( 'setqflist( {0} )'.format( json.dumps( [ { 'bufnr': 22, 'filename': '1_first_file', 'lnum': 1, 'col': 1, 'text': 'first_file_replacement ', 'type': 'F' }, { 'bufnr': 19, 'filename': '2_another_file', 'lnum': 2, 'col': 1, 'text': 'second_file_replacement ', 'type': 'F' } ] ) ) ), ] ) # And it is ReplaceChunks that prints the message showing the number of # changes echo_text_vim_width.assert_has_exact_calls( [ call( 'Applied 2 changes' ), ] )