-
Notifications
You must be signed in to change notification settings - Fork 25
Added command history feature #18 #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This commit adds a command history feature. It works similarly to other command shells, where the up and down arrow keys cycle through recently used commands. The user can make changes to a previous command's text before running it again. If the user has already entered part of a command and then scrolls through the history, the partial command is saved at the beginning of the history list.we This feature requires a significant amount of memory to be used for storing the command history list. As a rule of thumb, command history should only be enabled on systems with at least 8k of RAM (Arduino MEGA and better). It can be enabled on smaller systems, but only when (CONFIG_SHELL_MAX_INPUT * (CONFIG_SHELL_COMMAND_HISTORY + 1)) + 4 bytes of RAM are available. For a history list that is 10 commands long and the default input buffer length 0f 70, this would be 774 bytes. This much memory usage only makes sense on some systems, so this feature is disabled by default. To enable it, set the CONFIG_SHELL_COMMAND_HISTORY macro in Shell.h to the desired command history list length. The max history length is 255 entries. To implement this feature, the following changes were made: --A number of global variables were added (4 bytes), and count was moved from a static in shell_task to be a global as well --shellbuf is expanded into a two dimensional array, the first dimension is the list of historic commands, and the second dimension is the index within that command buffer. The command history list is implemented as a ring buffer. --Added shell_clear_command(), a public function to clear the current command buffer and displayed text in the shell --Basic processing of VT100 escape sequences, including Command Sequence Indroducer sequences, for receiving arrow keys. This may also lead to implementing the left and right arrow keys as a future project, allowing the user to move a cursor left and right when typing a command. The biggest hurdle to this right now is that editing the middle or beginning of a long command will lead to lots of inserting in the middle of a command buffer, which will be slow. --In addition to using count to track the length of an entered command, command text (including arguments) are now terminated by a NULL char --When command history is enabled, command text (including arguments) are now copied to a new buffer for parsing. This prevents the NULL string terminators between each argument from being added to the command history entry.
Adds Dont Linemode and Will Echo Telnet options to the Telnet example. These are needed for cleanly sending arrow keys. NOTE: Putty doesn't respect Dont Linemode, and requires that Terminal->Local Line Editing be forced off. Also fixed a typo in Shell.h
A note on using command history with Telnet... The default behavior in the Telnet clients I tested with (BSD telnet included with Centos, PuTTY, and screen) is to not send arrow key control sequences until the enter key is pressed. This is due to Telnet's LINEMODE option being the default, where the client waits for an entire line to be input, and the enter key pressed, before sending data to the server. A server can request that this mode be turned off (called Character-at-a-time mode, where characters are sent as soon as they are pressed), but only the BSD telnet client seems to respect this option. PuTTY allows the user to set this option explicitly (Terminal->Local Line Editing->Force Off), and the setting can be saved as part of a connection profile. Screen doesn't seem to have this option (at least I couldn't find it). I've updated the PR to include a new version of the Shell_Telnet example which sets the Telnet option "Dont Linemode". I also saw some issues with some clients double-echoing characters, so I added the "Will Echo" Telnet option to indicate to the client that the server will handle echoing typed characters. |
I did some additional research and troubleshooting and learned that the reason some clients didn't like the Telnet modes I was setting was because the Telnet standards have evolved after the references I was working with. The current correct way to set up character at a time mode is to explicitly set up character echoing on the remote side, as well as having the server suppress the Telnet Go Ahead function. The correct way of doing this is demonstrated in the version of the Shell_Telnet example I've uploaded (it's also a bit cleaner, using macros instead of raw hex). With this way of doing things, this works with BSD telnet, PuTTY, and screen with the default settings. Note: for Backspace to work correctly with the default settings, #9 is also required. Without this PR, you must set up your telnet client to send the proper control sequence or press Ctrl-H to delete characters. |
This commit adds a command history feature #18. It works similarly to other command shells, where the up and down arrow keys cycle through recently used commands. The user can make changes to a previous command's text before running it again. If the user has already entered part of a command and then scrolls through the history, the partial command is saved at the beginning of the history list.we This feature requires a significant amount of memory to be used for storing the command history list. As a rule of thumb, command history should only be enabled on systems with at least 8k of RAM (Arduino MEGA and better). It can be enabled on smaller systems, but only when (CONFIG_SHELL_MAX_INPUT * (CONFIG_SHELL_COMMAND_HISTORY + 1)) + 4 bytes of RAM are available. For a history list that is 10 commands long and the default input buffer length of 70, this would be 774 bytes. This much memory usage only makes sense on some systems, so this feature is disabled by default. To enable it, set the CONFIG_SHELL_COMMAND_HISTORY macro in Shell.h to the desired command history list length. The max history length is 255 entries.
To implement this feature, the following changes were made:
--A number of global variables were added (4 bytes), and count was moved from a static in shell_task to be a global as well
--shellbuf is expanded into a two dimensional array, the first dimension is the list of historic commands, and the second dimension is the index within that command buffer. The command history list is implemented as a ring buffer.
--Added shell_clear_command(), a public function to clear the current command buffer and displayed text in the shell
--Basic processing of VT100 escape sequences, including Command Sequence Indroducer sequences, for receiving arrow keys. This may also lead to implementing the left and right arrow keys as a future project, allowing the user to move a cursor left and right when typing a command. The biggest hurdle to this right now is that editing the middle or beginning of a long command will lead to lots of inserting in the middle of a command buffer, which will be slow.
--In addition to using count to track the length of an entered command, command text (including arguments) are now terminated by a NULL char
--When command history is enabled, command text (including arguments) are now copied to a new buffer for parsing. This prevents the NULL string terminators between each argument from being added to the command history entry.