luakit icon indicating copy to clipboard operation
luakit copied to clipboard

Refactor support for multiple modes

Open aidanholm opened this issue 7 years ago • 2 comments

Currently each luakit window has only a single mode at any one time. This complicates many implementation details.

Motivation:

  1. Improve handling of menu and readline bindings. They are currently explicitly bound for all modes that use the menu/input bar, which is not ideal. Goal is to separate these bindings onto input and menu modes, which are activated automatically.
  2. Support implementing sub-modes like command::reverse-search or menu::filter without leaving parent mode.
  3. Remove special-case all mode: change to mode that's always active.
  4. Handle complicated mode states like command mode > reverse search > input vim binds > input normal mode

Possible solutions:

Solution 1: ordered set of modes

Each window has an ordered set of modes, each with their own bindings. Mode set order provides bind activation priority. For example, when in command mode and doing a reverse search (not yet implemented):

w.modes = { "all", "command", "command::reverse-search", "input", "menu" }
  • input and menu modes are added/removed on ibar/menu visibility change. These modes only have binds; no enter or leave functions.
  • Complicates returning to normal mode. Some modes will need to listen to mode-leave.
  • Has exclusivity problem. How to prevent e.g. normal and insert being active at the same time?
  • Makes it easy for plugins to extend modes.
  • How to handle mode changed hook? Called only on highest-priority mode with hook function?
  • API: w:mode_enter(name), w:mode_leave(name)

Solution 2: stack of modes

Same as above, but modes can only be pushed/popped, not added/removed at arbitrary positions.

  • Mostly eliminates mode exclusivity problem.
  • Easy to turn into solution 1 if extra flexibility is required.
  • API: as above, w:mode_leave(name) additionally pops all modes above named mode, in reverse order.

Orthogonal possibilities:

Major/minor mode split, like emacs

  • Well-understood model
  • Different usage from emacs: for luakit this is mostly managing bind sets, without changing other behavior.
  • Eliminates mode exclusivity problem
  • Unclear how to handle binding priorities.

Modes on several objects

  • Window object w, menu, input bar widget, etc.
  • Complicates specifying binds
  • Unclear how to handle binding priorities.

aidanholm avatar Jun 18 '17 02:06 aidanholm