A readline and libedit replacement that supports UTF-8, syntax highlighting, hints and Windows and is BSD licensed.

Overview

Read Evaluate Print Loop ++

demo

Build Status

A small, portable GNU readline replacement for Linux, Windows and MacOS which is capable of handling UTF-8 characters. Unlike GNU readline, which is GPL, this library uses a BSD license and can be used in any kind of program.

Origin

This replxx implementation is based on the work by ArangoDB Team and Salvatore Sanfilippo and 10gen Inc. The goal is to create a zero-config, BSD licensed, readline replacement usable in Apache2 or BSD licensed programs.

Features

  • single-line and multi-line editing mode with the usual key bindings implemented
  • history handling
  • completion
  • syntax highlighting
  • hints
  • BSD license source code
  • Only uses a subset of VT100 escapes (ANSI.SYS compatible)
  • UTF8 aware
  • support for Linux, MacOS and Windows

It deviates from Salvatore's original goal to have a minimal readline replacement for the sake of supporting UTF8 and Windows. It deviates from 10gen Inc.'s goal to create a C++ interface to linenoise. This library uses C++ internally, but to the user it provides a pure C interface that is compatible with the original linenoise API. C interface.

Requirements

To build this library, you will need a C++11-enabled compiler and some recent version of CMake.

Build instructions

*nix

  1. Create a build directory
mkdir -p build && cd build
  1. Build the library
cmake -DCMAKE_BUILD_TYPE=Release .. && make
  1. Install the library at the default target location
sudo make install

The default installation location can be adjusted by setting the DESTDIR variable when invoking make install:

make DESTDIR=/tmp install

Windows

  1. Create a build directory in MS-DOS command prompt
md build
cd build
  1. Generate Visual Studio solution file with cmake
  • 32 bit:
cmake -G "Visual Studio 12 2013" -DCMAKE_BUILD_TYPE=Release ..
  • 64 bit:
cmake -G "Visual Studio 12 2013 Win64" -DCMAKE_BUILD_TYPE=Release ..
  1. Open the generated file replxx.sln in the build subdirectory with Visual Studio.

Tested with...

  • Linux text only console ($TERM = linux)
  • Linux KDE terminal application ($TERM = xterm)
  • Linux xterm ($TERM = xterm)
  • Linux Buildroot ($TERM = vt100)
  • Mac OS X iTerm ($TERM = xterm)
  • Mac OS X default Terminal.app ($TERM = xterm)
  • OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen)
  • IBM AIX 6.1
  • FreeBSD xterm ($TERM = xterm)
  • ANSI.SYS
  • Emacs comint mode ($TERM = dumb)
  • Windows

Please test it everywhere you can and report back!

Let's push this forward!

Patches should be provided in the respect of linenoise sensibility for small and easy to understand code that and the license restrictions. Extensions must be submitted under a BSD license-style. A contributor license is required for contributions.

Comments
  • Line continuation support

    Line continuation support

    I ran into your library, which looks stunning (thank you), and was wondering if it supported line continuation. For example, my need requires that the user be able to "enter" and continue to the next line, with a numerical indicator of the line. Except for the builtin (help format, save, etc... ) commands are ended with a semi-colon ";" ... something like this ...

    replxx> this
          2 is
          3 an
          4 example of 
          5 continuation lines;
    replxx> this is an example of  continuation lines;
    

    I haven't dug into the library yet, so I thought I'd ask before spending to much time. Any advice, example, or information you can provide would be greatly appreciated.

    Thank you

    enhancement 
    opened by nvanwyen 39
  • Refactor CMake to be more modernized

    Refactor CMake to be more modernized

    Overview

    This allows us to close #52

    A few "distribution" changes are needed to upgrade the library to follow CMake's modern approach. The biggest change here is that we set whether replxx is a shared library or not via BUILD_SHARED_LIBS. We also have a few dependent options now that become enabled based on whether replxx is being built by itself or as part of a larger project.

    Please let me know if you'd like more changes made to fit the previous workflow.

    Changelog

    This removes the "you can build both" approach, but this is considered "best practice" by modern standards

    Bumped the minimum CMake version to 3.14

    Fallback to C++11 if not defined

    add_subdirectory usage is now safe

    Compiler flags rely on generator expressions

    Update options to fit REPLXX_<> naming scheme

    Use find_package(Threads) for -pthread support

    Add basic find_package config support

    Fix potential name clash for examples if built in larger project

    Fix install location for various items to fall under GNU Install Dirs

    opened by bruxisma 18
  • Hook hint colouring does not work in Windows10 (at least)

    Hook hint colouring does not work in Windows10 (at least)

    hook hints themselves seem to work, you just can't see them as the colouring isn't set, this may be because it's using VT codes and are not decoding. All other colours elsewhere work fine, it just seems to be when there's more than one hint.

    opened by HexTank 17
  • Headers #undef Windows-defined definitions which can be needed

    Headers #undef Windows-defined definitions which can be needed

    The replxx.h and .hxx headers undef DELETE and ERROR, which are set to required values by Windows headers. I'm not going to justify Windows doing that (their headers are full of #defines)! One, in replxx.h is even redundant — I think these both came from the original linenoise source.

    However, we have code that requires those defines that replxx masks.

    I don't see a non-breaking way to fix this; locally, I have renamed them to DEL and _ERROR and then removed the undefs, which worked for me.

    opened by fnxweb 15
  • fix tick on Windows

    fix tick on Windows

    after some try I found the c++-api examples' tick can not run on Windows:

    C:\Work\Sources\replxx>example.exe m
    Welcome to Replxx
    Press 'tab' to view autocompletions
    Type '.help' for help
    Type '.quit' or '.exit' to exit
    
    0
    
    Exiting Replxx
    

    It causes by "write failed" runtime error, because WrtieConsoleA in src/windows.cxx:131 returns 6: invalid handle. it seems the logic in terminal::writeB are not correct, this is the fix.

    btw I also removed the only one cout occurs in source.

    opened by starwing 14
  • Adding simple Unit Tests

    Adding simple Unit Tests

    What are your thoughts on adding some simple Unit Tests? I was thinking some Google Tests but another framework would work just as good.

    I was thinking that taking the examples and putting them in a unit test form could be nice.

    help needed 
    opened by amarcum 11
  • Word break escape support?

    Word break escape support?

    For a project I'm trying to migrate away from GNU/Readline to this library here. I encountered an issue I couldn't figure out yet.

    In readline there is support for escaping characters like spaces and quotes. So when you set the work break character to a space it won't be actually recognized as a word break, allowing to auto complete strings with spaces in it, while at the same time it is possible to kind of "restart" the completion when an actual unescaped space is passed.

    Does this library support this?

    enhancement 
    opened by magiruuvelvet 11
  • Allow user defined key bindings (refactor replxx_impl.cxx).

    Allow user defined key bindings (refactor replxx_impl.cxx).

    It'd be nice to have the option to auto-complete a line/command with the first available hint when pressing enter/return, rather than have to do it explicitly by tabbing. This would allow emulating the code completion behavior of typical IDEs (and search engine input boxes.)

    It doesn't look like this is currently possible, or is it?

    Thanks.

    enhancement help needed 
    opened by ajg 11
  • Case insensitive history search and completion.

    Case insensitive history search and completion.

    After switching clickhouse-client to use the upstream replxx, we found three missing PRs in our fork which are lost.

    1. https://github.com/ClickHouse-Extras/replxx/pull/3
    2. https://github.com/ClickHouse-Extras/replxx/pull/4
    3. https://github.com/ClickHouse-Extras/replxx/pull/15

    I wonder if it's ok to land)

    opened by amosbird 10
  • replxx_clear_screen is broken on windows

    replxx_clear_screen is broken on windows

    On windows replxx_clear_screen causes the prompt to appear in the last line of the console window instead of the first and it appears shifted one row to the left, that is the prompt is printed without the first letter.

    opened by nlebedenco 10
  • Add ability to avoid updating current session history after dumping to file

    Add ability to avoid updating current session history after dumping to file

    Before this patch replxx, while saving to the history file always reload the history from the disk and add new items from that file into the current session. This looks incovenient, if user code calls history_save() after each command (to save history ASAP, example of such program is clickhouse-client) since if you run two programs with replxx completion the completion will overlaps after each command.

    Looks like at least this should be configurable.

    opened by azat 10
  • Update license on Unicode.org's ConvertUTF code

    Update license on Unicode.org's ConvertUTF code

    Apply license fix from LLVM:

    The code was relicensed by its owner (Unicode.org) a long time back, but we still had the old (problematic) license in our fork.

    Note that the source files have not been distributed from unicode.org since 2009 (due to being buggy and unmaintained upstream), but they were given this license before that.

    opened by minfrin 0
  • Fix uncaught exception from ReplxxImpl dtor

    Fix uncaught exception from ReplxxImpl dtor

    You may get uncaugh exception (in case of i.e. broken pipe):

    terminating with uncaught exception of type std::runtime_error: write failed
    

    On destroy:

    (lldb) target create "clickhouse-22.8-release" --core "core.clickhouse-clie.402986-642410"
    bt
    Core file '/wrk/core.clickhouse-clie.402986-642410' (x86_64) was loaded.
    (lldb) bt
    * thread #1, name = 'clickhouse-clie', stop reason = signal SIGABRT
      * frame #0: 0x00007f03fb5c900b libc.so.6`raise + 203
        frame #1: 0x00007f03fb5a8859 libc.so.6`abort + 299
        frame #2: 0x000000001b703f44 clickhouse-22.8-release`::abort_message(format=<unavailable>) at abort_message.cpp:78:5
        frame #3: 0x000000001b703dd4 clickhouse-22.8-release`demangling_terminate_handler() at cxa_default_handlers.cpp:67:21
        frame #4: 0x000000001b721063 clickhouse-22.8-release`std::__terminate(func=<unavailable>)()) at cxa_handlers.cpp:59:9
        frame #5: 0x000000001b720fce clickhouse-22.8-release`std::terminate() at cxa_handlers.cpp:88:17
        frame #6: 0x000000000a3b21db clickhouse-22.8-release`__clang_call_terminate + 11
        frame #7: 0x00000000189b1bfc clickhouse-22.8-release`replxx::Replxx::ReplxxImpl::~ReplxxImpl(this=0x00007f03fa945308) at replxx_impl.cxx:336:1
        frame #8: 0x00000000189b1ce9 clickhouse-22.8-release`replxx::Replxx::ReplxxImpl::~ReplxxImpl(this=0x00007f03fa945300) at replxx_impl.cxx:334:41
        frame #9: 0x00000000188b0644 clickhouse-22.8-release`ReplxxLineReader::~ReplxxLineReader() [inlined] std::__1::unique_ptr<replxx::Replxx::ReplxxImpl, void (*)(replxx::Replxx::ReplxxImpl*)>::reset(this=<unavailable>, __p=<unavailable>) at unique_ptr.h:315:7
        frame #10: 0x00000000188b0626 clickhouse-22.8-release`ReplxxLineReader::~ReplxxLineReader() [inlined] std::__1::unique_ptr<replxx::Replxx::ReplxxImpl, void (*)(replxx::Replxx::ReplxxImpl*)>::~unique_ptr(this=<unavailable>) at unique_ptr.h:269
        frame #11: 0x00000000188b0626 clickhouse-22.8-release`ReplxxLineReader::~ReplxxLineReader() [inlined] replxx::Replxx::~Replxx(this=<unavailable>) at replxx.hxx:76
        frame #12: 0x00000000188b0626 clickhouse-22.8-release`ReplxxLineReader::~ReplxxLineReader(this=0x00007ffd10038440) at ReplxxLineReader.cpp:229
        frame #13: 0x00000000158b2100 clickhouse-22.8-release`DB::ClientBase::runInteractive(this=0x00007ffd10038620) at ClientBase.cpp:2067:1
        frame #14: 0x000000000a4de372 clickhouse-22.8-release`DB::Client::main(this=0x00007ffd10038620, (null)=<unavailable>) at Client.cpp:261:9
        frame #15: 0x0000000018923a86 clickhouse-22.8-release`Poco::Util::Application::run(this=0x00007ffd10038620) at Application.cpp:334:8
        frame #16: 0x000000000a4ed341 clickhouse-22.8-release`mainEntryClickHouseClient(argc=39, argv=0x00007f03fa8201c0) at Client.cpp:1220:23
        frame #17: 0x000000000a3b17ab clickhouse-22.8-release`main(argc_=<unavailable>, argv_=<unavailable>) at main.cpp:449:12
        frame #18: 0x00007f03fb5aa083 libc.so.6`__libc_start_main + 243
        frame #19: 0x000000000a17032e clickhouse-22.8-release`_start + 46
    
    opened by azat 0
  • segmentation fault on down arrow keypress

    segmentation fault on down arrow keypress

    The following REPL session break replxx for me:

    --> (+ 0.18 0.2)
    0.38
    -->
    

    On the third line, after pressing arrow down (history next, while there is no next element) segfaults my program. I presume there's a guard against a common case like this missing.

    GDB backtrace:

    #0  __memmove_avx_unaligned_erms ()
        at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:443
    #1  0x000000000042f42a in std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<char32_t> (__first=0x0, __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿",
        __last=<optimized out>)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algobase.h:431
    #2  std::__copy_move_a2<false, char32_t const*, char32_t*> (__first=0x0,
        __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿", __last=<optimized out>)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algobase.h:494
    #3  std::__copy_move_a1<false, char32_t const*, char32_t*> (__first=0x0,
        __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿", __last=<optimized out>)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algobase.h:522
    #4  std::__copy_move_a<false, __gnu_cxx::__normal_iterator<char32_t const*, std::vector<char32_t, std::allocator<char32_t> > >, char32_t*> (
        __first=non-dereferenceable iterator for std::vector,
        __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿", __last=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algobase.h:530
    #5  std::copy<__gnu_cxx::__normal_iterator<char32_t const*, std::vector<char32_t, std::allocator<char32_t> > >, char32_t*> (
        __first=non-dereferenceable iterator for std::vector,
        __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿", __last=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algobase.h:619
    #6  std::__uninitialized_copy<true>::__uninit_copy<__gnu_cxx::__normal_iterator<char32_t const*, std::vector<char32_t, std::allocator<char32_t> > >, char32_t*> (
        __first=non-dereferenceable iterator for std::vector,
        __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿", __last=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_uninitialized.h:110
    #7  std::uninitialized_copy<__gnu_cxx::__normal_iterator<char32_t const*, std::vector<char32_t, std::allocator<char32_t> > >, char32_t*> (
        __first=non-dereferenceable iterator for std::vector,
    --Type <RET> for more, q to quit, c to continue without paging--
        __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿", __last=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_uninitialized.h:148
    #8  std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<char32_t const*, std::vector<char32_t, std::allocator<char32_t> > >, char32_t*, char32_t> (
        __first=non-dereferenceable iterator for std::vector,
        __result=0x4ba340 U"\xf7886c00翿\xf7886c00翿", __last=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_uninitialized.h:333
    #9  std::vector<char32_t, std::allocator<char32_t> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<char32_t const*, std::vector<char32_t, std::allocator<char32_t> > > > (
        this=0x4b2f78, __n=250, __first=non-dereferenceable iterator for std::vector,
        __last=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1514
    #10 std::vector<char32_t, std::allocator<char32_t> >::operator= (this=0x4b2f78,
        __x=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/vector.tcc:226
    #11 0x000000000044533f in replxx::UnicodeString::assign (this=0x4b2f78, other_=...)
        at replxx/unicodestring.hxx:93
    #12 replxx::Replxx::ReplxxImpl::history_move (this=0x4b2f60, previous_=<optimized out>)
        at replxx/replxx_impl.cxx:1956
    #13 0x000000000043d419 in replxx::Replxx::ReplxxImpl::line_next (this=0x4ba340)
        at replxx/replxx_impl.cxx:1932
    #14 0x000000000043ce77 in replxx::Replxx::ReplxxImpl::action (this=0x4b2f60,
        actionTrait_=6, handler_=<optimized out>, code_=63712 U'')
        at replxx/replxx_impl.cxx:1408
    #15 0x0000000000446b4f in replxx::Replxx::ReplxxImpl::input (this=0x4b2f60, prompt=...)
        at /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:590
    #16 0x0000000000417444 in main (argc=<optimized out>, argv=<optimized out>)
        at replxx/replxx.cxx:150
    

    My code is located in the kspalaiologos/kamilalisp repository. NB: I keep my own copy of replxx, since I dislike the bloaty buildsystem bundled with the official distribution.

    opened by kspalaiologos 5
  • fix shared library in windows

    fix shared library in windows

    When compiling with commands cmake -DCMAKE_INSTALL_PREFIX=replxx -DBUILD_SHARED_LIBS=ON -G "MinGW Makefiles" .. & make on windows, we will get such some errors as undefined reference to replxx::color::bold(replxx::Replxx::Color); undefined reference to replxx::Replxx::HistoryScan::next()

    opened by field-chicken 0
Owner
Marcin Konarski
Anarcho-capitalist, atheist, C++ programmer, Unix admin/user. Into SF books and movies. Enjoys traveling, history, alternative music. Loves indian food & sushi.
Marcin Konarski
A small self-contained alternative to readline and libedit

Linenoise A minimal, zero-config, BSD licensed, readline replacement used in Redis, MongoDB, and Android. Single and multi line editing mode with the

Salvatore Sanfilippo 3.1k Jan 2, 2023
Yori is a CMD replacement shell that supports backquotes, job control, and improves tab completion, file matching, aliases, command history, and more.

Yori is a CMD replacement shell that supports backquotes, job control, and improves tab completion, file matching, aliases, command history, and more.

Malcolm Smith 1.1k Dec 30, 2022
crypted admin shell: SSH-like strong crypto remote admin shell for Linux, BSD, Android, Solaris and OSX

crypted admin shell: SSH-like strong crypto remote admin shell for Linux, BSD, Android, Solaris and OSX

Sebastian 135 Jan 2, 2023
Table maker, true color, nested table, unicode, xterm & markdown syntax, ...

tabulate Source for the above image can be found here Table of Contents tabulate Table of Contents Quick Start Formatting Options Word Wrapping Font A

Kiran Nowak 8 Jul 31, 2022
Bitset Sort, a faster std::sort replacement.

Bitset Sort Bitset Sort is a variant of quick sort, specifically BlockQuickSort. Bitset Sort uses a carefully written partition function to let the co

null 66 Dec 1, 2022
The new Windows Terminal and the original Windows console host, all in the same place!

The new Windows Terminal and the original Windows console host, all in the same place!

Microsoft 86.8k Dec 29, 2022
Free open-source modern C++17 / C++20 framework to create console, forms (GUI like WinForms) and unit test applications on Microsoft Windows, Apple macOS and Linux.

xtd Modern C++17/20 framework to create console (CLI), forms (GUI like WinForms) and tunit (unit tests like Microsoft Unit Testing Framework) applicat

Gammasoft 434 Dec 30, 2022
Traffic capture and intercept program based on Windows Filtering Platform (WFT)

Traffic capture and intercept program based on Windows Filtering Platform (WFT)

null 2 Oct 17, 2021
A Windows Shell Extension for the Pixar USD file format.

Activision USD Shell Extension A Windows Shell Extension for the Pixar USD file format. Windows Explorer Features Hydra Realtime Preview Thumbnails Co

null 319 Dec 28, 2022
Windows command line program for Spleeter, written in pure C, no need of Python.

SpleeterMsvcExe is a Windows command line program for Spleeter, which can be used directly. It is written in pure C language, using ffmpeg to read and write audio files, and using Tensorflow C API to make use of Spleeter models. No need to install Python environment, and it does not contain anything related to Python.

Wudi 181 Dec 5, 2022
为了让 Windows 平台上的 ssh agent 能适配多种 ssh client 和在 wsl 环境下使用的工具

ssh-agent-bridge 为了让 Windows 平台上的 ssh agent 能适配多种 ssh client 和在 wsl 环境下使用的工具 Windows 平台上存在着多种 ssh agent 的实现,由于 Windows 平台的特殊性,这些 agent 程序都有一套自行实现的进程间通

Apache553 67 Dec 1, 2022
A Command-Line-Interface Debugger for 64-bit Windows written in C.

Debugger-For-Windows A command-line-interface debugger for 64-bit Windows. [email protected]:/mnt/c/Projects/C/Debugger$ ./Debugger.exe ./Tests/test.ex

Tomer Gibor 1 Nov 3, 2021
Windows Package Manager CLI (aka winget)

Welcome to the Windows Package Manager Client (aka winget.exe) repository This repository contains the source code for the Windows Package Manager Cli

Microsoft 18.4k Dec 27, 2022
udmp-parser: A Windows user minidump C++ parser library.

udmp-parser: A Windows user minidump C++ parser library. This is a cross-platform (Windows / Linux / OSX / x86 / x64) C++ library that parses Windows

Axel Souchet 95 Dec 13, 2022
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).

args Note that this library is essentially in maintenance mode. I haven't had the time to work on it or give it the love that it deserves. I'm not add

Taylor C. Richberger 1.1k Jan 4, 2023
CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.

CLI11: Command line parser for C++11 What's new • Documentation • API Reference CLI11 is a command line parser for C++11 and beyond that provides a ri

null 2.4k Dec 30, 2022
A (relatively) small node library to clone and pull git repositories in a standalone manner thanks to libgit2, powered by WebAssembly and Emscripten

simple-git-wasm A (relatively) small node library to clone and pull git repositories in a standalone manner thanks to libgit2, powered by WebAssembly

Powercord 21 Oct 16, 2022
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).

args Note that this library is essentially in maintenance mode. I haven't had the time to work on it or give it the love that it deserves. I'm not add

Taylor C. Richberger 896 Aug 31, 2021
Flexible and fast Z-shell plugin manager that will allow installing everything from GitHub and other sites.

ZINIT News Zinit Wiki Quick Start Install Automatic Installation (Recommended) Manual Installation Usage Introduction Plugins and snippets Upgrade Zin

z-shell 26 Nov 15, 2022