summaryrefslogtreecommitdiff
path: root/interactive.h
blob: 316f94953b26cfa88c562c054aa0b2fbd94e495a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* 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);