summaryrefslogtreecommitdiffstats
path: root/src/buffer.rs
Commit message (Collapse)AuthorAgeFilesLines
* Update left + right arrow keys, backspace with width fixRory Dudley2024-12-161-51/+62
| | | | | | | | | | | This patch updates the codepaths of the arrow keys and backspace keys to calculate the width correctly when moving around in the buffer. See commit ac5152886fed ("Workaround for faulty unicode_width values") for more details, or you can also read the large comment at the top of the new width! macro (which was added to reduce some redundant code, since we need to properly compute character width in 4 different places). Signed-off-by: Rory Dudley <rory@netc.lu>
* Workaround for faulty unicode_width valuesRory Dudley2024-12-161-7/+42
| | | | | | | | | | After a bit of analysis work, I believe the unicode_width library is returning incorrect widths for certain characters (i.e. returning a width of 0, when the width should be 1). This patch adds a workaround for that in the comp() function, alongside a long comment documentating the issue with more resources and tools. Signed-off-by: Rory Dudley <rory@netc.lu>
* More buffer bug fixesRory Dudley2024-12-131-3/+13
| | | | | | | | | | | | | | | | | | | Always append a newline to the end of the buffer. This ensures that the shell will not quit if the user simply presses the return key without any other input. Fix a disrepency between the buffer length, and text width in the comp function. The length of the buffer is the number of indices, whereas the width of the buffer is the summed width of each character within the buffer. We need the length when operating on the buffer's indicies, but the width when dealing with what actually gets outputted to the shell. In this case, the the width was being used where the length (bpos) should've been, and was causing an index out of bounds error for any strings that contained a character wider than 1. This rectifies the issue, as well as refactors some code that was (appropriately) using the width. Signed-off-by: Rory Dudley <rory@netc.lu>
* Rewrite of the buffer code + proper UTF-8 supportRory Dudley2024-12-121-293/+475
| | | | | | | | | | | | | | | | | | This patch rewrites much of the code in src/buffer.rs to (utlimately), be less buggy. It also changed getchar() to have proper support for UTF-8 characters. The autocomplete function was also enhanced to support completions with filenames that have spaces in their paths. It handles these by placing a backslash ('\') before each space in the filename. There is not yet any completion support with quote ('), nor double-quote characters ("). The buffer is still navigable with arrow keys, so arbitrary deletions and insertions are still possible. Deletions and insertions with multi-width UTF-8 characters work as expected. Signed-off-by: Rory Dudley <rory@netc.lu> Notes: The complection function only works if the cursor is at the end of the buffer. Pressing tab anywhere else will result in functionally a no op.
* Fix Tab/Shift+Tab autocomplete behaviorRory Dudley2024-09-301-32/+57
| | | | | | | | | | | | | | | | | | | | | | | Previously, switching between Tab and Shift+Tab while cycling through autocomplete options could temporarily mess up the order of items. This patch fixes that flaw by adding two new variables to help keep track of the state: - 'last', the last key that was recorded by getchar(), - and 'length', which keeps track of the length of the last buffer generated by the autocomplete() function. These variables are then checked first whenever the user uses Tab or Shift+Tab. The last know buffer 'length' is used to deal with overflow in the case of Shift+Tab. Finally, the logic for processing the autocomplete directory was moved below the code for handling the actual user input (i.e. appending to the getline() buffer). This is because the last character in the buffer (i.e. the last character the user typed) is important for properly updating the autcomplete working directory. Signed-off-by: Rory Dudley <rory@netc.lu>
* Add backslashes to words with spaces in autocomplete()Rory Dudley2024-09-301-1/+11
| | | | | | | | This patch makes it so that the autcomplete() function automatically inserts the backslash character (`\`) into words with spaces when cylcing through the options. Signed-off-by: Rory Dudley <rory@netc.lu>
* Don't panic if autcomplete() failsRory Dudley2024-09-301-45/+4
| | | | | | | If, for whatever reason, the autocomplete() functions fails, don't panic and quit. Instead, return an empty string. Signed-off-by: Rory Dudley <rory@netc.lu>
* Expand filepath autocompleteRory Dudley2024-09-301-15/+134
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch expands upon the last one, by providing a filepath autcomplete routine, which works more similarly to that of zsh or bash. It works for: - Any paths containing the current directory (`.`) - Any paths containing the parent directory (`..`) - Any paths containing the root directory (`/`) - Any paths that don't contain any explicit directory (defaults to the current directory, i.e. `.`) In order to achieve this, the pwd (present working directory) was broken out from the autocomplete() function, and is now recomputed every time a character is typed (in the getline() function). pwd always starts off as the current directory, but may change based off of user input. If the current directory cannot be read (likely due to a permissions issue), dwvsh defaults to the user's home directory for now. The filepath autocomplete also works for paths with mutliple directories now (i.e. /etc/mail/xxx), will still allow you to autocomplete files and directories beginning with 'xxx' inside the '/etc/mail' directory. It is also possible to use the tilda character (`~`) with the filepath autocomplete now (it denotes the user's home directory, for instance, autocomplete works for '~/.config/'). Finally, some logic for Shift+Tab was added to autocomplete. It works the same as Tab, except runs backwards through the files and directories (as opposed to forwards). Signed-off-by: Rory Dudley <rory@netc.lu>
* Add autocompleteRory Dudley2024-09-301-16/+161
| | | | | | | | | This patch adds a fairly rudimentary form of autocomplete. For starters, it only works for filepaths, not for programs. Additionally, it currently only works for the present working directory. You cannot yet autocomplete even one more level deep. Signed-off-by: Rory Dudley <rory@netc.lu>
* Slight refactor of getchar() and more handling for getline()Rory Dudley2024-09-301-30/+118
| | | | | | | | | | | | | | | | | | The getchar() function was changed so that it is able to detect some ANSI escape sequences. To better handle this, getchar() now returns a value from the Key enum, indicating whether or not an escape sequence was found. Currently, the only escape sequences the function deals with are arrow keys. Handling of the left and right arrow keys were added to the getline() function, in order to allow a user to go back and edit their command inplace. Up and down arrow keys are also handled, but they are just ignored for now (i.e. they do not move the cursor around anymore). The local 'pos' variable became an Arc<Mutex<usize>>, since it needs to be reset to 0 if ctrl-c is pressed (the handler for which is outside the scope of getline()). Signed-off-by: Rory Dudley <rory@netc.lu>
* Keep track of position in getline()Rory Dudley2024-09-301-0/+10
| | | | | | | Keep track of the cursor position in getline(), this way it is not possible to backspace the prompt. Signed-off-by: Rory Dudley <rory@netc.lu>
* Replace io::stdin().read_line() with custom functionRory Dudley2024-09-301-0/+59
Added the termios crate to facilitate the changing of certain terminal options. It is a wrapper around the termios C library, so 'man 3 termios' for more details. Added the custom getchar() function, with retrieves characters from STDIN as they are typed by the user (as opposed to waiting for a newline, like io::stdin().read_line()). This is necessary, since keys like <tab> and <up> have special functionality, which needs to be acted on before command submission. Added the custom getline() function, which uses getchar() to read characters as they are typed. The getline() function contains the logic for the various key presses. For most characters, we simply push the byte to a buffer, and print it out to the screen (since getline() assumes ECHO is off). Signed-off-by: Rory Dudley <rory@netc.lu>