From cb6684b63b3c4c5a90e194c5719bc82690180f30 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 31 Jan 2014 23:46:14 +0000 Subject: 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200595 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/CMakeLists.txt | 1 + unittests/LineEditor/CMakeLists.txt | 7 ++++ unittests/LineEditor/LineEditor.cpp | 82 +++++++++++++++++++++++++++++++++++++ unittests/LineEditor/Makefile | 15 +++++++ unittests/Makefile | 4 +- 5 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 unittests/LineEditor/CMakeLists.txt create mode 100644 unittests/LineEditor/LineEditor.cpp create mode 100644 unittests/LineEditor/Makefile (limited to 'unittests') diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 52702ba23a..84685e1c24 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(CodeGen) add_subdirectory(DebugInfo) add_subdirectory(ExecutionEngine) add_subdirectory(IR) +add_subdirectory(LineEditor) add_subdirectory(MC) add_subdirectory(Object) add_subdirectory(Option) diff --git a/unittests/LineEditor/CMakeLists.txt b/unittests/LineEditor/CMakeLists.txt new file mode 100644 index 0000000000..c6823d8f90 --- /dev/null +++ b/unittests/LineEditor/CMakeLists.txt @@ -0,0 +1,7 @@ +set(LLVM_LINK_COMPONENTS + LineEditor + ) + +add_llvm_unittest(LineEditorTests + LineEditor.cpp + ) diff --git a/unittests/LineEditor/LineEditor.cpp b/unittests/LineEditor/LineEditor.cpp new file mode 100644 index 0000000000..cb115bd7de --- /dev/null +++ b/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 Completions; + + TestListCompleter(const std::vector &Completions) + : Completions(Completions) {} + + std::vector operator()(StringRef Buffer, + size_t Pos) const { + EXPECT_TRUE(Buffer.empty()); + EXPECT_EQ(0u, Pos); + return Completions; + } +}; + +TEST_F(LineEditorTest, ListCompleters) { + std::vector 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); +} diff --git a/unittests/LineEditor/Makefile b/unittests/LineEditor/Makefile new file mode 100644 index 0000000000..058b6e46eb --- /dev/null +++ b/unittests/LineEditor/Makefile @@ -0,0 +1,15 @@ +##===- unittests/LineEditor/Makefile -----------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +TESTNAME = LineEditor +LINK_COMPONENTS := lineeditor + +include $(LEVEL)/Makefile.config +include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/Makefile b/unittests/Makefile index dbef6cf9b3..37f654065c 100644 --- a/unittests/Makefile +++ b/unittests/Makefile @@ -9,8 +9,8 @@ LEVEL = .. -PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo \ - ExecutionEngine IR Linker MC Object Option Support Transforms +PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo ExecutionEngine IR \ + LineEditor Linker MC Object Option Support Transforms include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest -- cgit v1.2.3