If you are Vim user you heard about EasyMotion and Hop. This library is exactly this concept but for Textual! Just type your shortcut and focus/press widget you want. No mouse needed!
Please always pin version of this library as API may change rapidly. It is experimental project and some staff may be modified.
Just simply install via pip
:
pip3 install hoptex
Hoptex allow to focus object and additionaly press it. By default:
space
will highlightfocusable
widgets and allow to focus choosen onectrl o
will focus and press widgets that arefocusable
and haveon_click
or_on_click
method.
The most basic usage is just adding decorator on your Textual app like this:
from textual.app import App
from hoptex import hoptex
@hoptex()
class NewTextualApp(App):
...
That is all. Super easy, right?
To choose which widgets will be highlighted Hoptex checks for three condition:
- Widget have property
focusable=True
. - Widget is in allow list (then will be forced to be highlighted)
- Widget is in blocked list (it have priority to exclude widget over allow list)
This parameters can be changed in @hoptex
parameter filter_lists
using HoptexFilterWidgetsConfig
.
By default allow_list
and block_list
are empty and include_focusable=True
.
Example can be like this:
from textual.demo import DemoApp, LocationLink # Tested on Texutal 0.30.0 Demo App
from textual.widgets import TextLog
from hoptex import hoptex
from hoptex.configs import HoptexWidgetsFiltersConfig
widgets_filters = HoptexWidgetsFiltersConfig(allow_list=[LocationLink], block_list=[TextLog])
@hoptex(widgets_filters=widgets_filters)
class WrappedDemoApp(DemoApp):
...
If you do not like default bindings you can change them with HoptexBindingConfig
.
It has four fields, which you can replace with keybinding like in Textual:
focus
, default tospace
-> Run Hoptex screen to focus widgetpress
, default toctrl p
-> Run Hoptex screen to focus and press/click widgetquit
, default toescape
-> Quits from Hoptex screenunfocus
, default toescape
-> Unfocuses from any widgets (if you are in e.x. text window, you need first to unfocus to usespace
)
and also four config fields, that takes dictionary that will be injected in standard Binding field:
focus_conf
, default to{"description": "Hop Focus"}
press_conf
, default to{"description": "Hop Press"}
quit_conf
, default to{"description": "Hop Quit", "show": False}
unfocus_conf
, default to{"description": "Hop Unfocus", "show": False}
from textual.demo import DemoApp
from hoptex import hoptex
from hoptex.configs import HoptexBindingConfig
bindings = HoptexBindingConfig(press="ctrl g", press_conf={"description": "Another description"})
@hoptex(bindings=bindings)
class DemoAppMy(DemoApp):
...
You can also inject custom label appearance, by label
value. It should inherit from Static
and allow for one argument (the letter that will be displayed).
However easier way is to change CSS of HopLabel
, which default is to:
HopLabel {
width: 1;
height: 1;
color: yellow;
text-style: bold;
background: black;
}
- Support more widgets on screen
- Allow to use hoptex as wrapper for application (open any app with hoptex support)
- If no place to jump, return
- Color change
- list of characters
- custom Widget to mark
- python/typing#213