123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /*
- * Copyright (c) 2019 - 2021 Stefan Strobel <stefan.strobel@shimatta.net>
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */
- /**
- * @file shellmatta_escape.c
- * @brief functions to parse and generate escape sequences
- * @author Stefan Strobel <stefan.strobel@shimatta.net>
- */
- /**
- * @addtogroup shellmatta_escape
- * @{
- */
- #include "shellmatta.h"
- #include "shellmatta_escape.h"
- #include "shellmatta_utils.h"
- #include "shellmatta_history.h"
- #include "shellmatta_autocomplete.h"
- #include <stdint.h>
- /**
- * @brief processes the excape character stream of the instance and checks
- * if an arrow key was pressed
- * @param[in] inst pointer to a shellmatta instance
- * @return #SHELLMATTA_OK if an arrow key was pressed
- */
- shellmatta_retCode_t escape_processArrowKeys(shellmatta_instance_t *inst)
- {
- shellmatta_retCode_t ret = SHELLMATTA_USE_FAULT;
- if ('[' == inst->escapeChars[0])
- {
- ret = SHELLMATTA_OK;
- switch (inst->escapeChars[1])
- {
- case 'A': /* arrow up */
- history_storeCmd(inst);
- if(false == inst->historyReadUp)
- {
- (void)history_navigate(inst, -1);
- }
- inst->historyReadUp = true;
- history_restoreCmd(inst);
- (void)history_navigate(inst, -1);
- break;
- case 'B': /* arrow down */
- /*! -# ignore the key if the history buffer points to the last entry */
- if((inst->historyRead != inst->historyEnd))
- {
- history_storeCmd(inst);
- if(true == inst->historyReadUp)
- {
- (void)history_navigate(inst, 1);
- }
- inst->historyReadUp = false;
- (void)history_navigate(inst, 1);
- history_restoreCmd(inst);
- }
- break;
- case 'C': /* arrow right */
- utils_forwardCursor(inst, 1u);
- break;
- case 'D': /* arrow left */
- utils_rewindCursor(inst, 1u);
- break;
- default:
- /** ignore unknown escape */
- ret = SHELLMATTA_USE_FAULT;
- break;
- }
- }
- return ret;
- }
- /**
- * @brief handles a ANSI escape sequence to be able to react to some
- * special keys
- * @param[in] inst pointer to a shellmatta instance
- * @param[in] data new received character of the escape sequence
- */
- void escape_handleSequence(shellmatta_instance_t *inst, char data)
- {
- switch (inst->escapeCounter)
- {
- case 1u:
- inst->escapeChars[inst->escapeCounter - 1] = data;
- inst->escapeCounter ++;
- break;
- case 2u:
- inst->escapeChars[inst->escapeCounter - 1] = data;
- /** -# check if an arrow key was pressed */
- if(SHELLMATTA_OK == escape_processArrowKeys(inst))
- {
- inst->escapeCounter = 0u;
- }
- /** -# check if end was pressed */
- else if ( (0x4f == inst->escapeChars[0])
- && (0x46 == inst->escapeChars[1]))
- {
- utils_forwardCursor(inst, inst->inputCount - inst->cursor);
- inst->escapeCounter = 0u;
- }
- /** -# if the highest bit is not set this is usually not the end of the
- * sequence - so we go on */
- else if(0u == (0x40 & data))
- {
- inst->escapeCounter ++;
- }
- else
- {
- inst->escapeCounter = 0u;
- }
- break;
- case 3u:
- /** -# check if delete was pressed */
- inst->escapeChars[inst->escapeCounter - 1] = data;
- if( (0x5b == inst->escapeChars[0])
- && (0x33 == inst->escapeChars[1])
- && (0x7e == inst->escapeChars[2]))
- {
- utils_removeChars(inst, 1u, false);
- inst->escapeCounter = 0u;
- }
- /** -# check if pos1 was pressed */
- else if ( (0x5bu == inst->escapeChars[0])
- && (0x31u == inst->escapeChars[1])
- && (0x7eu == inst->escapeChars[2]))
- {
- utils_rewindCursor(inst, inst->cursor);
- inst->escapeCounter = 0u;
- }
- else if(0u == (0x40u & data))
- {
- inst->escapeCounter ++;
- }
- else
- {
- inst->escapeCounter = 0u;
- }
- break;
- default:
- inst->escapeCounter = 0u;
- break;
- }
- }
- /**
- * @}
- */
|