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 0x27 {-'-} -> chompEscape 0x27 {-'-} pos end start revChunks
120 0x5C {-\-} -> chompEscape 0x5C {-\-} pos end start revChunks
123 !newPos = plusPtr pos 1
125 chompChunks newPos end newPos (addSlice start pos revChunks)
129 !width = P.getCharWidth word
130 !newPos = plusPtr pos width
132 chompChunks newPos end start revChunks
135chompEscape :: Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> [Chunk] -> [Chunk]
136chompEscape escape pos end start revChunks =
138 !pos1 = plusPtr pos 1
140 chompChunks pos1 end pos1 (Escape escape : addSlice start pos revChunks)
143addSlice :: Ptr Word8 -> Ptr Word8 -> [Chunk] -> [Chunk]
144addSlice start end revChunks =
147 else Slice start (minusPtr end start) : revChunks
155 = Slice (Ptr Word8) Int
159fromChunks :: [Chunk] -> String
161 unsafeDupablePerformIO (stToIO (
162 do let !len = sum (map chunkToWidth chunks)
163 mba <- newByteArray len
164 writeChunks mba 0 chunks
169chunkToWidth :: Chunk -> Int
176writeChunks :: MBA RealWorld -> Int -> [Chunk] -> ST RealWorld ()
177writeChunks mba offset chunks =
185 do copyFromPtr ptr mba offset len
186 let !newOffset = offset + len
187 writeChunks mba newOffset chunks
190 do writeWord8 mba offset 0x5C {- \ -}
191 writeWord8 mba (offset + 1) word
192 let !newOffset = offset + 2
193 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