@@ -1151,7 +1151,7 @@ defmodule Code.Fragment do
1151
1151
{ rev_tokens , rev_terminators } =
1152
1152
with [ close , open , { _ , _ , :__cursor__ } = cursor | rev_tokens ] <- rev_tokens ,
1153
1153
{ _ , [ _ | after_fn ] } <- Enum . split_while ( rev_terminators , & ( elem ( & 1 , 0 ) != :fn ) ) ,
1154
- true <- maybe_missing_stab? ( rev_tokens ) ,
1154
+ true <- maybe_missing_stab? ( rev_tokens , false ) ,
1155
1155
[ _ | rev_tokens ] <- Enum . drop_while ( rev_tokens , & ( elem ( & 1 , 0 ) != :fn ) ) do
1156
1156
{ [ close , open , cursor | rev_tokens ] , after_fn }
1157
1157
else
@@ -1165,14 +1165,22 @@ defmodule Code.Fragment do
1165
1165
tokens =
1166
1166
with { before_start , [ _ | _ ] = after_start } <-
1167
1167
Enum . split_while ( rev_terminators , & ( elem ( & 1 , 0 ) not in [ :do , :fn ] ) ) ,
1168
- true <- maybe_missing_stab? ( rev_tokens ) ,
1168
+ true <- maybe_missing_stab? ( rev_tokens , true ) ,
1169
1169
opts =
1170
1170
Keyword . put ( opts , :check_terminators , { :cursor , before_start } ) ,
1171
1171
{ :error , { meta , _ , ~c" end" } , _rest , _warnings , trailing_rev_tokens } <-
1172
1172
:elixir_tokenizer . tokenize ( to_charlist ( trailing_fragment ) , line , column , opts ) do
1173
1173
trailing_tokens =
1174
1174
reverse_tokens ( meta [ :line ] , meta [ :column ] , trailing_rev_tokens , after_start )
1175
1175
1176
+ # If the cursor has its own line, then we do not trim new lines trailing tokens.
1177
+ # Otherwise we want to drop any newline so we drop the next tokens after eol.
1178
+ trailing_tokens =
1179
+ case rev_tokens do
1180
+ [ _close , _open , { _ , _ , :__cursor__ } , { :eol , _ } | _ ] -> trailing_tokens
1181
+ _ -> Enum . drop_while ( trailing_tokens , & match? ( { :eol , _ } , & 1 ) )
1182
+ end
1183
+
1176
1184
Enum . reverse ( rev_tokens , drop_tokens ( trailing_tokens , 0 ) )
1177
1185
else
1178
1186
_ -> reverse_tokens ( line , column , rev_tokens , rev_terminators )
@@ -1196,12 +1204,16 @@ defmodule Code.Fragment do
1196
1204
Enum . reverse ( tokens , terminators )
1197
1205
end
1198
1206
1207
+ # Otherwise we drop all tokens, trying to build a minimal AST
1208
+ # for cursor completion.
1199
1209
defp drop_tokens ( [ { :"}" , _ } | _ ] = tokens , 0 ) , do: tokens
1200
1210
defp drop_tokens ( [ { :"]" , _ } | _ ] = tokens , 0 ) , do: tokens
1201
1211
defp drop_tokens ( [ { :")" , _ } | _ ] = tokens , 0 ) , do: tokens
1202
1212
defp drop_tokens ( [ { :">>" , _ } | _ ] = tokens , 0 ) , do: tokens
1203
1213
defp drop_tokens ( [ { :end , _ } | _ ] = tokens , 0 ) , do: tokens
1204
1214
defp drop_tokens ( [ { :"," , _ } | _ ] = tokens , 0 ) , do: tokens
1215
+ defp drop_tokens ( [ { :";" , _ } | _ ] = tokens , 0 ) , do: tokens
1216
+ defp drop_tokens ( [ { :eol , _ } | _ ] = tokens , 0 ) , do: tokens
1205
1217
defp drop_tokens ( [ { :stab_op , _ , :-> } | _ ] = tokens , 0 ) , do: tokens
1206
1218
1207
1219
defp drop_tokens ( [ { :"}" , _ } | tokens ] , counter ) , do: drop_tokens ( tokens , counter - 1 )
@@ -1220,13 +1232,13 @@ defmodule Code.Fragment do
1220
1232
defp drop_tokens ( [ _ | tokens ] , counter ) , do: drop_tokens ( tokens , counter )
1221
1233
defp drop_tokens ( [ ] , 0 ) , do: [ ]
1222
1234
1223
- defp maybe_missing_stab? ( [ { :after , _ } | _ ] ) , do: true
1224
- defp maybe_missing_stab? ( [ { :do , _ } | _ ] ) , do: true
1225
- defp maybe_missing_stab? ( [ { :fn , _ } | _ ] ) , do: true
1226
- defp maybe_missing_stab? ( [ { :else , _ } | _ ] ) , do: true
1227
- defp maybe_missing_stab? ( [ { :catch , _ } | _ ] ) , do: true
1228
- defp maybe_missing_stab? ( [ { :rescue , _ } | _ ] ) , do: true
1229
- defp maybe_missing_stab? ( [ { :stab_op , _ , :-> } | _ ] ) , do: false
1230
- defp maybe_missing_stab? ( [ _ | tail ] ) , do: maybe_missing_stab? ( tail )
1231
- defp maybe_missing_stab? ( [ ] ) , do: false
1235
+ defp maybe_missing_stab? ( [ { :after , _ } | _ ] , _stab_choice? ) , do: true
1236
+ defp maybe_missing_stab? ( [ { :do , _ } | _ ] , _stab_choice? ) , do: true
1237
+ defp maybe_missing_stab? ( [ { :fn , _ } | _ ] , _stab_choice? ) , do: true
1238
+ defp maybe_missing_stab? ( [ { :else , _ } | _ ] , _stab_choice? ) , do: true
1239
+ defp maybe_missing_stab? ( [ { :catch , _ } | _ ] , _stab_choice? ) , do: true
1240
+ defp maybe_missing_stab? ( [ { :rescue , _ } | _ ] , _stab_choice? ) , do: true
1241
+ defp maybe_missing_stab? ( [ { :stab_op , _ , :-> } | _ ] , stab_choice? ) , do: stab_choice?
1242
+ defp maybe_missing_stab? ( [ _ | tail ] , stab_choice? ) , do: maybe_missing_stab? ( tail , stab_choice? )
1243
+ defp maybe_missing_stab? ( [ ] , _stab_choice? ) , do: false
1232
1244
end
0 commit comments