P5BP2TLBQTAEP5EDP3YX2ZE5NJJ74DG47PCOSPPMRUELA7SDPX5QC 6W6OJAUT3KLOXXKYR4GA3MG4ACLO2T4KX3SGD2KZDX6MYEZYTPHAC 5SFTBD4FW6GQPKRUJBAII5R2EZPDYG6CH57BIJD4IVZBE6JZB2ZQC XCVPXP4UBFU25NF6VQC3MEYHHH45RL2UXM5TA6O23NA64FPCCCJQC CNJGJCJZ6LRHHIRSRATSE3D3Z5OQGSSTDMXCPVXSKRQLYJFME6IAC KJLCU4X5Z3CZM4AORMWIKOPBWPVTDMLK4LYH7UXBJFUGL7AUQCSQC TIAIRD7L5GWH22TOLDAGCIDCJDZ53YWK3KHQOH3EIU7RZEOEP32AC A6E5SE5JPWUJJYIUS4CF7NMB5GM2SIIUXUZASSOVD467YWI5SCQQC WBKXA5RVL5DSEJZ4OBDBCTNRT3Q4VFEVQNA344CET3BHY7CY7H5AC LSCUXT3235I5ZZPZM2MMGLECHU2LAX2TKLRHDULONDAS5JEWTB7QC WXZC34LZCQADXI3LEPDFDWHCVKYDC54WPCVYSUN3XSABH4VRHVJAC BVKFLEK2IK7AOIXLU3KGN7XNWP7KSJLGOPJKJIR7MU4LGN4J5EGQC | .left => if c' > bc then some p else some acc.get!| .right => if c' < bc then some p else some acc.get!| .up => if r' > br then some p else some acc.get!| .down => if r' < br then some p else some acc.get!
| .left => if c' > bc then some p else acc| .right => if c' < bc then some p else acc| .up => if r' > br then some p else acc| .down => if r' < br then some p else acc
def PieceTable.fromByteArray (bytes : ByteArray) (buildLeafBits : Bool := true) (buildOnEdit : Bool := false) : PieceTable :=
def PieceTable.fromByteArray (bytes : ByteArray) (buildLeafBits : Bool := true) (buildOnEdit : Bool := false) (threshold : Nat := 524288) : PieceTable :=
original := bytes, addBuffers := #[], tree := PieceTree.empty, bloomBuildLeafBits := buildLeafBits, bloomBuildOnEdit := true,
original := bytes, addBuffers := #[], tree := PieceTree.empty, bloomBuildLeafBits := buildLeafBits, bloomBuildOnEdit := buildLeafBits && bytes.size < threshold,
def PieceTable.fromString (s : String) (buildLeafBits : Bool := true) (buildOnEdit : Bool := false) : PieceTable :=PieceTable.fromByteArray s.toUTF8 buildLeafBits buildOnEdit
def PieceTable.fromString (s : String) (buildLeafBits : Bool := true) (buildOnEdit : Bool := false) (threshold : Nat := 524288) : PieceTable :=PieceTable.fromByteArray s.toUTF8 buildLeafBits buildOnEdit thresholddef PieceTable.rebuildBlooms (pt : PieceTable) : PieceTable :={ pt with tree := PieceTree.rebuildBloomsForTree pt.tree pt }
Id.run dolet mut cumBytes : Array UInt64 := #[0]let mut cumLines : Array UInt64 := #[0]let mut cumChars : Array UInt64 := #[0]for i in [0:children.size] dolet child := children[i]!
let (cumBytes, cumLines, cumChars) := children.foldl(fun (cb, cl, cc) child =>
let prevBytes := cumBytes.back!let prevLines := cumLines.back!let prevChars := cumChars.back!cumBytes := cumBytes.push (prevBytes + s.bytes)cumLines := cumLines.push (prevLines + s.lines)cumChars := cumChars.push (prevChars + s.chars)return {cumulativeBytes := cumBytes,cumulativeLines := cumLines,cumulativeChars := cumChars}
def buildBloomForChildren (children : Array ViE.PieceTree) : ViE.SearchBloom := Id.run doif children.isEmpty thenreturn ViE.SearchBloom.emptylet mut acc := searchMetaOf children[0]!for i in [1:children.size] doacc := combineBloom acc (searchMetaOf children[i]!)return acc
def buildBloomForChildren (children : Array ViE.PieceTree) : ViE.SearchBloom :=match children[0]? with| none => ViE.SearchBloom.empty| some first =>(children.extract 1 children.size).foldl(fun acc child => combineBloom acc (searchMetaOf child))(searchMetaOf first)
def patternTrigramHashes (pattern : ByteArray) : Array (Nat × Nat) := Id.run doif pattern.size < 3 thenreturn #[]let arr := pattern.datalet limit := pattern.size - 2let mut hashes : Array (Nat × Nat) := #[]for i in [0:limit] dolet b0 := arr[i]!let b1 := arr[i + 1]!let b2 := arr[i + 2]!hashes := hashes.push (hash1 b0 b1 b2, hash2 b0 b1 b2)return hashes
def patternTrigramHashes (pattern : ByteArray) : Array (Nat × Nat) :=if pattern.size < 3 then #[]elselet arr := pattern.data(Array.range (pattern.size - 2)).map fun i =>(hash1 arr[i]! arr[i + 1]! arr[i + 2]!, hash2 arr[i]! arr[i + 1]! arr[i + 2]!)
/-- Traverse the tree and rebuild bloom bits for every leaf node.Used by :bloom on-demand build for files that exceeded the load-time threshold. -/partial def rebuildBloomsForTree (t : ViE.PieceTree) (pt : ViE.PieceTable) : ViE.PieceTree :=let buildPt := { pt with bloomBuildLeafBits := true, bloomBuildOnEdit := true }match t with| ViE.PieceTree.empty => ViE.PieceTree.empty| ViE.PieceTree.leaf pieces s _ =>ViE.PieceTree.leaf pieces s (buildBloomForPieces pieces buildPt)| ViE.PieceTree.internal children s _ im =>let newChildren := children.map (rebuildBloomsForTree · pt)ViE.PieceTree.internal newChildren s (buildBloomForChildren newChildren) im
let s' := ViE.startOrUpdateSearch state pattern direction true
let state' :=if state.config.searchBloomBuildLeafBits thenlet activeBuf := state.getActiveBufferif !(ViE.PieceTree.searchMetaOf activeBuf.table.tree).hasBits thenstate.updateActiveBuffer fun buf => { buf with table := buf.table.rebuildBlooms }else stateelse statelet s' := ViE.startOrUpdateSearch state' pattern direction true
let buffers := ws.buffers.filter (fun b => b.filename.isSome)
-- Exclude virtual buffers (explorer/preview) so they are not treated as real files on restore.let buffers := ws.buffers.filter (fun b =>match b.filename with| some fname => !fname.startsWith "explorer://" && !fname.startsWith "preview://"| none => false)
content := content ++ b.filename.get! ++ "\n"if b.id == activeBuffer.id thenlet cursor := state.getCursorcontent := content ++ s!"{cursor.row} {cursor.col}\n"elsecontent := content ++ "0 0\n"
if let some fname := b.filename thencontent := content ++ fname ++ "\n"if b.id == activeBuffer.id thenlet cursor := state.getCursorcontent := content ++ s!"{cursor.row} {cursor.col}\n"elsecontent := content ++ "0 0\n"