allowing keys to be mapped to colon commands
This commit is contained in:
parent
5063b0108c
commit
1d511c000d
4
main.c
4
main.c
|
@ -570,6 +570,8 @@ inputbox_activate_cb(GtkEntry *entry, gpointer user_data) {
|
|||
text = (char*)gtk_entry_get_text(entry);
|
||||
if (text[0] == ':') {
|
||||
for (i = 0; i < LENGTH(commands); i++) {
|
||||
if (commands[i].cmd == NULL)
|
||||
break;
|
||||
len = strlen(commands[i].cmd);
|
||||
if (length >= len && !strncmp(&text[1], commands[i].cmd, len) && (text[len + 1] == ' ' || !text[len + 1])) {
|
||||
found = TRUE;
|
||||
|
@ -798,6 +800,8 @@ complete(const Arg *arg) {
|
|||
/* command completion */
|
||||
listlen = LENGTH(commands);
|
||||
for (i = 0; i < listlen; i++) {
|
||||
if (commands[i].cmd == NULL)
|
||||
break;
|
||||
cmdlen = strlen(commands[i].cmd);
|
||||
if (!highlight || (n < MAX_LIST_SIZE && len - 1 <= cmdlen && !strncmp(&str[1], commands[i].cmd, len - 1))) {
|
||||
p = s = malloc(sizeof(char*) * (highlight ? sizeof(COMPLETION_TAG_OPEN) + sizeof(COMPLETION_TAG_CLOSE) - 1 : 1) + cmdlen);
|
||||
|
|
82
utilities.c
82
utilities.c
|
@ -214,8 +214,24 @@ parse_colour(char *color) {
|
|||
}
|
||||
|
||||
gboolean
|
||||
changemapping(Key * search_key, int maprecord) {
|
||||
process_line_arg(const Arg *arg) {
|
||||
return process_line(arg->s);
|
||||
}
|
||||
|
||||
gboolean
|
||||
changemapping(Key *search_key, int maprecord, char *cmd) {
|
||||
KeyList *current, *newkey;
|
||||
Arg a = { .s = cmd };
|
||||
|
||||
/* sanity check */
|
||||
if (maprecord < 0 && cmd == NULL) {
|
||||
/* possible states:
|
||||
* - maprecord >= 0 && cmd == NULL: mapping to internal symbol
|
||||
* - maprecord < 0 && cmd != NULL: mapping to command line
|
||||
* - maprecord >= 0 && cmd != NULL: cmd will be ignored, treated as mapping to internal symbol
|
||||
* - anything else (gets in here): an error, hence we return FALSE */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
current = keylistroot;
|
||||
|
||||
|
@ -226,8 +242,15 @@ changemapping(Key * search_key, int maprecord) {
|
|||
current->Element.modkey == search_key->modkey &&
|
||||
current->Element.key == search_key->key
|
||||
) {
|
||||
current->Element.func = commands[maprecord].func;
|
||||
current->Element.arg = commands[maprecord].arg;
|
||||
if (maprecord >= 0) {
|
||||
/* mapping to an internal signal */
|
||||
current->Element.func = commands[maprecord].func;
|
||||
current->Element.arg = commands[maprecord].arg;
|
||||
} else {
|
||||
/* mapping to a command line */
|
||||
current->Element.func = process_line_arg;
|
||||
current->Element.arg = a;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
current = current->next;
|
||||
|
@ -240,8 +263,15 @@ changemapping(Key * search_key, int maprecord) {
|
|||
newkey->Element.mask = search_key->mask;
|
||||
newkey->Element.modkey = search_key->modkey;
|
||||
newkey->Element.key = search_key->key;
|
||||
newkey->Element.func = commands[maprecord].func;
|
||||
newkey->Element.arg = commands[maprecord].arg;
|
||||
if (maprecord >= 0) {
|
||||
/* mapping to an internal signal */
|
||||
newkey->Element.func = commands[maprecord].func;
|
||||
newkey->Element.arg = commands[maprecord].arg;
|
||||
} else {
|
||||
/* mapping to a command line */
|
||||
newkey->Element.func = process_line_arg;
|
||||
newkey->Element.arg = a;
|
||||
}
|
||||
newkey->next = NULL;
|
||||
|
||||
if (keylistroot == NULL) keylistroot = newkey;
|
||||
|
@ -255,7 +285,7 @@ gboolean
|
|||
mappings(const Arg *arg) {
|
||||
char line[255];
|
||||
|
||||
if ( !arg->s ) {
|
||||
if (!arg->s) {
|
||||
set_error("Missing argument.");
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -269,7 +299,7 @@ mappings(const Arg *arg) {
|
|||
}
|
||||
|
||||
gboolean
|
||||
process_mapping(char * keystring, int maprecord) {
|
||||
process_mapping(char *keystring, int maprecord, char *cmd) {
|
||||
Key search_key;
|
||||
|
||||
search_key.mask = 0;
|
||||
|
@ -331,31 +361,51 @@ process_mapping(char * keystring, int maprecord) {
|
|||
search_key.modkey= keystring[0];
|
||||
search_key.key = keystring[4];
|
||||
}
|
||||
return (changemapping(&search_key, maprecord));
|
||||
return (changemapping(&search_key, maprecord, cmd));
|
||||
}
|
||||
|
||||
gboolean
|
||||
process_map_line(char *line) {
|
||||
int listlen, i;
|
||||
char *c;
|
||||
char *c, *cmd;
|
||||
my_pair.line = line;
|
||||
c = search_word (0);
|
||||
c = search_word(0);
|
||||
|
||||
if (!strlen (my_pair.what))
|
||||
if (!strlen(my_pair.what))
|
||||
return FALSE;
|
||||
while (isspace (*c) && *c)
|
||||
while (isspace(*c) && *c)
|
||||
c++;
|
||||
|
||||
if (*c == ':' || *c == '=')
|
||||
c++;
|
||||
my_pair.line = c;
|
||||
c = search_word (1);
|
||||
if (!strlen (my_pair.value))
|
||||
c = search_word(1);
|
||||
if (!strlen(my_pair.value))
|
||||
return FALSE;
|
||||
listlen = LENGTH(commands);
|
||||
for (i = 0; i < listlen; i++) {
|
||||
if (strlen(commands[i].cmd) == strlen(my_pair.value) && strncmp(commands[i].cmd, my_pair.value, strlen(my_pair.value)) == 0)
|
||||
return process_mapping(my_pair.what, i);
|
||||
/* commands is fixed size */
|
||||
if (commands[i].cmd == NULL)
|
||||
break;
|
||||
if (strlen(commands[i].cmd) == strlen(my_pair.value) && strncmp(commands[i].cmd, my_pair.value, strlen(my_pair.value)) == 0) {
|
||||
/* map to an internal symbol */
|
||||
return process_mapping(my_pair.what, i, NULL);
|
||||
}
|
||||
}
|
||||
/* if this is reached, the mapping is not for one of the internal symbol - test for command line structure */
|
||||
if (strlen(my_pair.value) > 1 && strncmp(my_pair.value, ":", 1) == 0) {
|
||||
/* The string begins with a colon, like a command line, but it's not _just_ a colon,
|
||||
* i.e. increasing the pointer by one will not go 'out of bounds'.
|
||||
* We don't actually check that the command line after the = is valid.
|
||||
* This is user responsibility, the worst case is the new mapping simply doing nothing.
|
||||
* Since we will pass the command to the same function which also handles the config file lines,
|
||||
* we have to strip the colon itself (a colon counts as a commented line there - like in vim).
|
||||
* Last, but not least, the second argument being < 0 signifies to the function that this is a
|
||||
* command line mapping, not a mapping to an existing internal symbol. */
|
||||
cmd = (char *)malloc(sizeof(char) * strlen(my_pair.value));
|
||||
strncpy(cmd, (my_pair.value + 1), strlen(my_pair.value) - 1);
|
||||
cmd[strlen(cmd)] = '\0';
|
||||
return process_mapping(my_pair.what, -1, cmd);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,10 @@ gboolean process_save_qmark(const char *bm, WebKitWebView *webview);
|
|||
void make_keyslist(void);
|
||||
gboolean parse_colour(char *color);
|
||||
gboolean mappings(const Arg *arg);
|
||||
gboolean process_mapping(char * keystring, int maprecord);
|
||||
gboolean process_mapping(char *keystring, int maprecord, char *cmd);
|
||||
gboolean process_map_line(char *line);
|
||||
gboolean changemapping(Key * search_key, int maprecord);
|
||||
gboolean changemapping(Key *search_key, int maprecord, char *cmd);
|
||||
gboolean process_line_arg(const Arg *arg);
|
||||
gboolean build_taglist(const Arg *arg, FILE *f);
|
||||
void set_error(const char *error);
|
||||
void give_feedback(const char *feedback);
|
||||
|
|
Loading…
Reference in New Issue