davatorium / rofi

Rofi: A window switcher, application launcher and dmenu replacement
https://davatorium.github.io/rofi/
Other
13.24k stars 613 forks source link

[REQUEST] rofi as multi-row multi-value data entry engine #1269

Open etosan opened 3 years ago

etosan commented 3 years ago

Before creating a feature request

What is the user problem or growth opportunity you want to see solved?

For a longest time rofi can be used as a simple input box tool (probably since -dmenu). This capability blows other scriptable input tools away. It would be awesome, if it could be used for any generic data input (think "mainframe input screen mask"), especially multiple input fields input.

Why use it as input box?

It is very keyboard friendly and has quite complete and powerful input line editing engine, that integrates very well with GUI (XOrg, perhaps wayland in the future), so this usecase is not really unexpected. In "input box hack" the trick is to provide rofi with empty input, so there is nothing to choose from, but let user type in the entry and consume rofi's output as the answer.

Currently I am using something similar to this: rofi -dmenu -p "${PROMPT}" -theme-str "listview { enabled: false; } entry { placeholder: \"${EXAMPLE}\"; }" -disable-history -no-plugins

Recently, I was in a situation where I wanted to get two input values instead of one.

Of course one can just spawn rofi two times to get each value in turn, but that turns out to be quite time consuming. Or, if one is smarter, one can "parse out" multiple input values from single rofi output with a hack, by using some special char in input as value separator, like comma "," for example . Eg:

# ...
TWO_VALUES="$(rofi -dmenu -p "${PROMPT} ...)"
VALUE_A="$(echo "${TWO_VALUES}" | cut -d',' -f1)"
VALUE_B="$(echo "${TWO_VALUES}" | cut -d',' -f2)"
# ...

However what if I have more values and some of them with defaults? It gets hairy...

...I know, rofi is not supposed to be data entry input box, but bear with me, please. And I know some will say "use the right tool for the job", and that there should be separate tool just for inputs, but let me entertain you for a moment.

It turns out rofi, thanks to it's no-bullshit design, is actually poised to be exactly that kind of the tool: ultimate input/dataentry tool. Instead of being usable only for no-nonsense selection, after extension, it would be also usable for no-nonsense data entry.

First, let us write down properties that no-nonsese (eg. ultimate) data entry tool should have (and also state of their implementation in rofi):

No matter how I look at it, rofi already does most of the magic required and has proper design for everything, that would be nice to have in such a tool. I believe rofi could be adapted for such use case relatively easily (as in: instead of writing entirely new tool from scratch to replicate everything rofi does it would be easier and more worthwile to extend rofi itself). Tools like zenity, qarma or newt (and TUI crap ) can not even compare.

Thus I propose introduction of new mode: edit or entry perhaps even dataentry mode.

This mode would add value input field/box to each row, with possibility to be set to default value on spawning. This mode would also keep top prompt for search in datafields names/values. Messagebox part would be also handy, to inform user about current data entry stage. I would suggest adding support for new top row, akin to window title, this would come in handy for naming the "dialog" overall, and would leave prompt box in front of searchbox free to change with search mode (name/values) toggle (like "search in datafield names:"/"search in datafield values:"). Pressing "move selector up" or "move selector down" command/keybinds in searchbox would immediately break search and allow user to navigate to datafield of interest (the one they want to edit). Up would move selector to the end of the list, down to the start, for example. Writing search query that would select single datafield (eg row) would, by default, switch input immediately to selected datafield's row's value input box. Enter after datafield's value edit would return focus to either search box or to roe selection scrolling depending on which mode was active when datafield's value inputbox was activated.

Some global command (like ctrl+enter) would send current dataset for evaluation. If dataset has some required values missing, rofi would notify the user with error message, and perhaps by highlighting and selecting only problematic datafields. Should the dataset be complete, rofi would return it as either specially formatted output, or by some other protocol, to dataset mode handling "script". This should be probably discussed and investigated. Esc bound command would cancel whole input entry.

As said, in this dataentry mode rofi would need to be able to return list of all the datafields eg. all rows and their values by default, instead of just one, as it does now (I believe single datafield selection should be returnable still, but kept as configurable possibility). The dataset format needs to be discussed. It should be easiest to work with (one output line is one value per datafield?), yet also such, that it allows easy use of rofi's insane flexibility. Each datafield should have ability to have unique ID attribute set so that it can be uniquely identified in the dataset "soup" (would also allow for translations and such).

There are few details that would need to be ironed out, and whole thing needs to be implemented.

For example how to handle entry definition feed and population and final dataset return.

I know there are many rofi applications already, but if I am not mistaken each uses rofi only as single input entry selector and search engine solely. No current rofi application allows to use it as multi-datafields entry tool.

I would like to know if rofi authors and contributors would be open to such mode, and what are the chances of this mode materializing. If there are no resources or other constraints to implement this mode, would this mode be acceptable as an patch from 3rd parties? Or there is general consensus that rofi should be remain data picker only?

How do you know that this problem exists today? Why is this important?

See the previous section for "discovery". Here is why this is important:

Rofi essentially solved "keyboardist's picking" problem for millions of users. It was not first such a tool but it certainly is one of the best and most featureful. There are many rofi clones now. With rofi, keyboard picking in GUI is no more an issue. It became solved problem.

Yet we are still missing effective "keyboard friendly" dataentry input tool. Especially one that works well in GUIs, that can be controlled exclusively from keyboard, that can be scripted easily and that supports more than one datafield. Scriptable dataentry tools like zenity, qarma, newt (and others) are too stuck in past, in broken point and click gui paradigm, emulating broken gui metaphors, written in broken point and click gui frameworks. That makes them impossible to control from keyboard effectively and universally, as whole baseline they build up from is fundamentally broken for that usecase. This new rofi mode would probably solve even that problem, problem of sane dataentry.

Finally, picking and dataentry are two most common tasks one can do on a computer. With addition of this mode, one would only need one tool, rofi, to handle both tasks.

Who will benefit from it?

I believe having single, keyboard focused, highly universal, highly tuned, highly usable, high performant tool like rofi with this extension certainly would be, would benefit everybody in open source community. It would allow many to drop their ad-hoc solutions and allow them to standardize on only one generic tool for the majority of the input tasks.

This would incredibly increase "GUI integrability" of many command line tools and custom user scripts.

Version

1.6.1

Configuration

N\A default configuration.

github-actions[bot] commented 3 years ago

@etosan: hello! :wave:

This issue is being automatically closed because it does not follow the issue template.

DaveDavenport commented 3 years ago

I currently have no plans (or the time) to extend rofi with functionality like this.

I am also not sure rofi is the best place to implement this, it would require a significant rewriting of rofi's internal structure. IMHO rofi is already very complex for its simple task.

etosan commented 3 years ago

I currently have no plans (or the time) to extend rofi with functionality like this.

Understood, I was afraid this would be a primary issue too. I thought, as quite a lot of functionality is already there, this would not be that complicated, but yes I have no clue.

I am also not sure rofi is the best place to implement this, it would require a significant rewriting of rofi's internal structure. IMHO rofi is already very complex for its simple task.

I see! So, although rofi looks relatively straightforward from the outside, I guess it's multi-threaded, asynchronous search capabilities and other crazy advanced features make it quite complex inside. And so, from the cursory description of the dataentry mode, you then think, this would then still require very significant rearchitecting of it's internal structures and machinery to accommodate for such usecase? As in, is rofi too complex, or this mode too crazy, too much different, from the modes, to be meaningfully added?

I admit, I never looked deeper at the code than superficially, so I have no idea about it's internal structures, and frankly, personally I was just imagining use of some nasty "hacks", to piggybacking this mode on top of what is already here. But you say this would be neither possible, nor very pretty (eg. even if possible, it would still not be maintainable in the end)? As in rofi has so much functionality inside now, that this mode would essentially break a "camel's back", and all that added complexity would not be worth it in end?