diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2014-12-21 17:08:33 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2014-12-21 17:08:33 +0000 |
| commit | 7a7ad57871dc23882c482a52fbd258923b59cdf0 (patch) | |
| tree | c5791cff87240ea8343123deacb7f976d415ecc1 /src | |
| parent | 5b94b7315223bb30709700f886c8de9771f5657a (diff) | |
Support absolute paths when completing commands
Diffstat (limited to 'src')
| -rw-r--r-- | src/file.cc | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/src/file.cc b/src/file.cc index 5bab7304..0012d256 100644 --- a/src/file.cc +++ b/src/file.cc @@ -339,8 +339,6 @@ std::vector<String> complete_filename(StringView prefix, std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos) { String real_prefix = parse_filename(prefix.substr(0, cursor_pos)); - String dirname; - String fileprefix = real_prefix; ByteCount dir_end = -1; for (ByteCount i = 0; i < real_prefix.length(); ++i) @@ -349,6 +347,27 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos) dir_end = i; } + if (dir_end != -1) + { + auto dirname = real_prefix.substr(0, dir_end + 1); + auto fileprefix = real_prefix.substr(dir_end + 1); + auto filter = [&](const dirent& entry) + { + struct stat st; + if (stat((dirname + entry.d_name).c_str(), &st)) + return false; + bool executable = (st.st_mode & S_IXUSR) + | (st.st_mode & S_IXGRP) + | (st.st_mode & S_IXOTH); + return S_ISDIR(st.st_mode) or (S_ISREG(st.st_mode) and executable); + }; + std::vector<String> res = list_files(fileprefix, dirname, filter); + for (auto& file : res) + file = dirname + file; + std::sort(res.begin(), res.end()); + return res; + } + typedef decltype(stat::st_mtime) TimeSpec; struct CommandCache @@ -358,17 +377,8 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos) }; static UnorderedMap<String, CommandCache> command_cache; - std::vector<StringView> path; - if (dir_end != -1) - { - path.emplace_back(real_prefix.substr(0, dir_end + 1)); - fileprefix = real_prefix.substr(dir_end + 1); - } - else - path = split(getenv("PATH"), ':'); - std::vector<String> res; - for (auto dir : path) + for (auto dir : split(getenv("PATH"), ':')) { String dirname = dir; if (not dirname.empty() and dirname.back() != '/') @@ -396,7 +406,7 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos) } for (auto& cmd : cache.commands) { - if (prefix_match(cmd, fileprefix)) + if (prefix_match(cmd, real_prefix)) res.push_back(cmd); } } |
