Comment-region Yi example

Let’s make yi do k3wl stuff!

Comment region

The emacs ‘comment-region’ function prepends each line the region with a comment character, such as ‘#’ for perl. Let’s recreate a simple commentRegion function in yi. Edit your ~/.yi/YiConfig.hs file by adding the following code:

commentRegionB :: BufferM ()
commentRegionB = do 
  mark <- getSelectionMarkPointB
  p <- pointB
  let region = mkRegion mark p
  text <- readRegionB region
  let newText = unlines $ map ("# " ++ ) $ lines text
  replaceRegionB region newText

Also, remember to add it to the export list on the first line of the file, and then run M-x reconfigE. Now you can select a region (ctrl-space to set mark) and then do M-x commentRegionB.

The getSelectionMarkPointB and pointB function have type “BufferM Int”. In other words, they (potentially) modify a buffers state and yield an integer. Next, readRegionB has type “BufferM String” so it yields a string. We munge the string with some non-monadic haskell, and use replaceRegionB to update the buffer.

What did this function achieve? We’ve plumbed together various buffer-updating monads and standard haskell functions to create a compound BufferM action which, when executed, will modify the current buffer’s state to comment out the region.

So there was a caveat there: “when executed”. Who actually ‘runs’ this recipe? We’ll worry about that some other time. For now, it’s enough to know that you can ‘run’ these from within Yi by calling them via “M-x whatever”.

Before we move on, let’s refactor the code a bit to separate out useful functions.

currentRegionB :: BufferM Region
currentRegionB = do
  mark &lt;- getSelectionMarkPointB
  p &lt;- pointB
  return $ mkRegion mark p

mapCurrentRegionB :: (String -> String) -> BufferM ()
mapCurrentRegionB f = do
  region &lt;- currentRegionB
  readRegionB region >>= replaceRegionB region . f

commentRegionB :: BufferM ()
commentRegionB = do 
  mapCurrentRegionB (unlines . map ("# " ++) . lines)

Now let’s move on to a slightly more complex example which involves the IO monad.

Back to hello world, up to the index, or onwards to diary example.