/* SPDX-License-Identifier: GPL-2.0 */ /** \file interactive.h Interactive sessions based on the GNU readline library. * * This API is used by para_client(1), para_audioc(1) and para_play(1). * The API is twofold: The first part consists of structures and functions * which implement interactive line editing. The second part implements * programmable completion. All functions declared here are defined in \ref * interactive.c. All function and structure names start with "i9e", which * is short for "interactive". * * To start an interactive editing session, programs define and initialize * an instance of struct \ref i9e_client_info and pass a pointer to this * instance to \ref i9e_open() in order to register the interactive task to * the scheduler. These users set the poll function of the scheduler to \ref * i9e_poll() and employ \ref i9e_log() as the log function. * * The completion functions are run when para_client(1) or para_audioc(1) * are started in completion mode, or when the tab key is pressed during an * interactive session. */ /** Structure passed as input to the completers. */ struct i9e_completion_info { char *buffer; /**< The full line. */ char *word; /**< The (partial) word the cursor is in. */ int point; /**< Cursor position. */ char **argv; /**< Vector of words in \a buffer. */ int argc; /**< Number of elements(words) in argv. */ int word_num; /**< The cursor is on this word. */ }; /** Completion information returned by the completers. */ struct i9e_completion_result { /** NULL-terminated array of possible completions. */ char **matches; /** Whether standard filename completion should be performed. */ bool filename_completion_desired; /** Suppress adding a space character after the completed word. */ bool dont_append_space; }; /** * Define a completer which does nothing. * * \param name Determines the name of the function to be defined. */ #define I9E_DUMMY_COMPLETER(name) static void name ## _completer( \ __a_unused struct i9e_completion_info *ciname, \ struct i9e_completion_result *result) {result->matches = NULL;} /** * A completer is simply a function pointer and name of the command for which * it performs completion. */ struct i9e_completer { /** The command for which this completer provides completion. */ const char *name; /** The completer returns all possible completions via the second parameter. */ void (*completer)(struct i9e_completion_info *, struct i9e_completion_result *); }; /** * The i9e configuration settings of the client. * * A structure of this type must be allocated and filled in by the client * before it is passed to the i9e subsystem via \ref i9e_open(). */ struct i9e_client_info { /** Threshold for i9e_log(). */ int loglevel; /** Complete input lines are passed to this callback function. */ int (*line_handler)(char *line); /** In single key mode, this callback is executed instead. */ int (*key_handler)(int key); /** The array of valid key sequences for the readline library. */ char **bound_keyseqs; /** File descriptors to use for input/output/log. */ int fds[3]; /** Text of the current prompt. */ char *prompt; /** Where to store the readline history. */ char *history_file; /** * The array of completers, one per command. This is used for * completing the first word (the command) and for calling the right * completer if the cursor is not on the first word. */ const struct i9e_completer *completers; /** * If non-NULL, this node is attached immediately to the stdout buffer * tree node of the i9e subsystem. */ struct btr_node *producer; }; int i9e_open(struct i9e_client_info *ici, struct sched *s); void i9e_attach_to_stdout(struct btr_node *producer); void i9e_print_status_bar(char *buf, unsigned len); void i9e_close(void); void i9e_signal_dispatch(int sig_num); __printf_2_3 void i9e_log(int ll, const char* fmt,...); int i9e_poll(struct pollfd *fds, nfds_t nfds, int timeout); int i9e_extract_completions(const char *word, char * const *string_list, char ***result); char **i9e_complete_commands(const char *word, const struct i9e_completer *completers); void i9e_complete_option(char * const *opts, struct i9e_completion_info *ci, struct i9e_completion_result *cr); unsigned i9e_get_nonopt_argnum(char * const *opts, struct i9e_completion_info *ci); int i9e_cword_is_option_arg(char * const *opts, struct i9e_completion_info *ci); int i9e_print_completions(const struct i9e_completer *completers); int i9e_get_error(void); void i9e_ll_completer(struct i9e_completion_info *ci, struct i9e_completion_result *cr);