summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/filesystem/FileLocator.cpp79
-rw-r--r--src/plugins/filesystem/FileLocator.hpp7
-rw-r--r--test/plugins/filesystem/FileLocatorTest.cpp54
-rw-r--r--testdata/filesystem/autocomplete/a.test0
-rw-r--r--testdata/filesystem/autocomplete/a.test.backup0
-rw-r--r--testdata/filesystem/autocomplete/a.test~0
-rw-r--r--testdata/filesystem/autocomplete/b.test10
-rw-r--r--testdata/filesystem/autocomplete/b.test20
-rw-r--r--testdata/filesystem/autocomplete/c0
-rw-r--r--testdata/filesystem/autocomplete/c.test0
-rw-r--r--testdata/filesystem/autocomplete/de0
11 files changed, 108 insertions, 32 deletions
diff --git a/src/plugins/filesystem/FileLocator.cpp b/src/plugins/filesystem/FileLocator.cpp
index 9a39901..d2b4bb6 100644
--- a/src/plugins/filesystem/FileLocator.cpp
+++ b/src/plugins/filesystem/FileLocator.cpp
@@ -38,6 +38,19 @@ namespace fs = boost::filesystem;
namespace ousia {
+/**
+ * Function used internally to ignore backup files when performing auto
+ * completion.
+ *
+ * @param fn is the filename that should be checked for looking like a temporary
+ * or backup file.
+ * @return true if the file might be a backup file, false otherwise.
+ */
+static bool isBackupFile(const std::string fn)
+{
+ return Utils::endsWith(fn, "~") || Utils::endsWith(fn, "backup");
+}
+
void FileLocator::addPath(const std::string &path,
std::vector<std::string> &paths)
{
@@ -135,7 +148,7 @@ static bool iteratePaths(const FileLocator::SearchPaths &searchPaths,
// Check whether the given resource has an absolute path -- if yes, call the
// callback function and do not try any search paths
if (dir.is_absolute()) {
- return callback(dir, filename);
+ return callback(dir, filename, dir);
}
// If the path starts with "./" or "../" only perform relative lookups!
@@ -151,7 +164,7 @@ static bool iteratePaths(const FileLocator::SearchPaths &searchPaths,
#endif
// Concatenate the searchpath with the given directory
fs::path curDir = fs::path(*it) / dir;
- if (callback(curDir, filename)) {
+ if (callback(curDir, filename, dir)) {
return true;
}
}
@@ -173,7 +186,7 @@ static bool iteratePaths(const FileLocator::SearchPaths &searchPaths,
curDir = curDir / dir;
// If we already found a fitting resource there, use that.
- if (callback(curDir, filename)) {
+ if (callback(curDir, filename, dir)) {
return true;
}
}
@@ -185,23 +198,23 @@ bool FileLocator::doLocate(Resource &resource, const std::string &path,
const ResourceType type,
const std::string &relativeTo) const
{
- return iteratePaths(
- searchPaths, path, type, relativeTo,
- [&](const fs::path &dir, const std::string &filename) -> bool {
- // Combine directory and filename
- fs::path p = dir / filename;
-
- // Check whether p exists
- if (fs::exists(p) && fs::is_regular_file(p)) {
- std::string location = fs::canonical(p).generic_string();
+ return iteratePaths(searchPaths, path, type, relativeTo,
+ [&](const fs::path &dir, const std::string &filename,
+ const fs::path &) -> bool {
+ // Combine directory and filename
+ fs::path p = dir / filename;
+
+ // Check whether p exists
+ if (fs::exists(p) && fs::is_regular_file(p)) {
+ std::string location = fs::canonical(p).generic_string();
#ifdef FILELOCATOR_DEBUG_PRINT
- std::cout << "FileLocator: Found at " << location << std::endl;
+ std::cout << "FileLocator: Found at " << location << std::endl;
#endif
- resource = Resource(true, *this, type, location);
- return true;
- }
- return false;
- });
+ resource = Resource(true, *this, type, location);
+ return true;
+ }
+ return false;
+ });
}
std::vector<std::string> FileLocator::doAutocomplete(
@@ -210,19 +223,39 @@ std::vector<std::string> FileLocator::doAutocomplete(
{
std::vector<std::string> res;
iteratePaths(searchPaths, path, type, relativeTo,
- [&](const fs::path &dir, const std::string &filename) -> bool {
+ [&](const fs::path &dir, const std::string &filename,
+ const fs::path &originalDir) -> bool {
// Make sure the given directory actually is a directory
if (!fs::is_directory(dir)) {
return false;
}
+ // Check whether the file itself exists -- if yes, return this file
+ // directly intead of performing any autocomplete
+ fs::path p = dir / filename;
+ if (fs::exists(p) && fs::is_regular_file(p)) {
+ res.push_back((originalDir / filename).generic_string());
+ return true;
+ }
+
+ // Append a point to the filename -- this allows us to only take files
+ // into acount that actually extend the extension
+ const std::string fn = filename + ".";
+
// Iterate over the directory content
fs::directory_iterator end;
for (fs::directory_iterator it(dir); it != end; it++) {
- const std::string fn = it->path().filename().generic_string();
- if (!fn.empty() && fn[fn.size() - 1] != '~' &&
- Utils::startsWith(fn, filename)) {
- res.push_back(it->path().generic_string());
+ // Only consider regular files
+ fs::path p = it->path();
+ if (!fs::is_regular_file(p)) {
+ continue;
+ }
+
+ // Fetch the filename of the found file, ignore temporary files
+ const std::string fn2 = it->path().filename().generic_string();
+ if (!fn.empty() && !isBackupFile(fn2) &&
+ Utils::startsWith(fn2, fn)) {
+ res.push_back((originalDir / fn2).generic_string());
}
}
return !res.empty();
diff --git a/src/plugins/filesystem/FileLocator.hpp b/src/plugins/filesystem/FileLocator.hpp
index 14988a8..ad64db8 100644
--- a/src/plugins/filesystem/FileLocator.hpp
+++ b/src/plugins/filesystem/FileLocator.hpp
@@ -38,11 +38,8 @@
namespace ousia {
/**
- * @file FileLocator.hpp
- *
- * This is a FileLocator employing the boost path class for file finding.
- *
- * @author Benjamin Paassen - bpaassen@techfak.uni-bielefeld.de
+ * The FileLocator class is an implementation of the abstract ResourceLocator
+ * interface used to locate resources in the filesystem.
*/
class FileLocator : public ResourceLocator {
public:
diff --git a/test/plugins/filesystem/FileLocatorTest.cpp b/test/plugins/filesystem/FileLocatorTest.cpp
index 361a3ca..22db926 100644
--- a/test/plugins/filesystem/FileLocatorTest.cpp
+++ b/test/plugins/filesystem/FileLocatorTest.cpp
@@ -18,6 +18,8 @@
#include <gtest/gtest.h>
+#include <set>
+
#include <plugins/filesystem/FileLocator.hpp>
#include <plugins/filesystem/SpecialPaths.hpp>
@@ -142,10 +144,11 @@ TEST(FileLocator, locate)
assert_not_located(locator, "c.txt", "", ResourceType::SCRIPT);
}
-TEST(FileLocator, locateAbsolute){
+TEST(FileLocator, locateAbsolute)
+{
FileLocator locator;
- // construct the absolute path by utilizing SpecialPaths and
- fs::path testdataDir {SpecialPaths::getDebugTestdataDir()};
+ // construct the absolute path by utilizing SpecialPaths and
+ fs::path testdataDir{SpecialPaths::getDebugTestdataDir()};
fs::path absolute = fs::canonical(testdataDir);
absolute /= "filesystem";
absolute /= "a.txt";
@@ -217,7 +220,50 @@ TEST(FileLocator, testDefaultSearchPaths)
assert_located(locator, "domain/book.osxml", "", ResourceType::UNKNOWN);
assert_located(locator, "book.osxml", "", ResourceType::DOMAIN_DESC);
assert_not_located(locator, "color.osxml", "", ResourceType::UNKNOWN);
- assert_located(locator, "typesystem/color.osxml", "", ResourceType::UNKNOWN);
+ assert_located(locator, "typesystem/color.osxml", "",
+ ResourceType::UNKNOWN);
assert_located(locator, "color.osxml", "", ResourceType::TYPESYSTEM);
}
+
+TEST(FileLocator, autocompleteIgnoreBackupFiles)
+{
+ FileLocator locator;
+ locator.addUnittestSearchPath("filesystem");
+
+ auto res = locator.autocomplete("autocomplete/a");
+ ASSERT_EQ(std::vector<std::string>{"autocomplete/a.test"}, res);
+}
+
+TEST(FileLocator, autocompleteAmbiguous)
+{
+ FileLocator locator;
+ locator.addUnittestSearchPath("filesystem");
+
+ auto res = locator.autocomplete("autocomplete/b");
+
+ std::set<std::string> resSet;
+ resSet.insert(res.begin(), res.end());
+
+ ASSERT_EQ(
+ std::set<std::string>({"autocomplete/b.test1", "autocomplete/b.test2"}),
+ resSet);
+}
+
+TEST(FileLocator, autocompleteExisting)
+{
+ FileLocator locator;
+ locator.addUnittestSearchPath("filesystem");
+
+ auto res = locator.autocomplete("autocomplete/c");
+ ASSERT_EQ(std::vector<std::string>{"autocomplete/c"}, res);
+}
+
+TEST(FileLocator, autocompleteExtensionOnly)
+{
+ FileLocator locator;
+ locator.addUnittestSearchPath("filesystem");
+
+ auto res = locator.autocomplete("autocomplete/d");
+ ASSERT_EQ(std::vector<std::string>{}, res);
+}
}
diff --git a/testdata/filesystem/autocomplete/a.test b/testdata/filesystem/autocomplete/a.test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/a.test
diff --git a/testdata/filesystem/autocomplete/a.test.backup b/testdata/filesystem/autocomplete/a.test.backup
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/a.test.backup
diff --git a/testdata/filesystem/autocomplete/a.test~ b/testdata/filesystem/autocomplete/a.test~
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/a.test~
diff --git a/testdata/filesystem/autocomplete/b.test1 b/testdata/filesystem/autocomplete/b.test1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/b.test1
diff --git a/testdata/filesystem/autocomplete/b.test2 b/testdata/filesystem/autocomplete/b.test2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/b.test2
diff --git a/testdata/filesystem/autocomplete/c b/testdata/filesystem/autocomplete/c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/c
diff --git a/testdata/filesystem/autocomplete/c.test b/testdata/filesystem/autocomplete/c.test
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/c.test
diff --git a/testdata/filesystem/autocomplete/de b/testdata/filesystem/autocomplete/de
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/testdata/filesystem/autocomplete/de