DFHack / dfhack

Memory hacking library for Dwarf Fortress and a set of tools that use it
Other
1.84k stars 462 forks source link

Refine keybinding scopes for scripts (reducing pollution of `hotkeys` screen) #1739

Open TymurGubayev opened 3 years ago

TymurGubayev commented 3 years ago

The default keybinding for twaterlvl is as follows. https://github.com/DFHack/dfhack/blob/a7232499ac78ae85346cac43254eea4ee156dc90/dfhack.init-example#L10

It would be nice to change it to something like keybinding add Ctrl-W@dwarfmode|dungeonmode twaterlvl reducing pollution of the Alt-F1 list.

This isn't always that easy: view-unit-reports has some advanced logic finding current_selected_unit, it would require at least 3 alternatives and won't be exact anyway. It would be nice if we could define a guard-function in a script the same way a plugin can.

Relevant code in hotkeys.cpp and PluginManager.cpp: https://github.com/DFHack/dfhack/blob/a7232499ac78ae85346cac43254eea4ee156dc90/plugins/hotkeys.cpp#L27 https://github.com/DFHack/dfhack/blob/a7232499ac78ae85346cac43254eea4ee156dc90/library/PluginManager.cpp#L1007-L1011 https://github.com/DFHack/dfhack/blob/a7232499ac78ae85346cac43254eea4ee156dc90/library/PluginManager.cpp#L527-L533

On a relevant note, the hotkey-plugin could use the same method ls-command uses to access script help.

lethosor commented 3 years ago

Definitely on-board with adding more specific contexts if they make sense. twaterlvl does technically work from any screen, but it would make the most sense to run it from the screens you mentioned to see it take effect.

Using getScriptHelp for one-line script descriptions would also be good, although it's not currently available to plugins, so that would need to be changed. In C++, more detailed help can also be retrieved from PluginCommands currently, but not scripts. There is a Lua dfhack.script_help() that works for scripts in any language, but calling it from C++ is a bit more tricky.

Some more thoughts I had related to this:

When it comes to the hotkeys plugin, I think one of its goals is making hotkeys discoverable. I suppose it makes sense to hide keybindings that only work in other contexts, but if a command can't be invoked currently due to a guard (e.g. no unit selected), I think it should at least be displayed, maybe with an indication that it has additional requirements to run. I think these are currently displayed, at least.

view-unit-info and other scripts that operate on a selected DF object could potentially work in a huge number of contexts - for instance, here is the backing logic for getSelectedUnit(). I've previously thought about allowing keybindings to specify a basic predefined "guard" in addition to (or instead of) a context (maybe like Alt-F!unit or Alt-F@dwarfmode!unit), which could help restrict the context in which any command could run, including scripts. It could be confusing to have this behavior be separate from the PluginCommand's guard, though. Maybe it would make sense for e.g. a keybinding that you only want to run if a unit is selected, even if the command itself works in other UI states, though.

Implementing guards in scripts are an interesting idea, but would pretty much have to be set up on an opt-in basis because some existing Lua scripts are written to modify game state at load time. For instance, something similar to the system that allows Lua scripts to support the enable/disable commands could work. I might also be concerned about the overhead of calling lots of Lua-implemented guards at one time, but that probably wouldn't be significant for most users.