Notes From Some Examination of Some Yi Configs
Earlier I’d posted very briefly about some User Yi Configs.
In particular I’m currently curious as to how to customise for, say, adding a new ex command to Yi.
I noted that the Ex commands were listed in Yi.Keymap.Vim.Ex. (Note, there is some discordance between the version on GitHub now, and Yi 0.8.1, as Vim2 has since replaced the older Vim keymappings). And somehow in Yi.Keymap.Vim these … are taken into the configuration. I’m not particularly sure how at present.
Anyway, beyond this, I had another look at how custom actions had been configured by some users.
A Vim Keymap Configured with Customized Keymap
Jeff’s config has these lines:
myConfig :: Config
= defaultVimConfig
myConfig = myVimKeymap
{ defaultKm ...
,
}
= mkKeymap $ defKeymap `override` \super self -> super
myVimKeymap = v_top_level super ||>
{ v_top_level ';' ?>>! resetRegexE)
(char
= (v_ins_char super ||> tabKeymap) <|>
, v_ins_char 's' ?>>! moveToNextBufferMark deleteSnippets
choice [ ctrlCh KLeft) ?>>! prevWordB
, meta (spec KRight) ?>>! nextWordB
, meta (spec
] }
Note:
myVimKeymap
has typeKeymapSet
.
- The
override
thing is due to Yi’sData.Proto
, which isn’t exposed in Hackage. (KeymapSet
has record entriestopKeymap
andinsertKeymap
, so I’m not sure ifv_top_level
andv_ins_char
is archaic).
choice
is of typeMonadInteract m w e => [m a] -> m a
, as defined inYi.Interact
.
- The operator
(||>)
is of typeMonadInteract f w e => f a -> f a -> f a
inYi.Interact
.
- The operator
(?>>!)
is of type
(MonadInteract m Action Event, YiAction a x, Show x) => Event -> a -> m ()
inYi.Keymap.Keys
.
- (And, if you’re that novice at Haskell,
(<|>)
is to do withAlternative
).
It seems Jeff has mapped ';'
to do something like :noh
in Vim.
(resetRegexE
in Yi.Search
.. hey, Yi.Search
has documentation!).
tabKeymap
is a function Jeff defines in the config, which seems to be for
inserting snippets making use of Yi.Snippets
and Yi.Snippets.Haskell
.
There also seems to be inputs for Insert mode, so that Alt+Left
(or Alt+Right
) will move by words left/right.
An Emacs Keymap with a Simple Config
Reiner’s config takes a different approach (although is ‘based’ on the Emacs keymap):
= configMain defaultEmacsConfig setup
main
setup :: ConfigM ()
= do
setup "pango", "vte", "vty"]
setFrontendPreferences [.= Just 9
fontSize
globalBindKeys globalBindings.= publishedActionsEvaluator
evaluator "createDirectory" yiCreateDirectory
publishAction
addMode Haskell.fastMode'c' ?>> ctrlCh 's' ?>>! insertHaskSection) modeBindKeys Haskell.fastMode (ctrlCh
Note:
configMain
has typeConfig -> ConfigM () -> IO ()
, inYi.Config.Simple
publishAction
has type(YiAction a x, Show x) => String -> a -> ConfigM ()
inYi.Eval
.
I’m not sure what "vte"
is; and am unsure about these Mode
s.
The thing to note, though, is that this configuration as per Yi.Config.Simple
and its (ab)use of do
notation makes for a configuration file which looks
much closer to a .vimrc
or other whatever else.
publishAction
looks like a way to add a custom Ex-like command, although in
this case the configuration is for Emacs not Vim. I suspect it will work, but
will need to try.
(Not clear how the equivalent would be set with the non-Simple
configs).
A Vim Keymap with Overridden Bindings
Michal’s Config (which is somewhat documented) has the following code of interest:
myKeymapSet :: KeymapSet
= V2.mkKeymapSet $ V2.defVimConfig `override` \super this ->
myKeymapSet let eval = V2.pureEval this
in super {
-- Here we can add custom bindings.
-- See Yi.Keymap.Vim.Common for datatypes and
-- Yi.Keymap.Vim.Utils for useful functions like mkStringBindingE
-- In case of conflict, that is if there exist multiple bindings
-- whose prereq function returns WholeMatch,
-- the first such binding is used.
-- So it's important to have custom bindings first.
= myBindings eval ++ V2.vimBindings super
V2.vimBindings
}
myBindings :: (String -> EditorM ()) -> [V2.VimBinding]
=
myBindings eval let nmap x y = V2.mkStringBindingE V2.Normal V2.Drop (x, y, id)
= V2.VimBindingE (\evs state -> case V2.vsMode state of
imap x y V2.Insert _ ->
fmap (const (y >> return V2.Continue))
`V2.matchesString` x)
(evs -> V2.NoMatch)
_ = V2.mkStringBindingY V2.Normal (x, y, id)
nmap' x y in [
-- Tab traversal
"<C-h>" previousTabE
nmap "<C-l>" nextTabE
, nmap "<C-l>" nextTabE
, nmap
-- Press space to clear incremental search highlight
" " (eval ":nohlsearch<CR>")
, nmap ...
, ]
All the V2
is somewhat unnecessary.
pureEval
has typeVimConfig -> String -> EditorM ()
.impureEval
has typeVimConfig -> String -> YiM ()
, but I’m not sure of the difference here.myBindings
has type(String -> EditorM ()) -> [VimBinding]
.
This binds keys to eval
something. (In this case, space to call :noh
).
The way Michal modifies his KeymapSet
is quite different from Jeff’s.