diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2014-01-31 23:46:14 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2014-01-31 23:46:14 +0000 |
commit | c7d437c1188e7be2403328dee4192e9f3f015abc (patch) | |
tree | f4f477bab572fa73c5b28382e0ffe49cc82b91f4 /llvm/unittests/LineEditor/LineEditor.cpp | |
parent | f7d4101156fd3f5c034edde12adb1eabde07cef5 (diff) | |
download | llvm-c7d437c1188e7be2403328dee4192e9f3f015abc.zip llvm-c7d437c1188e7be2403328dee4192e9f3f015abc.tar.gz llvm-c7d437c1188e7be2403328dee4192e9f3f015abc.tar.bz2 |
Introduce line editor library.
This library will be used by clang-query. I can imagine LLDB becoming another
client of this library, so I think LLVM is a sensible place for it to live.
It wraps libedit, and adds tab completion support.
The code is loosely based on the line editor bits in LLDB, with a few
improvements:
- Polymorphism for retrieving the list of tab completions, based on
the concept pattern from the new pass manager.
- Tab completion doesn't corrupt terminal output if the input covers
multiple lines. Unfortunately this can only be done in a truly horrible
way, as far as I can tell. But since the alternative is to implement our
own line editor (which I don't think LLVM should be in the business of
doing, at least for now) I think it may be acceptable.
- Includes a fallback for the case where the user doesn't have libedit
installed.
Note that this uses C stdio, mainly because libedit also uses C stdio.
Differential Revision: http://llvm-reviews.chandlerc.com/D2200
llvm-svn: 200595
Diffstat (limited to 'llvm/unittests/LineEditor/LineEditor.cpp')
-rw-r--r-- | llvm/unittests/LineEditor/LineEditor.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/llvm/unittests/LineEditor/LineEditor.cpp b/llvm/unittests/LineEditor/LineEditor.cpp new file mode 100644 index 0000000..cb115bd --- /dev/null +++ b/llvm/unittests/LineEditor/LineEditor.cpp @@ -0,0 +1,82 @@ +//===-- LineEditor.cpp ----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/LineEditor/LineEditor.h" +#include "llvm/Support/Path.h" +#include "gtest/gtest.h" + +using namespace llvm; + +class LineEditorTest : public testing::Test { +public: + SmallString<64> HistPath; + LineEditor *LE; + + LineEditorTest() { + init(); + } + + void init() { + sys::fs::createTemporaryFile("temp", "history", HistPath); + ASSERT_FALSE(HistPath.empty()); + LE = new LineEditor("test", HistPath); + } + + ~LineEditorTest() { + delete LE; + sys::fs::remove(HistPath.str()); + } +}; + +TEST_F(LineEditorTest, HistorySaveLoad) { + LE->saveHistory(); + LE->loadHistory(); +} + +struct TestListCompleter { + std::vector<LineEditor::Completion> Completions; + + TestListCompleter(const std::vector<LineEditor::Completion> &Completions) + : Completions(Completions) {} + + std::vector<LineEditor::Completion> operator()(StringRef Buffer, + size_t Pos) const { + EXPECT_TRUE(Buffer.empty()); + EXPECT_EQ(0u, Pos); + return Completions; + } +}; + +TEST_F(LineEditorTest, ListCompleters) { + std::vector<LineEditor::Completion> Comps; + + Comps.push_back(LineEditor::Completion("foo", "int foo()")); + LE->setListCompleter(TestListCompleter(Comps)); + LineEditor::CompletionAction CA = LE->getCompletionAction("", 0); + EXPECT_EQ(LineEditor::CompletionAction::AK_Insert, CA.Kind); + EXPECT_EQ("foo", CA.Text); + + Comps.push_back(LineEditor::Completion("bar", "int bar()")); + LE->setListCompleter(TestListCompleter(Comps)); + CA = LE->getCompletionAction("", 0); + EXPECT_EQ(LineEditor::CompletionAction::AK_ShowCompletions, CA.Kind); + ASSERT_EQ(2u, CA.Completions.size()); + ASSERT_EQ("int foo()", CA.Completions[0]); + ASSERT_EQ("int bar()", CA.Completions[1]); + + Comps.clear(); + Comps.push_back(LineEditor::Completion("fee", "int fee()")); + Comps.push_back(LineEditor::Completion("fi", "int fi()")); + Comps.push_back(LineEditor::Completion("foe", "int foe()")); + Comps.push_back(LineEditor::Completion("fum", "int fum()")); + LE->setListCompleter(TestListCompleter(Comps)); + CA = LE->getCompletionAction("", 0); + EXPECT_EQ(LineEditor::CompletionAction::AK_Insert, CA.Kind); + EXPECT_EQ("f", CA.Text); +} |