@@ -3,6 +3,8 @@ module BuiltinExecution.Libs.Parser
33open FSharp.Control .Tasks
44open System.Threading .Tasks
55open System.Text
6+ open System.Globalization
7+ open System
68
79open Prelude
810open LibExecution.RuntimeTypes
@@ -33,7 +35,21 @@ let fns : List<BuiltInFn> =
3335 let byteIndexToCharIndex ( byteIndex : int ) ( text : string ) : int =
3436 let bytes = Encoding.UTF8.GetBytes( text)
3537 let subText = Encoding.UTF8.GetString( bytes, 0 , byteIndex)
36- subText.Length
38+ StringInfo.ParseCombiningCharacters( subText). Length
39+
40+ let getUnicodeAwareSubstring
41+ ( line : string )
42+ ( startIndex : int )
43+ ( endIndex : int )
44+ =
45+ let textElements = StringInfo.GetTextElementEnumerator( line)
46+ let mutable result = " "
47+ let mutable currentIndex = 0
48+ while textElements.MoveNext() do
49+ if currentIndex >= startIndex && currentIndex < endIndex then
50+ result <- result + ( textElements.GetTextElement())
51+ currentIndex <- currentIndex + 1
52+ result
3753
3854 let rec mapNodeAtCursor ( cursor : TreeCursor ) : Dval =
3955 let mutable children = []
@@ -48,8 +64,9 @@ let fns : List<BuiltInFn> =
4864
4965 let fields =
5066 let mapPoint ( point : Point ) =
67+ let pointRow = point.row + 1
5168 let fields =
52- [ " row" , DInt64 point.row ; " column" , DInt64 point.column ]
69+ [ " row" , DInt64 pointRow ; " column" , DInt64 point.column ]
5370 DRecord( pointTypeName, pointTypeName, [], Map fields)
5471
5572 let startPos = cursor.Current.StartPosition
@@ -59,26 +76,33 @@ let fns : List<BuiltInFn> =
5976 let fields = [ " start" , mapPoint startPos; " end_" , mapPoint endPos ]
6077 DRecord( rangeTypeName, rangeTypeName, [], Map fields)
6178
62- let startCharIndex = byteIndexToCharIndex startPos.column sourceCode
63- let endCharIndex = byteIndexToCharIndex endPos.column sourceCode
64-
6579 let sourceText =
6680 let lines = String.splitOnNewline sourceCode
6781 if lines.Length = 0 then
6882 " "
6983 else
84+ let startLine = lines[ startPos.row]
85+ let endLine = lines[ endPos.row]
86+ let startCharIndex = byteIndexToCharIndex startPos.column startLine
87+ let endCharIndex = byteIndexToCharIndex endPos.column endLine
88+
7089 match startPos.row with
7190 | row when row = endPos.row ->
72- lines [ row ][ startCharIndex .. ( endCharIndex - 1 )]
91+ getUnicodeAwareSubstring startLine startCharIndex endCharIndex
7392 | _ ->
74- let firstLine = lines[ startPos.row][ startCharIndex..]
93+ let firstLine =
94+ getUnicodeAwareSubstring
95+ startLine
96+ startCharIndex
97+ startLine.Length
7598 let middleLines =
7699 if startPos.row + 1 <= endPos.row - 1 then
77100 lines[ startPos.row + 1 .. endPos.row - 1 ]
101+ |> List.map ( fun line ->
102+ getUnicodeAwareSubstring line 0 line.Length)
78103 else
79104 []
80- let lastLine = lines[ endPos.row][.. ( endCharIndex - 1 )]
81-
105+ let lastLine = getUnicodeAwareSubstring endLine 0 endCharIndex
82106 String.concat " \n " ( firstLine :: middleLines @ [ lastLine ])
83107
84108 let fieldName =
0 commit comments