summaryrefslogtreecommitdiff
path: root/src/HStyle/Block.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/HStyle/Block.hs')
-rw-r--r--src/HStyle/Block.hs64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/HStyle/Block.hs b/src/HStyle/Block.hs
new file mode 100644
index 0000000..2fe38a2
--- /dev/null
+++ b/src/HStyle/Block.hs
@@ -0,0 +1,64 @@
+-- | A block of code
+{-# LANGUAGE OverloadedStrings #-}
+module HStyle.Block
+ ( Block
+ , fromText
+ , prettyBlock
+ , toLines
+ , subBlock
+ , perLine
+ , absoluteLineNumber
+ ) where
+
+import Data.Text (Text)
+import Data.Vector (Vector)
+import qualified Data.Vector as V
+import qualified Data.Text as T
+
+data Block = Block
+ { blockOffset :: Int
+ , blockLines :: Vector Text
+ } deriving (Show)
+
+fromText :: Text -> Block
+fromText text = Block
+ { blockOffset = 0
+ , blockLines = V.fromList $ T.lines text
+ }
+
+prettyBlock :: Int -> Block -> Text
+prettyBlock indent block = T.unlines $
+ map ((T.replicate indent " " `T.append`) . pretty) $
+ zip [offset + 1 ..] $ V.toList lines'
+ where
+ offset = blockOffset block
+ lines' = blockLines block
+ width = length $ show (offset + V.length lines')
+
+ pretty (ln, t) =
+ let ln' = T.pack (show ln)
+ lnl = T.length ln'
+ in T.replicate (width - lnl) " " `T.append`
+ ln' `T.append` " " `T.append` t
+
+toLines :: Block -> [Text]
+toLines = V.toList . blockLines
+
+-- | Subblock from start to end -- including both.
+subBlock :: Int -> Int -> Block -> Block
+subBlock start end block = Block
+ { blockOffset = blockOffset block + start - 1
+ , blockLines = V.slice (start - 1) (end - start + 1) $ blockLines block
+ }
+
+-- | Create a new block for every line.
+perLine :: Block -> [Block]
+perLine (Block offset lines') = map line $
+ zip [offset + 0 ..] $ V.toList lines'
+ where
+ line (i, t) = Block i $ V.singleton t
+
+-- | Convert relative line number (within this block, 1-based) to an absolute
+-- line number
+absoluteLineNumber :: Int -> Block -> Int
+absoluteLineNumber i = (+ i) . blockOffset