tridactyl/design.md
2017-02-13 17:42:48 +00:00

7 KiB

Tridactyl

Replace ff's default control mechanism with one modelled on the one true editor, Vim.

Principles:

* Keyboard > mouse
* default keybinds should be Vim-like
* actions should be composable and repeatable
* ex mode should expose all the browser functionality anyone might want
* Arguable: most (all?) actions should have an ex mode version (departure from Vim?)
* users can map actions and commands to other keys

Other objectives:

* be fast - the whole point of a keyboard interface is to be more efficient, don't compromise that with slow code
* don't crash - we're the new UI and we shouldn't crash
* be maintainable - code should be well documented, reasoned about and tested.

Non-objectives for v1:

* insert mode (embedded (n)vim would be good for future)
* caret or visual mode - I'm not good enough at vim to find these easier than selecting with the mouse, and they require text motions, which I would prefer to delegate to vim.

Prior art:

* pentadactyl/vimperator - dying with XUL
* cVim/vimium
* vimfx - transitioning to WebExtensions, but no ex commands
* qutebrowser/jumanji - see standalone route.

Standalone route

Some small browsers exist that use webkit/webengine for the heavy lifting. Two notable examples even have vim-like interfaces: qutebrowser and jumanji.

Extending them might be easy, depending on the quality of the existing code base. We also need to evaluate these projects for maintainability: they're obviously going to have much less development power.

If it's comparable to this project done in webextensions, then we might want to just build our own/fork/contribute.

But what do we lose? What do the non-gecko bits of firefox do? What's left in the chrome repo if you remove webengine? I don't really know.

* Kerning/font presentation code? (text in qutebrowser looks bad on Windows, don't know why)
* Cross-platform OS shit
* Firefox sync is neat and would be missed.
* safebrowsing?
* how much security stuff in engine/vs browser?
* webm, webgl and similar? Presumably handled either by the engine or externally, but maybe picking and maintaining link to external thing is expensive.
* flash handling?
* What UI stuff are we not replacing?
* developer tools (neat, but no reason for us to re-implement).

We also lose access to the existing addon/extension repos. Maybe if we implemented webextension support in our own browser we'd get them back? Don't know how difficult that is.

A life without the addon store:

What addons do I use and would I miss them?

Should be part of the browser anyway:

* stylish --> :style, or maybe .vimperator/styles/ (with magic comments?)
* greasemonkey --> builtin/extensions/autocmds
* site blocker --> /etc/hosts

Maybe not:

* element hiding rules (ublock) not supported
* tree tabs --> better :buffer?
* lazarus form recovery is brilliant...
* noscript is shit anyway
* hide fedora is neat, but maybe just an element hiding list? Maybe it does have to parse differently.
* example of neat addon that a smaller browser wouldn't have available, anyway.
* ref control is neat, but the UI is pants. Would be easy to build an ex-mode interface.
* pwgen is trivial
* https everywhere --> builtin?

WebExtension option

Firefox, Chrome, Opera, and probably more support WebExtensions and there seems to be some interest in standardising. If we can get what we want with WebExtensions then we get a free ride on browser development and there's a bigger pool of developers who could contribute to the project.

cVim and vimium implement some kind of vim experience using webextensions, but (allegedly) this gives a poor experience. Definitely neither allow you to modify the browser UI. Possibly the statusline and keyboard input mechanism is a bit shonky because it has to run in the tab's context rather than the browser's (in any case, can't override Chrome's own keybinds).

TODO:

* Test cVim and vimium
* Look for UI WebExtension proposals

Required WebExtension APIs

Don't exist:

* keyboard (not yet existent) (if content script isn't nice enough)
* ui (for hiding and for non-content-script statusline, tho not so important)

Do exist:

* storage (.vimperatorrc)
* tabs
* history (for auto completion of open, etc)
* bookmarks (auto completion, obvious)
* windows (buffers)
* webNavigation (autocmds) - maybe content script would just do this for us.

Stuff we want to do that I know how to do:

* Show hints:
    * For each link in viewport (how to restrict to viewport?):
	    * Add an element styled to appear on top of it
	    * Listen for keystrokes.
    * Does vimperator just go for <a> tags? I think it probably knows about elements that can be clicked for other effects.
* Change tab
    * tabs.update(tabtodisplay, {active: true})
* Change window focus
    * windows.update(windowtofocus, {focused: true})

Stuff I don't know how to do:

  • Use promises properly.

  • Use promises from a sane language (coffeescript, livescript, elm, etc).

  • Find promises to cancel their chain.

  • Communication between background and content scripts.

  • Access a single tab's history

  • scroll

  • print

  • zoom

  • access OS clipboards

  • redo/undo (in text boxes)

  • ff elctrolysis framework (concurrency)

    • Do we automatically use it with we're using webextensions? Seems unlikely...
    • How to store state?
      • e.g. command history, marks, mappings, configuration, autocmd registry,

Vimperator features in sort of priority order for a MVP

Normal mode

j/k gt/gT H/L b / n N f y ]] rapid hint mode?

Ex commands

o t w nnoremap h source save autocmd

+autocomplete

Hard mode

:js :!

Architecture

ex-commands as functions (typed and with helper functions in some other scope):

* open(url)
* scroll(x=+10)
* mark(<elem>)
* map(actions, keys)
* ...

helper functions for actions:

* scroll-x, scroll-y
* jumplist.get/getrelative/store
* undo-tab-deletion

Count and range:

* given as arguments?
* just repeat the call 'count' times?

for default actions, a mapping from key to helper function.

Generated parsers (command and normal mode):

* command mode pretty conventional. Include type checking.
* For auto-complete to work, need to be able to parse partial results sensibly.
* actions will be a slightly weirder grammar:
* More permissive
* Time sensitive

* In vim, actions compose as you write them (d takes a motion as an argument, for example), I can't think of any examples of this in vimperator: actions sometimes take a count or argument, but that argument is never an action.

* If actions did compose, we would have to give them types, as vim does for motions, and the parsing would be less trivial.

Autocomplete functions for commands:

* Split from implementation of command.
* Could perhaps be automatic from command's parameter types?

Some actions have their own interactive mini-mode:

* hints
* searching