From 258637222f7897439e0ff7adef736f6cb163e10a Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 20 May 2013 14:10:53 +0200 Subject: [PATCH] Word completion can optionally look for candidates in all buffers completers option accept word=buffer or word=all values --- src/input_handler.cc | 33 +++++++++++++++++++++++++-------- src/option_manager.cc | 4 ++-- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/input_handler.cc b/src/input_handler.cc index 3d5d196c..f36fca9a 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -6,6 +6,7 @@ #include "event_manager.hh" #include "normal.hh" #include "register_manager.hh" +#include "buffer_manager.hh" #include "user_interface.hh" #include "utf8.hh" #include "window.hh" @@ -495,7 +496,7 @@ struct BufferCompletion bool is_valid() const { return begin.is_valid() and not candidates.empty(); } }; -static BufferCompletion complete_word(const BufferIterator& pos) +static BufferCompletion complete_word(const BufferIterator& pos, bool other_buffers) { if (pos.is_begin() or not is_word(*utf8::previous(pos))) return {}; @@ -512,17 +513,31 @@ static BufferCompletion complete_word(const BufferIterator& pos) Regex re(ex.begin(), ex.end()); using RegexIt = boost::regex_iterator; - CandidateList result; + std::unordered_set matches; for (RegexIt it(buffer.begin(), buffer.end(), re), re_end; it != re_end; ++it) { auto& match = (*it)[0]; if (match.first <= pos and pos < match.second) continue; - - String content = buffer.string(match.first, match.second); - if (not contains(result, content)) - result.emplace_back(std::move(content)); + matches.insert(buffer.string(match.first, match.second)); } + if (other_buffers) + { + for (const auto& buf : BufferManager::instance()) + { + if (buf.get() == &buffer) + continue; + for (RegexIt it(buf->begin(), buf->end(), re), re_end; it != re_end; ++it) + { + auto& match = (*it)[0]; + matches.insert(buf->string(match.first, match.second)); + } + } + } + CandidateList result; + std::copy(make_move_iterator(matches.begin()), + make_move_iterator(matches.end()), + inserter(result, result.begin())); std::sort(result.begin(), result.end()); return { begin, end, std::move(result), begin.buffer().timestamp() }; } @@ -670,8 +685,10 @@ private: BufferIterator cursor = m_context.editor().main_selection().last(); if (contains(completers, "option")) m_completions = complete_opt(cursor, m_context.options()); - if (not m_completions.is_valid() and contains(completers, "word")) - m_completions = complete_word(cursor); + if (not m_completions.is_valid() and + (contains(completers, "word=buffer") or + contains(completers, "word=all"))) + m_completions = complete_word(cursor, contains(completers, "word=all")); if (not m_completions.is_valid()) return false; diff --git a/src/option_manager.cc b/src/option_manager.cc index 80b78bbc..e3d78489 100644 --- a/src/option_manager.cc +++ b/src/option_manager.cc @@ -121,11 +121,11 @@ GlobalOptions::GlobalOptions() declare_option("filetype", ""); declare_option>("completions", {}); declare_option>("path", { "./", "/usr/include" }); - declare_option>("completers", {"option", "word"}, + declare_option>("completers", {"option", "word=buffer"}, [](const std::unordered_set& s) { for (auto& v : s) { - if (v != "option" and v != "word") + if (v != "option" and v != "word=buffer" and v != "word=all") throw runtime_error(v + " is not a recognised value for completers"); } });