summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-03-23 08:22:34 +1100
committerMaxime Coste <mawww@kakoune.org>2018-03-23 08:22:34 +1100
commita732037b539db23010fcb379d643159670e05960 (patch)
treee0bd8f7a579310e86572858e12e5a3379a70fb31
parent42404ddb3a6822fd5777e7d2582b2fe74b43c48b (diff)
Support `%` in `path` option to mean current buffer directory
In the end, % is not that painful to work with as its only set seldomly, and we usually dont need to use expansion at the same time. Moreover, it just requires a single \ to be escaped. Fixes #1562
-rw-r--r--src/file.cc13
-rw-r--r--src/file.hh6
-rw-r--r--src/insert_completer.cc7
-rw-r--r--src/main.cc2
-rw-r--r--src/normal.cc7
5 files changed, 24 insertions, 11 deletions
diff --git a/src/file.cc b/src/file.cc
index f4db41b6..49a1e6ab 100644
--- a/src/file.cc
+++ b/src/file.cc
@@ -48,14 +48,21 @@ public:
: runtime_error(format("fd {}: {}", fd, error_desc)) {}
};
-String parse_filename(StringView filename)
+String parse_filename(StringView filename, StringView buf_dir)
{
auto prefix = filename.substr(0_byte, 2_byte);
if (prefix == "~" or prefix == "~/")
return homedir() + filename.substr(1_byte);
+ if ((prefix == "%" or prefix == "%/") and not buf_dir.empty())
+ return buf_dir + filename.substr(1_byte);
return filename.str();
}
+String parse_filename(StringView filename)
+{
+ return parse_filename(filename, {});
+}
+
std::pair<StringView, StringView> split_path(StringView path)
{
auto it = find(path | reverse(), '/');
@@ -331,7 +338,7 @@ void write_buffer_to_backup_file(Buffer& buffer)
}
}
-String find_file(StringView filename, ConstArrayView<String> paths)
+String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths)
{
struct stat buf;
if (filename.substr(0_byte, 1_byte) == "/")
@@ -348,7 +355,7 @@ String find_file(StringView filename, ConstArrayView<String> paths)
return "";
}
- for (auto candidate : paths | transform(parse_filename))
+ for (auto candidate : paths | transform([&](StringView s) { return parse_filename(s, buf_dir); }))
{
if (not candidate.empty() and candidate.back() != '/')
candidate += '/';
diff --git a/src/file.hh b/src/file.hh
index 232ff539..5986ab2f 100644
--- a/src/file.hh
+++ b/src/file.hh
@@ -19,8 +19,10 @@ class Regex;
using CandidateList = Vector<String, MemoryDomain::Completion>;
-// parse ~/ and $env values in filename and returns the translated filename
+// parse ~/ and %/ in filename and returns the translated filename
+String parse_filename(StringView filename, StringView buf_dir);
String parse_filename(StringView filename);
+
String real_path(StringView filename);
String compact_path(StringView filename);
@@ -54,7 +56,7 @@ void write_buffer_to_file(Buffer& buffer, StringView filename, bool force = fals
void write_buffer_to_fd(Buffer& buffer, int fd);
void write_buffer_to_backup_file(Buffer& buffer);
-String find_file(StringView filename, ConstArrayView<String> paths);
+String find_file(StringView filename, StringView buf_dir, ConstArrayView<String> paths);
bool file_exists(StringView filename);
Vector<String> list_files(StringView directory);
diff --git a/src/insert_completer.cc b/src/insert_completer.cc
index 5bd1efe7..8db65556 100644
--- a/src/insert_completer.cc
+++ b/src/insert_completer.cc
@@ -246,6 +246,13 @@ InsertCompletion complete_filename(const SelectionList& sels,
{
if (not dir.empty() and dir.back() != '/')
dir += '/';
+ if (dir.substr(0, 2_byte) == "%/")
+ {
+ if (not (buffer.flags() & Buffer::Flags::File))
+ continue;
+ dir = split_path(buffer.name()).first.str() + '/' + dir.substr(2_byte);
+ }
+
for (auto& filename : Kakoune::complete_filename(dir + prefix,
options["ignored_files"].get<Regex>()))
{
diff --git a/src/main.cc b/src/main.cc
index f1ae9f81..3ac73b42 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -323,7 +323,7 @@ void register_options()
Regex{});
reg.declare_option("filetype", "buffer filetype", ""_str);
reg.declare_option("path", "path to consider when trying to find a file",
- Vector<String, MemoryDomain::Options>({ "./", "/usr/include" }));
+ Vector<String, MemoryDomain::Options>({ "./", "%/", "/usr/include" }));
reg.declare_option("completers", "insert mode completers to execute.",
InsertCompleterDescList({
InsertCompleterDesc{ InsertCompleterDesc::Filename, {} },
diff --git a/src/normal.cc b/src/normal.cc
index 05a5246e..968293b6 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -278,11 +278,8 @@ void goto_commands(Context& context, NormalParams params)
return;
auto paths = context.options()["path"].get<Vector<String, MemoryDomain::Options>>();
- StringView buffer_dir = split_path(buffer.name()).first;
- if (not buffer_dir.empty())
- paths.insert(paths.begin(), buffer_dir.str());
-
- String path = find_file(filename, paths);
+ const StringView buffer_dir = split_path(buffer.name()).first;
+ String path = find_file(filename, buffer_dir, paths);
if (path.empty())
throw runtime_error(format("unable to find file '{}'", filename));