@@ -3,6 +3,8 @@ module BuiltinExecution.Libs.Parser
3
3
open FSharp.Control .Tasks
4
4
open System.Threading .Tasks
5
5
open System.Text
6
+ open System.Globalization
7
+ open System
6
8
7
9
open Prelude
8
10
open LibExecution.RuntimeTypes
@@ -33,7 +35,21 @@ let fns : List<BuiltInFn> =
33
35
let byteIndexToCharIndex ( byteIndex : int ) ( text : string ) : int =
34
36
let bytes = Encoding.UTF8.GetBytes( text)
35
37
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
37
53
38
54
let rec mapNodeAtCursor ( cursor : TreeCursor ) : Dval =
39
55
let mutable children = []
@@ -48,8 +64,9 @@ let fns : List<BuiltInFn> =
48
64
49
65
let fields =
50
66
let mapPoint ( point : Point ) =
67
+ let pointRow = point.row + 1
51
68
let fields =
52
- [ " row" , DInt64 point.row ; " column" , DInt64 point.column ]
69
+ [ " row" , DInt64 pointRow ; " column" , DInt64 point.column ]
53
70
DRecord( pointTypeName, pointTypeName, [], Map fields)
54
71
55
72
let startPos = cursor.Current.StartPosition
@@ -59,26 +76,33 @@ let fns : List<BuiltInFn> =
59
76
let fields = [ " start" , mapPoint startPos; " end_" , mapPoint endPos ]
60
77
DRecord( rangeTypeName, rangeTypeName, [], Map fields)
61
78
62
- let startCharIndex = byteIndexToCharIndex startPos.column sourceCode
63
- let endCharIndex = byteIndexToCharIndex endPos.column sourceCode
64
-
65
79
let sourceText =
66
80
let lines = String.splitOnNewline sourceCode
67
81
if lines.Length = 0 then
68
82
" "
69
83
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
+
70
89
match startPos.row with
71
90
| row when row = endPos.row ->
72
- lines [ row ][ startCharIndex .. ( endCharIndex - 1 )]
91
+ getUnicodeAwareSubstring startLine startCharIndex endCharIndex
73
92
| _ ->
74
- let firstLine = lines[ startPos.row][ startCharIndex..]
93
+ let firstLine =
94
+ getUnicodeAwareSubstring
95
+ startLine
96
+ startCharIndex
97
+ startLine.Length
75
98
let middleLines =
76
99
if startPos.row + 1 <= endPos.row - 1 then
77
100
lines[ startPos.row + 1 .. endPos.row - 1 ]
101
+ |> List.map ( fun line ->
102
+ getUnicodeAwareSubstring line 0 line.Length)
78
103
else
79
104
[]
80
- let lastLine = lines[ endPos.row][.. ( endCharIndex - 1 )]
81
-
105
+ let lastLine = getUnicodeAwareSubstring endLine 0 endCharIndex
82
106
String.concat " \n " ( firstLine :: middleLines @ [ lastLine ])
83
107
84
108
let fieldName =
0 commit comments