.ocamlinit: XDG base directory lookup. (#8834)

master
Daniel Bünzli 2019-09-25 13:50:25 +02:00 committed by Armaël Guéneau
parent 776fcc3919
commit 17ef076000
6 changed files with 88 additions and 17 deletions

View File

@ -131,6 +131,13 @@ Working version
(Whitequark and Jacques-Henri Jourdan, review by Gabriel Scherer
and Xavier Clerc)
* #8834, `ocaml`: adhere to the XDG base directory specification to
locate an `.ocamlinit` file. Reads an `$XDG_CONFIG_HOME/ocaml/init.ml`
file before trying to lookup `~/.ocamlinit`. On Windows the behaviour
is unchanged.
(Daniel C. Bünzli, review by David Allsopp, Armaël Guéneau and
Nicolás Ojeda Bär)
### Standard library:
- #8832: List.find_map : ('a -> 'b option) -> 'a list -> 'b option

View File

@ -302,8 +302,14 @@ is invoked, it will read phrases from an initialization file before
giving control to the user. The default file is
.B .ocamlinit
in the current directory if it exists, otherwise
.B XDG_CONFIG_HOME/ocaml/init.ml
according to the XDG base directory specification lookup if it exists (on
Windows this is skipped), otherwise
.B .ocamlinit
in the user's home directory. You can specify a different initialization file
in the user's home directory (
.B HOME
variable).
You can specify a different initialization file
by using the
.BI \-init \ file
option, and disable initialization files by using the
@ -327,7 +333,10 @@ When printing error messages, the toplevel system
attempts to underline visually the location of the error. It
consults the TERM variable to determines the type of output terminal
and look up its capabilities in the terminal database.
.TP
.B XDG_CONFIG_HOME HOME
.B .ocamlinit
lookup procedure (see above).
.SH SEE ALSO
.BR ocamlc (1), \ ocamlopt (1), \ ocamlrun (1).
.br

View File

@ -66,9 +66,12 @@ its contents are read as a sequence of OCaml phrases
and executed as per the "#use" directive
described in section~\ref{s:toplevel-directives}.
The evaluation outcode for each phrase are not displayed.
If the current directory does not contain an ".ocamlinit" file, but
the user's home directory (environment variable "HOME") does, the
latter is read and executed as described below.
If the current directory does not contain an ".ocamlinit" file,
the file "XDG_CONFIG_HOME/ocaml/init.ml" is looked up according
to the XDG base directory specification and used instead (on Windows
this is skipped). If that file doesn't exist then an [.ocamlinit] file
in the users' home directory (determined via environment variable "HOME") is
used if existing.
The toplevel system does not perform line editing, but it can
easily be used in conjunction with an external line editor such as
@ -132,7 +135,8 @@ attempts to underline visually the location of the error. It
consults the "TERM" variable to determines the type of output terminal
and look up its capabilities in the terminal database.
\item["HOME"] Directory where the ".ocamlinit" file is searched.
\item["XDG_CONFIG_HOME", "HOME"]
".ocamlinit" lookup procedure (see above).
\end{options}
\end{unix}

View File

@ -287,7 +287,8 @@ the toplevel is running with the "#directory" directive
\item["-init" \var{file}]
Load the given file instead of the default initialization file.
The default file is ".ocamlinit" in the current directory if it
exists, otherwise ".ocamlinit" in the user's home directory.
exists, otherwise "XDG_CONFIG_HOME/ocaml/init.ml" or
".ocamlinit" in the user's home directory.
}%top
\notop{%

View File

@ -544,17 +544,42 @@ let _ =
Clflags.dlcode := true;
()
let find_ocamlinit () =
let ocamlinit = ".ocamlinit" in
if Sys.file_exists ocamlinit then Some ocamlinit else
let getenv var = match Sys.getenv var with
| exception Not_found -> None | "" -> None | v -> Some v
in
let exists_in_dir dir file = match dir with
| None -> None
| Some dir ->
let file = Filename.concat dir file in
if Sys.file_exists file then Some file else None
in
let home_dir () = getenv "HOME" in
let config_dir () =
if Sys.win32 then None else
match getenv "XDG_CONFIG_HOME" with
| Some _ as v -> v
| None ->
match home_dir () with
| None -> None
| Some dir -> Some (Filename.concat dir ".config")
in
let init_ml = Filename.concat "ocaml" "init.ml" in
match exists_in_dir (config_dir ()) init_ml with
| Some _ as v -> v
| None -> exists_in_dir (home_dir ()) ocamlinit
let load_ocamlinit ppf =
if !Clflags.noinit then ()
else match !Clflags.init_file with
| Some f -> if Sys.file_exists f then ignore (use_silently ppf f)
else fprintf ppf "Init file not found: \"%s\".@." f
| None ->
if Sys.file_exists ".ocamlinit" then ignore (use_silently ppf ".ocamlinit")
else try
let home_init = Filename.concat (Sys.getenv "HOME") ".ocamlinit" in
if Sys.file_exists home_init then ignore (use_silently ppf home_init)
with Not_found -> ()
match find_ocamlinit () with
| None -> ()
| Some file -> ignore (use_silently ppf file)
;;
let set_paths () =

View File

@ -498,17 +498,42 @@ let _ =
Env.import_crcs ~source:Sys.executable_name crc_intfs;
()
let find_ocamlinit () =
let ocamlinit = ".ocamlinit" in
if Sys.file_exists ocamlinit then Some ocamlinit else
let getenv var = match Sys.getenv var with
| exception Not_found -> None | "" -> None | v -> Some v
in
let exists_in_dir dir file = match dir with
| None -> None
| Some dir ->
let file = Filename.concat dir file in
if Sys.file_exists file then Some file else None
in
let home_dir () = getenv "HOME" in
let config_dir () =
if Sys.win32 then None else
match getenv "XDG_CONFIG_HOME" with
| Some _ as v -> v
| None ->
match home_dir () with
| None -> None
| Some dir -> Some (Filename.concat dir ".config")
in
let init_ml = Filename.concat "ocaml" "init.ml" in
match exists_in_dir (config_dir ()) init_ml with
| Some _ as v -> v
| None -> exists_in_dir (home_dir ()) ocamlinit
let load_ocamlinit ppf =
if !Clflags.noinit then ()
else match !Clflags.init_file with
| Some f -> if Sys.file_exists f then ignore (use_silently ppf f)
else fprintf ppf "Init file not found: \"%s\".@." f
| None ->
if Sys.file_exists ".ocamlinit" then ignore (use_silently ppf ".ocamlinit")
else try
let home_init = Filename.concat (Sys.getenv "HOME") ".ocamlinit" in
if Sys.file_exists home_init then ignore (use_silently ppf home_init)
with Not_found -> ()
match find_ocamlinit () with
| None -> ()
| Some file -> ignore (use_silently ppf file)
;;
let set_paths () =