Skip to content
Browse files

stuff

  • Loading branch information...
1 parent 82faa4a commit d5fcdac3135758a649ad26f951917cd9b659189c Tammer Saleh committed Feb 26, 2013
Showing with 876 additions and 508 deletions.
  1. +36 −10 vim/bundle/YouCompleteMe/README.md
  2. +1 −1 vim/bundle/YouCompleteMe/autoload/youcompleteme.vim
  3. +10 −7 vim/bundle/YouCompleteMe/cpp/BoostParts/CMakeLists.txt
  4. +9 −0 vim/bundle/YouCompleteMe/cpp/CMakeLists.txt
  5. +25 −6 vim/bundle/YouCompleteMe/cpp/ycm/CMakeLists.txt
  6. +6 −25 vim/bundle/YouCompleteMe/cpp/ycm/ClangCompleter/ClangCompleter.cpp
  7. +19 −4 vim/bundle/YouCompleteMe/cpp/ycm/ClangCompleter/CompletionData.cpp
  8. +21 −22 vim/bundle/YouCompleteMe/cpp/ycm/IdentifierCompleter.cpp
  9. +4 −4 vim/bundle/YouCompleteMe/cpp/ycm/IdentifierCompleter.h
  10. +4 −2 vim/bundle/YouCompleteMe/cpp/ycm/IdentifierUtils.cpp
  11. +8 −7 vim/bundle/YouCompleteMe/cpp/ycm/PythonSupport.cpp
  12. +3 −3 vim/bundle/YouCompleteMe/cpp/ycm/PythonSupport.h
  13. +13 −0 vim/bundle/YouCompleteMe/cpp/ycm/Result.h
  14. +18 −0 vim/bundle/YouCompleteMe/cpp/ycm/tests/IdentifierUtils_test.cpp
  15. +10 −12 vim/bundle/YouCompleteMe/doc/youcompleteme.txt
  16. +45 −2 vim/bundle/YouCompleteMe/install.sh
  17. +3 −2 vim/bundle/YouCompleteMe/plugin/youcompleteme.vim
  18. +4 −1 vim/bundle/YouCompleteMe/python/completers/all/omni_completer.py
  19. +19 −14 vim/bundle/YouCompleteMe/python/completers/cpp/flags.py
  20. +5 −1 vim/bundle/YouCompleteMe/python/vimsupport.py
  21. +7 −6 vim/bundle/vim-fugitive/plugin/fugitive.vim
  22. +1 −0 vim/bundle/vim-git/ftdetect/git.vim
  23. +1 −1 vim/bundle/vim-javascript/README.md
  24. +4 −4 vim/bundle/vim-javascript/indent/javascript.vim
  25. +8 −8 vim/bundle/vim-javascript/syntax/javascript.vim
  26. +24 −4 vim/bundle/vim-less/syntax/less.vim
  27. +16 −0 vim/bundle/vim-rails/CONTRIBUTING.markdown
  28. +0 −17 vim/bundle/vim-rails/README.markdown
  29. +292 −262 vim/bundle/vim-rails/autoload/rails.vim
  30. +34 −58 vim/bundle/vim-rails/doc/rails.txt
  31. +1 −1 vim/bundle/vim-rails/plugin/rails.vim
  32. +39 −0 vim/bundle/vim-rbenv/README.markdown
  33. +21 −0 vim/bundle/vim-rbenv/doc/rbenv.txt
  34. +100 −0 vim/bundle/vim-rbenv/plugin/rbenv.vim
  35. +56 −21 vim/bundle/vim-ruby/ftplugin/ruby.vim
  36. +6 −1 vim/bundle/vim-ruby/indent/ruby.vim
  37. +2 −2 vim/bundle/vim-ruby/syntax/ruby.vim
  38. +1 −0 vim/update_bundles
View
46 vim/bundle/YouCompleteMe/README.md
@@ -124,7 +124,7 @@ Install YouCompleteMe with [Vundle][].
using Vundle and the ycm_core library API has changed (happens rarely), YCM will
notify you to recompile it. You should then rerun the install process.
-Install CMake. `sudo apt-get install cmake`
+Install development tools and CMake: `sudo apt-get install build-essential cmake`
Make sure you have Python headers installed: `sudo apt-get install python-dev`.
@@ -147,6 +147,12 @@ YCM comes with sane defaults for its options, but you still may want to take a
look at what's available for configuration. There are a few interesting options
that are conservatively turned off by default that you may want to turn on.
+Windows Installation
+--------------------
+
+YCM has **no official support for Windows**, but that doesn't mean you can't get
+it to work there. See the [Windows Installation Guide][win-wiki] wiki page. Feel
+free to add to it.
Full Installation Guide
-----------------------
@@ -314,7 +320,7 @@ or in any directory above it in the hierarchy (recursively); when the file is
found, it is loaded (only once!) as a Python module. YCM calls a `FlagsForFile`
method in that module which should provide it with the information necessary to
compile the current file. (You can also provide a path to a global
-`.ycm_extra_conf.py` file and override this searching behavior. See the Options
+`.ycm_extra_conf.py` file, which will be used as a fallback. See the Options
section for more details.)
This system was designed this way so that the user can perform any arbitrary
@@ -640,11 +646,10 @@ Default: `<leader>d`
### The `g:ycm_global_ycm_extra_conf` option
-Normally, YCM searches for a `.ycm_extra_conf.py` file for compilation flags
-(see the User Guide for more details on how this works). You can use this option
-to override this searching behavior by providing a full, absolute path to a
-global `.ycm_extra_conf.py` file (although you can call the global file whatever
-you want).
+Normally, YCM searches for a '.ycm_extra_conf.py' file for compilation flags
+(see the User Guide for more details on how this works). This option specifies
+a fallback path to a config file which is used if no '.ycm_extra_conf.py' is
+found.
You can place such a global file anywhere in your filesystem.
@@ -671,11 +676,12 @@ Default: `[see next line]`
\ 'c' : ['->', '.'],
\ 'objc' : ['->', '.'],
\ 'cpp,objcpp' : ['->', '.', '::'],
- \ 'perl,php' : ['->'],
- \ 'cs,java,javascript,d,vim,ruby,python,perl6,scala,vb,elixir' : ['.'],
+ \ 'perl' : ['->'],
+ \ 'php' : ['->', '::'],
+ \ 'cs,java,javascript,d,vim,ruby,python,perl6,scala,vb,elixir,go' : ['.'],
\ 'lua' : ['.', ':'],
\ 'erlang' : [':'],
- }
+ \ }
FAQ
---
@@ -803,6 +809,25 @@ to use. You may need to set these flags to something else, but you need to make
sure you use the same version of Python that your Vim binary is built against,
which is highly likely to be the system's default Python.
+### I get `Vim: Caught deadly signal SEGV` on Vim startup
+
+This can happen on some Linux distros. If you encounter this situation, run Vim
+under `gdb`. You'll probably see something like this in the output when Vim
+crashes:
+
+```
+undefined symbol: clang_CompileCommands_dispose
+```
+
+This means that Vim is trying to load a `libclang.so` that is too old. You need
+at least a 3.2 libclang. Some distros ship with a system `libclang.so` that
+identifies itself as 3.2 but is not; it was cut from the upstream sources before
+the official 3.2 release and some API changes (like the addition of the
+CompileCommands API) were added after their cut.
+
+So just go through the installation guide and make sure you are using a correct
+`libclang.so`. I recommend downloading prebuilt binaries from llvm.org.
+
### Why isn't YCM just written in plain VimScript, FFS?
Because of the identifier completion engine and subsequence-based filtering.
@@ -876,3 +901,4 @@ This software is licensed under the [GPL v3 license][gpl].
[issue18]: https://github.com/Valloric/YouCompleteMe/issues/18
[delimitMate]: https://github.com/Raimondi/delimitMate
[completer-api]: https://github.com/Valloric/YouCompleteMe/blob/master/python/completers/completer.py
+[win-wiki]: https://github.com/Valloric/YouCompleteMe/wiki/Windows-Installation-Guide
View
2 vim/bundle/YouCompleteMe/autoload/youcompleteme.vim
@@ -44,7 +44,7 @@ function! youcompleteme#Enable()
if !pyeval( 'ycm.CompatibleWithYcmCore()')
echohl WarningMsg |
- \ echomsg "YouCompleteMe unavailable, ycm_core too old, PLEASE RECOMPILE" |
+ \ echomsg "YouCompleteMe unavailable: ycm_core too old, PLEASE RECOMPILE ycm_core" |
\ echohl None
return
endif
View
17 vim/bundle/YouCompleteMe/cpp/BoostParts/CMakeLists.txt
@@ -21,12 +21,6 @@
#
# bcp call: bcp boost/utility.hpp boost/python.hpp boost/bind.hpp boost/lambda/lambda.hpp boost/exception/all.hpp boost/tuple/tuple_io.hpp boost/tuple/tuple_comparison.hpp boost/regex.hpp boost/foreach.hpp boost/smart_ptr.hpp boost/algorithm/string_regex.hpp boost/thread.hpp boost/unordered_map.hpp boost/unordered_set.hpp boost/format.hpp boost/ptr_container/ptr_container.hpp boost/filesystem.hpp boost/filesystem/fstream.hpp boost/utility.hpp ../BoostParts
-# WARNING: When doing this from fresh boost sources, note that in the file
-# /boost/config/user.hpp the BOOST_ALL_NO_LIB define has been uncommented.
-# Otherwise, we will get linker errors on MSVC because of boost auto-linking. If
-# you don't care about Windows then feel free to use the raw boost version of
-# /boost/config/user.hpp
-
cmake_minimum_required( VERSION 2.8 )
project( BoostParts )
@@ -77,7 +71,16 @@ endif()
#############################################################################
-if( MSVC )
+# Due to a bug/misconfiguration/stupidity, boost 1.52 and libc++ don't like each
+# other much: a compilation error "Constexpr function never produces a constant
+# expression" pops up when trying to compile anything that uses
+# boost/chrono/duration.hpp (namely boost/thread for us). This is a workaround
+# that prevents this from happening. Also present in cpp/ycm/CMakeLists.txt.
+# See here for more details: https://svn.boost.org/trac/boost/ticket/7671
+# TODO: remove this when it's fixed upstream (probably boost 1.53).
+add_definitions( -DBOOST_THREAD_DONT_USE_CHRONO )
+
+if( MSVC OR CYGWIN )
# BOOST_PYTHON_SOURCE makes boost use the correct __declspec and
# BOOST_ALL_NO_LIB turns off MSVC library autolinking
add_definitions( -DBOOST_PYTHON_SOURCE -DBOOST_ALL_NO_LIB )
View
9 vim/bundle/YouCompleteMe/cpp/CMakeLists.txt
@@ -82,5 +82,14 @@ else()
"Your C++ compiler does NOT support C++11, compiling in C++03 mode." )
endif()
+# Check if platform is 64 bit
+if( NOT APPLE )
+ if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
+ set( 64_BIT_PLATFORM 0 )
+ else()
+ set( 64_BIT_PLATFORM 1 )
+ endif()
+endif()
+
add_subdirectory( BoostParts )
add_subdirectory( ycm )
View
31 vim/bundle/YouCompleteMe/cpp/ycm/CMakeLists.txt
@@ -56,8 +56,13 @@ if ( USE_CLANG_COMPLETER AND NOT USE_SYSTEM_LIBCLANG AND NOT PATH_TO_LLVM_ROOT )
set( CLANG_DIRNAME "clang+llvm-3.2-x86_64-apple-darwin11" )
set( CLANG_MD5 "fbdca3b4e8cdaa2352f2aeb038a16532" )
else()
- set( CLANG_DIRNAME "clang+llvm-3.2-x86_64-linux-ubuntu-12.04" )
- set( CLANG_MD5 "81821e339d7300afb76aca8edab2cf4f" )
+ if ( 64_BIT_PLATFORM )
+ set( CLANG_DIRNAME "clang+llvm-3.2-x86_64-linux-ubuntu-12.04" )
+ set( CLANG_MD5 "81821e339d7300afb76aca8edab2cf4f" )
+ else()
+ set( CLANG_DIRNAME "clang+llvm-3.2-x86-linux-ubuntu-12.04" )
+ set( CLANG_MD5 "cea2d01b3206e92a8df7b079935c070b" )
+ endif()
endif()
set( CLANG_FILENAME "${CLANG_DIRNAME}.tar.gz" )
@@ -207,6 +212,11 @@ if ( EXTRA_RPATH )
set( CMAKE_INSTALL_RPATH "${EXTRA_RPATH}:${CMAKE_INSTALL_RPATH}" )
endif()
+# Needed on Linux machines, but not on Macs
+if ( UNIX AND NOT APPLE )
+ set( EXTRA_LIBS rt )
+endif()
+
#############################################################################
# Due to a bug/misconfiguration/stupidity, boost 1.52 and libc++ don't like each
@@ -218,6 +228,11 @@ endif()
# TODO: remove this when it's fixed upstream (probably boost 1.53).
add_definitions( -DBOOST_THREAD_DONT_USE_CHRONO )
+if( MSVC OR CYGWIN )
+ # BOOST_PYTHON_SOURCE makes boost use the correct __declspec and
+ # BOOST_ALL_NO_LIB turns off MSVC library autolinking
+ add_definitions( -DBOOST_PYTHON_SOURCE -DBOOST_ALL_NO_LIB )
+endif()
#############################################################################
add_library( ${PROJECT_NAME} SHARED
@@ -228,6 +243,7 @@ target_link_libraries( ${PROJECT_NAME}
BoostParts
${PYTHON_LIBRARIES}
${LIBCLANG_TARGET}
+ ${EXTRA_LIBS}
)
if ( LIBCLANG_TARGET )
@@ -265,10 +281,13 @@ endif()
# for our module
set_target_properties( ${PROJECT_NAME} PROPERTIES PREFIX "")
-# Even on macs, we want a .so extension instead of a .dylib which is what cmake
-# would give us by default. Python won't recognize a .dylib as a module, but it
-# will recognize a .so
-if ( NOT WIN32 )
+if ( WIN32 OR CYGWIN )
+ # This is the extension for compiled Python modules on Windows
+ set_target_properties( ${PROJECT_NAME} PROPERTIES SUFFIX ".pyd")
+else()
+ # Even on macs, we want a .so extension instead of a .dylib which is what
+ # cmake would give us by default. Python won't recognize a .dylib as a module,
+ # but it will recognize a .so
set_target_properties( ${PROJECT_NAME} PROPERTIES SUFFIX ".so")
endif()
View
31 vim/bundle/YouCompleteMe/cpp/ycm/ClangCompleter/ClangCompleter.cpp
@@ -53,26 +53,6 @@ namespace YouCompleteMe {
extern const unsigned int MAX_ASYNC_THREADS;
extern const unsigned int MIN_ASYNC_THREADS;
-namespace {
-
-// TODO: replace this with ResultAnd from Result.h
-struct CompletionDataAndResult {
- CompletionDataAndResult( const CompletionData *completion_data,
- const Result &result )
- : completion_data_( completion_data ), result_( result ) {}
-
- bool operator< ( const CompletionDataAndResult &other ) const {
- return result_ < other.result_;
- }
-
- const CompletionData *completion_data_;
- Result result_;
-};
-
-
-} // unnamed namespace
-
-
ClangCompleter::ClangCompleter()
: candidate_repository_( CandidateRepository::Instance() ),
threading_enabled_( false ),
@@ -202,7 +182,7 @@ Future< void > ClangCompleter::UpdateTranslationUnitAsync(
make_shared< ClangPackagedTask >();
clang_packaged_task->parsing_task_ = packaged_task< void >(
- boost::move( functor ) );
+ boost::move( functor ) );
unique_future< void > future =
clang_packaged_task->parsing_task_.get_future();
clang_task_.Set( clang_packaged_task );
@@ -411,7 +391,7 @@ std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
std::vector< const Candidate * > repository_candidates =
candidate_repository_.GetCandidatesForStrings( completion_datas );
- std::vector< CompletionDataAndResult > data_and_results;
+ std::vector< ResultAnd< CompletionData* > > data_and_results;
for ( uint i = 0; i < repository_candidates.size(); ++i ) {
const Candidate *candidate = repository_candidates[ i ];
@@ -422,7 +402,8 @@ std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
Result result = candidate->QueryMatchResult( query );
if ( result.IsSubsequence() ) {
- CompletionDataAndResult data_and_result( &completion_datas[ i ], result );
+ ResultAnd< CompletionData* > data_and_result( &completion_datas[ i ],
+ result );
data_and_results.push_back( boost::move( data_and_result ) );
}
}
@@ -432,9 +413,9 @@ std::vector< CompletionData > ClangCompleter::SortCandidatesForQuery(
std::vector< CompletionData > sorted_completion_datas;
sorted_completion_datas.reserve( data_and_results.size() );
- foreach ( const CompletionDataAndResult & data_and_result,
+ foreach ( const ResultAnd< CompletionData* > & data_and_result,
data_and_results ) {
- sorted_completion_datas.push_back( *data_and_result.completion_data_ );
+ sorted_completion_datas.push_back( *data_and_result.extra_object_ );
}
return sorted_completion_datas;
View
23 vim/bundle/YouCompleteMe/cpp/ycm/ClangCompleter/CompletionData.cpp
@@ -24,14 +24,19 @@
namespace {
char CursorKindToVimKind( CXCursorKind kind ) {
- // TODO: actually it appears that Vim will show returned kinds even when they
- // do not match the "approved" list, so let's use that
switch ( kind ) {
- case CXCursor_UnexposedDecl:
case CXCursor_StructDecl:
- case CXCursor_UnionDecl:
+ return 's';
+
case CXCursor_ClassDecl:
+ case CXCursor_ClassTemplate:
+ return 'c';
+
case CXCursor_EnumDecl:
+ return 'e';
+
+ case CXCursor_UnexposedDecl:
+ case CXCursor_UnionDecl:
case CXCursor_TypedefDecl:
return 't';
@@ -41,6 +46,9 @@ char CursorKindToVimKind( CXCursorKind kind ) {
case CXCursor_FunctionDecl:
case CXCursor_CXXMethod:
case CXCursor_FunctionTemplate:
+ case CXCursor_ConversionFunction:
+ case CXCursor_Constructor:
+ case CXCursor_Destructor:
return 'f';
case CXCursor_VarDecl:
@@ -49,6 +57,13 @@ char CursorKindToVimKind( CXCursorKind kind ) {
case CXCursor_MacroDefinition:
return 'd';
+ case CXCursor_ParmDecl:
+ return 'p';
+
+ case CXCursor_Namespace:
+ case CXCursor_NamespaceAlias:
+ return 'n';
+
default:
return 'u'; // for 'unknown', 'unsupported'... whatever you like
}
View
43 vim/bundle/YouCompleteMe/cpp/ycm/IdentifierCompleter.cpp
@@ -29,11 +29,8 @@
#include <algorithm>
using boost::packaged_task;
-using boost::bind;
using boost::unique_future;
-using boost::make_shared;
using boost::shared_ptr;
-using boost::bind;
using boost::thread;
namespace YouCompleteMe {
@@ -138,7 +135,7 @@ void IdentifierCompleter::AddCandidatesToDatabaseFromBuffer(
const std::string &buffer_contents,
const std::string &filetype,
const std::string &filepath,
- bool collect_from_comments_and_strings) {
+ bool collect_from_comments_and_strings ) {
ClearCandidatesStoredForFile( filetype, filepath );
std::string new_contents =
@@ -162,15 +159,15 @@ void IdentifierCompleter::AddCandidatesToDatabaseFromBufferAsync(
return;
boost::function< void() > functor =
- bind( &IdentifierCompleter::AddCandidatesToDatabaseFromBuffer,
- boost::ref( *this ),
- boost::move( buffer_contents ),
- boost::move( filetype ),
- boost::move( filepath ),
- collect_from_comments_and_strings );
+ boost::bind( &IdentifierCompleter::AddCandidatesToDatabaseFromBuffer,
+ boost::ref( *this ),
+ boost::move( buffer_contents ),
+ boost::move( filetype ),
+ boost::move( filepath ),
+ collect_from_comments_and_strings );
buffer_identifiers_task_stack_.Push(
- make_shared< packaged_task< void > >( boost::move( functor ) ) );
+ boost::make_shared< packaged_task< void > >( boost::move( functor ) ) );
}
@@ -204,14 +201,15 @@ Future< AsyncResults > IdentifierCompleter::CandidatesForQueryAndTypeAsync(
return Future< AsyncResults >();
FunctionReturnsStringVector functor =
- bind( &IdentifierCompleter::CandidatesForQueryAndType,
- boost::cref( *this ),
- query,
- filetype );
+ boost::bind( &IdentifierCompleter::CandidatesForQueryAndType,
+ boost::cref( *this ),
+ query,
+ filetype );
- QueryTask task = make_shared< packaged_task< AsyncResults > >(
- bind( ReturnValueAsShared< std::vector< std::string > >,
- boost::move( functor ) ) );
+ QueryTask task =
+ boost::make_shared< packaged_task< AsyncResults > >(
+ boost::bind( ReturnValueAsShared< std::vector< std::string > >,
+ boost::move( functor ) ) );
unique_future< AsyncResults > future = task->get_future();
@@ -288,13 +286,14 @@ void IdentifierCompleter::InitThreads() {
std::min( MAX_ASYNC_THREADS, thread::hardware_concurrency() ) );
for ( int i = 0; i < query_threads_to_create; ++i ) {
- query_threads_.create_thread( bind( QueryThreadMain,
- boost::ref( latest_query_task_ ) ) );
+ query_threads_.create_thread(
+ boost::bind( QueryThreadMain,
+ boost::ref( latest_query_task_ ) ) );
}
buffer_identifiers_thread_.reset(
- new boost::thread( BufferIdentifiersThreadMain,
- boost::ref( buffer_identifiers_task_stack_ ) ) );
+ new boost::thread( BufferIdentifiersThreadMain,
+ boost::ref( buffer_identifiers_task_stack_ ) ) );
}
View
8 vim/bundle/YouCompleteMe/cpp/ycm/IdentifierCompleter.h
@@ -57,10 +57,10 @@ class IdentifierCompleter : boost::noncopyable {
const std::string &filepath );
void AddCandidatesToDatabaseFromBuffer(
- const std::string &buffer_contents,
- const std::string &filetype,
- const std::string &filepath,
- bool collect_from_comments_and_strings );
+ const std::string &buffer_contents,
+ const std::string &filetype,
+ const std::string &filepath,
+ bool collect_from_comments_and_strings );
// NOTE: params are taken by value on purpose! With a C++11 compiler we can
// avoid an expensive copy of buffer_contents if the param is taken by value
View
6 vim/bundle/YouCompleteMe/cpp/ycm/IdentifierUtils.cpp
@@ -30,9 +30,11 @@ const char *COMMENT_AND_STRING_REGEX =
"|"
"/\\*.*?\\*/" // C-style comments, '/* ... */'
"|"
- "'[^']*'" // Anything inside single quotes, '...'
+ // Anything inside single quotes, '...', but mind the escaped quote
+ "'(?:\\\\'|.)*?'"
"|"
- "\"[^\"]*\""; // Anything inside double quotes, "..."
+ // Anything inside double quotes, "...", but mind the escaped double quote
+ "\"(?:\\\\\"|.)*?\"";
const char *IDENTIFIER_REGEX = "[_a-zA-Z]\\w*";
View
15 vim/bundle/YouCompleteMe/cpp/ycm/PythonSupport.cpp
@@ -32,8 +32,8 @@ namespace YouCompleteMe {
namespace {
std::vector< const Candidate * > CandidatesFromObjectList(
- const pylist &candidates,
- const std::string &candidate_property ) {
+ const pylist &candidates,
+ const std::string &candidate_property ) {
int num_candidates = len( candidates );
std::vector< std::string > candidate_strings;
candidate_strings.reserve( num_candidates );
@@ -44,21 +44,22 @@ std::vector< const Candidate * > CandidatesFromObjectList(
} else {
object holder = extract< object >( candidates[ i ] );
candidate_strings.push_back( extract< std::string >(
- holder[ candidate_property.c_str() ] ) );
+ holder[ candidate_property.c_str() ] ) );
}
}
return CandidateRepository::Instance().GetCandidatesForStrings(
- candidate_strings );
+ candidate_strings );
}
} // unnamed namespace
boost::python::list FilterAndSortCandidates(
- const boost::python::list &candidates,
- const std::string &candidate_property,
- const std::string &query ) {
+ const boost::python::list &candidates,
+ const std::string &candidate_property,
+ const std::string &query ) {
pylist filtered_candidates;
+
if ( query.empty() )
return filtered_candidates;
View
6 vim/bundle/YouCompleteMe/cpp/ycm/PythonSupport.h
@@ -27,9 +27,9 @@ namespace YouCompleteMe {
// the candidates and a user query, returns a new sorted python list with the
// original objects that survived the filtering.
boost::python::list FilterAndSortCandidates(
- const boost::python::list &candidates,
- const std::string &candidate_property,
- const std::string &query );
+ const boost::python::list &candidates,
+ const std::string &candidate_property,
+ const std::string &query );
} // namespace YouCompleteMe
View
13 vim/bundle/YouCompleteMe/cpp/ycm/Result.h
@@ -99,6 +99,19 @@ struct ResultAnd {
Result result_;
};
+template< class T >
+struct ResultAnd<T* > {
+ ResultAnd( const T* extra_object, const Result &result )
+ : extra_object_( extra_object ), result_( result ) {}
+
+ bool operator< ( const ResultAnd &other ) const {
+ return result_ < other.result_;
+ }
+
+ const T* extra_object_;
+ Result result_;
+};
+
} // namespace YouCompleteMe
#endif /* end of include guard: RESULT_H_CZYD2SGN */
View
18 vim/bundle/YouCompleteMe/cpp/ycm/tests/IdentifierUtils_test.cpp
@@ -65,12 +65,30 @@ TEST( IdentifierUtilsTest, RemoveIdentifierFreeTextWorks ) {
EXPECT_STREQ( RemoveIdentifierFreeText(
"foo \n"
+ "bar 'fo\\'oz\\nfoo'\n"
+ "qux"
+ ).c_str(),
+ "foo \n"
+ "bar \n"
+ "qux" );
+
+ EXPECT_STREQ( RemoveIdentifierFreeText(
+ "foo \n"
"bar \"foo\"\n"
"qux"
).c_str(),
"foo \n"
"bar \n"
"qux" );
+
+ EXPECT_STREQ( RemoveIdentifierFreeText(
+ "foo \n"
+ "bar \"fo\\\"oz\\nfoo\"\n"
+ "qux"
+ ).c_str(),
+ "foo \n"
+ "bar \n"
+ "qux" );
}
View
22 vim/bundle/YouCompleteMe/doc/youcompleteme.txt
@@ -97,17 +97,16 @@ identifier-based completion engine. It collects all of the identifiers in the
current file and other files you visit and searches them when you type
(identifiers are put into per-filetype groups).
-The demo also shows the semantic engine in use. The current semantic engine
-supports only C-family languages. When the user presses '.', '->' or '::'
-while typing in insert mode, the semantic engine is triggered (it can also be
-triggered with a keyboard shortcut; see the rest of the docs).
+The demo also shows the semantic engine in use. When the user presses '.',
+'->' or '::' while typing in insert mode, the semantic engine is triggered (it
+can also be triggered with a keyboard shortcut; see the rest of the docs).
The last thing that you can see in the demo is YCM's integration with
Syntastic [4] (the little red X that shows up in the left gutter) if you are
-editing a file with semantic engine support. As Clang compiles your file and
-detects warnings or errors, they will be piped to Syntastic for display. You
-don't need to save your file or press any keyboard shortcut to trigger this,
-it "just happens" in the background.
+editing a C-family file. As Clang compiles your file and detects warnings or
+errors, they will be piped to Syntastic for display. You don't need to save
+your file or press any keyboard shortcut to trigger this, it "just happens" in
+the background.
In essence, YCM obsoletes the following Vim plugins because it has all of
their features plus extra:
@@ -718,10 +717,9 @@ Default: '<leader>d'
The *g:ycm_global_ycm_extra_conf* option
Normally, YCM searches for a '.ycm_extra_conf.py' file for compilation flags
-(see the User Guide for more details on how this works). You can use this
-option to override this searching behavior by providing a full, absolute path
-to a global '.ycm_extra_conf.py' file (although you can call the global file
-whatever you want).
+(see the User Guide for more details on how this works). This option specifies
+a fallback path to a config file which is used if no '.ycm_extra_conf.py' is
+found.
You can place such a global file anywhere in your filesystem.
View
47 vim/bundle/YouCompleteMe/install.sh
@@ -21,13 +21,56 @@ function homebrew_cmake_install {
fi
}
+function python_finder {
+ python_library="-DPYTHON_LIBRARY="
+ python_include="-DPYTHON_INCLUDE_DIR="
+
+ # The CMake 'FindPythonLibs' Module does not work properly.
+ # So we are forced to do its job for it.
+ python_prefix=$(python-config --prefix | sed 's/^[ \t]*//')
+ if [ -f "${python_prefix}/Python" ]; then
+ python_library+="${python_prefix}/Python"
+ python_include+="${python_prefix}/Headers"
+ else
+ which_python=$(python -c 'import sys;print(sys.version)' | sed 's/^[ \t]*//')
+ which_python="python${which_python:0:3}"
+ lib_python="${python_prefix}/lib/lib${which_python}"
+ if [ -f "${lib_python}.a" ]; then
+ python_library+="${lib_python}.a"
+ else
+ python_library+="${lib_python}.dylib"
+ fi
+ python_include+="${python_prefix}/include/${which_python}"
+ fi
+
+ echo "${python_library} ${python_include}"
+}
+
+function num_cores {
+ num_cpus=1
+ if [[ `uname -s` == "Linux" ]]; then
+ num_cpus=$(grep -c ^processor /proc/cpuinfo)
+ else
+ # Works on Mac and FreeBSD
+ num_cpus=$(sysctl -n hw.ncpu)
+ fi
+ echo $num_cpus
+}
+
function install {
ycm_dir=`pwd`
build_dir=`mktemp -d -t ycm_build.XXXX`
pushd $build_dir
- cmake -G "Unix Makefiles" $1 . $ycm_dir/cpp
- make ycm_core
+
+ if [[ `uname -s` == "Darwin" ]]; then
+ cmake -G "Unix Makefiles" $(python_finder) $1 . $ycm_dir/cpp
+ else
+ cmake -G "Unix Makefiles" $1 . $ycm_dir/cpp
+ fi
+
+ make -j $(num_cores) ycm_core
popd
+ rm -rf $build_dir
}
function linux_cmake_install {
View
5 vim/bundle/YouCompleteMe/plugin/youcompleteme.vim
@@ -106,8 +106,9 @@ let g:ycm_semantic_triggers =
\ 'c' : ['->', '.'],
\ 'objc' : ['->', '.'],
\ 'cpp,objcpp' : ['->', '.', '::'],
- \ 'perl,php' : ['->'],
- \ 'cs,java,javascript,d,vim,ruby,python,perl6,scala,vb,elixir' : ['.'],
+ \ 'perl' : ['->'],
+ \ 'php' : ['->', '::'],
+ \ 'cs,java,javascript,d,vim,ruby,python,perl6,scala,vb,elixir,go' : ['.'],
\ 'lua' : ['.', ':'],
\ 'erlang' : [':'],
\ } )
View
5 vim/bundle/YouCompleteMe/python/completers/all/omni_completer.py
@@ -53,7 +53,10 @@ def CandidatesForQueryAsyncInner( self, query ):
vimsupport.EscapeForVim( query ),
"')" ]
- self.stored_candidates = vim.eval( ''.join( omnifunc_call ) )
+ items = vim.eval( ''.join( omnifunc_call ) )
+ if hasattr( items, 'words' ):
+ items = items.words
+ self.stored_candidates = filter( bool, items )
def AsyncCandidateRequestReadyInner( self ):
View
33 vim/bundle/YouCompleteMe/python/completers/cpp/flags.py
@@ -27,10 +27,11 @@
YCM_EXTRA_CONF_FILENAME = '.ycm_extra_conf.py'
NO_EXTRA_CONF_FILENAME_MESSAGE = ('No {0} file detected, so no compile flags '
- 'are available. Thus no semantic support for C/C++/ObjC/ObjC++.').format(
- YCM_EXTRA_CONF_FILENAME )
-GLOBAL_YCM_EXTRA_CONF_FILE = vimsupport.GetVariableValue(
- "g:ycm_global_ycm_extra_conf" )
+ 'are available. Thus no semantic support for C/C++/ObjC/ObjC++. See the '
+ 'docs for details.').format( YCM_EXTRA_CONF_FILENAME )
+GLOBAL_YCM_EXTRA_CONF_FILE = os.path.expanduser(
+ vimsupport.GetVariableValue( "g:ycm_global_ycm_extra_conf" )
+)
class Flags( object ):
def __init__( self ):
@@ -92,27 +93,31 @@ def _FlagsModuleForFile( self, filename ):
def _FlagsModuleSourceFileForFile( filename ):
"""For a given filename, finds its nearest YCM_EXTRA_CONF_FILENAME file that
- will compute the flags necessary to compile the file. Returns None if no
- YCM_EXTRA_CONF_FILENAME file could be found. Uses the global ycm_extra_conf
- file if one is set."""
-
- if ( GLOBAL_YCM_EXTRA_CONF_FILE and
- os.path.exists( GLOBAL_YCM_EXTRA_CONF_FILE ) ):
- return GLOBAL_YCM_EXTRA_CONF_FILE
+ will compute the flags necessary to compile the file. If no
+ YCM_EXTRA_CONF_FILENAME file could be found, try to use
+ GLOBAL_YCM_EXTRA_CONF_FILE instead. If that also fails, return None.
+ Uses the global ycm_extra_conf file if one is set."""
+ ycm_conf_file = None
parent_folder = os.path.dirname( filename )
old_parent_folder = ''
while True:
current_file = os.path.join( parent_folder, YCM_EXTRA_CONF_FILENAME )
if os.path.exists( current_file ):
- return current_file
+ ycm_conf_file = current_file
+ break
old_parent_folder = parent_folder
parent_folder = os.path.dirname( parent_folder )
+ if parent_folder is old_parent_folder:
+ break
+
+ if ( not ycm_conf_file and GLOBAL_YCM_EXTRA_CONF_FILE and
+ os.path.exists( GLOBAL_YCM_EXTRA_CONF_FILE ) ):
+ ycm_conf_file = GLOBAL_YCM_EXTRA_CONF_FILE
- if parent_folder == old_parent_folder:
- return None
+ return ycm_conf_file
def _RandomName():
View
6 vim/bundle/YouCompleteMe/python/vimsupport.py
@@ -60,7 +60,11 @@ def PostVimMessage( message ):
def EchoText( text ):
- vim.command( "echom '{0}'".format( EscapeForVim( text ) ) )
+ def EchoLine( text ):
+ vim.command( "echom '{0}'".format( EscapeForVim( text ) ) )
+
+ for line in text.split( '\n' ):
+ EchoLine( line )
def EscapeForVim( text ):
View
13 vim/bundle/vim-fugitive/plugin/fugitive.vim
@@ -133,7 +133,7 @@ function! fugitive#extract_git_dir(path) abort
return ''
endfunction
-function! s:Detect(path)
+function! fugitive#detect(path)
if exists('b:git_dir') && (b:git_dir ==# '' || b:git_dir =~# '/$')
unlet b:git_dir
endif
@@ -162,10 +162,10 @@ endfunction
augroup fugitive
autocmd!
- autocmd BufNewFile,BufReadPost * call s:Detect(expand('<amatch>:p'))
- autocmd FileType netrw call s:Detect(expand('%:p'))
- autocmd User NERDTreeInit,NERDTreeNewRoot call s:Detect(b:NERDTreeRoot.path.str())
- autocmd VimEnter * if expand('<amatch>')==''|call s:Detect(getcwd())|endif
+ autocmd BufNewFile,BufReadPost * call fugitive#detect(expand('<amatch>:p'))
+ autocmd FileType netrw call fugitive#detect(expand('%:p'))
+ autocmd User NERDTreeInit,NERDTreeNewRoot call fugitive#detect(b:NERDTreeRoot.path.str())
+ autocmd VimEnter * if expand('<amatch>')==''|call fugitive#detect(getcwd())|endif
autocmd BufWinLeave * execute getwinvar(+bufwinnr(+expand('<abuf>')), 'fugitive_leave')
augroup END
@@ -1356,6 +1356,7 @@ function! s:diffthis()
let w:fugitive_diff_restore .= &l:wrap ? ' wrap' : ' nowrap'
let w:fugitive_diff_restore .= ' foldmethod=' . &l:foldmethod
let w:fugitive_diff_restore .= ' foldcolumn=' . &l:foldcolumn
+ let w:fugitive_diff_restore .= ' foldlevel=' . &l:foldlevel
if has('cursorbind')
let w:fugitive_diff_restore .= (&l:cursorbind ? ' ' : ' no') . 'cursorbind'
endif
@@ -2250,7 +2251,7 @@ augroup fugitive_temp
\ if has_key(s:temp_files,expand('<afile>:p')) |
\ let b:git_dir = s:temp_files[expand('<afile>:p')] |
\ let b:git_type = 'temp' |
- \ call s:Detect(expand('<afile>:p')) |
+ \ call fugitive#detect(expand('<afile>:p')) |
\ setlocal bufhidden=delete |
\ nnoremap <buffer> <silent> q :<C-U>bdelete<CR>|
\ endif
View
1 vim/bundle/vim-git/ftdetect/git.vim
@@ -1,6 +1,7 @@
" Git
autocmd BufNewFile,BufRead *.git/{,modules/**/}{COMMIT_EDIT,MERGE_}MSG set ft=gitcommit
autocmd BufNewFile,BufRead *.git/config,.gitconfig,.gitmodules set ft=gitconfig
+autocmd BufNewFile,BufRead */.config/git/config set ft=gitconfig
autocmd BufNewFile,BufRead *.git/modules/**/config set ft=gitconfig
autocmd BufNewFile,BufRead git-rebase-todo set ft=gitrebase
autocmd BufNewFile,BufRead .msg.[0-9]*
View
2 vim/bundle/vim-javascript/README.md
@@ -4,7 +4,7 @@ JavaScript bundle for vim, this bundle provides syntax and indent plugins.
> Indentation of javascript in vim is terrible, and this is the very end of it.
-## Feature
+## Features
1. very correct indentation for javascript
2. support javascript indentation in html (provided by [lepture](https://github.com/lepture))
View
8 vim/bundle/vim-javascript/indent/javascript.vim
@@ -33,13 +33,13 @@ set cpo&vim
" ============
" Regex of syntax group names that are or delimit string or are comments.
-let s:syng_strcom = 'javaScript\%(String\|RegexpString\|CommentTodo\|LineComment\|Comment\|DocComment\)'
+let s:syng_strcom = 'string\|regex\|comment\c'
" Regex of syntax group names that are strings.
-let s:syng_string = 'javaScript\%(RegexpString\)'
+let s:syng_string = 'regex\c'
" Regex of syntax group names that are strings or documentation.
-let s:syng_multiline = 'javaScriptDocComment\|javaScriptComment'
+let s:syng_multiline = 'comment\c'
" Expression used to check whether we should skip a match with searchpair().
let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_strcom."'"
@@ -116,7 +116,7 @@ function s:GetMSL(lnum, in_one_line_scope)
" Don't use lines that are part of a one line scope as msl unless the
" flag in_one_line_scope is set to 1
"
- if a:in_one_line_scope
+ if a:in_one_line_scope
break
end
let msl_one_line = s:Match(lnum, s:one_line_scope_regex)
View
16 vim/bundle/vim-javascript/syntax/javascript.vim
@@ -1,10 +1,8 @@
" Vim syntax file
" Language: JavaScript
-" Maintainer: Yi Zhao (ZHAOYI) <zzlinux AT hotmail DOT com>
-" Last Change By: Marc Harter
-" Last Change: February 18, 2011
+" Maintainer: Josh Perez <josh at goatslacker.com>
" Version: 0.7.9
-" Changes: Updates JSDoc syntax
+" URL: https://github.com/pangloss/vim-javascript
"
" TODO:
" - Add the HTML syntax inside the JSDoc
@@ -78,14 +76,15 @@ syntax region javaScriptRegexpCharClass start=+\[+ end=+\]+ contained
syntax region javaScriptRegexpString start=+\(\(\(return\|case\)\s\+\)\@<=\|\(\([)\]"']\|\d\|\w\)\s*\)\@<!\)/\(\*\|/\)\@!+ skip=+\\\\\|\\/+ end=+/[gimy]\{,4}+ contains=javaScriptSpecial,javaScriptRegexpCharClass,@htmlPreproc oneline
syntax match javaScriptNumber /\<-\=\d\+L\=\>\|\<0[xX]\x\+\>/
syntax match javaScriptFloat /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/
-syntax match javaScriptLabel /\<\w\+\(\s*:\)\@=/
+syntax match javaScriptLabel /\<[a-zA-Z_$][0-9a-zA-Z_$\-]*\(\s*:\)\@=/
"" JavaScript Prototype
syntax keyword javaScriptPrototype prototype
"" Program Keywords
syntax keyword javaScriptSource import export
-syntax keyword javaScriptType const undefined var void yield
+syntax keyword javaScriptCommonJS require module exports
+syntax keyword javaScriptType const undefined var void yield
syntax keyword javaScriptOperator delete new in instanceof let typeof
syntax keyword javaScriptBoolean true false
syntax keyword javaScriptNull null
@@ -154,11 +153,11 @@ endif "DOM/HTML/CSS
"" Code blocks
" there is a name collision with javaScriptExpression in html.vim, hence the use of the '2' here
-syntax cluster javaScriptExpression2 contains=javaScriptComment,javaScriptLineComment,javaScriptDocComment,javaScriptStringD,javaScriptStringS,javaScriptRegexpString,javaScriptNumber,javaScriptFloat,javaScriptSource,javaScriptThis,javaScriptType,javaScriptOperator,javaScriptBoolean,javaScriptNull,javaScriptFunction,javaScriptGlobalObjects,javaScriptExceptions,javaScriptFutureKeys,javaScriptDomErrNo,javaScriptDomNodeConsts,javaScriptHtmlEvents,javaScriptDotNotation,javaScriptBracket,javaScriptParen,javaScriptBlock,javaScriptParenError
+syntax cluster javaScriptExpression2 contains=javaScriptComment,javaScriptLineComment,javaScriptDocComment,javaScriptStringD,javaScriptStringS,javaScriptRegexpString,javaScriptNumber,javaScriptFloat,javaScriptSource,javaScriptCommonJS,javaScriptThis,javaScriptType,javaScriptOperator,javaScriptBoolean,javaScriptNull,javaScriptFunction,javaScriptGlobalObjects,javaScriptExceptions,javaScriptFutureKeys,javaScriptDomErrNo,javaScriptDomNodeConsts,javaScriptHtmlEvents,javaScriptDotNotation,javaScriptBracket,javaScriptParen,javaScriptBlock,javaScriptParenError
syntax cluster javaScriptAll contains=@javaScriptExpression2,javaScriptLabel,javaScriptConditional,javaScriptRepeat,javaScriptBranch,javaScriptStatement,javaScriptTernaryIf
syntax region javaScriptBracket matchgroup=javaScriptBracket transparent start="\[" end="\]" contains=@javaScriptAll,javaScriptParensErrB,javaScriptParensErrC,javaScriptBracket,javaScriptParen,javaScriptBlock,@htmlPreproc
syntax region javaScriptParen matchgroup=javaScriptParen transparent start="(" end=")" contains=@javaScriptAll,javaScriptParensErrA,javaScriptParensErrC,javaScriptParen,javaScriptBracket,javaScriptBlock,@htmlPreproc
-syntax region javaScriptBlock matchgroup=javaScriptBlock transparent start="{" end="}" contains=@javaScriptAll,javaScriptParensErrA,javaScriptParensErrB,javaScriptParen,javaScriptBracket,javaScriptBlock,@htmlPreproc
+syntax region javaScriptBlock matchgroup=javaScriptBlock transparent start="{" end="}" contains=@javaScriptAll,javaScriptParensErrA,javaScriptParensErrB,javaScriptParen,javaScriptBracket,javaScriptBlock,@htmlPreproc
syntax region javaScriptTernaryIf matchgroup=javaScriptTernaryIfOperator start=+?+ end=+:+ contains=@javaScriptExpression2
"" catch errors caused by wrong parenthesis
@@ -231,6 +230,7 @@ if version >= 508 || !exists("did_javascript_syn_inits")
HiLink javaScriptLabel Label
HiLink javaScriptSpecial Special
HiLink javaScriptSource Special
+ HiLink javaScriptCommonJS Include
HiLink javaScriptGlobalObjects Special
HiLink javaScriptExceptions Special
View
28 vim/bundle/vim-less/syntax/less.vim
@@ -9,9 +9,9 @@ runtime! after/syntax/css/*.vim
syn case ignore
-syn region lessDefinition transparent matchgroup=cssBraces start='{' end='}' contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssTagName,cssPseudoClass,cssUrl,cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,lessDefinition,lessComment,lessClassChar,lessVariable,lessMixinChar,lessAmpersandChar,lessFunction,@cssColors fold
+syn region lessDefinition transparent matchgroup=cssBraces start='{' end='}' contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssTagName,cssPseudoClass,cssUrl,cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,lessDefinition,lessComment,lessClassChar,lessVariable,lessMixinChar,lessAmpersandChar,lessFunction,lessNestedSelector,@cssColors fold
-syn match lessVariable "@[[:alnum:]_-]\+" contained
+syn match lessVariable "@[[:alnum:]_-]\+" contained
syn match lessVariable "@[[:alnum:]_-]\+" nextgroup=lessVariableAssignment skipwhite
syn match lessVariableAssignment ":" contained nextgroup=lessVariableValue skipwhite
syn match lessVariableValue ".*;"me=e-1 contained contains=lessVariable,lessOperator,lessDefault,cssValue.*,@cssColors "me=e-1 means that the last char of the pattern is not highlighted
@@ -21,13 +21,33 @@ syn match lessOperator "-" contained
syn match lessOperator "/" contained
syn match lessOperator "*" contained
+syn match lessNestedSelector "[^/]* {"me=e-1 contained contains=cssTagName,cssAttributeSelector,lessAmpersandChar,lessVariable,lessMixinChar,lessFunction,lessNestedProperty
+syn match lessNestedProperty "[[:alnum:]]\+:"me=e-1 contained
+
syn match lessDefault "!default" contained
syn match lessMixinChar "\.[[:alnum:]_-]\@=" contained nextgroup=lessClass
syn match lessAmpersandChar "&" contained nextgroup=lessClass,cssPseudoClass
syn match lessClass "[[:alnum:]_-]\+" contained
-syn keyword lessFunction lighten darken saturate desaturate fadein fadeout spin hue saturation lightness containedin=cssDefinition contained
+" functions {{{
+
+" string functions
+syn keyword lessFunction escape e % containedin=cssDefinition contained
+" misc functions
+syn keyword lessFunction color unit containedin=cssDefinition contained
+" math functions
+syn keyword lessFunction ceil floor percentage round containedin=cssDefinition contained
+" color definition
+syn keyword lessFunction rgb rgba argb hsl hsla hsv hsva containedin=cssDefinition contained
+" color channel information
+syn keyword lessFunction hue saturation lightness red green blue alpha luma containedin=cssDefinition contained
+" color operations
+syn keyword lessFunction saturate desaturate lighten darken fadein fadeout fade spin mix greyscale contrast containedin=cssDefinition contained
+" color blending
+syn keyword lessFunction multiply screen overlay softlight hardlight difference exclusion average negation containedin=cssDefinition contained
+
+" }}}
syn match lessComment "//.*$" contains=@Spell
@@ -38,7 +58,7 @@ hi def link lessComment Comment
hi def link lessFunction Function
hi def link lessMixinChar Special
hi def link lessAmpersandChar Special
+hi def link lessNestedProperty Type
hi def link lessClass PreProc
let b:current_syntax = "less"
-
View
16 vim/bundle/vim-rails/CONTRIBUTING.markdown
@@ -0,0 +1,16 @@
+If your [commit message sucks][suck], I'm not going to accept your pull
+request. I've explained very politely dozens of times that [my general
+guidelines][guidelines] are absolute rules on my own repositories, so I may
+lack the energy to explain it to you yet another time. And please, if I ask
+you to change something, `git commit --amend` and `git push -f`.
+
+If a feature idea is nontrivial, you should probably open an issue to [discuss
+it][] before attempting a pull request. One of the biggest challenges in
+maintaining rails.vim has been beating back the bloat, so do not assume that
+your idea will make the cut. And if I like your idea, I'm generally amenable
+to just knocking it out myself, rather than making you familiarize yourself
+with a 4 thousand line code base.
+
+[suck]: http://stopwritingramblingcommitmessages.com/
+[guidelines]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+[discuss it]: http://www.igvita.com/2011/12/19/dont-push-your-pull-requests/
View
17 vim/bundle/vim-rails/README.markdown
@@ -114,23 +114,6 @@ meantime, here's how you can set up `:make` to run the current test:
autocmd User Bundler
\ if &makeprg !~# 'bundle' | setl makeprg^=bundle\ exec\ | endif
-## Contributing
-
-If your [commit message sucks](http://stopwritingramblingcommitmessages.com/),
-I'm not going to accept your pull request. I've explained very politely
-dozens of times that
-[my general guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
-are absolute rules on my own repositories, so I may lack the energy to
-explain it to you yet another time. And please, if I ask you to change
-something, `git commit --amend`.
-
-Beyond that, don't be shy about asking before patching. What takes you
-hours might take me minutes simply because I have both domain knowledge
-and a perverse knowledge of VimScript so vast that many would consider
-it a symptom of mental illness. On the flip side, some ideas I'll
-reject no matter how good the implementation is. "Send a patch" is an
-edge case answer in my book.
-
## Self-Promotion
Like rails.vim? Follow the repository on
View
554 vim/bundle/vim-rails/autoload/rails.vim
@@ -37,12 +37,15 @@ function! s:startswith(string,prefix)
return strpart(a:string, 0, strlen(a:prefix)) ==# a:prefix
endfunction
-function! s:uniq(list)
- let seen = {}
+function! s:uniq(list) abort
let i = 0
+ let seen = {}
while i < len(a:list)
- if has_key(seen,a:list[i])
- call remove(a:list, i)
+ if (a:list[i] ==# '' && exists('empty')) || has_key(seen,a:list[i])
+ call remove(a:list,i)
+ elseif a:list[i] ==# ''
+ let i += 1
+ let empty = 1
else
let seen[a:list[i]] = 1
let i += 1
@@ -73,6 +76,14 @@ function! s:rquote(str)
endif
endfunction
+function! s:fnameescape(file) abort
+ if exists('*fnameescape')
+ return fnameescape(a:file)
+ else
+ return escape(a:file," \t\n*?[{`$\\%#'\"|!<")
+ endif
+endfunction
+
function! s:sname()
return fnamemodify(s:file,':t:r')
endfunction
@@ -98,6 +109,10 @@ function! s:app_path(...) dict
return join([self.root]+a:000,'/')
endfunction
+function! s:app_has_path(path) dict
+ return getftime(a:path) != -1
+endfunction
+
function! s:app_has_file(file) dict
return filereadable(self.path(a:file))
endfunction
@@ -138,7 +153,7 @@ function! s:app_find_file(name, ...) dict abort
endtry
endfunction
-call s:add_methods('app',['path','has_file','find_file'])
+call s:add_methods('app',['path','has_path','has_file','find_file'])
" Split a path into a list. From pathogen.vim
function! s:pathsplit(path) abort
@@ -305,12 +320,10 @@ endfunction
function! s:find_projection(projections, filename) abort
let f = a:filename
for c in a:projections
- for prefix in s:split(get(c, 'prefix', []))
- for suffix in s:split(get(c, 'suffix', '.rb'))
- if s:startswith(f, prefix) && f[-strlen(suffix) : - 1] ==# suffix
- return [f[strlen(prefix) : -strlen(suffix)-1], c]
- endif
- endfor
+ for [prefix, suffix] in s:projection_pairs(c)
+ if s:startswith(f, prefix) && f[-strlen(suffix) : - 1] ==# suffix
+ return [f[strlen(prefix) : -strlen(suffix)-1], c]
+ endif
endfor
endfor
return ['', {}]
@@ -825,11 +838,7 @@ function! s:app_has(feature) dict
let features = self.cache.get('features')
if !has_key(features,a:feature)
let path = get(map,a:feature,a:feature.'/')
- if path =~# '/$'
- let features[a:feature] = isdirectory(rails#app().path(path))
- else
- let features[a:feature] = filereadable(rails#app().path(path))
- endif
+ let features[a:feature] = rails#app().has_path(path)
endif
return features[a:feature]
endfunction
@@ -852,12 +861,14 @@ function! s:app_ruby_shell_command(cmd) dict abort
endfunction
function! s:app_script_shell_command(cmd) dict abort
- if !empty(glob(rails#app().path('.zeus.sock'))) && a:cmd =~# '^\%(console\|dbconsole\|destroy\|generate\|server\|runner\)\>'
+ if rails#app().has_path('.zeus.sock') && a:cmd =~# '^\%(console\|dbconsole\|destroy\|generate\|server\|runner\)\>'
return 'zeus '.a:cmd
- elseif self.has_file('script/rails')
+ elseif self.has_path('script/rails')
let cmd = 'script/rails '.a:cmd
- elseif self.has_file('script/' . matchstr(a:cmd, '\w\+'))
+ elseif self.has_path('script/' . matchstr(a:cmd, '\w\+'))
let cmd = 'script/'.a:cmd
+ elseif self.has_path('bin/rails')
+ let cmd = 'bin/rails '.a:cmd
elseif self.has('bundler')
return 'bundle exec rails ' . a:cmd
else
@@ -929,9 +940,10 @@ call s:add_methods('app', ['ruby_shell_command','script_shell_command','execute_
" Commands {{{1
function! s:BufCommands()
- call s:BufFinderCommands()
call s:BufNavCommands()
call s:BufScriptWrappers()
+ command! -buffer -bar -nargs=+ Rnavcommand :call s:Navcommand(<bang>0,<f-args>)
+ command! -buffer -bar -nargs=* -bang Rabbrev :call s:Abbrev(<bang>0,<f-args>)
command! -buffer -bar -nargs=? -bang -count -complete=customlist,s:Complete_rake Rake :call s:Rake(<bang>0,!<count> && <line1> ? -1 : <count>,<q-args>)
command! -buffer -bar -nargs=? -bang -range -complete=customlist,s:Complete_preview Rpreview :call s:Preview(<bang>0,<line1>,<q-args>)
command! -buffer -bar -nargs=? -bang -complete=customlist,s:Complete_environments Rlog :call s:Log(<bang>0,<q-args>)
@@ -981,26 +993,52 @@ function! s:Log(bang,arg)
endif
endfunction
-function! rails#new_app_command(bang,...)
- if a:0 == 0
- if a:bang
- echo msg
- else
- !rails
- endif
- return
+function! rails#new_app_command(bang,...) abort
+ if !a:0 && a:bang
+ echo "rails.vim ".g:autoloaded_rails
+ elseif !a:0 || a:1 !=# 'new'
+ return 'echoerr '.string('Usage: rails new <path>')
endif
- let args = map(copy(a:000),'expand(v:val)')
+
+ let args = copy(a:000)
if a:bang
- let args = ['--force'] + args
+ let args += ['--force']
endif
- exe '!rails '.join(map(copy(args),'s:rquote(v:val)'),' ')
- for dir in args
- if dir !~# '^-' && filereadable(dir.'/README')
- edit `=dir.'/README'`
- return
+
+ if &shellpipe !~# 'tee' && index(args, '--skip') < 0 && index(args, '--force') < 0
+ let args += ['--skip']
+ endif
+
+ let temp = tempname()
+ try
+ exe '!rails' join(map(copy(args),'s:rquote(v:val)'),' ') &shellpipe temp
+ catch /^Vim:Interrupt/
+ endtry
+
+ if filereadable(expand(args[1]))
+ let lines = readfile(temp)
+ if get(lines, 0, '') =~# ' $'
+ let pos = '2cc'
+ let lines[0] .= '.'
+ call writefile(lines, temp)
+ else
+ let pos = 'cfirst'
endif
- endfor
+
+ let old_errorformat = &l:errorformat
+ let chdir = exists("*haslocaldir") && haslocaldir() ? 'lchdir' : 'chdir'
+ let cwd = getcwd()
+ try
+ exe chdir s:fnameescape(expand(args[1]))
+ let &l:errorformat = s:efm_generate
+ exe 'cgetfile' temp
+ exe pos
+ finally
+ let &l:errorformat = old_errorformat
+ exe chdir s:fnameescape(cwd)
+ endtry
+ endif
+ return ''
endfunction
function! s:app_tags_command() dict
@@ -1020,10 +1058,10 @@ function! s:app_tags_command() dict
call s:error("ctags not found")
return ''
endif
- if !isdirectory(self.path('tmp'))
+ if !self.has_path('tmp')
call mkdir(self.path('tmp'), 'p')
endif
- exe '!'.cmd.' -f '.s:escarg(self.path("tmp/tags")).' -R --langmap="ruby:+.rake.builder.rjs" '.g:rails_ctags_arguments.' '.s:escarg(self.path())
+ exe '!'.cmd.' -f '.s:escarg(self.path("tags")).' -R --langmap="ruby:+.rake.builder.rjs" '.g:rails_ctags_arguments.' '.s:escarg(self.path())
return ''
endfunction
@@ -1076,7 +1114,8 @@ function! s:app_rake_tasks() dict
if self.cache.needs('rake_tasks')
call s:push_chdir()
try
- let lines = split(system("rake -T"),"\n")
+ let output = system(self.has_path('bin/rake') ? self.ruby_shell_command('bin/rake -T') : 'rake -T')
+ let lines = split(output, "\n")
finally
call s:pop_command()
endtry
@@ -1124,9 +1163,12 @@ function! s:Rake(bang,lnum,arg)
let old_makeprg = &l:makeprg
let old_errorformat = &l:errorformat
try
- if !empty(glob(rails#app().path('.zeus.sock'))) && executable('zeus')
+ call s:push_chdir(1)
+ if rails#app().has_path('.zeus.sock') && executable('zeus')
let &l:makeprg = 'zeus rake'
- elseif exists('b:bundler_root') && b:bundler_root ==# rails#app().path()
+ elseif rails#app().has_path('bin/rake')
+ let &l:makeprg = rails#app().ruby_shell_command('bin/rake')
+ elseif rails#app().has('bundler')
let &l:makeprg = 'bundle exec rake'
else
let &l:makeprg = 'rake'
@@ -1154,10 +1196,7 @@ function! s:Rake(bang,lnum,arg)
let withrubyargs = '-r ./config/boot -r '.s:rquote(self.path('config/environment')).' -e "puts \%((in \#{Dir.getwd}))" '
if arg =~# '^notes\>'
let &l:errorformat = '%-P%f:,\ \ *\ [%*[\ ]%l]\ [%t%*[^]]] %m,\ \ *\ [%*[\ ]%l] %m,%-Q'
- " %D to chdir is apparently incompatible with %P multiline messages
- call s:push_chdir(1)
exe 'make! '.arg
- call s:pop_command()
if !a:bang
cwindow
endif
@@ -1201,6 +1240,7 @@ function! s:Rake(bang,lnum,arg)
finally
let &l:errorformat = old_errorformat
let &l:makeprg = old_makeprg
+ call s:pop_command()
endtry
endfunction
@@ -1443,22 +1483,30 @@ endfunction
function! s:BufScriptWrappers()
command! -buffer -bang -bar -nargs=* -complete=customlist,s:Complete_script Rscript :execute rails#app().script_command(<bang>0,<f-args>)
command! -buffer -bang -bar -nargs=* -complete=customlist,s:Complete_script Rails :execute rails#app().script_command(<bang>0,<f-args>)
- command! -buffer -bar -nargs=* -complete=customlist,s:Complete_generate Rgenerate :execute rails#app().generate_command(<bang>0,<f-args>)
- command! -buffer -bar -nargs=* -complete=customlist,s:Complete_destroy Rdestroy :execute rails#app().destroy_command(<bang>0,<f-args>)
+ command! -buffer -bang -bar -nargs=* -complete=customlist,s:Complete_generate Rgenerate :execute rails#app().generator_command(<bang>0,'generate',<f-args>)
+ command! -buffer -bar -nargs=* -complete=customlist,s:Complete_destroy Rdestroy :execute rails#app().generator_command(1,'destroy',<f-args>)
command! -buffer -bar -nargs=? -bang -complete=customlist,s:Complete_server Rserver :execute rails#app().server_command(<bang>0,<q-args>)
command! -buffer -bang -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rrunner :execute rails#app().runner_command(<bang>0 ? -2 : (<count>==<line2>?<count>:-1),<f-args>)
command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rp :execute rails#app().runner_command(<count>==<line2>?<count>:-1,'p begin '.<f-args>.' end')
command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rpp :execute rails#app().runner_command(<count>==<line2>?<count>:-1,'require %{pp}; pp begin '.<f-args>.' end')
command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Ry :execute rails#app().runner_command(<count>==<line2>?<count>:-1,'y begin '.<f-args>.' end')
endfunction
+function! s:app_gems() dict abort
+ if self.has('bundler') && exists('*bundler#project')
+ return bundler#project(self.path()).gems()
+ else
+ return {}
+ endif
+endfunction
+
function! s:app_generators() dict abort
if self.cache.needs('generators')
let paths = [self.path('vendor/plugins/*'), self.path('lib'), expand("~/.rails")]
- if self.has('bundler') && exists('*bundler#project')
- let gems = values(bundler#project(self.path()).gems())
- let paths += map(copy(gems), 'v:val . "/lib/rails"')
- let paths += map(copy(gems), 'v:val . "/lib"')
+ if !empty(self.gems())
+ let gems = values(self.gems())
+ let paths += map(values(self.gems()), 'v:val . "/lib/rails"')
+ let paths += map(values(self.gems()), 'v:val . "/lib"')
let builtin = []
else
let builtin = ['assets', 'controller', 'generator', 'helper', 'integration_test', 'jbuilder', 'jbuilder_scaffold_controller', 'mailer', 'migration', 'model', 'resource', 'scaffold', 'scaffold_controller', 'task']
@@ -1478,8 +1526,10 @@ function! s:app_script_command(bang,...) dict
let msg = "rails.vim ".g:autoloaded_rails
if a:0 == 0 && a:bang && rails#buffer().type_name() == ''
echo msg." (Rails)"
+ return
elseif a:0 == 0 && a:bang
echo msg." (Rails-".rails#buffer().type_name().")"
+ return
endif
let str = ""
let cmd = a:0 ? a:1 : "console"
@@ -1562,58 +1612,43 @@ function! s:app_server_command(bang,arg) dict
return ''
endfunction
-function! s:app_destroy_command(bang,...) dict
- if a:0 == 0
- return self.execute_script_command('destroy')
- elseif a:0 == 1
- return self.execute_script_command('destroy '.s:rquote(a:1))
- endif
- let str = ""
- let c = 1
- while c <= a:0
- let str .= " " . s:rquote(a:{c})
- let c += 1
- endwhile
- call self.execute_script_command('destroy'.str)
- call self.cache.clear('user_classes')
- return ''
+function! s:color_efm(pre, before, after)
+ return a:pre . '%\S%# %#' . a:before . "\e[0m %#" . a:after . ',' .
+ \ a:pre . ' %#'.a:before.' %#'.a:after . ','
endfunction
-function! s:app_generate_command(bang,...) dict
- if a:0 == 0
- return self.execute_script_command('generate')
- elseif a:0 == 1
- return self.execute_script_command('generate '.s:rquote(a:1))
- endif
+let s:efm_generate =
+ \ s:color_efm('%-G', 'invoke', '%f') .
+ \ s:color_efm('%-G', 'conflict', '%f') .
+ \ s:color_efm('%-G', 'run', '%f') .
+ \ s:color_efm('Overwrite%.%#', '%m', '%f') .
+ \ s:color_efm('', '%m', '%f') .
+ \ '%-G%.%#'
+
+function! s:app_generator_command(bang,...) dict
+ call self.cache.clear('user_classes')
+ call self.cache.clear('features')
let cmd = join(map(copy(a:000),'s:rquote(v:val)'),' ')
- if cmd !~ '-p\>' && cmd !~ '--pretend\>'
- let execstr = self.script_shell_command('generate '.cmd.' -p -f')
+ let old_makeprg = &l:makeprg
+ let old_errorformat = &l:errorformat
+ try
+ let &l:makeprg = self.script_shell_command(cmd)
+ let &l:errorformat = s:efm_generate
call s:push_chdir(1)
- try
- let res = system(execstr)
- finally
- call s:pop_command()
- endtry
- let junk = '\%(\e\[[0-9;]*m\)\='
- let file = matchstr(res,junk.'\s\+\%(create\|force\)'.junk.'\s\+\zs\f\+\.rb\ze\n')
- if file == ""
- let file = matchstr(res,junk.'\s\+\%(identical\)'.junk.'\s\+\zs\f\+\.rb\ze\n')
- endif
- else
- let file = ""
- endif
- if !self.execute_script_command('generate '.cmd) && file != ''
- call self.cache.clear('user_classes')
- call self.cache.clear('features')
- if file =~ '^db/migrate/\d\d\d\d'
- let file = get(self.relglob('',s:sub(file,'\d+','[0-9]*[0-9]')),-1,file)
+ if a:bang
+ make!
+ else
+ make
endif
- edit `=self.path(file)`
- endif
+ finally
+ call s:pop_command()
+ let &l:errorformat = old_errorformat
+ let &l:makeprg = old_makeprg
+ endtry
return ''
endfunction
-call s:add_methods('app', ['generators','script_command','runner_command','server_command','destroy_command','generate_command'])
+call s:add_methods('app', ['gems','generators','script_command','runner_command','server_command','generator_command'])
function! s:Complete_script(ArgLead,CmdLine,P)
let cmd = s:sub(a:CmdLine,'^\u\w*\s+','')
@@ -1639,8 +1674,10 @@ function! s:Complete_script(ArgLead,CmdLine,P)
\ rails#app().relglob('features/', '**/*', '.feature'), a:ArgLead)
elseif target ==# 'migration' || target ==# 'session_migration'
return s:migrationList(a:ArgLead,"","")
+ elseif target ==# 'mailer'
+ return s:mailerList(a:ArgLead,"","")
elseif target =~# '^\w*\%(model\|resource\)$' || target =~# '\w*scaffold\%(_controller\)\=$' || target ==# 'mailer'
- return s:modelList(a:ArgLead,"","")
+ return s:completion_filter(rails#app().relglob('app/models/','**/*','.rb'), a:ArgLead)
else
return []
endif
@@ -2120,18 +2157,17 @@ function! s:RailsIncludefind(str,...)
endfunction
" }}}1
-" File Finders {{{1
+" Projection Commands {{{1
function! s:addfilecmds(type)
let l = s:sub(a:type,'^.','\l&')
for prefix in ['E', 'S', 'V', 'T', 'D', 'R', 'RE', 'RS', 'RV', 'RT', 'RD']
let cplt = " -complete=customlist,".s:sid.l."List"
- exe "command! -buffer -bar ".(prefix =~# 'D' ? '-range=0 ' : '')."-nargs=*".cplt." ".prefix.l." :execute s:".l.'Edit("'.(prefix =~# 'D' ? '<line1>' : '').prefix.'<bang>",<f-args>)'
+ exe "command! -buffer -bar ".(prefix =~# 'D' ? '-range=0 ' : '')."-nargs=*".cplt." ".prefix.l." :execute s:".l.'Edit("'.(prefix =~# 'D' ? '<line1>' : '').s:sub(prefix, '^R', '').'<bang>",<f-args>)'
endfor
endfunction
-function! s:BufFinderCommands()
- command! -buffer -bar -nargs=+ Rnavcommand :call s:Navcommand(<bang>0,<f-args>)
+function! s:BufProjectionCommands()
call s:define_navcommand('environment', {
\ 'prefix': 'config/environments/',
\ 'default': ['config/application.rb', 'config/environment.rb']})
@@ -2198,7 +2234,7 @@ function! s:BufFinderCommands()
\ 'spec/features/': "require 'spec_helper'\n\ndescribe \"%h\" do\nend",
\ 'spec/integration/': "require 'spec_helper'\n\ndescribe \"%h\" do\nend",
\ 'features/': "Feature: %h",
- \ 'spec/acceptance': "Feature: %h"},
+ \ 'spec/acceptance/': "Feature: %h"},
\ 'default': [
\ 'test/test_helper.rb',
\ 'features/support/env.rb',
@@ -2391,14 +2427,26 @@ function! s:Navcommand(bang,...)
return s:define_navcommand(name, command)
endfunction
-function! s:define_navcommand(name, command) abort
- let command = extend({'default': '', 'glob': '**/*'}, a:command)
- let command.prefix = s:split(get(command, 'prefix', []))
- let command.suffix = s:split(get(command, 'suffix', ['.rb']))
- if has_key(command, 'affinity') && command.default ==# ''
- let command.default = command.affinity . '()'
+function! s:define_navcommand(name, projection) abort
+ let projection = extend({'default': '', 'glob': '**/*'}, a:projection)
+ if !has_key(projection, 'format')
+ let projection.prefix = s:split(get(projection, 'prefix', []))
+ let projection.suffix = s:split(get(projection, 'suffix', ['.rb']))
+ if empty(projection.prefix)
+ return
+ endif
+ endif
+ if has_key(projection, 'affinity') && empty(projection.default)
+ let projection.default = projection.affinity . '()'
+ endif
+ if get(projection, 'command', 1) =~# '^0\=$'
+ return
+ endif
+ if type(get(projection, 'command', 1)) ==# type('')
+ let name = projection.command
+ else
+ let name = s:gsub(a:name, '[[:space:][:punct:]]', '')
endif
- let name = s:gsub(a:name, ' ', '')
if name !~# '^[a-z]\+$'
return s:error("E182: Invalid command name ".name)
endif
@@ -2408,12 +2456,13 @@ function! s:define_navcommand(name, command) abort
\ '-complete=customlist,'.s:sid.'CommandList ' .
\ prefix . name . ' :execute s:CommandEdit(' .
\ string((prefix =~# 'D' ? '<line1>' : '') . s:sub(prefix, '^R', '') . "<bang>") . ',' .
- \ string(a:name) . ',' . string(command) . ',<f-args>)'
+ \ string(a:name) . ',' . string(projection) . ',<f-args>)'
endfor
endfunction
function! s:CommandList(A,L,P)
- let cmd = matchstr(a:L,'\CR[A-Z]\=\w\+')
+ let cmd = matchstr(a:L,'\C[A-Z]\w\+')
+ let g:cmd = cmd
exe cmd." &"
let command = s:last_options
let matches = []
@@ -2558,7 +2607,8 @@ function! s:localeEdit(cmd,...)
if c =~# '\.'
return s:edit(a:cmd,rails#app().find_file(c,'config/locales',[],'config/locales/'.c))
else
- return s:findedit(a:cmd,rails#app().find_file(c,'config/locales',['.yml','.rb'],'config/locales/'.c))
+ return rails#buffer().open_command(a:cmd, c, 'locale', {
+ \ 'format': ['config/locales/%s.yml', 'config/locales/%s.rb']})
endif
endfunction
@@ -2818,7 +2868,9 @@ function! s:projection_pairs(options)
let pairs = []
if has_key(a:options, 'format')
for format in s:split(a:options.format)
- let pairs += [s:split(format, '%s')]
+ if format =~# '%s'
+ let pairs += [s:split(format, '%s')]
+ endif
endfor
else
for prefix in s:split(get(a:options, 'prefix', []))
@@ -2851,11 +2903,11 @@ function! s:readable_open_command(cmd, argument, name, options) dict abort
endif
elseif a:argument ==# '' && type(default) == type([])
for file in default
- if self.app().has_file(file)
- return cmd . ' ' . fnameescape(self.app().path(file))
+ if self.app().has_path(file)
+ return cmd . ' ' . s:fnameescape(self.app().path(file))
endif
endfor
- return cmd . ' ' . fnameescape(self.app().path(a:default[0]))
+ return cmd . ' ' . s:fnameescape(self.app().path(a:default[0]))
else
let root = a:argument
endif
@@ -2864,16 +2916,19 @@ function! s:readable_open_command(cmd, argument, name, options) dict abort
endif
let pairs = s:projection_pairs(a:options)
for [prefix, suffix] in pairs
+ if root ==# '.' && self.app().has_path(prefix)
+ return cmd . ' ' . s:fnameescape(rails#app().path(prefix))
+ endif
let file = self.app().path(prefix . (suffix =~# '\.rb$' ? rails#underscore(root) : root) . suffix)
if filereadable(file)
- return cmd . ' ' . fnameescape(simplify(file)) . '|exe ' . s:sid . 'djump('.string(djump) . ')'
+ return cmd . ' ' . s:fnameescape(simplify(file)) . '|exe ' . s:sid . 'djump('.string(djump) . ')'
endif
endfor
if djump !~# '^!'
- return 'echoerr '.string('No such '.a:name.' '.a:argument)
+ return 'echoerr '.string('No such '.tr(a:name, '_', ' ').' '.a:argument)
endif
for [prefix, suffix] in pairs
- if isdirectory(self.app().path(prefix))
+ if self.app().has_path(prefix)
let file = self.app().path(prefix . (suffix =~# '\.rb$' ? rails#underscore(root) : root) . suffix)
if !isdirectory(fnamemodify(file, ':h'))
call mkdir(fnamemodify(file, ':h'), 'p')
@@ -2888,9 +2943,12 @@ function! s:readable_open_command(cmd, argument, name, options) dict abort
\ '%S': rails#camelize(root),
\ '%h': toupper(root[0]) . tr(rails#underscore(root), '_', ' ')[1:-1],
\ '%%': '%'}
+ if suffix =~# '\.js\>'
+ let placeholders['%S'] = s:gsub(placeholders['%S'], '::', '.')
+ endif
call map(template, 'substitute(v:val, "%.", "\\=get(placeholders, submatch(0), submatch(0))", "g")')
call map(template, 's:gsub(v:val, "\t", " ")')
- return cmd . ' ' . fnameescape(simplify(file)) . '|call setline(1, '.string(template).')' . '|set nomod'
+ return cmd . ' ' . s:fnameescape(simplify(file)) . '|call setline(1, '.string(template).')' . '|set nomod'
endif
endfor
return 'echoerr '.string("Couldn't find destination directory for ".a:name.' '.a:argument)
@@ -2914,7 +2972,7 @@ function! s:findedit(cmd,files,...) abort
endif
if file == ''
let testcmd = "edit"
- elseif isdirectory(rails#app().path(file))
+ elseif rails#app().has_path(file.'/')
let arg = file == "." ? rails#app().path() : rails#app().path(file)
let testcmd = s:editcmdfor(cmd).' '.(a:0 ? a:1 . ' ' : '').s:escarg(arg)
exe testcmd
@@ -2955,11 +3013,11 @@ function! s:Alternate(cmd,line1,line2,count,...)
return call('s:Edit',[1,a:cmd]+a:000)
endif
else
- let file = s:getopt(a:count ? 'related' : 'alternate', 'bl')
- if file == ''
- let file = rails#buffer().related(a:count)
+ let file = [s:getopt(a:count ? 'related' : 'alternate', 'bl')]
+ if empty(file[0])
+ let file = rails#buffer().alternate(a:count)
endif
- if file != ''
+ if !empty(file)
call s:findedit(a:cmd,file)
else
call s:warn("No alternate file is defined")
@@ -2983,7 +3041,7 @@ function! s:Complete_related(A,L,P)
endif
endfunction
-function! s:readable_related(...) dict abort
+function! s:readable_alternate(...) dict abort
let f = self.name()
let [root, projection] = s:find_projection(values(self.app().projections()), f)
let placeholders = {
@@ -2998,191 +3056,170 @@ function! s:readable_related(...) dict abort
call filter(related, 'v:val !~# "%m"')
endif
if !empty(related)
- call map(related, 'substitute(v:val, "%.", "\\=get(placeholders, submatch(0), submatch(0))", "g")')
- return s:gsub(join(related, "\n"), '\%m', lastmethod)
+ return map(related, 's:gsub(substitute(v:val, "%.", "\\=get(placeholders, submatch(0), submatch(0))", "g"), "\\%m", lastmethod)')
endif
endif
if self.type_name('controller','mailer') && lastmethod != ""
let view = self.resolve_view(lastmethod, line('.'))
if view !=# ''
- return view
+ return [view]
else
- return s:sub(s:sub(s:sub(f,'/application%(_controller)=\.rb$','/shared_controller.rb'),'/%(controllers|models|mailers)/','/views/'),'%(_controller)=\.rb$','/'.lastmethod)
+ return [s:sub(s:sub(s:sub(f,'/application%(_controller)=\.rb$','/shared_controller.rb'),'/%(controllers|models|mailers)/','/views/'),'%(_controller)=\.rb$','/'.lastmethod)]
endif
- elseif f =~ '\<config/environments/'
- return "config/database.yml#". fnamemodify(f,':t:r')
- elseif f =~ '\<config/database\.yml$'
+ elseif f =~# '^config/environments/'
+ return ['config/database.yml#'. fnamemodify(f,':t:r')]
+ elseif f ==# 'config/database.yml'
if lastmethod != ""
- return "config/environments/".lastmethod.".rb"
+ return ['config/environments/'.lastmethod.'.rb']
else
- return "config/application.rb\nconfig/environment.rb"
+ return ['config/application.rb', 'config/environment.rb']
endif
- elseif f =~ '\<config/routes\.rb$' | return "config/database.yml"
- elseif f =~ '\<config/\%(application\|environment\)\.rb$'
- return "config/routes.rb"
elseif self.type_name('view-layout')
- return s:sub(s:sub(f,'/views/','/controllers/'),'/layouts/(\k+)\..*$','/\1_controller.rb')
+ return [s:sub(s:sub(f,'/views/','/controllers/'),'/layouts/(\k+)\..*$','/\1_controller.rb')]
elseif self.type_name('view')
let controller = s:sub(s:sub(f,'/views/','/controllers/'),'/(\k+%(\.\k+)=)\..*$','_controller.rb#\1')
let controller2 = s:sub(s:sub(f,'/views/','/controllers/'),'/(\k+%(\.\k+)=)\..*$','.rb#\1')
let mailer = s:sub(s:sub(f,'/views/','/mailers/'),'/(\k+%(\.\k+)=)\..*$','.rb#\1')
let model = s:sub(s:sub(f,'/views/','/models/'),'/(\k+)\..*$','.rb#\1')
if self.app().has_file(s:sub(controller,'#.{-}$',''))
- return controller
+ return [controller]
elseif self.app().has_file(s:sub(controller2,'#.{-}$',''))
- return controller2
+ return [controller2]
elseif self.app().has_file(s:sub(mailer,'#.{-}$',''))
- return mailer
+ return [mailer]
elseif self.app().has_file(s:sub(model,'#.{-}$','')) || model =~ '_mailer\.rb#'
- return model
+ return [model]
else
- return controller
+ return [controller]
endif
elseif self.type_name('controller')
- return s:sub(s:sub(f,'/controllers/','/helpers/'),'%(_controller)=\.rb$','_helper.rb')
+ return [s:sub(s:sub(f,'/controllers/','/helpers/'),'%(_controller)=\.rb$','_helper.rb')]
elseif self.type_name('model-arb')
let table_name = matchstr(join(self.getline(1,50),"\n"),'\n\s*self\.table_name\s*=\s*[:"'']\zs\w\+')
if table_name == ''
let table_name = rails#pluralize(s:gsub(s:sub(fnamemodify(f,':r'),'.{-}<app/models/',''),'/','_'))
endif
- return self.app().migration('0#'.table_name)
+ return ['db/schema.rb#'.table_name]
elseif self.type_name('model-aro')
- return s:sub(f,'_observer\.rb$','.rb')
- elseif self.type_name('db-schema')
- return self.app().migration(1)
+ return [s:sub(f,'_observer\.rb$','.rb')]
+ elseif self.type_name('db-schema') && !empty(lastmethod)
+ return ['app/models/' . rails#singularize(lastmethod) . '.rb']
endif
endif
if root !=# '' && has_key(projection, 'alternate')
- return join(map(s:split(projection.alternate), 'substitute(v:val, "%.", "\\=get(placeholders, submatch(0), submatch(0))", "g")'), "\n")
- endif
- if f =~ '\<config/environments/'
- return "config/application.rb\nconfig/environment.rb"
- elseif f == 'README'
- return "config/database.yml"
- elseif f =~ '\<config/database\.yml$' | return "config/routes.rb"
- elseif f =~ '\<config/routes\.rb$'
- return "config/application.rb\nconfig/environment.rb"
- elseif f =~ '\<config/\%(application\|environment\)\.rb$'
- return "config/database.yml"
+ return map(s:split(projection.alternate), 'substitute(v:val, "%.", "\\=get(placeholders, submatch(0), submatch(0))", "g")')
+ endif
+ if f =~# '^config/environments/'
+ return ['config/application.rb', 'config/environment.rb']
+ elseif f =~# '\.example\.yml$\|\.yml\.example$'
+ return [s:sub(f, '\.example\.yml$|\.yml\.example$', '.yml')]
+ elseif f =~# '\.yml$'
+ return [s:sub(f, '\.yml$', '\.example.yml'), f . '.example']
+ elseif f =~# '^README\%(\.\w\+\)\=$'
+ return ['config/database.yml']
+ elseif f ==# 'config/routes.rb'
+ return ['config/application.rb', 'config/environment.rb']
+ elseif f =~# '^config/\%(application\|environment\)\.rb$'
+ return ['config/routes.rb']
elseif f ==# 'Gemfile'
- return 'Gemfile.lock'
+ return ['Gemfile.lock']
elseif f ==# 'Gemfile.lock'
- return 'Gemfile'
- elseif f =~ '\<db/migrate/'
+ return ['Gemfile']
+ elseif f =~# '^db/migrate/'
let migrations = sort(self.app().relglob('db/migrate/','*','.rb'))
let me = matchstr(f,'\<db/migrate/\zs.*\ze\.rb$')
- if !exists('l:lastmethod') || lastmethod == 'down'
+ if !exists('lastmethod') || lastmethod == 'down' || (a:0 && a:1 == 1)
let candidates = reverse(filter(copy(migrations),'v:val < me'))
let migration = "db/migrate/".get(candidates,0,migrations[-1]).".rb"
else
let candidates = filter(copy(migrations),'v:val > me')
let migration = "db/migrate/".get(candidates,0,migrations[0]).".rb"
endif
- return migration . (exists('l:lastmethod') && lastmethod != '' ? '#'.lastmethod : '')
- elseif f =~ '\<application\.js$'
- return "app/helpers/application_helper.rb"
+ return [migration . (exists('lastmethod') && !empty(lastmethod) ? '#'.lastmethod : '')]
+ elseif f =~# '\<application\.js$'
+ return ['app/helpers/application_helper.rb']
elseif self.type_name('javascript')
- return "public/javascripts/application.js"
- elseif self.type_name('db/schema')
- return self.app().migration('')
+ return ['app/assets/javascripts/application.js', 'public/javascripts/application.js']
+ elseif self.type_name('db-schema') || f =~# '^db/\w\+_structure.sql$'
+ return ['db/seeds.rb']
+ elseif f ==# 'db/seeds.rb'
+ return ['db/schema.rb', 'db/'.s:environment().'_structure.sql']
elseif self.type_name('view')
let spec1 = fnamemodify(f,':s?\<app/?spec/?')."_spec.rb"
let spec2 = fnamemodify(f,':r:s?\<app/?spec/?')."_spec.rb"
let spec3 = fnamemodify(f,':r:r:s?\<app/?spec/?')."_spec.rb"
if self.app().has_file(spec1)
- return spec1
+ return [spec1]
elseif self.app().has_file(spec2)
- return spec2
+ return [spec2]
elseif self.app().has_file(spec3)
- return spec3
+ return [spec3]
elseif self.app().has('spec')
- return spec2
+ return [spec2]
else
if self.type_name('view-layout')
let dest = fnamemodify(f,':r:s?/layouts\>??').'/layout.'.fnamemodify(f,':e')
else
let dest = f
endif
- return s:sub(s:sub(dest,'<app/views/','test/functional/'),'/[^/]*$','_controller_test.rb')
+ return [s:sub(s:sub(dest,'<app/views/','test/functional/'),'/[^/]*$','_controller_test.rb')]
endif
elseif self.type_name('controller-api')
- let api = s:sub(s:sub(f,'/controllers/','/apis/'),'_controller\.rb$','_api.rb')
- return api
+ return [s:sub(s:sub(f,'/controllers/','/apis/'),'_controller\.rb$','_api.rb')]
elseif self.type_name('api')
- return s:sub(s:sub(f,'/apis/','/controllers/'),'_api\.rb$','_controller.rb')
+ return [s:sub(s:sub(f,'/apis/','/controllers/'),'_api\.rb$','_controller.rb')]
+ elseif self.type_name('lib')
+ return [s:sub(f,'<lib/(.*)\.rb$','test/lib/\1_test.rb'),
+ \ s:sub(f,'<lib/(.*)\.rb$','test/unit/\1_test.rb'),
+ \ s:sub(f,'<lib/(.*)\.rb$','spec/lib/\1_spec.rb')]
elseif self.type_name('fixtures') && f =~ '\<spec/'
- let file = rails#singularize(fnamemodify(f,":t:r")).'_spec.rb'
- return file
+ return ['spec/models/' . self.model_name() . '_spec.rb']
elseif self.type_name('fixtures')
- let file = rails#singularize(fnamemodify(f,":t:r")).'_test.rb'
- return file
- elseif f == ''
- call s:warn("No filename present")
- elseif f =~ '\<test/unit/routing_test\.rb$'
- return 'config/routes.rb'
- elseif self.type_name('spec-view')
- return s:sub(s:sub(f,'<spec/','app/'),'_spec\.rb$','')
- elseif fnamemodify(f,":e") == "rb"
- let file = fnamemodify(f,":r")
- if file =~ '_\%(test\|spec\)$'
- let file = s:sub(file,'_%(test|spec)$','.rb')
- let app_and_test_swap = s:sub(file, '<%(test|spec)/', 'app/')
- else
- let file .= '_test.rb'
- let app_and_test_swap = s:sub(file,'<app/','test/')
- endif
- if self.type_name('helper')
- return app_and_test_swap."\n".
- \s:sub(file,'<app/helpers/','test/unit/helpers/')."\n".
- \s:sub(s:sub(file,'_test\.rb$','_spec.rb'),'<app/helpers/','spec/helpers/')
- elseif self.type_name('model')
- return app_and_test_swap."\n".
- \s:sub(file,'<app/models/','test/unit/')."\n".
- \s:sub(s:sub(file,'_test\.rb$','_spec.rb'),'<app/models/','spec/models/')
- elseif self.type_name('controller')
- return app_and_test_swap."\n".
- \s:sub(file,'<app/controllers/','test/functional/')."\n".
- \s:sub(s:sub(file,'_test\.rb$','_spec.rb'),'app/controllers/','spec/controllers/')
- elseif self.type_name('mailer')
- return app_and_test_swap."\n".
- \s:sub(file,'<app/m%(ailer|odel)s/','test/unit/')."\n".
- \s:sub(s:sub(file,