{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PackageImports #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Yi.Rectangle where
import Control.Monad (forM_)
import Data.List (sort, transpose)
import Data.Monoid ((<>))
import qualified Data.Text as T (Text, concat, justifyLeft, length)
import Yi.Buffer
import Yi.Editor (EditorM, getRegE, setRegE, withCurrentBuffer)
import qualified Yi.Rope as R
import Yi.String (lines', mapLines, unlines')
getRectangle :: BufferM (Region, Int, Int)
getRectangle :: BufferM (Region, Int, Int)
getRectangle = do
Region
r <- BufferM Region
getSelectRegionB
Region
extR <- TextUnit -> Region -> BufferM Region
unitWiseRegion TextUnit
Line Region
r
[Int
lowCol,Int
highCol] <- [Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort ([Int] -> [Int]) -> BufferM [Int] -> BufferM [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Point -> BufferM Int) -> [Point] -> BufferM [Int]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Point -> BufferM Int
colOf [Region -> Point
regionStart Region
r, Region -> Point
regionEnd Region
r]
(Region, Int, Int) -> BufferM (Region, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Region
extR, Int
lowCol, Int
highCol)
multiSplit :: [Int] -> R.YiString -> [R.YiString]
multiSplit :: [Int] -> YiString -> [YiString]
multiSplit [] YiString
l = [YiString
l]
multiSplit (Int
x:[Int]
xs) YiString
l = YiString
left YiString -> [YiString] -> [YiString]
forall a. a -> [a] -> [a]
: [Int] -> YiString -> [YiString]
multiSplit ((Int -> Int) -> [Int] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract Int
x) [Int]
xs) YiString
right
where (YiString
left, YiString
right) = Int -> YiString -> (YiString, YiString)
R.splitAt Int
x YiString
l
onRectangle :: (Int -> Int -> R.YiString -> R.YiString) -> BufferM ()
onRectangle :: (Int -> Int -> YiString -> YiString) -> BufferM ()
onRectangle Int -> Int -> YiString -> YiString
f = do
(Region
reg, Int
l, Int
r) <- BufferM (Region, Int, Int)
getRectangle
(YiString -> YiString) -> Region -> BufferM ()
modifyRegionB ((YiString -> YiString) -> YiString -> YiString
mapLines (Int -> Int -> YiString -> YiString
f Int
l Int
r)) Region
reg
openRectangle :: BufferM ()
openRectangle :: BufferM ()
openRectangle = (Int -> Int -> YiString -> YiString) -> BufferM ()
onRectangle Int -> Int -> YiString -> YiString
openLine
where
openLine :: Int -> Int -> YiString -> YiString
openLine Int
l Int
r YiString
line =
YiString
left YiString -> YiString -> YiString
forall a. Semigroup a => a -> a -> a
<> Int -> Char -> YiString
R.replicateChar (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l) Char
' ' YiString -> YiString -> YiString
forall a. Semigroup a => a -> a -> a
<> YiString
right
where (YiString
left, YiString
right) = Int -> YiString -> (YiString, YiString)
R.splitAt Int
l YiString
line
stringRectangle :: R.YiString -> BufferM ()
stringRectangle :: YiString -> BufferM ()
stringRectangle YiString
inserted = (Int -> Int -> YiString -> YiString) -> BufferM ()
onRectangle Int -> Int -> YiString -> YiString
stringLine
where stringLine :: Int -> Int -> YiString -> YiString
stringLine Int
l Int
r YiString
line = YiString
left YiString -> YiString -> YiString
forall a. Semigroup a => a -> a -> a
<> YiString
inserted YiString -> YiString -> YiString
forall a. Semigroup a => a -> a -> a
<> YiString
right
where [YiString
left,YiString
_,YiString
right] = [Int] -> YiString -> [YiString]
multiSplit [Int
l,Int
r] YiString
line
killRectangle :: EditorM ()
killRectangle :: EditorM ()
killRectangle = do
[YiString]
cutted <- BufferM [YiString] -> EditorM [YiString]
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM [YiString] -> EditorM [YiString])
-> BufferM [YiString] -> EditorM [YiString]
forall a b. (a -> b) -> a -> b
$ do
(Region
reg, Int
l, Int
r) <- BufferM (Region, Int, Int)
getRectangle
YiString
text <- Region -> BufferM YiString
readRegionB Region
reg
let ([YiString]
cutted, [YiString]
rest) = [(YiString, YiString)] -> ([YiString], [YiString])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(YiString, YiString)] -> ([YiString], [YiString]))
-> [(YiString, YiString)] -> ([YiString], [YiString])
forall a b. (a -> b) -> a -> b
$ (YiString -> (YiString, YiString))
-> [YiString] -> [(YiString, YiString)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap YiString -> (YiString, YiString)
cut ([YiString] -> [(YiString, YiString)])
-> [YiString] -> [(YiString, YiString)]
forall a b. (a -> b) -> a -> b
$ YiString -> [YiString]
R.lines' YiString
text
cut :: R.YiString -> (R.YiString, R.YiString)
cut :: YiString -> (YiString, YiString)
cut YiString
line = let [YiString
left,YiString
mid,YiString
right] = [Int] -> YiString -> [YiString]
multiSplit [Int
l,Int
r] YiString
line
in (YiString
mid, YiString
left YiString -> YiString -> YiString
forall a. Semigroup a => a -> a -> a
<> YiString
right)
Region -> YiString -> BufferM ()
replaceRegionB Region
reg ([YiString] -> YiString
R.unlines [YiString]
rest)
[YiString] -> BufferM [YiString]
forall (m :: * -> *) a. Monad m => a -> m a
return [YiString]
cutted
YiString -> EditorM ()
setRegE ([YiString] -> YiString
R.unlines [YiString]
cutted)
yankRectangle :: EditorM ()
yankRectangle :: EditorM ()
yankRectangle = do
[YiString]
text <- YiString -> [YiString]
R.lines' (YiString -> [YiString]) -> EditorM YiString -> EditorM [YiString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EditorM YiString
getRegE
BufferM () -> EditorM ()
forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
withCurrentBuffer (BufferM () -> EditorM ()) -> BufferM () -> EditorM ()
forall a b. (a -> b) -> a -> b
$ [YiString] -> (YiString -> BufferM ()) -> BufferM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [YiString]
text ((YiString -> BufferM ()) -> BufferM ())
-> (YiString -> BufferM ()) -> BufferM ()
forall a b. (a -> b) -> a -> b
$ \YiString
t -> do
BufferM () -> BufferM ()
forall a. BufferM a -> BufferM a
savingPointB (BufferM () -> BufferM ()) -> BufferM () -> BufferM ()
forall a b. (a -> b) -> a -> b
$ YiString -> BufferM ()
insertN YiString
t
BufferM ()
lineDown