module Yi.Keymap.Emacs.KillRing where
import Control.Lens (assign, use, uses, (%=), (.=))
import Control.Monad (replicateM_, when)
import Data.List.NonEmpty (NonEmpty ((:|)))
import Data.Maybe (fromMaybe)
import Yi.Buffer
import Yi.Editor (EditorM, killringA, withCurrentBuffer)
import Yi.Keymap (YiM)
import Yi.KillRing (Killring (_krContents), krKilled, krPut)
import qualified Yi.Rope as R (YiString, fromString, toString)
import Yi.Types (withEditor)
import Yi.Utils (io)
import System.Hclip (getClipboard, setClipboard)
clipboardToKillring :: YiM ()
clipboardToKillring = do
text <- fmap R.fromString $ io getClipboard
withEditor $ do
text' <- killringGet
when (text' /= text) $ killringPut Forward text
killringToClipboard :: YiM ()
killringToClipboard = do
text <- withEditor killringGet
io . setClipboard $ R.toString text
killRegionB :: BufferM ()
killRegionB = getSelectRegionB >>= \r ->
if regionStart r == regionEnd r then bkillWordB else deleteRegionB r
killRegion :: YiM ()
killRegion = withCurrentBuffer killRegionB >> killringToClipboard
killLineB :: Maybe Int -> BufferM ()
killLineB mbr = replicateM_ (fromMaybe 1 mbr) $ do
eol <- atEol
let tu = if eol then Character else Line
deleteRegionB =<< regionOfPartNonEmptyB tu Forward
killLine :: Maybe Int -> YiM ()
killLine mbr = withCurrentBuffer (killLineB mbr) >> killringToClipboard
killringGet :: EditorM R.YiString
killringGet = do
text :| _ <- uses killringA _krContents
return text
killringPut :: Direction -> R.YiString -> EditorM ()
killringPut dir s = killringA %= krPut dir s
yankE :: EditorM ()
yankE = do
text :| _ <- uses killringA _krContents
withCurrentBuffer $ pointB >>= setSelectionMarkPointB >> insertN text
yank :: YiM ()
yank = clipboardToKillring >> withEditor yankE
killRingSaveE :: EditorM ()
killRingSaveE = do
(r, text) <- withCurrentBuffer $ do
r <- getSelectRegionB
text <- readRegionB r
assign highlightSelectionA False
return (r, text)
killringPut (regionDirection r) text
killRingSave :: YiM ()
killRingSave = withEditor killRingSaveE >> killringToClipboard
yankPopE :: EditorM ()
yankPopE = do
kr <- use killringA
withCurrentBuffer (deleteRegionB =<< getRawestSelectRegionB)
killringA .= let x :| xs = _krContents kr
in kr { _krContents = case xs of
[] -> x :| []
y:ys -> y :| ys ++ [x]
}
yankE
appendNextKillE :: EditorM ()
appendNextKillE = killringA . krKilled .= True