diff options
author | Andrés <andmarti@gmail.com> | 2021-03-25 13:49:18 -0300 |
---|---|---|
committer | Andrés <andmarti@gmail.com> | 2021-03-25 13:49:18 -0300 |
commit | bbf3d6552cb9a9cc287220acc6d6e83c3091ca3f (patch) | |
tree | 1b409c9a1a06b40ee7a516525c2b10a37d65c631 /src | |
parent | dca777c8d1401590f530c26cee2924190116948d (diff) |
Added mappings for command mode.
Handle <ESC> key in mappings.
Fixed vmaps in get_mappings function.
Diffstat (limited to 'src')
-rw-r--r-- | src/block.c | 17 | ||||
-rw-r--r-- | src/buffer.c | 12 | ||||
-rw-r--r-- | src/cmds_command.c | 6 | ||||
-rwxr-xr-x | src/gram.y | 17 | ||||
-rw-r--r-- | src/input.c | 56 | ||||
-rw-r--r-- | src/maps.c | 44 | ||||
-rw-r--r-- | src/maps.h | 1 |
7 files changed, 118 insertions, 35 deletions
diff --git a/src/block.c b/src/block.c index 13a628e..2a9773e 100644 --- a/src/block.c +++ b/src/block.c @@ -39,7 +39,7 @@ * \file block.c * \author Andrés Martinelli <andmarti@gmail.com> * \date 2017-07-18 - * \brief TODO Write a brief file description. + * \brief functions used for handling input */ #include "block.h" @@ -47,20 +47,17 @@ #include "utils/string.h" /** - * \brief TODO Document block_in_block() - * - * \details Find out if the int elements in the bus list are inside the - * ori list. If so, return the original ori position of it. - * + * \brief Function that tells if 'b' buffer is inside 'o' buffer + * \details Find out if the int elements in the 'b' list are inside the + * ori list. + * Since the b list could be in the middle of the o list, and not + * only at the beginning. * \param[in] o * \param[in] b - * - * \return TODO What does this return? + * \return the position in the 'o' list if found. returns -1 if not in block */ - // TODO: IMPROVE this. Use two while statements in order to create an array // from a block, and make them work separately. Leave the logic unmodified - int block_in_block (struct block * o, struct block * b) { int lori = get_bufsize(o); int lbus = get_bufsize(b); diff --git a/src/buffer.c b/src/buffer.c index d3ed274..1d58496 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -50,7 +50,7 @@ #include "utils/string.h" /** -* \brief Create buffer as list of blocks +* \brief Create buffer as list of blocks * * \return b */ @@ -106,6 +106,7 @@ void copybuffer(struct block * origen, struct block * destino) { return; } + /** * \brief Replace the element of a buffer at 'pos' with a '\0' * @@ -136,7 +137,7 @@ void del_buf (struct block * buf, int pos) { } /** -* \brief TODO Document fludh_buf() +* \brief TODO Document flush_buf() * * \param[in] buf * @@ -147,8 +148,7 @@ void flush_buf (struct block * buf) { if (buf == NULL) return; struct block * aux, * np; - for (aux = buf->pnext; aux != NULL; aux = np) - { + for (aux = buf->pnext; aux != NULL; aux = np) { np = aux->pnext; free(aux); } @@ -175,7 +175,7 @@ void erase_buf (struct block * buf) { } /** -* \brief Get size of buffer (indlucded special chars) +* \brief Get size of buffer (included special chars) * * \param[in] buf * @@ -247,7 +247,7 @@ int find_val(struct block * buf, int value) { if (b_aux->value == value) return 1; b_aux = b_aux->pnext; } - return 0; + return 0; } /** diff --git a/src/cmds_command.c b/src/cmds_command.c index 3f39000..5108b74 100644 --- a/src/cmds_command.c +++ b/src/cmds_command.c @@ -94,6 +94,9 @@ L"ccopy", L"cellcolor", L"color", L"cpaste", +L"cmap", +L"cnoremap", +L"cunmap", L"e csv", L"e tab", L"e txt", @@ -866,11 +869,14 @@ void do_commandmode(struct block * sb) { } else if ( ! wcsncmp(inputline, L"nmap", 4) || ! wcsncmp(inputline, L"imap", 4) || ! wcsncmp(inputline, L"vmap", 4) || + ! wcsncmp(inputline, L"cmap", 4) || ! wcsncmp(inputline, L"inoremap", 8) || ! wcsncmp(inputline, L"nnoremap", 8) || ! wcsncmp(inputline, L"vnoremap", 8) || + ! wcsncmp(inputline, L"cnoremap", 8) || ! wcsncmp(inputline, L"iunmap", 6) || ! wcsncmp(inputline, L"vunmap", 6) || + ! wcsncmp(inputline, L"cunmap", 6) || ! wcsncmp(inputline, L"nunmap", 6) ) { send_to_interp(inputline); @@ -203,13 +203,16 @@ token S_YANKCOL %token S_REDO %token S_UNDO %token S_IMAP +%token S_CMAP %token S_NMAP %token S_VMAP %token S_INOREMAP +%token S_CNOREMAP %token S_NNOREMAP %token S_VNOREMAP %token S_NUNMAP %token S_IUNMAP +%token S_CUNMAP %token S_VUNMAP %token S_COLOR %token S_CELLCOLOR @@ -612,6 +615,11 @@ command: scxfree($2); scxfree($3); } + | S_CMAP STRING STRING { + add_map($2, $3, COMMAND_MODE, 1); + scxfree($2); + scxfree($3); + } | S_NNOREMAP STRING STRING { add_map($2, $3, NORMAL_MODE, 0); scxfree($2); @@ -628,6 +636,11 @@ command: scxfree($2); scxfree($3); } + | S_CNOREMAP STRING STRING { + add_map($2, $3, COMMAND_MODE, 0); + scxfree($2); + scxfree($3); + } | S_NUNMAP STRING { del_map($2, NORMAL_MODE); @@ -643,6 +656,10 @@ command: scxfree($2); } + | S_CUNMAP STRING { + del_map($2, COMMAND_MODE); + scxfree($2); + } | S_COLOR STRING { #ifdef USECOLORS chg_color($2); diff --git a/src/input.c b/src/input.c index 338500c..205d6b5 100644 --- a/src/input.c +++ b/src/input.c @@ -67,6 +67,9 @@ int cmd_multiplier = 0; // Multiplier int cmd_pending = 0; // Command pending int cmd_digraph = 0; static wint_t digraph; +#ifdef MOUSE +MEVENT event; // mouse event +#endif /** * \brief Reads stdin for a valid command @@ -81,19 +84,29 @@ static wint_t digraph; */ void handle_input(struct block * buffer) { - struct timeval start_tv, m_tv; // For measuring timeout + struct timeval start_tv, m_tv, init_tv; // For measuring timeout gettimeofday(&start_tv, NULL); gettimeofday(&m_tv, NULL); + gettimeofday(&init_tv, NULL); // keep time when entering handle_input long msec = (m_tv.tv_sec - start_tv.tv_sec) * 1000L + (m_tv.tv_usec - start_tv.tv_usec) / 1000L; + long msec_init = (m_tv.tv_sec - init_tv.tv_sec) * 1000L + + (m_tv.tv_usec - init_tv.tv_usec) / 1000L; cmd_multiplier = 0; cmd_pending = 0; -#ifdef MOUSE - MEVENT event; // mouse event -#endif - while ( ! has_cmd(buffer, msec) && msec <= CMDTIMEOUT ) { + /* add char to buffer until valid command found. + * important: buffer may contain a valid command (for instance, + * just a letter in insert mode) but that buffer start may also + * be a possible mapping! (for instace kj in insert mode to exit the mode). + * if so, wait a 800ms, before triggering has_cmd.. + */ + while ( + ( ! has_cmd(buffer, msec) && msec <= CMDTIMEOUT) || + ( could_be_mapping(buffer) && msec_init < 800) + ) { + // if command pending, refresh 'ef' only. Multiplier and cmd pending if (cmd_pending) ui_print_mult_pend(); @@ -110,13 +123,14 @@ void handle_input(struct block * buffer) { return; } else #endif - if ( d == OKEY_ESC || d == ctl('g')) { + + if ( d == OKEY_ESC || d == ctl('g')) { break_waitcmd_loop(buffer); ui_print_mult_pend(); return; } - // Handle multiplier of commands in NORMAL mode. + // Handle multiplier of commands in NORMAL VISUAL and EDIT modes if ( return_value != -1 && isdigit(d) && ( buffer->value == L'\0' || iswdigit((wchar_t) buffer->value)) && ( curmode == NORMAL_MODE || curmode == VISUAL_MODE || curmode == EDIT_MODE ) @@ -135,19 +149,13 @@ void handle_input(struct block * buffer) { continue; } - /* - * Update time stap to reset timeout after each loop - * (Only if current mode is COMMAND, INSERT or EDIT) and for each - * user input as well. - */ - fix_timeout(&start_tv); /* - * Handle special characters input: BS TAG ENTER HOME END DEL PGUP + * Handle special characters input: BS TAB ENTER HOME END DEL PGUP * PGDOWN and alphanumeric characters */ if (is_idchar(d) || return_value != -1) { - // If in NORMAL, VISUAL or EDITION mode , change top left corner indicator + // If in NORMAL, VISUAL or EDITION mode, added '?' cmd_pending at the left of MODE if ( (curmode == NORMAL_MODE && d >= ' ') || //FIXME (curmode == EDIT_MODE && d >= ' ') || (curmode == VISUAL_MODE && d >= ' ') ) { @@ -173,9 +181,27 @@ void handle_input(struct block * buffer) { replace_maps(buffer); } + /* + * Update time stamp to reset timeout after each loop + * (start_tv changes only if current mode is COMMAND, INSERT or + * EDIT) and for each user input as well. + */ gettimeofday(&m_tv, NULL); msec = (m_tv.tv_sec - start_tv.tv_sec) * 1000L + (m_tv.tv_usec - start_tv.tv_usec) / 1000L; + + msec_init = (m_tv.tv_sec - init_tv.tv_sec) * 1000L + + (m_tv.tv_usec - init_tv.tv_usec) / 1000L; + if (msec_init > 4000) gettimeofday(&init_tv, NULL); // just to avoid overload + fix_timeout(&start_tv); + + // to handle map of ESC + if ( buffer->value == OKEY_ESC || buffer->value == ctl('g')) { + break_waitcmd_loop(buffer); + ui_print_mult_pend(); + return; + } + } if (msec >= CMDTIMEOUT) { // timeout. Command incomplete cmd_pending = 0; // No longer wait for a command, set flag. @@ -39,7 +39,7 @@ * \file maps.c * \author Andrés Martinelli <andmarti@gmail.com> * \date 2017-07-18 - * \brief TODO Write a tbrief file description. + * \brief file that contain the different functions to support mappings */ #include <stdlib.h> @@ -58,6 +58,30 @@ static map * maps; static int mapdepth = 0; int len_maps = 0; + +/** + * \brief could_be_mapping + * a buffer may contain a valid command (for instance, just a letter in insert mode) + * but that buffer beginning may also be a possible mapping + * + * \param[in] struct block * (b) + * \return 0 if false. 1 otherwise + */ + +int could_be_mapping(struct block * b) { + // Traverse session mappings + map * m = maps; + + while (m != NULL) { + // Check if 'b' buffer might be in mapping + if (block_in_block(m->in, b) == 0 && m->mode == curmode) + return 1; + m = m->psig; + } + return 0; +} + + /** * \brief TODO Document replace_maps() * @@ -124,6 +148,8 @@ struct block * get_mapbuf_str (char * str) { is_specialkey = 0; if (! strcasecmp(sk, "CR")) // CR - ENTER key addto_buf(buffer, OKEY_ENTER); + else if (! strcasecmp(sk, "ESC")) // ESC + addto_buf(buffer, OKEY_ESC); else if (! strcasecmp(sk, "TAB")) // TAB addto_buf(buffer, OKEY_TAB); else if (! strcasecmp(sk, "LEFT")) // LEFT @@ -232,7 +258,7 @@ int exists_map(char * in, int mode) { } /** - * \brief Ammend a mapping to the curren session + * \brief Ammend a mapping to the current session * * \param[in] in * \param[in] out @@ -350,8 +376,6 @@ void get_mapstr_buf (struct block * b, char * str) { sprintf(str + strlen(str), "%c", (char) a->value); } else if (a->value == OKEY_ENTER) { strcat(str, "<CR>"); // CR - ENTER - } else if ( a->value == (uncl(a->value) & 0x1f)) { // C-x - sprintf(str + strlen(str), "<C-%c>", uncl(a->value)); } else if (a->value == OKEY_TAB) { strcat(str, "<TAB>"); // TAB } else if (a->value == OKEY_LEFT) { @@ -374,6 +398,10 @@ void get_mapstr_buf (struct block * b, char * str) { strcat(str, "<PGDOWN>"); // PGDOWN } else if (a->value == OKEY_PGUP) { strcat(str, "<PGUP>"); // PGUP + } else if (a->value == OKEY_ESC) { + strcat(str, "<ESC>"); // ESC + } else if ( a->value == (uncl(a->value) & 0x1f)) { // C-x + sprintf(str + strlen(str), "<C-%c>", uncl(a->value)); } a = a->pnext; } @@ -411,6 +439,14 @@ void get_mappings(char * salida) { case INSERT_MODE: mode = 'i'; break; + + case VISUAL_MODE: + mode = 'v'; + break; + + case COMMAND_MODE: + mode = 'c'; + break; } get_mapstr_buf(m->in, min); get_mapstr_buf(m->out, mout); @@ -55,6 +55,7 @@ typedef struct map map; extern unsigned int curmode; +int could_be_mapping(struct block * b); int replace_maps (struct block * b); struct block * get_mapbuf_str (char * str); void del_maps (); |