1{-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}
2{-# LANGUAGE BangPatterns, EmptyDataDecls #-}
19import Prelude hiding (String)
20import qualified Data.ByteString.Builder as B
21import qualified Data.Coerce as Coerce
22import qualified Data.Name as Name
23import qualified Data.Utf8 as Utf8
24import Data.Utf8 (MBA, newByteArray, copyFromPtr, freeze, writeWord8)
25import Data.Word (Word8)
26import Foreign.Ptr (Ptr, plusPtr, minusPtr)
27import Foreign.ForeignPtr (withForeignPtr)
28import GHC.Exts (RealWorld)
29import GHC.IO (stToIO, unsafeDupablePerformIO, unsafePerformIO)
32import qualified Parse.Primitives as P
39-- INVARIANT: any Json.String is appropriately escaped already
40-- PERF: is this the right representation for Json.String? Maybe ByteString instead?
49isEmpty :: String -> Bool
58fromPtr :: Ptr Word8 -> Ptr Word8 -> String
63fromChars :: [Char] -> String
68fromSnippet :: P.Snippet -> String
73fromName :: Name.Name -> String
82toChars :: String -> [Char]
87{-# INLINE toBuilder #-}
88toBuilder :: String -> B.Builder
97fromComment :: P.Snippet -> String
98fromComment (P.Snippet fptr off len _ _) =
99 unsafePerformIO $ withForeignPtr fptr $ \ptr ->
101 !pos = plusPtr ptr off
102 !end = plusPtr pos len
103 !str = fromChunks (chompChunks pos end pos [])
108chompChunks :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> [Chunk] -> [Chunk]
109chompChunks pos end start revChunks =
111 reverse (addSlice start end revChunks)
114 !word = P.unsafeIndex pos
117 0x0A {-\n-} -> chompEscape 0x6E {-n-} pos end start revChunks
118 0x22 {-"-} -> chompEscape 0x22 {-"-} pos end start revChunks
119 0x5C {-\-} -> chompEscape 0x5C {-\-} pos end start revChunks
122 !newPos = plusPtr pos 1
124 chompChunks newPos end newPos (addSlice start pos revChunks)
128 !width = P.getCharWidth word
129 !newPos = plusPtr pos width
131 chompChunks newPos end start revChunks
134chompEscape :: Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> [Chunk] -> [Chunk]
135chompEscape escape pos end start revChunks =
137 !pos1 = plusPtr pos 1
139 chompChunks pos1 end pos1 (Escape escape : addSlice start pos revChunks)
142addSlice :: Ptr Word8 -> Ptr Word8 -> [Chunk] -> [Chunk]
143addSlice start end revChunks =
146 else Slice start (minusPtr end start) : revChunks
154 = Slice (Ptr Word8) Int
158fromChunks :: [Chunk] -> String
160 unsafeDupablePerformIO (stToIO (
161 do let !len = sum (map chunkToWidth chunks)
162 mba <- newByteArray len
163 writeChunks mba 0 chunks
168chunkToWidth :: Chunk -> Int
175writeChunks :: MBA RealWorld -> Int -> [Chunk] -> ST RealWorld ()
176writeChunks mba offset chunks =
184 do copyFromPtr ptr mba offset len
185 let !newOffset = offset + len
186 writeChunks mba newOffset chunks
189 do writeWord8 mba offset 0x5C {- \ -}
190 writeWord8 mba (offset + 1) word
191 let !newOffset = offset + 2
192 writeChunks mba newOffset chunks
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list