summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrés <andmarti@gmail.com>2021-03-25 13:49:18 -0300
committerAndrés <andmarti@gmail.com>2021-03-25 13:49:18 -0300
commitbbf3d6552cb9a9cc287220acc6d6e83c3091ca3f (patch)
tree1b409c9a1a06b40ee7a516525c2b10a37d65c631 /src
parentdca777c8d1401590f530c26cee2924190116948d (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.c17
-rw-r--r--src/buffer.c12
-rw-r--r--src/cmds_command.c6
-rwxr-xr-xsrc/gram.y17
-rw-r--r--src/input.c56
-rw-r--r--src/maps.c44
-rw-r--r--src/maps.h1
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);
diff --git a/src/gram.y b/src/gram.y
index 873417b..7b9f3ab 100755
--- a/src/gram.y
+++ b/src/gram.y
@@ -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.
diff --git a/src/maps.c b/src/maps.c
index d3778ec..f27714d 100644
--- a/src/maps.c
+++ b/src/maps.c
@@ -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);
diff --git a/src/maps.h b/src/maps.h
index 0c2f04f..4bdde69 100644
--- a/src/maps.h
+++ b/src/maps.h
@@ -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 ();