FAVK3BZP62D4KKDVNGX323UOVRPCW2NFLAHTVYBGQHRJSDI24XCQC WBKXA5RVL5DSEJZ4OBDBCTNRT3Q4VFEVQNA344CET3BHY7CY7H5AC R6L2TITEEB2XRNCTCGETAQ6UBYRMDKYL6TCPA3KVQTBCMPSN5ZJQC 6W6OJAUT3KLOXXKYR4GA3MG4ACLO2T4KX3SGD2KZDX6MYEZYTPHAC U45XPF3YKPXXRJ4MN24T2RV7GOL4FZKQSWX5P5I7WT4HC5XF4FHAC 5SFTBD4FW6GQPKRUJBAII5R2EZPDYG6CH57BIJD4IVZBE6JZB2ZQC GUD2J453E3UTRJZIEEUUJ3ZIGL72ETUXTO57XQIZ2Y3ZU3C2R55QC KFKFELOTH4NL4DMXXWJ36OK62HWNJ7JJTHWA76CYHWGTGXMRGYFQC A6E5SE5JPWUJJYIUS4CF7NMB5GM2SIIUXUZASSOVD467YWI5SCQQC TKAAHADV62OQORAO7MYRRRHTGPMG3GKXU4Z4MFNLAO6DLTSDU3CAC 32SDOYNGPOAAMEQMZLZUE3XE6D5CFSZU6M3JDRERUVPAB4TLZOOAC CNJGJCJZ6LRHHIRSRATSE3D3Z5OQGSSTDMXCPVXSKRQLYJFME6IAC ZL7ZSOEOGP2E24UEFC5VVPN5GTL3EUL34FA7F47WWWFPHJH2RS2AC name = "vie"version = "0.1.0"defaultTargets = ["vie"][[lean_lib]]name = "ViE"[[lean_exe]]name = "vie"root = "Main"[[lean_exe]]name = "test"root = "Test"[[lean_exe]]name = "bench"root = "Test.Benchmark"[[lean_lib]]name = "Test"buildType = "release"testDriver = "test"
"packages": [],"name": "editor",
"packages":[{"url": "https://github.com/4kusto/bliku","type": "git","subDir": null,"scope": "","rev": "2836947f0090b29b45b4f012db0a274fb2ac8aee","name": "bliku","manifestFile": "lake-manifest.json","inputRev": null,"inherited": false,"configFile": "lakefile.lean"}],"name": "vie",
def highlightLine (filename : Option String) (line : String) : Array Span :=match detectLanguage filename with| .plain => #[]| .lean => highlightLeanLine line| .markdown => highlightMarkdownLine line
abbrev highlightLine := Bliku.Tui.Syntax.highlightLine
structure Span wherestartByte : NatendByte : Natstyle : Stringderiving Repr, BEq, Inhabited
abbrev leanKeywordStyle := Bliku.Tui.Syntax.leanKeywordStyleabbrev leanCommentStyle := Bliku.Tui.Syntax.leanCommentStyleabbrev leanStringStyle := Bliku.Tui.Syntax.leanStringStyleabbrev leanNumberStyle := Bliku.Tui.Syntax.leanNumberStyle
def leanKeywordStyle : String := ViE.Color.toFg ViE.Color.Color.brightBluedef leanCommentStyle : String := ViE.Color.toFg ViE.Color.Color.brightBlackdef leanStringStyle : String := ViE.Color.toFg ViE.Color.Color.brightGreendef leanNumberStyle : String := ViE.Color.toFg ViE.Color.Color.brightMagenta
abbrev markdownHeadingStyle := Bliku.Tui.Syntax.markdownHeadingStyleabbrev markdownCodeStyle := Bliku.Tui.Syntax.markdownCodeStyleabbrev markdownLinkStyle := Bliku.Tui.Syntax.markdownLinkStyleabbrev markdownEmphasisStyle := Bliku.Tui.Syntax.markdownEmphasisStyle
def markdownHeadingStyle : String := ViE.Color.toFg ViE.Color.Color.brightCyandef markdownCodeStyle : String := ViE.Color.toFg ViE.Color.Color.brightYellowdef markdownLinkStyle : String := ViE.Color.toFg ViE.Color.Color.brightBluedef markdownEmphasisStyle : String := ViE.Color.toFg ViE.Color.Color.brightMagentadef detectLanguage (filename : Option String) : Language :=match filename with| none => .plain| some name =>if name.endsWith ".lean" then .leanelse if name.endsWith ".md" || name.endsWith ".markdown" then .markdownelse .plaindef styleForByteRange (spans : Array Span) (byteStart byteEnd : Nat) : Option String :=let rec loop (i : Nat) : Option String :=if i >= spans.size thennoneelselet s := spans[i]!if ViE.UI.overlapsByteRange (s.startByte, s.endByte) byteStart byteEnd thensome s.styleelseloop (i + 1)loop 0
abbrev detectLanguage := Bliku.Tui.Syntax.detectLanguageabbrev styleForByteRange := Bliku.Tui.Syntax.styleForByteRange
private def isMarkdownHeading (bytes : ByteArray) : Bool := Id.run dolet n := bytes.sizelet mut i := 0while i < n && bytes[i]! == 32 doi := i + 1if i >= n || bytes[i]! != 35 thenreturn falselet mut j := iwhile j < n && bytes[j]! == 35 doj := j + 1return j < n && bytes[j]! == 32private def isMarkdownFence (bytes : ByteArray) : Bool :=(bytes.size >= 3 && bytes[0]! == 96 && bytes[1]! == 96 && bytes[2]! == 96) ||(bytes.size >= 3 && bytes[0]! == 126 && bytes[1]! == 126 && bytes[2]! == 126)def highlightMarkdownLine (line : String) : Array Span := Id.run dolet bytes := line.toUTF8let n := bytes.sizeif isMarkdownHeading bytes thenreturn #[{ startByte := 0, endByte := n, style := markdownHeadingStyle }]if isMarkdownFence bytes thenreturn #[{ startByte := 0, endByte := n, style := markdownCodeStyle }]let mut spans : Array Span := #[]let mut i := 0while i < n doif bytes[i]! == 96 thenlet mut j := i + 1while j < n && bytes[j]! != 96 doj := j + 1if j < n thenspans := spans.push { startByte := i, endByte := j + 1, style := markdownCodeStyle }i := j + 1elsei := i + 1else if bytes[i]! == 91 thenlet mut j := i + 1while j < n && bytes[j]! != 93 doj := j + 1if j + 1 < n && bytes[j]! == 93 && bytes[j + 1]! == 40 thenlet mut k := j + 2while k < n && bytes[k]! != 41 dok := k + 1if k < n thenspans := spans.push { startByte := i, endByte := k + 1, style := markdownLinkStyle }i := k + 1elsei := i + 1elsei := i + 1else if bytes[i]! == 42 || bytes[i]! == 95 thenlet delim := bytes[i]!let mut j := i + 1while j < n && bytes[j]! != delim doj := j + 1if j < n && j > i + 1 thenspans := spans.push { startByte := i, endByte := j + 1, style := markdownEmphasisStyle }i := j + 1elsei := i + 1elsei := i + 1return spans
abbrev highlightMarkdownLine := Bliku.Tui.Syntax.highlightMarkdownLine
private def isAsciiLower (n : Nat) : Bool := 97 <= n && n <= 122private def isAsciiUpper (n : Nat) : Bool := 65 <= n && n <= 90private def isAsciiDigit (n : Nat) : Bool := 48 <= n && n <= 57private def isIdentStart (b : UInt8) : Bool :=let n := b.toNatisAsciiLower n || isAsciiUpper n || n == 95private def isIdentCont (b : UInt8) : Bool :=let n := b.toNatisIdentStart b || isAsciiDigit n || n == 39private def leanKeywords : Array String := #["abbrev", "axiom", "by", "class", "constant", "def", "deriving", "do","else", "end", "example", "from", "have", "if", "import", "in", "inductive","instance", "let", "match", "mutual", "namespace", "open", "opaque", "private","protected", "set_option", "show", "structure", "syntax", "termination_by","theorem", "unsafe", "variable", "where", "with"]
while i < n dolet b := bytes[i]!if b == 34 thenlet mut j := i + 1let mut escaped := falselet mut closed := falsewhile j < n && !closed dolet c := bytes[j]!if escaped thenescaped := falsej := j + 1else if c == 92 thenescaped := truej := j + 1else if c == 34 thenclosed := truej := j + 1elsej := j + 1spans := spans.push { startByte := i, endByte := j, style := leanStringStyle }i := jelse if i + 1 < n && bytes[i]! == 45 && bytes[i + 1]! == 45 thenspans := spans.push { startByte := i, endByte := n, style := leanCommentStyle }i := nelse if i + 1 < n && bytes[i]! == 47 && bytes[i + 1]! == 45 thenspans := spans.push { startByte := i, endByte := n, style := leanCommentStyle }i := nelse if isAsciiDigit b.toNat thenlet mut j := i + 1while j < n dolet c := bytes[j]!.toNatif isAsciiDigit c || c == 95 || c == 46 || c == 120 || c == 111 || c == 98 ||(65 <= c && c <= 70) || (97 <= c && c <= 102) thenj := j + 1elsebreakspans := spans.push { startByte := i, endByte := j, style := leanNumberStyle }i := jelse if isIdentStart b thenlet mut j := i + 1while j < n && isIdentCont (bytes[j]!) doj := j + 1let tok := String.fromUTF8! (bytes.extract i j)if leanKeywords.contains tok thenspans := spans.push { startByte := i, endByte := j, style := leanKeywordStyle }i := jelsei := i + 1return spans
/-- Find all occurrences of a byte pattern within a byte array. -/def findAllMatchesBytes (haystack : ByteArray) (needle : ByteArray) : Array (Nat × Nat) := Id.run dolet n := needle.sizelet h := haystack.sizeif n == 0 || h < n thenreturn #[]
abbrev findAllMatchesBytes := Bliku.Tui.findAllMatchesBytesabbrev overlapsByteRange := Bliku.Tui.overlapsByteRangeabbrev activeMatchRange := Bliku.Tui.activeMatchRange
let limit := h - n + 1let mut out : Array (Nat × Nat) := #[]for i in [0:limit] dolet mut matched := truefor j in [0:n] doif matched && haystack[i + j]! != needle[j]! thenmatched := falseif matched thenout := out.push (i, i + n)return outdef overlapsByteRange (r : Nat × Nat) (byteStart byteEnd : Nat) : Bool :=let (s, e) := rbyteStart < e && byteEnd > sdef activeMatchRange (hitRanges : Array (Nat × Nat)) (cursorByte : Option Nat) : Option (Nat × Nat) :=match cursorByte with| none => none| some cb =>let rec loop (i : Nat) : Option (Nat × Nat) :=if i >= hitRanges.size thennoneelselet m := hitRanges[i]!let (s, e) := mif s <= cb && cb < e thensome melseloop (i + 1)loop 0
/-- Pad a string on the left with spaces until it reaches the given width. -/def leftPad (s : String) (width : Nat) : String :=if s.length >= width then selse "".pushn ' ' (width - s.length) ++ sstructure Rect whererow : Natcol : Natheight : Natwidth : Natderiving Inhabited
abbrev leftPad := Bliku.Tui.leftPadabbrev Rect := Bliku.Tui.Rect