/* Processes remapping of a key. Returns error code. */ static int execute_after_remapping(const wchar_t rhs[], const wchar_t left_keys[], keys_info_t keys_info, key_info_t key_info, key_chunk_t *curr) { int result; if(rhs[0] == L'\0' && left_keys[0] == L'\0') { /* Nop command executed correctly. */ result = 0; } else if(rhs[0] == L'\0') { keys_info_t keys_info; init_keys_info(&keys_info, 1); enter_chunk(curr); result = dispatch_keys(left_keys, &keys_info, curr->no_remap, NO_COUNT_GIVEN); leave_chunk(curr); } else { wchar_t buf[16 + wcslen(rhs) + 1 + wcslen(left_keys) + 1]; buf[0] = '\0'; if(key_info.reg != NO_REG_GIVEN) { vifm_swprintf(buf, ARRAY_LEN(buf), L"\"%c", key_info.reg); } if(key_info.count != NO_COUNT_GIVEN) { vifm_swprintf(buf + wcslen(buf), ARRAY_LEN(buf) - wcslen(buf), L"%d", key_info.count); } wcscat(buf, rhs); wcscat(buf, left_keys); if(curr->conf.followed != FOLLOWED_BY_SELECTOR) { init_keys_info(&keys_info, 1); } enter_chunk(curr); result = dispatch_keys(buf, &keys_info, curr->no_remap, NO_COUNT_GIVEN); leave_chunk(curr); } return result; }
/* Performs action associated with the key (in curr), if any. Returns error * code. */ static int dispatch_key(key_info_t key_info, keys_info_t *keys_info, key_chunk_t *curr, const wchar_t keys[]) { const key_conf_t *const conf = &curr->conf; if(conf->type != USER_CMD && conf->type != BUILTIN_CMD) { const int result = execute_mapping_handler(conf, key_info, keys_info); const int finish_dispatching = result != 0 || *keys == L'\0' || conf->followed != FOLLOWED_BY_MULTIKEY; if(finish_dispatching) { return result; } /* Process the rest of the input after a command followed by multikey. */ return execute_keys_general_wrapper(keys, keys_info->after_wait, 0, curr->no_remap); } else { int result = has_def_handler() ? 0 : KEYS_UNKNOWN; if(curr->enters == 0) { result = execute_after_remapping(conf->data.cmd, keys, *keys_info, key_info, curr); } else if(has_def_handler()) { result = def_handler()(curr->key); if(result == 0) { result = execute_keys_general(keys, keys_info->after_wait, 0, curr->no_remap); } } if(result == KEYS_UNKNOWN && has_def_handler()) { /* curr shouldn't be freed here as if it was result would be 0. */ if(curr->enters == 0) { result = def_handler()(conf->data.cmd[0]); enter_chunk(curr); execute_keys_general(conf->data.cmd + 1, 0, 1, curr->no_remap); leave_chunk(curr); } else { int i; for(i = 0; conf->data.cmd[i] != '\0'; i++) { result = def_handler()(conf->data.cmd[i]); } } } return result; } }
/* Performs action associated with the key (in curr), if any. Returns error * code. */ static int dispatch_key(key_info_t key_info, keys_info_t *keys_info, key_chunk_t *curr, const wchar_t keys[]) { const key_conf_t *const conf = &curr->conf; if(curr->type != USER_CMD) { const int result = execute_mapping_handler(conf, key_info, keys_info); const int finish_dispatching = result != 0 || *keys == L'\0' || conf->followed != FOLLOWED_BY_MULTIKEY; if(finish_dispatching) { return result; } /* Process the rest of the input after a command followed by multikey. */ return execute_keys_general_wrapper(keys, keys_info->after_wait, 0, curr->no_remap); } else { if(curr->silent) { silence_ui(1); } int result = has_def_handler() ? 0 : KEYS_UNKNOWN; /* Protect chunk from deletion while it's in use. */ enter_chunk(curr); if(curr->enters == 1) { result = execute_after_remapping(conf->data.cmd, keys, *keys_info, key_info, curr); } else if(has_def_handler()) { result = def_handler()(curr->key); if(result == 0) { result = execute_keys_general(keys, keys_info->after_wait, 0, curr->no_remap); } } if(result == KEYS_UNKNOWN && has_def_handler()) { if(curr->enters == 1) { result = def_handler()(conf->data.cmd[0]); enter_chunk(curr); execute_keys_general(conf->data.cmd + 1, 0, 1, curr->no_remap); leave_chunk(curr); } else { int i; for(i = 0; conf->data.cmd[i] != '\0'; i++) { result = def_handler()(conf->data.cmd[i]); } } } if(curr->silent) { silence_ui(0); } /* Release the chunk, this will free it if deletion was attempted. */ leave_chunk(curr); return result; } }