summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2010-06-05 12:30:16 (GMT)
committerKevin Smith <git@kismith.co.uk>2010-06-05 12:30:16 (GMT)
commit087267cdfedeab2ae55776f7b7246c47f1d39d6d (patch)
tree47c5a3bedd1fa7eb61587a7bd17934f0927dbb9f /SwifTools
parent7bca08eb2829982865f1649483f9aa01b3413b1c (diff)
downloadswift-087267cdfedeab2ae55776f7b7246c47f1d39d6d.zip
swift-087267cdfedeab2ae55776f7b7246c47f1d39d6d.tar.bz2
Tab completion in MUCs.
Resolves: #440
Diffstat (limited to 'SwifTools')
-rw-r--r--SwifTools/SConscript1
-rw-r--r--SwifTools/TabComplete.cpp50
-rw-r--r--SwifTools/TabComplete.h25
-rw-r--r--SwifTools/UnitTest/SConscript3
-rw-r--r--SwifTools/UnitTest/TabCompleteTest.cpp152
5 files changed, 230 insertions, 1 deletions
diff --git a/SwifTools/SConscript b/SwifTools/SConscript
index 8da482a..18781c3 100644
--- a/SwifTools/SConscript
+++ b/SwifTools/SConscript
@@ -26,6 +26,7 @@ if env["SCONS_STAGE"] == "build" :
"AutoUpdater/AutoUpdater.cpp",
"AutoUpdater/PlatformAutoUpdaterFactory.cpp",
"Linkify.cpp",
+ "TabComplete.cpp",
]
if myenv.get("HAVE_SPARKLE", 0) :
diff --git a/SwifTools/TabComplete.cpp b/SwifTools/TabComplete.cpp
new file mode 100644
index 0000000..fd3fb6f
--- /dev/null
+++ b/SwifTools/TabComplete.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "SwifTools/TabComplete.h"
+#include "Swiften/Base/foreach.h"
+
+namespace Swift {
+
+void TabComplete::addWord(const String& word) {
+ words_.push_back(word);
+ if (word.getLowerCase().beginsWith(lastShort_)) {
+ lastCompletionCandidates_.push_back(word);
+ }
+}
+
+void TabComplete::removeWord(const String& word) {
+ words_.erase(std::remove(words_.begin(), words_.end(), word), words_.end());
+ lastCompletionCandidates_.erase(std::remove(lastCompletionCandidates_.begin(), lastCompletionCandidates_.end(), word), lastCompletionCandidates_.end());
+}
+
+String TabComplete::completeWord(const String& word) {
+ if (word == lastCompletion_) {
+ if (lastCompletionCandidates_.size() != 0) {
+ size_t match = 0;
+ for (match = 0; match < lastCompletionCandidates_.size(); match++) {
+ if (lastCompletionCandidates_[match] == lastCompletion_) {
+ break;
+ }
+ }
+ size_t nextIndex = match + 1;
+ nextIndex = nextIndex >= lastCompletionCandidates_.size() ? 0 : nextIndex;
+ lastCompletion_ = lastCompletionCandidates_[nextIndex];
+ }
+ } else {
+ lastShort_ = word.getLowerCase();
+ lastCompletionCandidates_.clear();
+ foreach (String candidate, words_) {
+ if (candidate.getLowerCase().beginsWith(word.getLowerCase())) {
+ lastCompletionCandidates_.push_back(candidate);
+ }
+ }
+ lastCompletion_ = lastCompletionCandidates_.size() > 0 ? lastCompletionCandidates_[0] : word;
+ }
+ return lastCompletion_;
+}
+
+}
diff --git a/SwifTools/TabComplete.h b/SwifTools/TabComplete.h
new file mode 100644
index 0000000..01e294f
--- /dev/null
+++ b/SwifTools/TabComplete.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "Swiften/Base/String.h"
+
+namespace Swift {
+ class TabComplete {
+ public:
+ void addWord(const String& word);
+ void removeWord(const String& word);
+ String completeWord(const String& word);
+ private:
+ std::vector<String> words_;
+ String lastCompletion_;
+ String lastShort_;
+ std::vector<String> lastCompletionCandidates_;
+ };
+}
diff --git a/SwifTools/UnitTest/SConscript b/SwifTools/UnitTest/SConscript
index 2622f39..8034905 100644
--- a/SwifTools/UnitTest/SConscript
+++ b/SwifTools/UnitTest/SConscript
@@ -1,5 +1,6 @@
Import("env")
env.Append(UNITTEST_SOURCES = [
- File("LinkifyTest.cpp")
+ File("LinkifyTest.cpp"),
+ File("TabCompleteTest.cpp")
])
diff --git a/SwifTools/UnitTest/TabCompleteTest.cpp b/SwifTools/UnitTest/TabCompleteTest.cpp
new file mode 100644
index 0000000..4d152f6
--- /dev/null
+++ b/SwifTools/UnitTest/TabCompleteTest.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include "SwifTools/TabComplete.h"
+
+using namespace Swift;
+
+class TabCompleteTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(TabCompleteTest);
+ CPPUNIT_TEST(testEmpty);
+ CPPUNIT_TEST(testNoMatch);
+ CPPUNIT_TEST(testOneMatch);
+ CPPUNIT_TEST(testTwoMatch);
+ CPPUNIT_TEST(testChangeMatch);
+ CPPUNIT_TEST(testRemoveDuringComplete);
+ CPPUNIT_TEST(testAddDuringComplete);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ TabCompleteTest() {};
+
+ void setUp() {
+ completer_ = TabComplete();
+ }
+
+ void testEmpty() {
+ String blah("Blah");
+ CPPUNIT_ASSERT_EQUAL(
+ blah,
+ completer_.completeWord(blah));
+ CPPUNIT_ASSERT_EQUAL(
+ blah,
+ completer_.completeWord(blah));
+ }
+
+ void testNoMatch() {
+ completer_.addWord("Bleh");
+ String blah("Blah");
+ CPPUNIT_ASSERT_EQUAL(
+ blah,
+ completer_.completeWord(blah));
+ CPPUNIT_ASSERT_EQUAL(
+ blah,
+ completer_.completeWord(blah));
+ }
+
+ void testOneMatch() {
+ String short1("Bl");
+ String long1("Blehling");
+ completer_.addWord(long1);
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(short1));
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(long1));
+ }
+
+ void testTwoMatch() {
+ String short1("Hur");
+ String long1("Hurgle");
+ String long2("Hurdler");
+ completer_.addWord(long1);
+ completer_.addWord("Blah");
+ completer_.addWord(long2);
+ completer_.addWord("Bleh");
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(short1));
+ CPPUNIT_ASSERT_EQUAL(
+ long2,
+ completer_.completeWord(long1));
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(long2));
+ }
+
+ void testChangeMatch() {
+ String short1("Hur");
+ String short2("Rub");
+ String long1("Hurgle");
+ String long2("Rubbish");
+ completer_.addWord(long2);
+ completer_.addWord("Blah");
+ completer_.addWord(long1);
+ completer_.addWord("Bleh");
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(short1));
+ CPPUNIT_ASSERT_EQUAL(
+ long2,
+ completer_.completeWord(short2));
+ CPPUNIT_ASSERT_EQUAL(
+ long2,
+ completer_.completeWord(long2));
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(short1));
+ }
+
+ void testRemoveDuringComplete() {
+ String short1("Kev");
+ String long1("Kevin");
+ String long2("Kevlar");
+ completer_.addWord(long1);
+ completer_.addWord("Blah");
+ completer_.addWord(long2);
+ completer_.addWord("Bleh");
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(short1));
+ completer_.removeWord(long1);
+ CPPUNIT_ASSERT_EQUAL(
+ long2,
+ completer_.completeWord(long1));
+ CPPUNIT_ASSERT_EQUAL(
+ long2,
+ completer_.completeWord(long2));
+ }
+
+ void testAddDuringComplete() {
+ String short1("Rem");
+ String long1("Remko");
+ String long2("Remove");
+ String long3("Remedial");
+ completer_.addWord(long1);
+ completer_.addWord("Blah");
+ completer_.addWord(long2);
+ completer_.addWord("Bleh");
+ CPPUNIT_ASSERT_EQUAL(
+ long1,
+ completer_.completeWord(short1));
+ completer_.addWord(long3);
+ CPPUNIT_ASSERT_EQUAL(
+ long2,
+ completer_.completeWord(long1));
+ CPPUNIT_ASSERT_EQUAL(
+ long3,
+ completer_.completeWord(long2));
+ }
+
+private:
+ TabComplete completer_;
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TabCompleteTest);