|
@@ -717,283 +717,3 @@ void tinyrl_reset_hist_pos(tinyrl_t *tinyrl)
|
|
|
{
|
|
|
hist_pos_reset(tinyrl->hist);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-#if 0
|
|
|
-
|
|
|
-/*----------------------------------------------------------------------- */
|
|
|
-/*
|
|
|
-tinyrl is called whenever a line is edited in any way.
|
|
|
-It signals that if we are currently viewing a history line we should transfer it
|
|
|
-to the current buffer
|
|
|
-*/
|
|
|
-static void changed_line(tinyrl_t * tinyrl)
|
|
|
-{
|
|
|
- /* if the current line is not our buffer then make it so */
|
|
|
- if (tinyrl->line != tinyrl->buffer) {
|
|
|
- /* replace the current buffer with the new details */
|
|
|
- free(tinyrl->buffer);
|
|
|
- tinyrl->line = tinyrl->buffer = lub_string_dup(tinyrl->line);
|
|
|
- tinyrl->buffer_size = strlen(tinyrl->buffer);
|
|
|
- assert(tinyrl->line);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*----------------------------------------------------------------------- */
|
|
|
-/*
|
|
|
- * A convenience function for displaying a list of strings in columnar
|
|
|
- * format on Readline's output stream. matches is the list of strings,
|
|
|
- * in argv format, such as a list of completion matches. len is the number
|
|
|
- * of strings in matches, and max is the length of the longest string in matches.
|
|
|
- * tinyrl function uses the setting of print-completions-horizontally to select
|
|
|
- * how the matches are displayed
|
|
|
- */
|
|
|
-void tinyrl_display_matches(const tinyrl_t *tinyrl,
|
|
|
- char *const *matches, unsigned int len, size_t max)
|
|
|
-{
|
|
|
- unsigned int width = tinyrl_vt100__get_width(tinyrl->term);
|
|
|
- unsigned int cols, rows;
|
|
|
-
|
|
|
- /* Find out column and rows number */
|
|
|
- if (max < width)
|
|
|
- cols = (width + 1) / (max + 1); /* allow for a space between words */
|
|
|
- else
|
|
|
- cols = 1;
|
|
|
- rows = len / cols + 1;
|
|
|
-
|
|
|
- assert(matches);
|
|
|
- if (matches) {
|
|
|
- unsigned int r, c;
|
|
|
- len--, matches++; /* skip the subtitution string */
|
|
|
- /* Print out a table of completions */
|
|
|
- for (r = 0; r < rows && len; r++) {
|
|
|
- for (c = 0; c < cols && len; c++) {
|
|
|
- const char *match = *matches++;
|
|
|
- len--;
|
|
|
- if ((c + 1) == cols) /* Last str in row */
|
|
|
- tinyrl_vt100_printf(tinyrl->term, "%s",
|
|
|
- match);
|
|
|
- else
|
|
|
- tinyrl_vt100_printf(tinyrl->term, "%-*s ",
|
|
|
- max, match);
|
|
|
- }
|
|
|
- tinyrl_crlf(tinyrl);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*-------------------------------------------------------- */
|
|
|
-/*
|
|
|
- * Returns an array of strings which is a list of completions for text.
|
|
|
- * If there are no completions, returns NULL. The first entry in the
|
|
|
- * returned array is the substitution for text. The remaining entries
|
|
|
- * are the possible completions. The array is terminated with a NULL pointer.
|
|
|
- *
|
|
|
- * entry_func is a function of two args, and returns a char *.
|
|
|
- * The first argument is text. The second is a state argument;
|
|
|
- * it is zero on the first call, and non-zero on subsequent calls.
|
|
|
- * entry_func returns a NULL pointer to the caller when there are no
|
|
|
- * more matches.
|
|
|
- */
|
|
|
-char **tinyrl_completion(tinyrl_t * tinyrl,
|
|
|
- const char *line, unsigned int start, unsigned int end,
|
|
|
- tinyrl_compentry_func_t * entry_func)
|
|
|
-{
|
|
|
- unsigned int state = 0;
|
|
|
- size_t size = 1;
|
|
|
- unsigned int offset = 1; /* Need at least one entry for the substitution */
|
|
|
- char **matches = NULL;
|
|
|
- char *match;
|
|
|
- /* duplicate the string upto the insertion point */
|
|
|
- char *text = lub_string_dupn(line, end);
|
|
|
-
|
|
|
- /* now try and find possible completions */
|
|
|
- while ((match = entry_func(tinyrl, text, start, state++))) {
|
|
|
- if (size == offset) {
|
|
|
- /* resize the buffer if needed - the +1 is for the NULL terminator */
|
|
|
- size += 10;
|
|
|
- matches =
|
|
|
- realloc(matches, (sizeof(char *) * (size + 1)));
|
|
|
- }
|
|
|
- /* not much we can do... */
|
|
|
- if (!matches)
|
|
|
- break;
|
|
|
- matches[offset] = match;
|
|
|
-
|
|
|
- /*
|
|
|
- * augment the substitute string with tinyrl entry
|
|
|
- */
|
|
|
- if (1 == offset) {
|
|
|
- /* let's be optimistic */
|
|
|
- matches[0] = lub_string_dup(match);
|
|
|
- } else {
|
|
|
- char *p = matches[0];
|
|
|
- size_t match_len = strlen(p);
|
|
|
- /* identify the common prefix */
|
|
|
- while ((tolower(*p) == tolower(*match)) && match_len--) {
|
|
|
- p++, match++;
|
|
|
- }
|
|
|
- /* terminate the prefix string */
|
|
|
- *p = '\0';
|
|
|
- }
|
|
|
- offset++;
|
|
|
- }
|
|
|
- /* be a good memory citizen */
|
|
|
- lub_string_free(text);
|
|
|
-
|
|
|
- if (matches)
|
|
|
- matches[offset] = NULL;
|
|
|
- return matches;
|
|
|
-}
|
|
|
-
|
|
|
-/*-------------------------------------------------------- */
|
|
|
-void tinyrl_delete_matches(char **tinyrl)
|
|
|
-{
|
|
|
- char **matches = tinyrl;
|
|
|
- while (*matches) {
|
|
|
- /* release the memory for each contained string */
|
|
|
- free(*matches++);
|
|
|
- }
|
|
|
- /* release the memory for the array */
|
|
|
- free(tinyrl);
|
|
|
-}
|
|
|
-
|
|
|
-/*-------------------------------------------------------- */
|
|
|
-void tinyrl_replace_line(tinyrl_t * tinyrl, const char *text, int clear_undo)
|
|
|
-{
|
|
|
- size_t new_len = strlen(text);
|
|
|
-
|
|
|
- /* ignored for now */
|
|
|
- clear_undo = clear_undo;
|
|
|
-
|
|
|
- /* ensure there is sufficient space */
|
|
|
- if (tinyrl_extend_line_buffer(tinyrl, new_len)) {
|
|
|
-
|
|
|
- /* overwrite the current contents of the buffer */
|
|
|
- strcpy(tinyrl->buffer, text);
|
|
|
-
|
|
|
- /* set the insert point and end point */
|
|
|
- tinyrl->point = tinyrl->end = new_len;
|
|
|
- }
|
|
|
- tinyrl_redisplay(tinyrl);
|
|
|
-}
|
|
|
-
|
|
|
-/*-------------------------------------------------------- */
|
|
|
-static tinyrl_match_e
|
|
|
-tinyrl_do_complete(tinyrl_t * tinyrl, bool_t with_extensions)
|
|
|
-{
|
|
|
- tinyrl_match_e result = TINYRL_NO_MATCH;
|
|
|
- char **matches = NULL;
|
|
|
- unsigned int start, end;
|
|
|
- bool_t completion = BOOL_FALSE;
|
|
|
- bool_t prefix = BOOL_FALSE;
|
|
|
- int i = 0;
|
|
|
-
|
|
|
- /* find the start and end of the current word */
|
|
|
- start = end = tinyrl->point;
|
|
|
- while (start && !isspace(tinyrl->line[start - 1]))
|
|
|
- start--;
|
|
|
-
|
|
|
- if (tinyrl->attempted_completion_function) {
|
|
|
- tinyrl->completion_over = BOOL_FALSE;
|
|
|
- tinyrl->completion_error_over = BOOL_FALSE;
|
|
|
- /* try and complete the current line buffer */
|
|
|
- matches = tinyrl->attempted_completion_function(tinyrl,
|
|
|
- tinyrl->line, start, end);
|
|
|
- }
|
|
|
- if (!matches && (BOOL_FALSE == tinyrl->completion_over)) {
|
|
|
- /* insert default completion call here... */
|
|
|
- }
|
|
|
- if (!matches)
|
|
|
- return result;
|
|
|
-
|
|
|
- /* identify and insert a common prefix if there is one */
|
|
|
- if (0 != strncmp(matches[0], &tinyrl->line[start],
|
|
|
- strlen(matches[0]))) {
|
|
|
- /*
|
|
|
- * delete the original text not including
|
|
|
- * the current insertion point character
|
|
|
- */
|
|
|
- if (tinyrl->end != end)
|
|
|
- end--;
|
|
|
- tinyrl_delete_text(tinyrl, start, end);
|
|
|
- if (BOOL_FALSE == tinyrl_insert_text(tinyrl, matches[0]))
|
|
|
- return TINYRL_NO_MATCH;
|
|
|
- completion = BOOL_TRUE;
|
|
|
- }
|
|
|
- for (i = 1; matches[i]; i++) {
|
|
|
- /* tinyrl is just a prefix string */
|
|
|
- if (0 == lub_string_nocasecmp(matches[0], matches[i]))
|
|
|
- prefix = BOOL_TRUE;
|
|
|
- }
|
|
|
- /* is there more than one completion? */
|
|
|
- if (matches[2]) {
|
|
|
- char **tmp = matches;
|
|
|
- unsigned int max, len;
|
|
|
- max = len = 0;
|
|
|
- while (*tmp) {
|
|
|
- size_t size = strlen(*tmp++);
|
|
|
- len++;
|
|
|
- if (size > max)
|
|
|
- max = size;
|
|
|
- }
|
|
|
- if (completion)
|
|
|
- result = TINYRL_COMPLETED_AMBIGUOUS;
|
|
|
- else if (prefix)
|
|
|
- result = TINYRL_MATCH_WITH_EXTENSIONS;
|
|
|
- else
|
|
|
- result = TINYRL_AMBIGUOUS;
|
|
|
- if (with_extensions || !prefix) {
|
|
|
- /* Either we always want to show extensions or
|
|
|
- * we haven't been able to complete the current line
|
|
|
- * and there is just a prefix, so let the user see the options
|
|
|
- */
|
|
|
- tinyrl_crlf(tinyrl);
|
|
|
- tinyrl_display_matches(tinyrl, matches, len, max);
|
|
|
- tinyrl_reset_line_state(tinyrl);
|
|
|
- }
|
|
|
- } else {
|
|
|
- result = completion ?
|
|
|
- TINYRL_COMPLETED_MATCH : TINYRL_MATCH;
|
|
|
- }
|
|
|
- /* free the memory */
|
|
|
- tinyrl_delete_matches(matches);
|
|
|
- /* redisplay the line */
|
|
|
- tinyrl_redisplay(tinyrl);
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-/*-------------------------------------------------------- */
|
|
|
-tinyrl_match_e tinyrl_complete_with_extensions(tinyrl_t * tinyrl)
|
|
|
-{
|
|
|
- return tinyrl_do_complete(tinyrl, BOOL_TRUE);
|
|
|
-}
|
|
|
-
|
|
|
-/*-------------------------------------------------------- */
|
|
|
-tinyrl_match_e tinyrl_complete(tinyrl_t * tinyrl)
|
|
|
-{
|
|
|
- return tinyrl_do_complete(tinyrl, BOOL_FALSE);
|
|
|
-}
|
|
|
-
|
|
|
-/*--------------------------------------------------------- */
|
|
|
-void tinyrl_completion_over(tinyrl_t * tinyrl)
|
|
|
-{
|
|
|
- tinyrl->completion_over = BOOL_TRUE;
|
|
|
-}
|
|
|
-
|
|
|
-/*--------------------------------------------------------- */
|
|
|
-void tinyrl_completion_error_over(tinyrl_t * tinyrl)
|
|
|
-{
|
|
|
- tinyrl->completion_error_over = BOOL_TRUE;
|
|
|
-}
|
|
|
-
|
|
|
-/*--------------------------------------------------------- */
|
|
|
-bool_t tinyrl_is_completion_error_over(const tinyrl_t * tinyrl)
|
|
|
-{
|
|
|
- return tinyrl->completion_error_over;
|
|
|
-}
|
|
|
-
|
|
|
-#endif
|