diff --git a/python/ycm/completers/general/filename_completer.py b/python/ycm/completers/general/filename_completer.py index 350f0890..add03e1b 100644 --- a/python/ycm/completers/general/filename_completer.py +++ b/python/ycm/completers/general/filename_completer.py @@ -18,6 +18,7 @@ import os import re +from collections import defaultdict from ycm.completers.completer import Completer from ycm.completers.cpp.clang_completer import InCFamilyFile @@ -25,6 +26,8 @@ from ycm.completers.cpp.flags import Flags from ycm.utils import ToUtf8IfNeeded from ycm.server import responses +EXTRA_INFO_MAP = { 1 : '[File]', 2 : '[Dir]', 3 : '[File&Dir]' } + class FilenameCompleter( Completer ): """ General completer that provides filename and filepath completions. @@ -137,18 +140,20 @@ def _GetPathsStandardCase( path_dir, use_working_dir, filepath ): def _GenerateCandidatesForPaths( absolute_paths ): - seen_basenames = set() - completion_dicts = [] - + extra_info = defaultdict(int) + basenames = [] for absolute_path in absolute_paths: basename = os.path.basename( absolute_path ) - if basename in seen_basenames: - continue - seen_basenames.add( basename ) - + if extra_info[ basename ] == 0: + basenames.append( basename ) is_dir = os.path.isdir( absolute_path ) + extra_info[ basename ] |= ( 2 if is_dir else 1 ) + + completion_dicts = [] + # Keep original ordering + for basename in basenames: completion_dicts.append( responses.BuildCompletionData( basename, - '[Dir]' if is_dir else '[File]' ) ) + EXTRA_INFO_MAP[ extra_info[ basename ] ] ) ) return completion_dicts diff --git a/python/ycm/completers/general/tests/filename_completer_test.py b/python/ycm/completers/general/tests/filename_completer_test.py new file mode 100644 index 00000000..bebdad3b --- /dev/null +++ b/python/ycm/completers/general/tests/filename_completer_test.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# +# Copyright (C) 2014 Davit Samvelyan +# +# This file is part of YouCompleteMe. +# +# YouCompleteMe is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# YouCompleteMe is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with YouCompleteMe. If not, see . + +import os +from nose.tools import eq_ +from ycm.completers.general.filename_completer import FilenameCompleter +from ycm import user_options_store + +test_dir = os.path.dirname( os.path.abspath( __file__ ) ) +data_dir = os.path.join( test_dir, "testdata", "filename_completer" ) +file_path = os.path.join( data_dir, "test.cpp" ) + +fnc = FilenameCompleter( user_options_store.DefaultOptions() ) +# We cache include flags for test.cpp file for unit testing. +fnc._flags.flags_for_file[ file_path ] = [ + "-I", os.path.join( data_dir, "include" ), + "-I", os.path.join( data_dir, "include", "Qt" ), + "-I", os.path.join( data_dir, "include", "QtGui" ), +] + +request_data = { + 'filepath' : file_path, + 'file_data' : { file_path : { 'filetypes' : 'cpp' } } +} + +def GetCompletionData( request_data ): + request_data[ 'start_column' ] = len( request_data[ 'line_value' ] ) + candidates = fnc.ComputeCandidatesInner( request_data ) + return [ ( c[ 'insertion_text' ], c[ 'extra_menu_info' ] ) for c in candidates ] + + + +def QuotedIncludeCompletion_test(): + request_data[ 'line_value' ] = '#include "' + data = GetCompletionData( request_data ) + eq_( [ + ( 'include', '[Dir]' ), + ( 'Qt', '[Dir]' ), + ( 'QtGui', '[File&Dir]' ), + ( 'QDialog', '[File]' ), + ( 'QWidget', '[File]' ), + ( 'test.cpp', '[File]' ), + ( 'test.hpp', '[File]' ), + ], data ) + + request_data[ 'line_value' ] = '#include "include/' + data = GetCompletionData( request_data ) + eq_( [ + ( 'Qt', '[Dir]' ), + ( 'QtGui', '[Dir]' ), + ], data ) + + +def IncludeCompletion_test(): + request_data[ 'line_value' ] = '#include <' + data = GetCompletionData( request_data ) + eq_( [ + ( 'Qt', '[Dir]' ), + ( 'QtGui', '[File&Dir]' ), + ( 'QDialog', '[File]' ), + ( 'QWidget', '[File]' ), + ], data ) + + request_data[ 'line_value' ] = '#include + +const char* c = ""; diff --git a/python/ycm/completers/general/tests/testdata/filename_completer/test.hpp b/python/ycm/completers/general/tests/testdata/filename_completer/test.hpp new file mode 100644 index 00000000..e69de29b