diff options
| author | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2020-05-25 18:32:10 +0300 |
|---|---|---|
| committer | Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> | 2020-05-25 18:34:42 +0300 |
| commit | b60cfc7df28faab8d51a4832e650710e8a45e1e9 (patch) | |
| tree | b84d620c3fc573895b31abd0a6a139cfdce1e6f9 /lib | |
| parent | 57d38aa7070ad9cb108bfffb1cf17f99f79c1322 (diff) | |
mu-server: restore readline-support
Restore readline support for `mu server' (but _only_ when readline is
found and when in tty mode)
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/utils/Makefile.am | 2 | ||||
| -rw-r--r-- | lib/utils/mu-readline.cc | 131 | ||||
| -rw-r--r-- | lib/utils/mu-readline.hh | 54 |
3 files changed, 187 insertions, 0 deletions
diff --git a/lib/utils/Makefile.am b/lib/utils/Makefile.am index 5a638ac..9faf5fe 100644 --- a/lib/utils/Makefile.am +++ b/lib/utils/Makefile.am @@ -53,6 +53,8 @@ libmu_utils_la_SOURCES= \ mu-log.h \ mu-command-parser.cc \ mu-command-parser.hh \ + mu-readline.cc \ + mu-readline.hh \ mu-sexp-parser.cc \ mu-sexp-parser.hh \ mu-str.c \ diff --git a/lib/utils/mu-readline.cc b/lib/utils/mu-readline.cc new file mode 100644 index 0000000..2fcd224 --- /dev/null +++ b/lib/utils/mu-readline.cc @@ -0,0 +1,131 @@ +/* +** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 3, or (at your option) any +** later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, +** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +*/ + +#include "mu-readline.hh" +#include "config.h" + +#include <iostream> +#include <unistd.h> +#include <string> +#include <glib.h> +#include <glib/gprintf.h> + +#ifdef HAVE_LIBREADLINE +# if defined(HAVE_READLINE_READLINE_H) +# include <readline/readline.h> +# elif defined(HAVE_READLINE_H) +# include <readline.h> +# else /* !defined(HAVE_READLINE_H) */ +extern char *readline (); +# endif /* !defined(HAVE_READLINE_H) */ +char *cmdline = NULL; +#else /* !defined(HAVE_READLINE_READLINE_H) */ +/* no readline */ +#endif /* HAVE_LIBREADLINE */ + +#ifdef HAVE_READLINE_HISTORY +# if defined(HAVE_READLINE_HISTORY_H) +# include <readline/history.h> +# elif defined(HAVE_HISTORY_H) +# include <history.h> +# else /* !defined(HAVE_HISTORY_H) */ +extern void add_history (); +extern int write_history (); +extern int read_history (); +# endif /* defined(HAVE_READLINE_HISTORY_H) */ +/* no history */ +#endif /* HAVE_READLINE_HISTORY */ + + +#if defined(HAVE_LIBREADLINE) && defined(HAVE_READLINE_HISTORY) +#define HAVE_READLINE (1) +#else +#define HAVE_READLINE (0) +#endif + +using namespace Mu; + +static bool is_a_tty{}; +static std::string hist_path; +static size_t max_lines{}; + +void +Mu::setup_readline (const std::string& histpath, size_t maxlines) +{ + is_a_tty = !!::isatty(::fileno(stdout)); + hist_path = histpath; + max_lines = maxlines; + +#if HAVE_READLINE + rl_bind_key('\t', rl_insert); // default (filenames) is not useful + using_history(); + read_history(hist_path.c_str()); + + if (max_lines > 0) + stifle_history(max_lines); +#endif /*HAVE_READLINE*/ +} + + +void +Mu::shutdown_readline () +{ +#if HAVE_READLINE + if (!is_a_tty) + return; + + write_history(hist_path.c_str()); + if (max_lines > 0) + history_truncate_file (hist_path.c_str(), max_lines); +#endif /*HAVE_READLINE*/ +} + + +std::string +Mu::read_line(bool& do_quit) +{ +#if HAVE_READLINE + if (is_a_tty) { + auto buf = readline(";; mu% "); + if (!buf) { + do_quit = true; + return {}; + } + std::string line{buf}; + ::free(buf); + return line; + } +#endif /*HAVE_READLINE*/ + + std::string line; + std::cout << ";; mu> "; + if (!std::getline(std::cin, line)) + do_quit = true; + + return line; +} + + +void +Mu::save_line(const std::string& line) { +#if HAVE_READLINE + if (is_a_tty) + add_history(line.c_str()); +#endif /*HAVE_READLINE*/ +} diff --git a/lib/utils/mu-readline.hh b/lib/utils/mu-readline.hh new file mode 100644 index 0000000..f892f28 --- /dev/null +++ b/lib/utils/mu-readline.hh @@ -0,0 +1,54 @@ +/* +** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 3, or (at your option) any +** later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software Foundation, +** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +** +*/ +#include <string> + +namespace Mu { + +/** + * Setup readline when available & on tty. + * + * @param histpath path to the history file + * @param max_lines maximum number of history to save + */ +void setup_readline(const std::string &histpath, size_t max_lines); + +/** + * Shutdown readline +* + */ +void shutdown_readline(); + + +/** + * Read a command line + * + * @param do_quit recceives whether we should quit. + * + * @return the string read or empty + */ +std::string read_line(bool &do_quit); + +/** + * Save a line to history (or do nothing when readline is not active) + * + * @param line a line. + */ +void save_line(const std::string &line); + +} // namespace Mu |
