Skip to content

Commit

Permalink
.ocamlinit: XDG base directory lookup. (#8834)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbuenzli authored and Armael committed Sep 25, 2019
1 parent 776fcc3 commit 17ef076
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 17 deletions.
7 changes: 7 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions man/ocaml.m
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,14 @@ use heuristics to enable colors only if the output supports them (an
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
Expand All @@ -327,7 +333,10 @@ use heuristics to enable colors only if the output supports them (an
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
Expand Down
12 changes: 8 additions & 4 deletions manual/manual/cmds/top.etex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}

Expand Down
3 changes: 2 additions & 1 deletion manual/manual/cmds/unified-options.etex
Original file line number Diff line number Diff line change
Expand Up @@ -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{%
Expand Down
35 changes: 30 additions & 5 deletions toplevel/opttoploop.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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 () =
Expand Down
35 changes: 30 additions & 5 deletions toplevel/toploop.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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 () =
Expand Down

0 comments on commit 17ef076

Please sign in to comment.