Notes From Some Examination of Some Yi Configs

Posted on July 7, 2014 by Richard Goulter
Tags: programming.haskell, programming.yi

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
    myConfig = defaultVimConfig
      { defaultKm = myVimKeymap
      , ...
      }

    myVimKeymap = mkKeymap $ defKeymap `override` \super self -> super
      { v_top_level = v_top_level super ||>
          (char ';' ?>>! resetRegexE)

      , v_ins_char  = (v_ins_char super ||> tabKeymap) <|>
          choice [ ctrlCh 's' ?>>! moveToNextBufferMark deleteSnippets
                 , meta (spec KLeft)  ?>>! prevWordB
                 , meta (spec KRight) ?>>! nextWordB
                 ]
      }

Note:

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):

    main = configMain defaultEmacsConfig setup

    setup :: ConfigM ()
    setup = do
      setFrontendPreferences ["pango", "vte", "vty"]
      fontSize .= Just 9

      globalBindKeys globalBindings
      evaluator .= publishedActionsEvaluator
      publishAction "createDirectory" yiCreateDirectory

      addMode Haskell.fastMode
      modeBindKeys Haskell.fastMode (ctrlCh 'c' ?>> ctrlCh 's' ?>>! insertHaskSection)

Note:

I’m not sure what "vte" is; and am unsure about these Modes. 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
    myKeymapSet = V2.mkKeymapSet $ V2.defVimConfig `override` \super this ->
        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.
              V2.vimBindings = myBindings eval ++ V2.vimBindings super
            }

    myBindings :: (String -> EditorM ()) -> [V2.VimBinding]
    myBindings eval =
        let nmap  x y = V2.mkStringBindingE V2.Normal V2.Drop (x, y, id)
            imap  x y = V2.VimBindingE (\evs state -> case V2.vsMode state of
                                        V2.Insert _ ->
                                            fmap (const (y >> return V2.Continue))
                                                 (evs `V2.matchesString` x)
                                        _ -> V2.NoMatch)
            nmap'  x y = V2.mkStringBindingY V2.Normal (x, y, id)
        in [
             -- Tab traversal
             nmap  "<C-h>" previousTabE
           , nmap  "<C-l>" nextTabE
           , nmap  "<C-l>" nextTabE

             -- Press space to clear incremental search highlight
           , nmap  " " (eval ":nohlsearch<CR>")
           , ...
           ]

All the V2 is somewhat unnecessary.

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.


Newer post Older post