`select` command not functioning as expected
Issue Description
When using the :select lf command to navigate through files, the command only navigates to the file instead of selecting it. This unexpected behavior makes it difficult to select files programmatically.
Expected Behavior
:select command should select the file just like using the :toggle.
Actual Behavior
:select command only navigates to the file and does not select it.
Workaround
I use :unselect, then :select, finally :toggle to simulate the expected-:select.
It's dirty and needs to handle the unique element problem, for example:
cmd fzf ${{
declare -a entries=()
# .... fzf ...
# entries <== fzf result
# Backup the current selections
for entry in $fs; do
entries+=("$entry")
done
lf -remote "send $id unselect"
# Select all entries
for entry in "${entries[@]}"; do
declare arg="$(printf '%q' "$entry")"
lf -remote "send $id select $arg"
lf -remote "send $id toggle"
done
}}
Proposed Solution
The select command should select the file. Alternatively, a new command (e.g., choose) can be added to select the file for backward compatibility.
Additional Information
lf version: r29 OS: macOS Monterey 12.6.1
Thank you for your attention to this matter.
The select command really just means 'focus', and doesn't have anything to do with file selections like the unselect command. I do agree that the naming is confusing, but I think the reason is historical.
The select command should select the file. Alternatively, a new command (e.g., choose) can be added to select the file for backward compatibility.
Actually the toggle command already does what you want - you can specify as arguments which files you want to select. Try typing :toggle file1 file2 file3 and see what happens.
Also in the script you have provided, if you're able to get all the quoted filenames into a single variable, you can achieve everything using a single lf -remote invocation:
lf -remote "send $id :unselect; toggle $files"
Thanks for your suggestions!
IMHO, the suggested approach of using the :toggle command with specific file arguments poses some limitations, particularly when it comes to user scripting. I would like to highlight the issues with this approach:
- Duplicate file entries in the
$filesargument result in no action being taken, requiring users to handle the removal of duplicate elements or array in their scripts. This adds unnecessary complexity, especially in shell scripting languages (I do this bytypeset -Uain ZSH). - Without unselecting files beforehand, there is uncertainty about the effect of the toggle command, potentially leading to unintended file deselection.
- The necessity of unselecting all previously selected files before executing the toggle command raises concerns about script efficiency.
I kindly request an improved file selection mechanism that addresses the limitations mentioned above and provides better support for scripting:
- Introduce a dedicated command (e.g.,
:choose) specifically designed for file selection. This command should select the specified files reliably, even when duplicates are present in the file arguments. - Ensure that the file selection mechanism supports scripting without the need for explicit unselection of files before making a selection. This would simplify scripting workflows, especially when dealing with a large number of selected files.
By implementing these enhancements, lf would offer a more robust and user-friendly solution for file selection, catering to the needs of both interactive usage and scripted workflows.
Thanks for your feedback. I should point out that the current commands appear to have been designed based on being able to provide useful keybindings rather than implementing a proper scripting API. For example, toggle is useful as a keybinding because a user generally expects that pressing the same key for selecting a file also unselects it, whereas your proposed choose doesn't provide a way for the user to unselect the file, and a different command and keybinding would have to be used.
That being said, your points do have merit, and based on what you have said I think we can propose the following:
focus- focuses the cursor onto a given path- Does what
selectcurrently does. Renaming the command is a breaking change, but unless this is done, it can potentially confuse new users into thinking thatselectis related tounselect. - Takes exactly one argument, which is the file to move the cursor to.
- Does what
select- marks a file(s) as selected- Takes as arguments the file(s) to be marked as selected. If no arguments are given, then select the currently focused file.
- Idempotent, specifying a file more than once leaves the file in a selected state.
- Applying this on a file that is already selected has no effect.
toggle- toggles a file(s) between selected and unselected states- Takes as arguments the file(s) to have their selection state toggled. If no arguments are given, then toggle the currently focused file.
- Not idempotent, specifying a file an even number of times has no effect, and specifying a file an odd number of times is equivalent to specifying a file once.
unselect- marks a file(s) as selected- Takes as arguments the file(s) to be marked as unselected. If no arguments are given, then toggle the currently focused file. This does mean that we will need a new way to simply unselect everything, maybe
clearselect. - Idempotent, specifying a file more than once leaves the file in an unselected state.
- Applying this on a file that is already unselected has no effect.
- Takes as arguments the file(s) to be marked as unselected. If no arguments are given, then toggle the currently focused file. This does mean that we will need a new way to simply unselect everything, maybe
This is just a draft, and it would take some time for it to be approved, if it even gets approved at all. While I support your request to improve the existing file selection commands, it is possible that others feel it's not worth implementing or making breaking changes. Hopefullly other people will be able to see this issue and provide some feedback.
Appreciates your proposed changes to the file selection commands! The modifications presented are thoughtful, and intuitive, and address the limitations of the current commands.
I wholeheartedly support the proposed changes as they offer clear benefits and practical improvements. The revised commands provide a more coherent and consistent approach to file selection, catering to both keybinding users and script developers. The new command names, such as :focus, :select, :toggle, and :unselect, accurately convey their intended functionalities and reduce confusion.
Once again, thank you for your incredibly proactive, responsive, and dedicated in assisting us with the discussions and problem-solving efforts 😇.
I really like @joelim-work 's suggestions in principle. In particular, using the word focus is a great idea, I think. After @kevin61416 pointed it out, the asymmetry between select and unselect is bothering me as well.
However, this would be a really annoying breaking change for people who use :select in their configs. One way to make it less annoying would be to make the change slowly. We could:
- Introduce the
:focuscommand - Create a
newselectbehavioroption. If it is not set,:selectis disabled. It could map to something like:echoerr "Use :focus instead of :select or set the newselectbehavior option after reading the docs". If the option is set,:selecthas the new behavior. - After a few versions of lf, make
newselectbehaviordefault to true and then remove it.
Do we think it's worth the trouble, @gokcehan and everyone? Or do we think it would be acceptable to switch to the new behavior more abruptly? (Update: Or do we do nothing? Or do we do something more backwards compatible & less elegant?)
Aside: the work focus is relevant to the discussion we had in https://github.com/gokcehan/lf/pull/1086. I'll mention it there.
Looking at the relesase notes from the past few releases, the breaking changes there are somewhat minor and IMO nowhere near as severe as changing existing commands as discussed here. I think lf is actually somewhat mature now, especially given the number of users, and I'm somewhat uninclined to just immediately change the behaviour without warning. @ilyagr's suggestion of rolling out the changes in a more gradual and controlled manner sounds much more reasonable to me.
I just want to point out a few more things:
- The
newselectbehavioroption should affect theunselectcommand as well if its behaviour is going to change too. I'm still not sure whetherunselectwithout any arguments should unselect the currently focused file, or every file, but I'm leaning towards the former so that it remains symmetrical with the newly proposedselectcommand. - I agree with making
selectdo nothing if thenewselectbehavioroption is not set, instead of maintaining the old behaviour for a couple of reasons:- It forces the user to switch to the newer
focuscommand. - There is no chance that the
echoerrfor the deprecation warning will be overwritten by a call toapp.ui.loadFileInfo, causing the user to not see it at all.
- It forces the user to switch to the newer
- The
on-selecthook command should be renamed toon-focusif we are going to change the terminology like this. - It's worth going through all of the code and documentation and changing the word 'select' to 'focus' where appropriate to avoid confusion. For instance I searched through the documentation, and there are a few places where the meaning can be confusing when the word 'select' is used to describe multiple different things, here is one of them: https://github.com/gokcehan/lf/blob/f04401ba4d43f21a084e603a52cf20f80b0c437d/doc.go#L923-L925
I'm not sure if I was clear, but when I was talking about "worth the trouble", I meant to suggest that doing nothing or coming up with some less-elegant but more backwards-compatible solution are also options we should consider.
Now that it seems we have an OK plan for making the change, I'm leaning towards that option, but I am curious what @gokcehan thinks.
@joelim-work is right in that these commands were mostly intended for keybindings rather than scripting. I used to try naming commands and default keybindings as consistent as possible (e.g. u for unselect or c for clear). If my memory is right, toggle was originally only for keybinding but someone suggested adding argument handling for scripting. select is different than others in that it is added as an alternative form of cd. I agree it is a little unfortunate that select and unselect ended up with such different semantics. Still, I think I lean toward not making any breaking changes at this point if possible even with a deprecation strategy.
If I understand this correctly, the only thing missing is a command that would unconditionally add file(s) to the selection. How about we add two new commands to select/unselect a list of files similar to what we have as glob-select/unselect? I thought maybe we can name these commands arg-select/unselect or list-select/unselect.
Actually you could argue that there are two issues here:
selectshould be renamed to something else (e.g.focus) so that it is less confusing- There is no way to unconditionally add files to a selection
If we were to solve problem 2 by simply adding new commands, while there would be no breaking changes, it would not necessarily solve problem 1. In fact it would make problem 1 more difficult to solve, because in addition to renaming select to focus, you would now also have to rename arg-select to select.
That being said, if you absolutely don't want to fix problem 1 because it involves potentially severe breaking changes, that is fine by me. But in this case I'm not sure whether problem 2 by itself is big enough to warrant adding new commands. While toggle with arguments may not always do what you want, you can always manually toggle files afterwards to adjust the selection list.
To be honest, my use of lf features is so minimal that none of the things proposed here will be a breaking change for me. In that sense, I guess it makes sense to leave the decision to active contributors again. The general consensus here seems to be in favor of the change so I think I can accept the change. Moving forward, I can see how this change can improve the program.
@joelim-work 's proposal seems fine. The only thing I can add here is that in addition to adding a new command clearselect (or clear-select), maybe we should also think of renaming the current clear command to something else for clarity (maybe clear-buffer?)
@ilyagr 's rolling out proposal also seems fine. I have nothing to add at this point.
I will try to go over the documentation, wiki, and the command line help again to see if the term change from select to focus might create any complications.
Hello, i'm sorry for barging in and necroposting, but i'd like to point out that a focus command like suggested in this comment would be great.
My use case for this would be for the fzf-jump integration proposed in the wiki, for starters. It works great for selecting and cding to a chosen directory but it doesn't focus (wink wink) on a chosen file, instead leaving the cursor at the top of the directory.
I've noticed the default search command, however, already implements this functionality.
Would it be possible to expose that so that it could be used in scripting somehow?
@itsdeadguy The select command already exists and should place the cursor on chosen file (e.g. select foo.txt). That comment was more about changing the name to focus, although at this point I think it's not likely to happen because it is a breaking change and will force a large number of users to update their configurations.
The select command [...] should place the cursor on chosen file (e.g. select foo.txt).
@joelim-work this has not been my experience, should we continue discussion here or should i open a new issue?
The select command [...] should place the cursor on chosen file (e.g. select foo.txt).
@joelim-work this has not been my experience, should we continue discussion here or should i open a new issue?
New issue please, and post your config file, steps to reproduce and anything else that might be helpful.
Also have you tried just simply typing :select <name_of_file> on the command line, and see what happens? That should move the cursor to that file.
To be honest, my use of
lffeatures is so minimal that none of the things proposed here will be a breaking change for me. In that sense, I guess it makes sense to leave the decision to active contributors again. The general consensus here seems to be in favor of the change so I think I can accept the change. Moving forward, I can see how this change can improve the program.@joelim-work 's proposal seems fine. The only thing I can add here is that in addition to adding a new command
clearselect(orclear-select), maybe we should also think of renaming the currentclearcommand to something else for clarity (maybeclear-buffer?)@ilyagr 's rolling out proposal also seems fine. I have nothing to add at this point.
I will try to go over the documentation, wiki, and the command line help again to see if the term change from select to focus might create any complications.
agree, clear is a bash cmd which was used to clear console. this was taken by lf, so i have to use echo . to clear the bottom piped cmd panel.
the function of current clear is yank-clear, used to clear the yanked files (yank-copy , and yank-move), so maybe rename to yank-clear or unyank or sth else.
about break change.
every software goes to the stage of choice, break or heavy lift.
there're some choices:
- discard old cmd config
- introduce a version control, if user defined version, keep the old version. otherwise use new one.
- nofy the broken changes and let user change their config
- introduce a bash tool to help user change their config.
- if still confused , let the community to vote ?
So it has been about half a year since I last commented on this topic.
As time has passed, I'm not really sure whether it's worth introducing extra commands just to unconditionally mark files as selected/unselected, and instead just keep the commands based on what users would typically map as keybindings (i.e. the current toggle/invert/unselect commands).
In this case I'm not sure what select should do, if it is to be interpreted as the opposite of unselect. If we don't change what select does, then there's also less motivation to add a focus command which would otherwise do the exact same thing.
Anyway we can keep this issue open for further discussion.