def OpenFilename_test( vim_current, vim_command ): # Options used to open a logfile options = { 'size': vimsupport.GetIntValue( '&previewheight' ), 'fix': True, 'watch': True, 'position': 'end' } vimsupport.OpenFilename( __file__, options ) vim_command.assert_has_exact_calls( [ call( '12split {0}'.format( __file__ ) ), call( "exec " "'au BufEnter <buffer> :silent! checktime {0}'".format( __file__ ) ), call( 'silent! normal G zz' ), call( 'silent! wincmd p' ) ] ) vim_current.buffer.options.__setitem__.assert_has_exact_calls( [ call( 'autoread', True ), ] ) vim_current.window.options.__setitem__.assert_has_exact_calls( [ call( 'winfixheight', True ) ] )
def _GetCommandRequestArguments( self, arguments, has_range, start_line, end_line ): extra_data = { 'options': { 'tab_size': vimsupport.GetIntValue( 'shiftwidth()' ), 'insert_spaces': vimsupport.GetBoolValue( '&expandtab' ) } } final_arguments = [] for argument in arguments: if argument.startswith( 'ft=' ): extra_data[ 'completer_target' ] = argument[ 3: ] continue elif argument.startswith( '--bufnr=' ): extra_data[ 'bufnr' ] = int( argument[ len( '--bufnr=' ): ] ) continue final_arguments.append( argument ) if has_range: extra_data.update( vimsupport.BuildRange( start_line, end_line ) ) self._AddExtraConfDataIfNeeded( extra_data ) return final_arguments, extra_data
def SendCommandRequest( self, arguments, modifiers, has_range, start_line, end_line ): final_arguments = [] for argument in arguments: # The ft= option which specifies the completer when running a command is # ignored because it has not been working for a long time. The option is # still parsed to not break users that rely on it. if argument.startswith( 'ft=' ): continue final_arguments.append( argument ) extra_data = { 'options': { 'tab_size': vimsupport.GetIntValue( 'shiftwidth()' ), 'insert_spaces': vimsupport.GetBoolValue( '&expandtab' ) } } if has_range: extra_data.update( vimsupport.BuildRange( start_line, end_line ) ) self._AddExtraConfDataIfNeeded( extra_data ) return SendCommandRequest( final_arguments, modifiers, self._user_options[ 'goto_buffer_command' ], extra_data )
def SendCommandRequest(self, arguments, completer, modifiers, has_range, start_line, end_line): extra_data = { 'options': { 'tab_size': vimsupport.GetIntValue('shiftwidth()'), 'insert_spaces': vimsupport.GetBoolValue('&expandtab') } } if has_range: extra_data.update(vimsupport.BuildRange(start_line, end_line)) self._AddExtraConfDataIfNeeded(extra_data) return SendCommandRequest(arguments, completer, modifiers, extra_data)
def ComputeCandidatesInner(self, request_data): if not self._omnifunc: return [] # Calling directly the omnifunc may move the cursor position. This is the # case with the default Vim omnifunc for C-family languages # (ccomplete#Complete) which calls searchdecl to find a declaration. This # function is supposed to move the cursor to the found declaration but it # doesn't when called through the omni completion mapping (CTRL-X CTRL-O). # So, we restore the cursor position after the omnifunc calls. line, column = vimsupport.CurrentLineAndColumn() try: start_column = vimsupport.GetIntValue(self._omnifunc + '(1,"")') if start_column < 0: # FIXME: Technically, if the returned value is -1 we should raise an # error. return [] # Use the start column calculated by the omnifunc, rather than our own # interpretation. This is important for certain languages where our # identifier detection is either incorrect or not compatible with the # behaviour of the omnifunc. Note: do this before calling the omnifunc # because it affects the value returned by 'query'. request_data['start_column'] = start_column + 1 # Vim internally moves the cursor to the start column before calling again # the omnifunc. Some omnifuncs like the one defined by the # LanguageClient-neovim plugin depend on this behavior to compute the list # of candidates. vimsupport.SetCurrentLineAndColumn(line, start_column) omnifunc_call = [ self._omnifunc, "(0,'", vimsupport.EscapeForVim(request_data['query']), "')" ] items = vim.eval(''.join(omnifunc_call)) if isinstance(items, dict) and 'words' in items: items = items['words'] if not hasattr(items, '__iter__'): raise TypeError(OMNIFUNC_NOT_LIST) return list(filter(bool, items)) except (TypeError, ValueError, vim.error) as error: vimsupport.PostVimMessage(OMNIFUNC_RETURNED_BAD_VALUE + ' ' + str(error)) return [] finally: vimsupport.SetCurrentLineAndColumn(line, column)
def _OpenLogfile(self, logfile): # Open log files in a horizontal window with the same behavior as the # preview window (same height and winfixheight enabled). Automatically # watch for changes. Set the cursor position at the end of the file. options = { 'size': vimsupport.GetIntValue('&previewheight'), 'fix': True, 'focus': False, 'watch': True, 'position': 'end' } vimsupport.OpenFilename(logfile, options)
def Initialise(): if vimsupport.VimIsNeovim(): return props = GetTextPropertyTypes() if 'YCM_HL_UNKNOWN' not in props: AddTextPropertyType( 'YCM_HL_UNKNOWN', highlight = 'WarningMsg' ) for token_type, group in HIGHLIGHT_GROUP.items(): prop = f'YCM_HL_{ token_type }' if prop not in props and vimsupport.GetIntValue( f"hlexists( '{ vimsupport.EscapeForVim( group ) }' )" ): AddTextPropertyType( prop, highlight = group )
def _OpenLogs(self, stdout=True, stderr=True): # Open log files in a horizontal window with the same behavior as the # preview window (same height and winfixheight enabled). Automatically # watch for changes. Set the cursor position at the end of the file. options = { 'size': vimsupport.GetIntValue('&previewheight'), 'fix': True, 'watch': True, 'position': 'end' } if stdout: vimsupport.OpenFilename(self._server_stdout, options) if stderr: vimsupport.OpenFilename(self._server_stderr, options)
def ShowDetailedDiagnostic( self, message_in_popup ): detailed_diagnostic = BaseRequest().PostDataToHandler( BuildRequestData(), 'detailed_diagnostic' ) if detailed_diagnostic and 'message' in detailed_diagnostic: message = detailed_diagnostic[ 'message' ] if message_in_popup and vimsupport.VimSupportsPopupWindows(): window = vim.current.window buffer_number = vimsupport.GetCurrentBufferNumber() diags_on_this_line = self._buffers[ buffer_number ].DiagnosticsForLine( window.cursor[ 0 ] ) lines = message.split( '\n' ) available_columns = vimsupport.GetIntValue( '&columns' ) col = window.cursor[ 1 ] + 1 if col > available_columns - 2: # -2 accounts for padding. col = 0 options = { 'col': col, 'padding': [ 0, 1, 0, 1 ], 'maxwidth': available_columns, 'close': 'click', 'fixed': 0, 'highlight': 'ErrorMsg', 'border': [ 1, 1, 1, 1 ], # Close when moving cursor 'moved': 'expr', } popup_func = 'popup_atcursor' for diag in diags_on_this_line: if message == diag[ 'text' ]: popup_func = 'popup_create' prop = vimsupport.GetTextPropertyForDiag( buffer_number, window.cursor[ 0 ], diag ) options.update( { 'textpropid': prop[ 'id' ], 'textprop': prop[ 'type' ], } ) options.pop( 'col' ) vim.eval( f'{ popup_func }( { lines }, { options } )' ) else: vimsupport.PostVimMessage( message, warning = False )
def Initialise(): if not vimsupport.VimSupportsVirtualText(): return False props = tp.GetTextPropertyTypes() if 'YCM_INLAY_UNKNOWN' not in props: tp.AddTextPropertyType('YCM_INLAY_UNKNOWN', highlight='YcmInlayHint', start_incl=1) if 'YCM_INLAY_PADDING' not in props: tp.AddTextPropertyType('YCM_INLAY_PADDING', highlight='YcmInvisible', start_incl=1) for token_type, group in HIGHLIGHT_GROUP.items(): prop = f'YCM_INLAY_{ token_type }' if prop not in props and vimsupport.GetIntValue( f"hlexists( '{ vimsupport.EscapeForVim( group ) }' )"): tp.AddTextPropertyType(prop, highlight=group, start_incl=1) return True
def ComputeCandidatesInner(self, request_data): if not self._omnifunc: return [] # Calling directly the omnifunc may move the cursor position. This is the # case with the default Vim omnifunc for C-family languages # (ccomplete#Complete) which calls searchdecl to find a declaration. This # function is supposed to move the cursor to the found declaration but it # doesn't when called through the omni completion mapping (CTRL-X CTRL-O). # So, we restore the cursor position after the omnifunc calls. line, column = vimsupport.CurrentLineAndColumn() try: start_column = vimsupport.GetIntValue(self._omnifunc + '(1,"")') # Vim only stops completion if the value returned by the omnifunc is -3 or # -2. In other cases, if the value is negative or greater than the current # column, the start column is set to the current column; otherwise, the # value is used as the start column. if start_column in (-3, -2): return [] if start_column < 0 or start_column > column: start_column = column # Use the start column calculated by the omnifunc, rather than our own # interpretation. This is important for certain languages where our # identifier detection is either incorrect or not compatible with the # behaviour of the omnifunc. Note: do this before calling the omnifunc # because it affects the value returned by 'query'. request_data['start_column'] = start_column + 1 # Vim internally moves the cursor to the start column before calling again # the omnifunc. Some omnifuncs like the one defined by the # LanguageClient-neovim plugin depend on this behavior to compute the list # of candidates. vimsupport.SetCurrentLineAndColumn(line, start_column) omnifunc_call = [ self._omnifunc, "(0,'", vimsupport.EscapeForVim(request_data['query']), "')" ] items = vim.eval(''.join(omnifunc_call)) if isinstance(items, dict) and 'words' in items: items = items['words'] if not hasattr(items, '__iter__'): raise TypeError(OMNIFUNC_NOT_LIST) # Vim allows each item of the list to be either a string or a dictionary # but ycmd only supports lists where items are all strings or all # dictionaries. Convert all strings into dictionaries. for index, item in enumerate(items): if not isinstance(item, dict): items[index] = {'word': item} return items except (TypeError, ValueError, vim.error) as error: vimsupport.PostVimMessage(OMNIFUNC_RETURNED_BAD_VALUE + ' ' + str(error)) return [] finally: vimsupport.SetCurrentLineAndColumn(line, column)