ndow :: MonadEditor m
    => Window -> BufferRef -> BufferM a -> m a
withGivenBufferAndWindow w k f = withEditor $ do
  accum <- asks configKillringAccumulate
  let edit e = let b = findBufferWith k e
                   (v, us, b') = runBufferFull w b f
               in (e & buffersA .~ mapAdjust' (const b') k (buffers e)
                     & killringA %~
                        if accum && all updateIsDelete us
                        then foldl (.) id $ reverse [ krPut dir s
                                                    | Delete _ dir s <- us ]
                        else id

                  , (us, v))
  (us, v) <- getsAndModify edit

  updHandler <- return . bufferUpdateHandler =<< ask
  unless (null us || null updHandler) $
    forM_ updHandler (\h -> withGivenBufferAndWindow w k (h us))
  return v

-- | Perform action with current window's buffer
withCurrentBuffer :
withGivenBufferAndWindow :: MonadEditor m
    => Window -> BufferRef -> BufferM a -> m a
withGivenBufferAndWindow w k f = withEditor $ do
  accum <- asks configKillringAccumulate
  let edit e = let b = findBufferWith k e
                   (v, us, b') = runBufferFull w b f
               in (e & buffersA .~ mapAdjust' (const b') k (buffers e)
                     & killringA %~
                        if accum && all updateIsDelete us
                        then foldl (.) id $ reverse [ krPut dir s
                                                    | Delete _ dir s <- us ]
                        else id

                  , (us, v))
  (us, v) <- getsAndModify edit

  updHandler <- return . bufferUpdateHandler =<< ask
  unless (null us || null updHandler) $
    forM_ updHandler (\h -> withGivenBufferAndWindow w k (h us))
  return v

-- | Perform action with current window's buffer
withGivenBufferAndWindow w k f = withEditor $ do
  accum <- asks configKillringAccumulate
  let edit e = let b = findBufferWith k e
                   (v, us, b') = runBufferFull w b f
               in (e & buffersA .~ mapAdjust' (const b') k (buffers e)
                     & killringA %~
                        if accum && all updateIsDelete us
                        then foldl (.) id $ reverse [ krPut dir s
                                                    | Delete _ dir s <- us ]
                        else id

                  , (us, v))
  (us, v) <- getsAndModify edit

  updHandler <- return . bufferUpdateHandler =<< ask
  unless (null us || null updHandler) $
    forM_ updHandler (\h -> withGivenBufferAndWindow w k (h us))
  return v

-- | Perform action with current window's buffer