mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
shell line edit: cursor, pos1, end, del, F1..
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- function keys in editor: cursor, del, pos1, end. F1=help, F2=show, F10=report
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ void Shell::start() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
line_buffer_.reserve(maximum_command_line_length_);
|
line_buffer_.reserve(maximum_command_line_length_);
|
||||||
oldline_.reserve(maximum_command_line_length_);
|
line_old_.reserve(maximum_command_line_length_);
|
||||||
oldline_.clear();
|
line_old_.clear();
|
||||||
display_banner();
|
display_banner();
|
||||||
display_prompt();
|
display_prompt();
|
||||||
shells_.insert(shared_from_this());
|
shells_.insert(shared_from_this());
|
||||||
@@ -148,8 +148,7 @@ void Shell::loop_normal() {
|
|||||||
// Interrupt (^C)
|
// Interrupt (^C)
|
||||||
line_buffer_.clear();
|
line_buffer_.clear();
|
||||||
println();
|
println();
|
||||||
prompt_displayed_ = false;
|
cursor_ = 0;
|
||||||
display_prompt();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\x04':
|
case '\x04':
|
||||||
@@ -160,51 +159,38 @@ void Shell::loop_normal() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '\x08':
|
case '\x08':
|
||||||
case '\x7F':
|
|
||||||
// Backspace (^H)
|
// Backspace (^H)
|
||||||
// Delete (^?)
|
case '\x7F':
|
||||||
if (!line_buffer_.empty()) {
|
// Del/Backspace (^?)
|
||||||
erase_characters(1);
|
if (line_buffer_.length() > cursor_) {
|
||||||
line_buffer_.pop_back();
|
line_buffer_.erase(line_buffer_.length() - cursor_ - 1, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\x09':
|
case '\x09':
|
||||||
// Tab (^I)
|
// Tab (^I)
|
||||||
process_completion();
|
process_completion();
|
||||||
|
cursor_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\x0A':
|
case '\x0A':
|
||||||
// Line feed (^J)
|
// Line feed (^J)
|
||||||
if (previous_ != '\x0D') {
|
if (previous_ != '\x0D') {
|
||||||
if (!line_buffer_.empty()) {
|
|
||||||
oldline_ = line_buffer_;
|
|
||||||
}
|
|
||||||
process_command();
|
process_command();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\x0C':
|
|
||||||
// New page (^L)
|
|
||||||
erase_current_line();
|
|
||||||
prompt_displayed_ = false;
|
|
||||||
display_prompt();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\x0D':
|
case '\x0D':
|
||||||
if (!line_buffer_.empty()) {
|
|
||||||
oldline_ = line_buffer_;
|
|
||||||
}
|
|
||||||
// Carriage return (^M)
|
// Carriage return (^M)
|
||||||
process_command();
|
process_command();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '\x0C':
|
||||||
|
// New page (^L)
|
||||||
case '\x15':
|
case '\x15':
|
||||||
// Delete line (^U)
|
// Delete line (^U)
|
||||||
erase_current_line();
|
|
||||||
prompt_displayed_ = false;
|
|
||||||
line_buffer_.clear();
|
line_buffer_.clear();
|
||||||
display_prompt();
|
cursor_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\x17':
|
case '\x17':
|
||||||
@@ -212,51 +198,91 @@ void Shell::loop_normal() {
|
|||||||
delete_buffer_word(true);
|
delete_buffer_word(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case '\033':
|
||||||
|
// esc
|
||||||
|
esc_ = 0x80;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (c >= '\x20' && c <= '\x7E') {
|
if (esc_) {
|
||||||
|
if (c == '[') {
|
||||||
|
// start of sequence
|
||||||
|
} else if (c >= '0' && (c <= '9')) {
|
||||||
|
// numbers
|
||||||
|
esc_ = (esc_ & 0x7F) * 10 + c - '0';
|
||||||
|
} else if (c == 'A') {
|
||||||
|
// cursor up
|
||||||
|
line_buffer_ = line_old_;
|
||||||
|
cursor_ = 0;
|
||||||
|
esc_ = 0;
|
||||||
|
} else if (c == 'B') {
|
||||||
|
// cursor down
|
||||||
|
line_buffer_.clear();
|
||||||
|
cursor_ = 0;
|
||||||
|
esc_ = 0;
|
||||||
|
} else if (c == 'C') {
|
||||||
|
// cursor right
|
||||||
|
if (cursor_) {
|
||||||
|
cursor_--;
|
||||||
|
}
|
||||||
|
esc_ = 0;
|
||||||
|
} else if (c == 'D') {
|
||||||
|
// cursor left
|
||||||
|
if (cursor_ < line_buffer_.length()) {
|
||||||
|
cursor_++;
|
||||||
|
}
|
||||||
|
esc_ = 0;
|
||||||
|
} else if (c == '~') {
|
||||||
|
// function keys with number
|
||||||
|
if ((esc_ == 3) && cursor_) {
|
||||||
|
// del
|
||||||
|
cursor_--;
|
||||||
|
line_buffer_.erase(line_buffer_.length() - cursor_ - 1, 1);
|
||||||
|
} else if (esc_ == 4) {
|
||||||
|
// end
|
||||||
|
cursor_ = 0;
|
||||||
|
} else if (esc_ == 1) {
|
||||||
|
// pos1
|
||||||
|
cursor_ = line_buffer_.length();
|
||||||
|
} else if (esc_ == 11) {
|
||||||
|
// F1 and F10
|
||||||
|
line_buffer_ = "help";
|
||||||
|
process_command();
|
||||||
|
} else if (esc_ == 12) {
|
||||||
|
// F2
|
||||||
|
line_buffer_ = "show";
|
||||||
|
process_command();
|
||||||
|
} else if (esc_ == 20) {
|
||||||
|
// F9
|
||||||
|
line_buffer_ = "send telegram \"0B \"";
|
||||||
|
cursor_ = 1;
|
||||||
|
} else if (esc_ == 21) {
|
||||||
|
// F10
|
||||||
|
line_buffer_ = "call system report";
|
||||||
|
process_command();
|
||||||
|
}
|
||||||
|
esc_ = 0;
|
||||||
|
} else {
|
||||||
|
// all other chars end sequence
|
||||||
|
esc_ = 0;
|
||||||
|
}
|
||||||
|
} else if (c >= '\x20' && c <= '\x7E') {
|
||||||
// ASCII text
|
// ASCII text
|
||||||
if (line_buffer_.length() < maximum_command_line_length_) {
|
if (line_buffer_.length() < maximum_command_line_length_) {
|
||||||
line_buffer_.push_back(c);
|
line_buffer_.insert(line_buffer_.length() - cursor_, 1, c);
|
||||||
write((uint8_t)c);
|
|
||||||
}
|
|
||||||
// cursor up, get last command
|
|
||||||
if ((c == 'A') && (previous_ == '[')) {
|
|
||||||
erase_current_line();
|
|
||||||
prompt_displayed_ = false;
|
|
||||||
line_buffer_ = oldline_;
|
|
||||||
display_prompt();
|
|
||||||
}
|
|
||||||
// cursor back, delete cursor chars
|
|
||||||
if ((c == 'D') && (previous_ == '[')) {
|
|
||||||
line_buffer_.pop_back();
|
|
||||||
line_buffer_.pop_back();
|
|
||||||
// alternative work as backspace
|
|
||||||
// if (line_buffer_.length() > 0) {
|
|
||||||
// line_buffer_.pop_back();
|
|
||||||
// }
|
|
||||||
erase_current_line();
|
|
||||||
prompt_displayed_ = false;
|
|
||||||
display_prompt();
|
|
||||||
}
|
|
||||||
// cursor forward, only delete cursor chars
|
|
||||||
if ((c == 'C') && (previous_ == '[')) {
|
|
||||||
line_buffer_.pop_back();
|
|
||||||
line_buffer_.pop_back();
|
|
||||||
erase_current_line();
|
|
||||||
prompt_displayed_ = false;
|
|
||||||
display_prompt();
|
|
||||||
}
|
|
||||||
// cursor down(B): Delete line
|
|
||||||
if ((c == 'B') && (previous_ == '[')) {
|
|
||||||
erase_current_line();
|
|
||||||
prompt_displayed_ = false;
|
|
||||||
line_buffer_.clear();
|
|
||||||
display_prompt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// common for all, display the complete line
|
||||||
|
erase_current_line();
|
||||||
|
prompt_displayed_ = false;
|
||||||
|
display_prompt();
|
||||||
|
if (cursor_) {
|
||||||
|
printf(F("\033[%dD"), cursor_);
|
||||||
|
}
|
||||||
|
|
||||||
previous_ = c;
|
previous_ = c;
|
||||||
|
|
||||||
// This is a hack to let TelnetStream know that command
|
// This is a hack to let TelnetStream know that command
|
||||||
@@ -428,16 +454,24 @@ void Shell::delete_buffer_word(bool display) {
|
|||||||
|
|
||||||
if (pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
line_buffer_.clear();
|
line_buffer_.clear();
|
||||||
if (display) {
|
cursor_ = 0;
|
||||||
erase_current_line();
|
|
||||||
prompt_displayed_ = false;
|
|
||||||
display_prompt();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (display) {
|
if (display) {
|
||||||
erase_characters(line_buffer_.length() - pos);
|
size_t pos1 = 0;
|
||||||
|
pos = 0;
|
||||||
|
while (pos1 < line_buffer_.length() - cursor_) {
|
||||||
|
pos = pos1;
|
||||||
|
pos1 = line_buffer_.find(' ', pos + 1);
|
||||||
|
}
|
||||||
|
line_buffer_.erase(pos, pos1 - pos);
|
||||||
|
if (line_buffer_.find(' ') == 0) {
|
||||||
|
line_buffer_.erase(0, 1);
|
||||||
|
}
|
||||||
|
cursor_ = line_buffer_.length() - pos;
|
||||||
|
} else {
|
||||||
|
line_buffer_.resize(pos);
|
||||||
|
cursor_ = 0;
|
||||||
}
|
}
|
||||||
line_buffer_.resize(pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +487,6 @@ void Shell::maximum_command_line_length(size_t length) {
|
|||||||
void Shell::process_command() {
|
void Shell::process_command() {
|
||||||
CommandLine command_line{line_buffer_};
|
CommandLine command_line{line_buffer_};
|
||||||
|
|
||||||
line_buffer_.clear();
|
|
||||||
println();
|
println();
|
||||||
prompt_displayed_ = false;
|
prompt_displayed_ = false;
|
||||||
|
|
||||||
@@ -467,8 +500,12 @@ void Shell::process_command() {
|
|||||||
} else {
|
} else {
|
||||||
println(F("No commands configured"));
|
println(F("No commands configured"));
|
||||||
}
|
}
|
||||||
|
line_old_ = line_buffer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor_ = 0;
|
||||||
|
line_buffer_.clear();
|
||||||
|
|
||||||
if (running()) {
|
if (running()) {
|
||||||
display_prompt();
|
display_prompt();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -903,9 +903,11 @@ class Shell : public std::enable_shared_from_this<Shell>, public uuid::log::Hand
|
|||||||
std::list<QueuedLogMessage> log_messages_; /*!< Queued log messages, in the order they were received. @since 0.1.0 */
|
std::list<QueuedLogMessage> log_messages_; /*!< Queued log messages, in the order they were received. @since 0.1.0 */
|
||||||
size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum command line length in bytes. @since 0.6.0 */
|
size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum command line length in bytes. @since 0.6.0 */
|
||||||
std::string line_buffer_; /*!< Command line buffer. Limited to maximum_command_line_length() bytes. @since 0.1.0 */
|
std::string line_buffer_; /*!< Command line buffer. Limited to maximum_command_line_length() bytes. @since 0.1.0 */
|
||||||
|
std::string line_old_; /*!< old Command line buffer.*/
|
||||||
size_t maximum_command_line_length_ = MAX_COMMAND_LINE_LENGTH; /*!< Maximum command line length in bytes. @since 0.6.0 */
|
size_t maximum_command_line_length_ = MAX_COMMAND_LINE_LENGTH; /*!< Maximum command line length in bytes. @since 0.6.0 */
|
||||||
unsigned char previous_ = 0; /*!< Previous character that was entered on the command line. Used to detect CRLF line endings. @since 0.1.0 */
|
unsigned char previous_ = 0; /*!< Previous character that was entered on the command line. Used to detect CRLF line endings. @since 0.1.0 */
|
||||||
std::string oldline_; /*!< old Command line buffer.*/
|
uint8_t cursor_ = 0; /*!< cursor position from end of line */
|
||||||
|
uint8_t esc_ = 0; /*!< esc sequence running */
|
||||||
Mode mode_ = Mode::NORMAL; /*!< Current execution mode. @since 0.1.0 */
|
Mode mode_ = Mode::NORMAL; /*!< Current execution mode. @since 0.1.0 */
|
||||||
std::unique_ptr<ModeData> mode_data_ = nullptr; /*!< Data associated with the current execution mode. @since 0.1.0 */
|
std::unique_ptr<ModeData> mode_data_ = nullptr; /*!< Data associated with the current execution mode. @since 0.1.0 */
|
||||||
bool stopped_ = false; /*!< Indicates that the shell has been stopped. @since 0.1.0 */
|
bool stopped_ = false; /*!< Indicates that the shell has been stopped. @since 0.1.0 */
|
||||||
|
|||||||
Reference in New Issue
Block a user