/* linenoise.h -- VERSION 1.0 * * Guerrilla line editing library against the idea that a line editing lib * needs to be 20,000 lines of C code. * * See linenoise.c for more information. * * ------------------------------------------------------------------------ * * Copyright (c) 2010-2014, Salvatore Sanfilippo * Copyright (c) 2010-2013, Pieter Noordhuis * * THIS IS A MODIFIED VERSION THAT REMOVES GLOBAL STATE AND SUPPORTS * OTHER IO THAN STDOUT/STDIN. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LINENOISE_H #define LINENOISE_H #ifndef LINENOISE_HISTORY_MAX_LINE #define LINENOISE_HISTORY_MAX_LINE 512 #endif #include #include #include #include #include "console/config.h" typedef struct linenoiseCompletions { size_t len; char **cvec; } linenoiseCompletions; /** * Get completions */ typedef void (linenoiseCompletionCallback)(const char *typed, linenoiseCompletions *); /** * Get a hint for typed text */ typedef char* (linenoiseHintsCallback)(const char *typed, int *color, int *bold); /** * Dispose of a hint returned by `linenoiseHintsCallback()` */ typedef void (linenoiseFreeHintsCallback)(void *); /** * Linenoise write callback. * * Return number of characters written, -1 on error. * "ctx" may be a fd cast to void* or other value passed during LN init */ typedef int (linenoiseWrite)(void *ctx, const char *text, int len); /** * Linenoise read callback. * * Return number of characters read, -1 on error; * "ctx" may be a fd cast to void* or other value passed during LN init */ typedef int (linenoiseRead)(void *ctx, char *dest, int count); /** * Linenoise state; exposed in header to allow static allocation * * Use `linenoiseStateInit()` to set default values. * * To shutdown, use `linenoiseHistoryFree()` and then free the struct as needed. */ struct linenoiseState { bool mlmode; /* Multi line mode. Default is single line. */ bool dumbmode; /* Dumb mode where line editing is disabled. Off by default */ bool echomode; /* Echo (meaningful only in dumb mode) */ bool allowCtrlDExit; int history_max_len; int history_len; char **history; char *buf; /* Edited line buffer. */ size_t buflen; /* Edited line buffer size. */ const char *prompt; /* Prompt to display. */ size_t plen; /* Prompt length. */ int pos; /* Current cursor position. */ int oldpos; /* Previous refresh cursor position. */ int len; /* Current edited line length. */ int cols; /* Number of columns in terminal. */ int maxrows; /* Maximum num of rows used so far (multiline mode) */ int history_index; /* The history index we are currently editing. */ linenoiseCompletionCallback *completionCallback; linenoiseHintsCallback *hintsCallback; linenoiseFreeHintsCallback *freeHintsCallback; void *rwctx; linenoiseWrite *write; linenoiseRead *read; }; /** * Initialize the state struct to defaults. * * Before the library is used, also set prompt, buffer, * the read/write callbacks, r/w context (if used), * completion, hint and free-hint callbacks */ void consLnStateInit(struct linenoiseState *ls); /** Set buffer and its capacity */ static inline void consLnSetBuf(struct linenoiseState *ls, char *buf, size_t cap) { ls->buf = buf; ls->buflen = cap - 1; /* Make sure there is always space for the nulterm */ } /** Set prompt pointer. Can be constant or dynamically allocated. * Will NOT be mutated by the library. */ static inline void consLnSetPrompt(struct linenoiseState *ls, const char *prompt) { ls->prompt = prompt; } /** Set buffer and its capacity */ static inline void consLnSetReadWrite(struct linenoiseState *ls, linenoiseRead *read, linenoiseWrite *write, void *ctx) { ls->read = read; ls->write = write; ls->rwctx = ctx; } /** Set completion CB */ static inline void consLnSetCompletionCallback(struct linenoiseState *ls, linenoiseCompletionCallback *compl) { ls->completionCallback = compl; } /** Set hint CB */ static inline void consLnSetHintsCallback(struct linenoiseState *ls, linenoiseHintsCallback *hints) { ls->hintsCallback = hints; } /** Set free hints CB */ static inline void consLnSetFreeHintsCallback(struct linenoiseState *ls, linenoiseFreeHintsCallback *freeh) { ls->freeHintsCallback = freeh; } /** This function is used by the callback function registered by the user * in order to add completion options given the input string when the * user typed . See the example.c source code for a very easy to * understand example. * * The completion will be duplicated, it does not need to live past calling * this function. * */ void consLnAddCompletion(linenoiseCompletions *lc, const char *text); /** The high level function that is the main API of the linenoise library. */ int consLnReadLine(struct linenoiseState *ls); // buffer is in "ls" /** This is the API call to add a new entry in the linenoise history. * It uses a fixed array of char pointers that are shifted (memmoved) * when the history max length is reached in order to remove the older * entry and make room for the new one, so it is not exactly suitable for huge * histories, but will work well for a few hundred of entries. * * Using a circular buffer is smarter, but a bit more complex to handle. */ int consLnHistoryAdd(struct linenoiseState *ls, const char *line); /** Set the maximum length for the history. This function can be called even * if there is already some history, the function will make sure to retain * just the latest 'len' elements if the new history length value is smaller * than the amount of items already inside the history. */ int consLnHistorySetMaxLen(struct linenoiseState *ls, int len); #if CONSOLE_FILE_SUPPORT /** Save the history in the specified file. On success 0 is returned, * on error -1 is returned. */ int consLnHistorySave(struct linenoiseState *ls, const char *filename); /** Load the history from the specified file. If the file does not exist * zero is returned and no operation is performed. * * If the file exists and the operation succeeded 0 is returned, otherwise * on error -1 is returned. */ int consLnHistoryLoad(struct linenoiseState *ls, const char *filename); #endif /** Free history buffer for instance */ void consLnHistoryFree(struct linenoiseState *ls); /** Clear the screen. Used to handle ctrl+l */ void consLnClearScreen(struct linenoiseState *ls); /** Set if to use or not the multi line mode. */ static inline void consLnSetMultiLine(struct linenoiseState *ls, int ml) { ls->mlmode = ml; } /** Get ml mode state */ static inline bool consLnGetMultiLine(struct linenoiseState *ls) { return ls->mlmode; } /** Set if terminal does not recognize escape sequences */ static inline void consLnSetDumbMode(struct linenoiseState *ls, int dumb) { ls->dumbmode = dumb; } /** Get dumb mode state */ static inline bool consLnGetDumbMode(struct linenoiseState *ls) { return ls->dumbmode; } /** Enable/disable echo on keypress (only applies to dumb mode) */ static inline void consLnSetEchoMode(struct linenoiseState *ls, int set) { ls->echomode = set; } /** Get echo mode state */ static inline bool consLnGetEchoMode(struct linenoiseState *ls) { return ls->echomode; } #endif /* LINENOISE_H */