#156: start of support for quoted strings

This commit is contained in:
Jérémie Dimino 2016-02-04 08:06:11 +00:00
parent b63e0f9225
commit fd7c663264
3 changed files with 37 additions and 19 deletions

View File

@ -74,7 +74,7 @@ let parse_longident tokens =
| l -> Some (longident_of_list l))
in
match tokens with
| ((Comment (_, false) | String false | Quotation (_, false)), _) :: _ ->
| ((Comment (_, false) | String (_, false) | Quotation (_, false)), _) :: _ ->
(* An unterminated command, string, or quotation. *)
None
| ((Uident id | Lident id), { idx1 = start }) :: tokens ->
@ -847,23 +847,23 @@ let complete ~syntax ~phrase_terminator ~input =
(start, lookup_assoc src (list_directives phrase_terminator))
(* Complete with ";;" when possible. *)
| [(Symbol "#", _); ((Lident _ | Uident _), _); (String true, { idx2 = stop })]
| [(Symbol "#", _); ((Lident _ | Uident _), _); (String true, _); (Blanks, { idx2 = stop })] ->
| [(Symbol "#", _); ((Lident _ | Uident _), _); (String (_, true), { idx2 = stop })]
| [(Symbol "#", _); ((Lident _ | Uident _), _); (String (_, true), _); (Blanks, { idx2 = stop })] ->
(stop, [(phrase_terminator, "")])
| [(Symbol "#", _); ((Lident _ | Uident _), _); (String true, _); (Symbol sym, { idx1 = start })] ->
| [(Symbol "#", _); ((Lident _ | Uident _), _); (String (_, true), _); (Symbol sym, { idx1 = start })] ->
if Zed_utf8.starts_with phrase_terminator sym then
(start, [(phrase_terminator, "")])
else
(0, [])
(* Completion on #require. *)
| [(Symbol "#", _); (Lident "require", _); (String false, loc)] ->
let pkg = String.sub input (loc.ofs1 + 1) (String.length input - loc.ofs1 - 1) in
| [(Symbol "#", _); (Lident "require", _); (String (tlen, false), loc)] ->
let pkg = String.sub input (loc.ofs1 + tlen) (String.length input - loc.ofs1 - tlen) in
let pkgs = lookup pkg (Fl_package_base.list_packages ()) in
(loc.idx1 + 1, List.map (fun pkg -> (pkg, "\"" ^ phrase_terminator)) (List.sort compare pkgs))
| [(Symbol "#", _); (Lident "typeof", _); (String false, loc)] ->
let prefix = String.sub input (loc.ofs1 + 1) (String.length input - loc.ofs1 - 1) in
| [(Symbol "#", _); (Lident "typeof", _); (String (tlen, false), loc)] ->
let prefix = String.sub input (loc.ofs1 + tlen) (String.length input - loc.ofs1 - tlen) in
begin match Longident.parse prefix with
| Longident.Ldot (lident, last_prefix) ->
let set = names_of_module lident in
@ -877,8 +877,8 @@ let complete ~syntax ~phrase_terminator ~input =
end
(* Completion on #load. *)
| [(Symbol "#", _); (Lident ("load" | "load_rec"), _); (String false, loc)] ->
let file = String.sub input (loc.ofs1 + 1) (String.length input - loc.ofs1 - 1) in
| [(Symbol "#", _); (Lident ("load" | "load_rec"), _); (String (tlen, false), loc)] ->
let file = String.sub input (loc.ofs1 + tlen) (String.length input - loc.ofs1 - tlen) in
let filter name = Filename.check_suffix name ".cma" || Filename.check_suffix name ".cmo" in
let map =
if Filename.is_relative file then
@ -898,8 +898,8 @@ let complete ~syntax ~phrase_terminator ~input =
#if OCAML_VERSION >= (4, 02, 0)
(* Completion on #ppx. *)
| [(Symbol "#", _); (Lident ("ppx"), _); (String false, loc)] ->
let file = String.sub input (loc.ofs1 + 1) (String.length input - loc.ofs1 - 1) in
| [(Symbol "#", _); (Lident ("ppx"), _); (String (tlen, false), loc)] ->
let file = String.sub input (loc.ofs1 + tlen) (String.length input - loc.ofs1 - tlen) in
let filter ~dir_ok name =
try
Unix.access name [Unix.X_OK];
@ -928,8 +928,8 @@ let complete ~syntax ~phrase_terminator ~input =
#endif
(* Completion on #use. *)
| [(Symbol "#", _); (Lident "use", _); (String false, loc)] ->
let file = String.sub input (loc.ofs1 + 1) (String.length input - loc.ofs1 - 1) in
| [(Symbol "#", _); (Lident "use", _); (String (tlen, false), loc)] ->
let file = String.sub input (loc.ofs1 + tlen) (String.length input - loc.ofs1 - tlen) in
let filter name =
match try Some (String.rindex name '.') with Not_found -> None with
| None ->
@ -955,8 +955,8 @@ let complete ~syntax ~phrase_terminator ~input =
List.map (function (w, Directory) -> (w, "") | (w, File) -> (w, "\"" ^ phrase_terminator)) result)
(* Completion on #directory and #cd. *)
| [(Symbol "#", _); (Lident ("cd" | "directory"), _); (String false, loc)] ->
let file = String.sub input (loc.ofs1 + 1) (String.length input - loc.ofs1 - 1) in
| [(Symbol "#", _); (Lident ("cd" | "directory"), _); (String (tlen, false), loc)] ->
let file = String.sub input (loc.ofs1 + tlen) (String.length input - loc.ofs1 - tlen) in
let list = list_directories (Filename.dirname file) in
let name = basename file in
let result = lookup name list in

View File

@ -117,7 +117,13 @@ rule tokens syntax context idx acc = parse
{ let ofs = lexeme_start lexbuf in
let idx2, terminated = string (idx + 1) lexbuf in
let loc = mkloc idx idx2 ofs (lexeme_end lexbuf) in
tokens syntax context idx2 ((String terminated, loc) :: acc) lexbuf }
tokens syntax context idx2 ((String (1, terminated), loc) :: acc) lexbuf }
| '{' (lowercase* as tag) '|'
{ let ofs = lexeme_start lexbuf in
let delim_len = String.length tag + 2 in
let idx2, terminated = quoted_string (idx + delim_len) tag lexbuf in
let loc = mkloc idx idx2 ofs (lexeme_end lexbuf) in
tokens syntax context idx2 ((String (delim_len, terminated), loc) :: acc) lexbuf }
| "'" [^'\'' '\\'] "'"
| "'\\" ['\\' '"' 'n' 't' 'b' 'r' ' ' '\'' 'x' '0'-'9'] eof
| "'\\" ['\\' '"' 'n' 't' 'b' 'r' ' ' '\''] "'"
@ -217,6 +223,18 @@ and string idx = parse
| eof
{ (idx, false) }
and quoted_string idx tag = parse
| '|' (lowercase* as tag2) '}'
{ let idx = idx + 2 + String.length tag2 in
if tag = tag2 then
(idx, true)
else
quoted_string idx tag lexbuf }
| eof
{ (idx, false) }
| uchar
{ quoted_string (idx + 1) tag lexbuf }
and quotation syntax depth idx1 idx2 ofs1 = parse
| '<' (':' ident)? ('@' lident)? '<'
{ quotation syntax (depth + 1) idx1 (idx2 + lexeme_size lexbuf) ofs1 lexbuf }

View File

@ -30,8 +30,8 @@ type t =
| Uident of string
| Constant of string
| Char
| String of bool
(** [String terminated]. *)
| String of int * bool
(** [String (quote_size, terminated)]. *)
| Comment of comment_kind * bool
(** [Comment (kind, terminated)]. *)
| Blanks