diff options
author | mongo <mongo@iomega> | 2016-04-15 16:20:17 -0300 |
---|---|---|
committer | mongo <mongo@iomega> | 2016-04-15 16:20:17 -0300 |
commit | f686ba184e0af3fd37aa8a743631a7a376f30843 (patch) | |
tree | e9a48dc691511a2961f93163944ba0ca1a84e5b3 /src/maps.c | |
parent | c0a088d7a4bc61e6e69fa5bd8964c39f68507c71 (diff) |
Renamed src.scim2 to src
Diffstat (limited to 'src/maps.c')
-rwxr-xr-x | src/maps.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/src/maps.c b/src/maps.c new file mode 100755 index 0000000..9ac16de --- /dev/null +++ b/src/maps.c @@ -0,0 +1,311 @@ +#include <stdlib.h> +#include <ctype.h> +#include <ncursesw/curses.h> +#include <string.h> +#include "maps.h" +#include "string.h" +#include "macros.h" +#include "color.h" +#include "conf.h" +#include "sc.h" +#include "block.h" +#include "utils/string.h" + +static map * maps; +static int mapdepth = 0; +int len_maps = 0; + +int replace_maps (struct block * b) { + int r = 0; + + if (++mapdepth == 1000) { + sc_error("recursive mapping"); + flush_buf(b); + mapdepth = 0; + return 0; + } + + // Traverse session mappings + map * m = maps; + while (m != NULL) { + // Check if a mapping already exists in 'b' buffer + int pos = block_in_block(b, m->in); + if (pos != -1 && m->mode == curmode) { + + // Replace m->in with m->out in 'b' list + if (replace_block_in_block(b, m->in, m->out) == -1) { + sc_error("error replacing maps"); + return -1; + } + r = 1; + break; + } + m = m->psig; + } + + if (r && m->recursive) replace_maps(b); // recursive mapping here! + return r; +} + +// create list of blocks based on map strings +struct block * get_mapbuf_str (char * str) { + struct block * buffer = create_buf(); + unsigned short l = strlen(str); + unsigned short i, j; + unsigned short is_specialkey = 0; + char sk[MAXSC+1]; + sk[0] = '\0'; + + for (i=0; i<l; i++) { + + // Add special keys + if (str[i] == '<') { + is_specialkey = 1; + + } else if (str[i] == '>') { + is_specialkey = 0; + if (! strcmp(sk, "CR")) // CR - ENTER key + addto_buf(buffer, OKEY_ENTER); + else if (! strcmp(sk, "TAB")) // TAB + addto_buf(buffer, OKEY_TAB); + else if (! strcmp(sk, "LEFT")) // LEFT + addto_buf(buffer, OKEY_LEFT); + else if (! strcmp(sk, "RIGHT")) // RIGHT + addto_buf(buffer, OKEY_RIGHT); + else if (! strcmp(sk, "DOWN")) // DOWN + addto_buf(buffer, OKEY_DOWN); + else if (! strcmp(sk, "UP")) // UP + addto_buf(buffer, OKEY_UP); + else if (! strcmp(sk, "DEL")) // DEL + addto_buf(buffer, OKEY_DEL); + else if (! strcmp(sk, "BS")) // BS + addto_buf(buffer, OKEY_BS); + else if (! strcmp(sk, "HOME")) // HOME + addto_buf(buffer, OKEY_HOME); + else if (! strcmp(sk, "END")) // END + addto_buf(buffer, OKEY_END); + else if (! strcmp(sk, "PGDOWN")) // PGDOWN + addto_buf(buffer, OKEY_PGDOWN); + else if (! strcmp(sk, "PGUP")) // PGUP + addto_buf(buffer, OKEY_PGUP); + else if (! strncmp(sk, "C-", 2) && strlen(sk) == 3 // C-X + && ( (sk[2] > 64 && sk[2] < 91) || (sk[2] > 96 && sk[2] < 123)) ) + addto_buf(buffer, ctl(tolower(sk[2]))); + + sk[0]='\0'; + + } else if (is_specialkey && strlen(sk) < MAXSC-1) { + add_char(sk, str[i], strlen(sk)); + + // Add some other characters + } else { + addto_buf(buffer, (int) str[i]); + } + } + + // If the buffer lacks the trailing '>', insert it + if (is_specialkey && i == l) { + j = strlen(sk); + addto_buf(buffer, '<'); + for (i=0; i<j; i++) addto_buf(buffer, (int) str[l-j+i]); + } + return buffer; +} + +// Remove mappings and free corresponding memory +void del_maps () { + map * m = maps; + map * e = m; + while (m != NULL) { + e = m->psig; + erase_buf(m->out); + erase_buf(m->in); + free(m); + m = e; + } + return; +} + +// Returns the las mapping of the current session +map * get_last_map() { + map * m = maps; + map * e = m; + + while (m != NULL) { + e = m; + m = m->psig; + } + return e; +} + +// Returns the position of a mapping for some mode if it already exists, -1 +// otherwise +int exists_map(char * in, int mode) { + map * m = maps; + char str_in[MAXMAPITEM] = ""; + int pos = -1; + + while (m != NULL) { + pos++; + get_mapstr_buf(m->in, str_in); + if ( ! strcmp(in, str_in) && m->mode == mode) { + return pos; + } + m = m->psig; + } + return -1; +} +// Append a mapping to the current session +void add_map(char * in, char * out, int mode, short recursive) { + map * m; + + // If the mapping already exists, replace its content, saving it position + int exists = exists_map(in, mode); + if (exists == -1) { + m = (map *) malloc (sizeof(map)); + } else { + m = maps; + while (exists--) m = m->psig; + erase_buf(m->in); + erase_buf(m->out); + exists = TRUE; + } + + m->out = (struct block *) get_mapbuf_str(out); + m->in = (struct block *) get_mapbuf_str(in); + m->mode = mode; + m->recursive = recursive; + + if (exists == TRUE) return; // in case a map was updated and not created! + +// Insert at the beginning +// m->psig = maps == NULL ? NULL : maps; +// maps = m; + + // Insert at the end + m->psig= NULL; + + if (maps == NULL) maps = m; + else + ((map *) get_last_map())->psig = m; + + len_maps++; + + return; +} + +// Remove a mapping from a specific MODE +void del_map(char * in, int mode) { + map * ant; + map * m = maps; + + if (m == NULL) return; + + // If the node is the fist one + char strin [MAXSC * get_bufsize(m->in)]; + get_mapstr_buf(m->in, strin); + if ( ! strcmp(in, strin) && mode == m->mode) { + maps = m->psig; + erase_buf(m->out); + erase_buf(m->in); + free(m); + len_maps--; + return; + } + + // If the node is in the middle or at the end + ant = m; + m = m->psig; + while (m != NULL) { + char strin [MAXSC * get_bufsize(m->in)]; + get_mapstr_buf(m->in, strin); + if ( ! strcmp(in, strin) && mode == m->mode) { + ant->psig = m->psig; + erase_buf(m->out); + erase_buf(m->in); + free(m); + m = ant->psig; + len_maps--; + return; + } + ant = m; + m = m->psig; + } + return; +} + +// Translate a block into a string +// special characters are in the <CR> form +void get_mapstr_buf (struct block * b, char * str) { + struct block * a = b; + int i, len = get_bufsize(a); + + str[0]='\0'; + for (i=0; i < len; i++) { + if (isprint(a->value)) { + 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) { + strcat(str, "<LEFT>"); // LEFT + } else if (a->value == OKEY_RIGHT) { + strcat(str, "<RIGHT>"); // RIGHT + } else if (a->value == OKEY_DOWN) { + strcat(str, "<DOWN>"); // DOWN + } else if (a->value == OKEY_UP) { + strcat(str, "<UP>"); // UP + } else if (a->value == OKEY_DEL) { + strcat(str, "<DEL>"); // DEL + } else if (a->value == OKEY_BS) { + strcat(str, "<BS>"); // BS + } else if (a->value == OKEY_HOME) { + strcat(str, "<HOME>"); // HOME + } else if (a->value == OKEY_END) { + strcat(str, "<END>"); // END + } else if (a->value == OKEY_PGDOWN) { + strcat(str, "<PGDOWN>"); // PGDOWN + } else if (a->value == OKEY_PGUP) { + strcat(str, "<PGUP>"); // PGUP + } + a = a->pnext; + } + return; +} + +// Save mapping's details in a char* +void get_mappings(char * salida) { + salida[0]='\0'; + if (maps == NULL) return; + char min[MAXMAPITEM] = ""; + char mout[MAXMAPITEM] = ""; + char nore[5] = ""; + + char mode = '\0'; + int i = 0; + map * m = maps; + + while (m != NULL) { + i++; + nore[0] = '\0'; + switch (m->mode) { + case NORMAL_MODE: + mode = 'n'; + break; + + case INSERT_MODE: + mode = 'i'; + break; + } + get_mapstr_buf(m->in, min); + get_mapstr_buf(m->out, mout); + if (!m->recursive) strcpy(nore, "nore"); + sprintf(salida + strlen(salida), "%3d + %c%smap \"%s\" = \"%s\"\n", i, mode, nore, min, mout); + m = m->psig; + } + + return; +} |