Browse Source

klish: Completion of equal part of possible completions

Serj Kalichev 1 year ago
parent
commit
4e2baf82d7
3 changed files with 39 additions and 6 deletions
  1. 35 4
      bin/klish/interactive.c
  2. 2 0
      tinyrl/tinyrl.h
  3. 2 2
      tinyrl/tinyrl/tinyrl.c

+ 35 - 4
bin/klish/interactive.c

@@ -228,15 +228,46 @@ bool_t completion_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
 	}
 
 	completions_num = faux_list_len(completions);
+
+	// Single possible completion
 	if (1 == completions_num) {
 		char *compl = (char *)faux_list_data(faux_list_head(completions));
 		tinyrl_line_insert(ctx->tinyrl, compl, strlen(compl));
 		tinyrl_redisplay(ctx->tinyrl);
+
+	// Multi possible completions
 	} else if (completions_num > 1) {
-		tinyrl_multi_crlf(ctx->tinyrl);
-		tinyrl_reset_line_state(ctx->tinyrl);
-		display_completions(ctx->tinyrl, completions, prefix, max_compl_len);
-		tinyrl_redisplay(ctx->tinyrl);
+		faux_list_node_t *eq_iter = NULL;
+		size_t eq_part = 0;
+		char *str = NULL;
+		char *compl = NULL;
+
+		// Try to find equal part for all possible completions
+		eq_iter = faux_list_head(completions);
+		str = (char *)faux_list_data(eq_iter);
+		eq_part = strlen(str);
+		eq_iter = faux_list_next_node(eq_iter);
+
+		while ((compl = (char *)faux_list_each(&eq_iter)) && (eq_part > 0)) {
+			size_t cur_eq = 0;
+			cur_eq = tinyrl_equal_part(ctx->tinyrl, str, compl);
+			if (cur_eq < eq_part)
+				eq_part = cur_eq;
+		}
+
+		// The equal part was found
+		if (eq_part > 0) {
+			tinyrl_line_insert(ctx->tinyrl, str, eq_part);
+			tinyrl_redisplay(ctx->tinyrl);
+
+		// There is no equal part for all completions
+		} else {
+			tinyrl_multi_crlf(ctx->tinyrl);
+			tinyrl_reset_line_state(ctx->tinyrl);
+			display_completions(ctx->tinyrl, completions,
+				prefix, max_compl_len);
+			tinyrl_redisplay(ctx->tinyrl);
+		}
 	}
 
 	faux_list_free(completions);

+ 2 - 0
tinyrl/tinyrl.h

@@ -99,6 +99,8 @@ void tinyrl_crlf(const tinyrl_t *tinyrl);
 void tinyrl_multi_crlf(const tinyrl_t *tinyrl);
 size_t tinyrl_width(const tinyrl_t *tinyrl);
 int tinyrl_printf(const tinyrl_t *tinyrl, const char *fmt, ...);
+size_t tinyrl_equal_part(const tinyrl_t *tinyrl,
+	const char *s1, const char *s2);
 
 
 bool_t tinyrl_line_insert(tinyrl_t *tinyrl, const char *text, size_t len);

+ 2 - 2
tinyrl/tinyrl/tinyrl.c

@@ -580,7 +580,7 @@ static void move_cursor(const tinyrl_t *tinyrl, size_t cur_pos, size_t target_po
 }
 
 
-static size_t str_equal_part(const tinyrl_t *tinyrl,
+size_t tinyrl_equal_part(const tinyrl_t *tinyrl,
 	const char *s1, const char *s2)
 {
 	const char *str1 = s1;
@@ -646,7 +646,7 @@ void tinyrl_redisplay(tinyrl_t *tinyrl)
 		size_t eq_chars = 0; // Printable symbols
 		size_t last_pos_chars = 0;
 		// If line and last line have the equal chars at begining
-		eq_bytes = str_equal_part(tinyrl, tinyrl->line.str, tinyrl->last.str);
+		eq_bytes = tinyrl_equal_part(tinyrl, tinyrl->line.str, tinyrl->last.str);
 		eq_chars = utf8_nsyms(tinyrl->last.str, eq_bytes);
 		last_pos_chars = utf8_nsyms(tinyrl->last.str, tinyrl->last.pos);
 		move_cursor(tinyrl, tinyrl->prompt_chars + last_pos_chars,