Skip to content
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

Feat command mode #58

Merged
merged 33 commits into from
May 22, 2019
Merged

Feat command mode #58

merged 33 commits into from
May 22, 2019

Conversation

NickHackman
Copy link
Contributor

@NickHackman NickHackman commented May 18, 2019

Features

  • infobar displays command mode input, and errors

Command Mode Features

 * h/help
 * q/quit
 * sort
 * ng/newglob, handles `~` and `$HOME` properly and directories are assumed to be `/dir/*`
 * df/destfolder
 * r/reverse
 * m/max

Known bugs:

  • In command mode: cannot type : due to the event buffer not being cleared this character is ignored, because it will commonly be added on first loop of get_command in /src/program/command_mode.rs

  • When program starts in a directory that has no images, Command mode isn't properly displayed on the infobar

Future Fixes

  • Decouple the rendering so that I and @gurgalex can update the infobar without having to pass the info to display to render_screen, allow updating of smaller components like the infobar before calling render or some other solution.

  • Force rendering, workaround solution being used for cases like newglob which should re-render when the current viewed image isn't in the new glob.

@gurgalex Here's how I'm handling it, few bugs I wanted to iron out before setting up the pull request

* Colon now enters command mode
* Added a modal approach kept track of in Program struct
    Current modes: normal, command, exit
* Changed previous fn run -> fn run_normal_mode
* Add basis for future command mode commands
* Modified infobar so that it takes a &str called msg in the case of
    command mode displays what the user is currently typing
* Add :help to print the help message and return to normal mode
* Add :quit to terminate the program from command mode
Command mode is any mode that requires user input

 * Moved command_mode related functions into its own file
 * Command Mode Features:
    * newglob (takes only one paramter). Properly handles ~/$HOME when
	provided by user. When the current path exists in the current vec of images
	and in the future one, remain at its index

    * sort (optionally one paramter). if called alone just performs the
	selected sort on the images, if provided with a second argument (a
	SortOrder) switch to that then sort. User is moved to new index
	of current image prior to sort

    * reverse, reverses the current set of images, keeping the index of
	the current image

    * destfolder, sets the destination folder

    * help, exits command mode and displays help info in normal mode

    * quit, terminates program

 * info bar displays user input, and that the user is in command mode
 * window event handling while in command mode
 * Moved the event match and Mode to ui.rs
 * Fixed bug, where input for :max could be 0 and it would be
    interpreted as 0 instead of infinitely many
@NickHackman NickHackman changed the title Feat command mode, redefine glob Feat command mode May 18, 2019
Increased performance, inside command_mode function get_command by not
rendering user input ever event, but only when it changes
@NickHackman
Copy link
Contributor Author

NickHackman commented May 19, 2019

@Davejkane, @gurgalex potential future issues based off of work done in command mode and discussed in #57

Future Feature Issues

  • Infobar is easier to update/decoupled from the rest of rendering or refractored in a way where smaller components of rendering can be updated or rendered without rerendering everything
  • Good First Issue Info bar accepts the input of error messages, changes the current image index field to a red color and displays "Error" and then the error message in the current image path field. Update errors to now, if possible, be sent to the infobar removing "Error:" when necessary from the message
  • Good First Issue Add the add command to command mode, which should follow the format :add glob file directory or :a glob file directory and append images to self.paths.images
  • Add autocomplete for command mode for files, commands, etc
  • Force rendering of application as mentioned above
  • Good First Issue Keep a history of command mode commands entered by user

Any other ideas? I feel like these are good first issues that require some work, but not like a crazy amount where they need to understand how the app functions as a whole.

edit: moved from a sub comment into main discussion.

* Enum that lists out the possible commands and implements FromStr for
each
@gurgalex
Copy link
Collaborator

gurgalex commented May 19, 2019

Good First Issue Add the delete command to command mode, which should follow the format :delete /path/to/image regex or :d /path/to/image otherwise delete current image from self.paths.images. Don't actually delete the file

Maybe untrack?. I'd like to reserve the word delete or remove for actually deleting an mage from storage.
Yes, the fn name currently is called remove_image, so possibly need to rename that sometime.

* Newglob wouldn't properly accept files like /home/etc/test\ file\ name
* Add dependency regex to be able to fix Newglob bug
* Add dependency shellexpand to properly handle ~/$HOME/env vars
* Minor refractors
* Render self.render_blank now passes command mode input to it to
properly render, so the user can populate the images
* Fixed bug, in newglob where it would crash on empty self.paths.images
@NickHackman
Copy link
Contributor Author

Update on progress:

  • Added dependency shellexpand to better expand ~ and $HOME and other env variables. Note shellexpand uses deprecated std::env::home_dir pull request sent in fixing that.
  • Fixed bug, where command bar wouldn't be rendered on empty images
  • Fixed bug, mentioned by @gurgalex where newglob wouldn't accept paths like /home/etc/path\ to\ dir/* by adding dependency regex (will be used later on for search as well)
  • Overall, restructure of code base in src/program/command_mode.rs to be more intuitive

Opening code for review

@NickHackman NickHackman marked this pull request as ready for review May 19, 2019 16:56
Copy link
Owner

@Davejkane Davejkane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made a couple of comments, nothing too major. In general I'm impressed with the code and certainly with the enthusiasm to just jump in and make such a huge feature. The project is going to be all the better for it.

src/program/command_mode.rs Outdated Show resolved Hide resolved
src/program/command_mode.rs Show resolved Hide resolved
src/infobar.rs Outdated Show resolved Hide resolved
src/program/command_mode.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated
Home => state.process_action(Action::First),
End => state.process_action(Action::Last),
Semicolon => {
if state.left_shift || state.right_shift {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really not sure this holds true on non-american keyboards. Shift semicolon does not always equal colon. Please see if there's another way to do this. Maybe a virtual keycode if you can get them working.

src/ui.rs Outdated Show resolved Hide resolved
This solution path was taken in response to the sketchy passing command
to render_screen. This is a more proactive approach that is easier to adapt in the future.

* Add Mode, Error, to display error messages
* ui.rs Mode variants now take Strings if they need to display on infobar
* Fixed documentation, removed TODOs
* Infobar::update now matches on Modes
Copy link
Collaborator

@gurgalex gurgalex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid recompiling the regex every time it is called. See https://docs.rs/regex/1.1.6/regex/#example-avoid-compiling-the-same-regex-in-a-loop

src/program/command_mode.rs Outdated Show resolved Hide resolved
@NickHackman
Copy link
Contributor Author

@Davejkane thanks for the advice/review! in the future I'm going to have a more cross platform mindset compared to currently as that seems like a big issue. In addition to that a more proactive mindset as well some of the code I wrote in this was quick and dirty/sketchy. I'm going to iron out these issues ASAP 😃

Yeah... this seemed like it wouldn't be too bad going in, but quickly became this behemoth.

I think that we should remove all the normal mode features from src/program/mod.rs -> src/program/normal_mode.rs or something along those lines to better layout the project, just a thought though

Copy link
Owner

@Davejkane Davejkane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still a few little things. I would like us to try to support windows if at all possible. At some point it would be nice to get a windows user on board. I have no idea if this even works on windows.

src/ui.rs Outdated Show resolved Hide resolved
src/program/command_mode.rs Outdated Show resolved Hide resolved
@gurgalex
Copy link
Collaborator

Vim seems to use @: for repeating the last operation in command mode.
https://vim.fandom.com/wiki/Repeat_last_change

@gurgalex
Copy link
Collaborator

We could address this later though.

@NickHackman
Copy link
Contributor Author

@gurgalex that sounds like maybe a different PR, but I like the idea

@Davejkane
Copy link
Owner

Davejkane commented May 22, 2019

@NickHackman wow, I'm impressed you got through so many tweaks. One of the big ones left is still that when I move or delete an image, the len of the images vector isn't being updated, meaning that then visiting the last file causes an out of bounds panic.

* delete and move would panic when deleting/moving from the end or on
empty
* command mode destfolder/df wouldn't remove escaped spaces
@NickHackman
Copy link
Contributor Author

NickHackman commented May 22, 2019

@Davejkane I don't think I wrote that bug, but fixed 👍

edit: Yeah, sorry that is certainly my fault

@Davejkane
Copy link
Owner

It was working fine before the new max_viewable logic. And as far as I can tell, it isn't fixed. I just tried to delete the last image when I had 4 images, and it crashed the program.

@NickHackman
Copy link
Contributor Author

NickHackman commented May 22, 2019

@Davejkane I'm confused, that's not reproducible on my end.
You updated your local repo after the push right?

@Davejkane
Copy link
Owner

Davejkane commented May 22, 2019

OK, just tried again and that seems to be fine, think pulling the branch didn't work. The program now seems to be exiting with this error message now Error: "SDL2 error: Text has zero width" when I hit q or esc. I promise that's my last gripe.

src/infobar.rs Outdated Show resolved Hide resolved
* Infobar was rendering empty Strings for the Exit mode
* If destfolder is still 'keep' change it whenever newglob changes
directories
@NickHackman
Copy link
Contributor Author

Honestly guys thank you so much for all the help, I didn't handle so many edge cases that would've come back to haunt me in the near future. I think we ironed at least a large majority of them, can never say they're all gone, but all the ones that I've tested for are gone. I'm honestly really happy with the result and the level of code quality 😄

It was a joy working with you both on this, and I hope to contribute to the project more in the future ❤️

Probably going to do #53 after this

Copy link
Collaborator

@gurgalex gurgalex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NickHackman
Thanks for all the help.

Should be the last change request from me.

  • Rename paths.current_dir to base_dir
  • Keep selected destination folder the same even if a new glob no longer contains the destination folder.

Example

Selected df
/home/alex/pictures

Current glob
/home/alex/*.png

New glob
/home/alex/Downloads/*.png

Destination folder is still
/home/alex/pictures

@@ -310,6 +335,9 @@ impl<'a> Program<'a> {
return Ok(());
}
self.newglob(&arguments);
if self.paths.dest_folder.ends_with("keep") {
self.paths.dest_folder = self.paths.current_dir.join("keep");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NickHackman

Sorry to request more changes.

The destination folder should be kept the same unless the user changes it with df

I believe the field current_dir should be called base_dir to say that this is the base directory from which the glob finds images.

Copy link
Contributor Author

@NickHackman NickHackman May 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your above example that's how it should function currently.

The only instance it would change in newglob is if the user hasn't modified the default destination folder. If that's the case we should maintain the invariant, stated in help/README, that the default folder should be ./keep

I think that would make sense, for instance running riv in /riv/src/program initially and going to ~/Pictures and hitting move it'd be really weird if we moved the image to /riv/src/program/keep rather than ~/Pictures/keep I personally would think that's unexpected.

I think that we should probably keep track if the user changes the destination folder in case of the instance where the user actually wants the folder name "keep" in a directory. That seems like a bug/unintended behavior.

* Changes to dest_folder is now kept track for the case
of newglob to maintain the invariant that if the user hasn't set dest
folder, images should be moved to "./keep" by default unless specified
otherwise
@Davejkane
Copy link
Owner

I like the behaviour of the keep folder as it is right now. As a user I'll probably make a keep folder on my desktop and jump around in different folders using new glob, and it's nice that the keep folder doesn't move with me.

I've just got a last little bit of QA to do before my blessing.

@NickHackman
Copy link
Contributor Author

@Davejkane okay, I'll remove that

@Davejkane
Copy link
Owner

Davejkane commented May 22, 2019

In the readme, it says that the command ? or help will toggle fullscreen. Please correct that.

I'm also a little surprised that toggling the help bar with h, and toggling it with the command mode aren't linked, so one can't undo the other. Also, the plain h command no longer works when there are no images loaded on initial load, even if I then newglob to get a bunch of pictures, h doesn't work.

Scrap that, hadn't seen you fixed it to question mark. 👍

Copy link
Owner

@Davejkane Davejkane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You did good. Well done. That was a bit epic, but we've pulled through. If there are any bugs, we'll catch them in follow up tickets, but it got past my QA for now. Now that we have this functionality, I'm going to write a couple of tickets.

README.md Show resolved Hide resolved
@Davejkane
Copy link
Owner

Davejkane commented May 22, 2019

@gurgalex are you happy with this PR now? (please approve if so)

@gurgalex
Copy link
Collaborator

@Davejkane

Doing some testing to see if this is functioning.

I like the behaviour of the keep folder as it is right now. As a user I'll probably make a keep folder on my desktop and jump around in different folders using new glob, and it's nice that the keep folder doesn't move with me.

@gurgalex
Copy link
Collaborator

Seems fine to me. Even though I'm not seeing a commit that undid the changes for a moving ./keep directory.

@Davejkane
Copy link
Owner

I'll do the merge.

@Davejkane Davejkane merged commit f2d49ba into Davejkane:development May 22, 2019
@NickHackman NickHackman deleted the feat-redefine-glob branch May 22, 2019 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants