summaryrefslogtreecommitdiff
path: root/src/input_handler.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2013-08-02 17:58:37 +0100
committerMaxime Coste <frrrwww@gmail.com>2013-08-02 17:58:37 +0100
commit6b66a3dfe5362b51fe5eaf93d5b5e5ab80224d96 (patch)
tree46555a653d013fe74c64efd24928672e5527e722 /src/input_handler.cc
parentaf17010524a21800b595e91631196b6a4f47d7c9 (diff)
Add support for filename insert mode completion
Diffstat (limited to 'src/input_handler.cc')
-rw-r--r--src/input_handler.cc48
1 files changed, 42 insertions, 6 deletions
diff --git a/src/input_handler.cc b/src/input_handler.cc
index 133c85b1..20588487 100644
--- a/src/input_handler.cc
+++ b/src/input_handler.cc
@@ -10,6 +10,7 @@
#include "user_interface.hh"
#include "utf8.hh"
#include "window.hh"
+#include "file.hh"
#include <unordered_map>
@@ -544,6 +545,38 @@ static BufferCompletion complete_word(const Buffer& buffer,
return { begin.coord(), end.coord(), std::move(result), buffer.timestamp() };
}
+static bool is_filename(char c)
+{
+ return isalnum(c) or c == '/' or c == '.' or c == '_' or c == '-';
+}
+
+static BufferCompletion complete_filename(const Buffer& buffer,
+ BufferCoord cursor_pos,
+ memoryview<String> path)
+{
+ auto pos = buffer.iterator_at(cursor_pos);
+ auto begin = pos;
+
+ while (begin != buffer.begin() and is_filename(*(begin-1)))
+ --begin;
+
+ if (begin == pos)
+ return {};
+
+ String prefix{begin, pos};
+ std::vector<String> res;
+ for (auto dir : path)
+ {
+ if (not dir.empty() and dir.back() != '/')
+ dir += '/';
+ for (auto& filename : complete_filename(dir + prefix, Regex{}))
+ res.push_back(filename.substr(dir.length()));
+ }
+ if (res.empty())
+ return {};
+ return { begin.coord(), pos.coord(), std::move(res), buffer.timestamp() };
+}
+
static BufferCompletion complete_opt(const Buffer& buffer,
BufferCoord cursor_pos,
OptionManager& options)
@@ -701,14 +734,17 @@ private:
if (not m_completions.is_valid())
{
auto& buffer = m_context.buffer();
- auto& completers = options()["completers"].get<std::unordered_set<String>>();
+ auto& completers = options()["completers"].get<std::vector<String>>();
BufferCoord cursor_pos = m_context.editor().main_selection().last();
if (contains(completers, "option"))
- m_completions = complete_opt(buffer, cursor_pos, m_context.options());
+ m_completions = complete_opt(buffer, cursor_pos, options());
if (not m_completions.is_valid() and
- (contains(completers, "word=buffer") or
- contains(completers, "word=all")))
- m_completions = complete_word(buffer, cursor_pos, contains(completers, "word=all"));
+ (contains(completers, "word=buffer") or contains(completers, "word=all")))
+ m_completions = complete_word(buffer, cursor_pos,
+ contains(completers, "word=all"));
+ if (not m_completions.is_valid() and contains(completers, "filename"))
+ m_completions = complete_filename(buffer, cursor_pos,
+ options()["path"].get<std::vector<String>>());
if (not m_completions.is_valid())
return false;
@@ -717,7 +753,7 @@ private:
m_matching_candidates = m_completions.candidates;
m_current_candidate = m_matching_candidates.size();
menu_show();
- m_matching_candidates.push_back(m_context.buffer().string(m_completions.begin, m_completions.end));
+ m_matching_candidates.push_back(buffer.string(m_completions.begin, m_completions.end));
}
return true;
}