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 Omnifunc(findstart, base): vimsupport.SetCurrentLineAndColumn(0, 0) if findstart: return 5 return ['length']
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)