From 07be3bc2d2647764fe1ae5cd02899be645ae1e25 Mon Sep 17 00:00:00 2001 From: "sumedh.pendurkar" Date: Wed, 19 Oct 2016 01:18:35 +0530 Subject: [PATCH] autocomplete:Restructured autocomplete function and renamed it to complete_a_word() --- src/global.c | 8 +++- src/nano.c | 12 +++++- src/proto.h | 3 +- src/text.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/global.c b/src/global.c index 029b68b..6dbb479 100644 --- a/src/global.c +++ b/src/global.c @@ -38,6 +38,8 @@ bool console; /* Whether we're running on a Linux VC (TRUE) or under X (FALSE). */ #endif +bool word_completion = FALSE; +/*Used for complete_a_word() to remember consecutive keystrokes */ bool meta_key; /* Whether the current keystroke is a Meta key. */ bool shift_held; @@ -483,6 +485,7 @@ const char *unjust_tag = N_("Unjustify"); /* Initialize the list of functions and the list of shortcuts. */ void shortcut_init(void) { + const char *auto_complete_tag = N_("Auto Complete"); const char *read_file_tag = N_("Read File"); const char *whereis_tag = N_("Where Is"); const char *replace_tag = N_("Replace"); @@ -526,6 +529,7 @@ void shortcut_init(void) const char *nano_browser_lefthand_msg = N_("Go to lefthand column"); const char *nano_browser_righthand_msg = N_("Go to righthand column"); #endif + const char *nano_auto_complete_msg = ("Look up for the current word in the file and complete it"); const char *nano_prevpage_msg = N_("Go one screenful up"); const char *nano_nextpage_msg = N_("Go one screenful down"); const char *nano_cut_msg = @@ -721,7 +725,8 @@ void shortcut_init(void) add_to_funcs(goto_dir_void, MBROWSER, N_("Go To Dir"), IFSCHELP(nano_gotodir_msg), BLANKAFTER, VIEW); #endif - + add_to_funcs(complete_a_word, MMAIN, auto_complete_tag, + IFSCHELP(nano_auto_complete_msg), TOGETHER, VIEW); #ifndef DISABLE_HELP /* The description ("x") and blank_after (0) are irrelevant, * because the help viewer does not have a help text. */ @@ -1064,6 +1069,7 @@ void shortcut_init(void) add_to_sclist(MMAIN, "^\\", do_replace, 0); add_to_sclist(MMAIN, "M-R", do_replace, 0); add_to_sclist(MMAIN, "F14", do_replace, 0); + add_to_sclist(MMAIN, "^]", complete_a_word, 0); add_to_sclist(MMOST, "^K", do_cut_text_void, 0); add_to_sclist(MMOST, "F9", do_cut_text_void, 0); add_to_sclist(MMAIN, "^U", do_uncut_text, 0); diff --git a/src/nano.c b/src/nano.c index a542073..06dfdeb 100644 --- a/src/nano.c +++ b/src/nano.c @@ -55,6 +55,7 @@ static struct termios oldterm; static struct sigaction act; /* Used to set up all our fun signal handlers. */ +int new_completion = 0; /* Create a new filestruct node. Note that we do not set prevnode->next * to the new line. */ filestruct *make_new_node(filestruct *prevnode) @@ -1687,7 +1688,6 @@ int do_input(bool allow_funcs) #endif ) preserve = TRUE; - #ifndef NANO_TINY if (s->scfunc == do_toggle_void) { do_toggle(s->toggle); @@ -1707,6 +1707,13 @@ int do_input(bool allow_funcs) #endif /* Execute the function of the shortcut. */ s->scfunc(); + /*Check if call for complete_a_word + * this helps to identify if consecutive calls are done + */ + if (s->scfunc == complete_a_word) + word_completion = TRUE; + else + word_completion = FALSE; #ifndef NANO_TINY /* If Shiftless movement occurred, discard a soft mark. */ if (openfile->mark_set && !shift_held && @@ -1730,6 +1737,9 @@ int do_input(bool allow_funcs) update_line(openfile->current, openfile->current_x); } } + else { + word_completion = FALSE; + } /* If we aren't cutting or copying text, and the key wasn't a toggle, * blow away the text in the cutbuffer upon the next cutting action. */ diff --git a/src/proto.h b/src/proto.h index 553418b..ab3c05f 100644 --- a/src/proto.h +++ b/src/proto.h @@ -32,7 +32,7 @@ extern volatile sig_atomic_t sigwinch_counter; #ifdef __linux__ extern bool console; #endif - +extern bool word_completion; extern bool meta_key; extern bool shift_held; @@ -605,6 +605,7 @@ void get_history_newer_void(void); #endif /* All functions in text.c. */ +void complete_a_word(void); #ifndef NANO_TINY void do_mark(void); #endif diff --git a/src/text.c b/src/text.c index d0d1955..01fd1c0 100644 --- a/src/text.c +++ b/src/text.c @@ -46,6 +46,134 @@ static filestruct *jusbottom = NULL; /* Pointer to the end of the justify buffer. */ #endif +/*Following three variables are used to store state of complete_a_word()*/ +static int prev_len = 0; +static int prev_search_pos = 0; +static filestruct *prev_search = NULL; + +/* Copy the word from the line which contains the pattern + * returns NULL for error + * else returns word + */ +char* copy_arrays(char *check_line, int start) +{ + char *word; + int i = start; + int len_of_word = 0; + + while (is_word_mbchar(&check_line[i], FALSE)) { + i++; + len_of_word++; + } + word = (char *)malloc((len_of_word + 1) * sizeof(char)); + if (word == NULL) + return NULL; + i = start; + int j = 0; + + while (is_word_mbchar(&check_line[i], FALSE)) { + word[j++] = check_line[i]; + i++; + } + word[j] = '\0'; + return word; +} + +/* This function finds out the current word which the user is typing + * searches for the word in the entire file + * replaces it, if only 1 match is found, else it suggests the possible completions + */ +void complete_a_word(void) +{ + filestruct *check_line = openfile->current; + char *to_find; + int i = 0; + char *word; + if (!word_completion) { + prev_len = 0; + prev_search = NULL; + prev_search_pos = 0; + } + /*remove the previous suggestion*/ + for (i = 0; i < prev_len; i++) + do_backspace(); + i = 0; + blank_statusbar(); + wnoutrefresh(bottomwin); + edit_refresh(); + int curpos = openfile->current_x, len_to_find = 0; + int to_find_start_pos = curpos; + int to_find_end_pos = curpos, j = 0, match = 0, curr_line_no = check_line->lineno; + + /*find the starting postion of current word*/ + while (to_find_start_pos-- != 0) + if (!is_word_mbchar(&check_line->data[to_find_start_pos], FALSE)) + break; + to_find_start_pos++; + to_find = (char *)malloc((to_find_end_pos - to_find_start_pos + 1) * sizeof(char)); + if (to_find == NULL) { + statusline(HUSH, "Insufficient Memory"); + return; + } + /*copy what is to be searched in to find*/ + while (to_find_start_pos + i < curpos) + to_find[len_to_find++] = check_line->data[to_find_start_pos + i++]; + to_find[len_to_find] = '\0'; + if (len_to_find == 0) + return; + /*Set the starting point of search*/ + if (prev_search) { + check_line = prev_search; + i = prev_search_pos; + } + else { + check_line = openfile->fileage; + i = 0; + } +/*Finding the current word in the entire file*/ + while (check_line != NULL) { + int len_data = strlen(check_line->data); + + for (; i < len_data; i++) { + for (j = 0; (i == 0 || !is_word_mbchar(&check_line->data[i - 1], FALSE)) + && j < len_to_find; j++) + if (to_find[j] != check_line->data[i + j] || + (check_line->lineno == curr_line_no && i == to_find_start_pos)) + break; + if (j == len_to_find && (i + j != len_data && + is_word_mbchar(&check_line->data[i + j], FALSE))) { + match++; + word = copy_arrays(check_line->data, i); + if (!word) { + statusline(HUSH, "Insufficient Memory"); + return; + } + else { + /*Output the word and store this state*/ + prev_len = strlen(word) - len_to_find; + do_output(&word[len_to_find], prev_len, FALSE); + prev_search = check_line; + prev_search_pos = i + 1; + return; + } + } + } + i = 0; + check_line = check_line->next; + } + /*No match found reset state*/ + if (match == 0) { + statusline(HUSH, "No match found"); + prev_len = 0; + prev_search_pos = 0; + prev_search = NULL; + } + free(to_find); + /*free words*/ + if (!word) + free(word); +} + #ifndef NANO_TINY /* Toggle the mark. */ void do_mark(void) -- 2.7.4