@@ -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
@@ -29,11 +31,20 @@ let fns : List<BuiltInFn> =
2931 fn =
3032 ( function
3133 | _, _, [ DString sourceCode ] ->
32- // This was added to handle EGCs correctly
3334 let byteIndexToCharIndex ( byteIndex : int ) ( text : string ) : int =
3435 let bytes = Encoding.UTF8.GetBytes( text)
3536 let subText = Encoding.UTF8.GetString( bytes, 0 , byteIndex)
36- subText.Length
37+ StringInfo.ParseCombiningCharacters( subText). Length
38+
39+ let processLine ( line : string ) ( startIndex : int ) ( endIndex : int ) =
40+ let textElements = StringInfo.GetTextElementEnumerator( line)
41+ let mutable result = " "
42+ let mutable currentIndex = 0
43+ while textElements.MoveNext() do
44+ if currentIndex >= startIndex && currentIndex < endIndex then
45+ result <- result + ( textElements.GetTextElement())
46+ currentIndex <- currentIndex + 1
47+ result
3748
3849 let rec mapNodeAtCursor ( cursor : TreeCursor ) : Dval =
3950 let mutable children = []
@@ -48,8 +59,9 @@ let fns : List<BuiltInFn> =
4859
4960 let fields =
5061 let mapPoint ( point : Point ) =
62+ let pointRow = point.row + 1
5163 let fields =
52- [ " row" , DInt64 point.row ; " column" , DInt64 point.column ]
64+ [ " row" , DInt64 pointRow ; " column" , DInt64 point.column ]
5365 DRecord( pointTypeName, pointTypeName, [], Map fields)
5466
5567 let startPos = cursor.Current.StartPosition
@@ -59,26 +71,29 @@ let fns : List<BuiltInFn> =
5971 let fields = [ " start" , mapPoint startPos; " end_" , mapPoint endPos ]
6072 DRecord( rangeTypeName, rangeTypeName, [], Map fields)
6173
62- let startCharIndex = byteIndexToCharIndex startPos.column sourceCode
63- let endCharIndex = byteIndexToCharIndex endPos.column sourceCode
64-
6574 let sourceText =
6675 let lines = String.splitOnNewline sourceCode
6776 if lines.Length = 0 then
6877 " "
6978 else
79+ let startLine = lines[ startPos.row]
80+ let endLine = lines[ endPos.row]
81+ let startCharIndex = byteIndexToCharIndex startPos.column startLine
82+ let endCharIndex = byteIndexToCharIndex endPos.column endLine
83+
7084 match startPos.row with
7185 | row when row = endPos.row ->
72- lines [ row ][ startCharIndex .. ( endCharIndex - 1 )]
86+ processLine startLine startCharIndex endCharIndex
7387 | _ ->
74- let firstLine = lines[ startPos.row][ startCharIndex..]
88+ let firstLine =
89+ processLine startLine startCharIndex startLine.Length
7590 let middleLines =
7691 if startPos.row + 1 <= endPos.row - 1 then
7792 lines[ startPos.row + 1 .. endPos.row - 1 ]
93+ |> List.map ( fun line -> processLine line 0 line.Length)
7894 else
7995 []
80- let lastLine = lines[ endPos.row][.. ( endCharIndex - 1 )]
81-
96+ let lastLine = processLine endLine 0 endCharIndex
8297 String.concat " \n " ( firstLine :: middleLines @ [ lastLine ])
8398
8499 let fieldName =
0 commit comments