From cdf8389e342565fb917049567f84e4ea5c2548c4 Mon Sep 17 00:00:00 2001 From: Benjamin Voisin Date: Tue, 10 Dec 2024 13:28:01 +0100 Subject: [PATCH 1/2] client: add support for nushell in the `opam env` command --- src/client/opamArg.ml | 1 + src/client/opamClient.ml | 2 +- src/client/opamCommands.ml | 8 ++++---- src/client/opamConfigCommand.ml | 19 ++++++++++++++++--- src/client/opamConfigCommand.mli | 4 ++-- src/core/opamStd.ml | 6 +++++- src/core/opamStd.mli | 2 +- src/format/opamTypes.mli | 2 +- src/format/opamTypesBase.ml | 1 + src/state/opamEnv.ml | 22 +++++++++++++++++----- 10 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/client/opamArg.ml b/src/client/opamArg.ml index 14c25057846..2f54d24c329 100644 --- a/src/client/opamArg.ml +++ b/src/client/opamArg.ml @@ -1135,6 +1135,7 @@ let shell_opt ?section cli validity = None,"csh",SH_csh; None,"zsh",SH_zsh; None,"fish",SH_fish; + None,"nu",SH_nu; Some cli2_2,"pwsh",SH_pwsh Powershell_pwsh; Some cli2_2,"cmd",SH_cmd; Some cli2_2,"powershell",SH_pwsh Powershell diff --git a/src/client/opamClient.ml b/src/client/opamClient.ml index 2b37a6f6fcc..d1a18d39166 100644 --- a/src/client/opamClient.ml +++ b/src/client/opamClient.ml @@ -1129,7 +1129,7 @@ let rec cygwin_menu ~bypass_checks ~interactive header = options, internal_option, Some warning | None -> match OpamStd.Sys.guess_shell_compat () with - | SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish -> + | SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish | SH_nu -> let default, warning = if kind = `Msys2 && OpamSystem.resolve_command pacman = None then internal_option, Printf.sprintf diff --git a/src/client/opamCommands.ml b/src/client/opamCommands.ml index 78d4d5b9641..c3278a9ba62 100644 --- a/src/client/opamCommands.ml +++ b/src/client/opamCommands.ml @@ -1419,7 +1419,7 @@ let config cli = `Ok (OpamConfigCommand.env gt sw ~set_opamroot ~set_opamswitch ~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish) - ~pwsh ~cmd:(shell=SH_cmd) + ~pwsh ~cmd:(shell=SH_cmd) ~nu:(shell=SH_nu) ~inplace_path)) | Some `revert_env, [] -> OpamGlobalState.with_ `Lock_none @@ fun gt -> @@ -1429,7 +1429,7 @@ let config cli = `Ok (OpamConfigCommand.ensure_env gt sw; OpamConfigCommand.print_eval_env ~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish) - ~pwsh ~cmd:(shell=SH_cmd) + ~pwsh ~cmd:(shell=SH_cmd) ~nu:(shell=SH_nu) (OpamEnv.add [] []))) | Some `list, [] -> OpamGlobalState.with_ `Lock_none @@ fun gt -> @@ -1734,12 +1734,12 @@ let env cli = OpamConfigCommand.env gt sw ~set_opamroot ~set_opamswitch ~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish) - ~pwsh ~cmd:(shell=SH_cmd) + ~pwsh ~cmd:(shell=SH_cmd) ~nu:(shell=SH_nu) ~inplace_path); | true -> OpamConfigCommand.print_eval_env ~csh:(shell=SH_csh) ~sexp ~fish:(shell=SH_fish) - ~pwsh ~cmd:(shell=SH_cmd) + ~pwsh ~cmd:(shell=SH_cmd) ~nu:(shell=SH_nu) (OpamEnv.add [] []) in let open Common_config_flags in diff --git a/src/client/opamConfigCommand.ml b/src/client/opamConfigCommand.ml index 314264de2d1..abb5f6a08c0 100644 --- a/src/client/opamConfigCommand.ml +++ b/src/client/opamConfigCommand.ml @@ -131,6 +131,14 @@ let print_sexp_env output env = aux env; output ")\n" +let rec print_nu_env output env = + match env with + | [] -> () + | (k,v,_)::r -> begin + Printf.ksprintf output "\t\"%s\" : \"%s\",\n" k v; + print_nu_env output r + end + let rec print_fish_env output env = let set_arr_cmd ?(modf=fun x -> x) k v = let v = modf @@ OpamStd.String.split v ':' in @@ -183,7 +191,7 @@ let print_without_cr s = output_string stdout s; flush stdout -let print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd env = +let print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd ~nu env = let env = (env : OpamTypes.env :> (string * string * string option) list) in let output_normally = OpamConsole.msg "%s" in let never_with_cr = @@ -202,6 +210,11 @@ let print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd env = print_pwsh_env output_normally env else if cmd then print_cmd_env output_normally env + else if nu then begin + Printf.ksprintf never_with_cr "{\n"; + print_nu_env never_with_cr env; + Printf.ksprintf never_with_cr "}" + end else print_env never_with_cr env @@ -331,7 +344,7 @@ let ensure_env gt switch = ignore (ensure_env_aux gt switch) let env gt switch ?(set_opamroot=false) ?(set_opamswitch=false) - ~csh ~sexp ~fish ~pwsh ~cmd ~inplace_path = + ~csh ~sexp ~fish ~pwsh ~cmd ~nu ~inplace_path = log "config-env"; let opamroot_not_current = let current = gt.root in @@ -371,7 +384,7 @@ let env gt switch ?(set_opamroot=false) ?(set_opamswitch=false) let env = ensure_env_aux ~set_opamroot ~set_opamswitch ~force_path gt switch in - print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd env + print_eval_env ~csh ~sexp ~fish ~pwsh ~cmd ~nu env [@@ocaml.warning "-16"] let subst gt fs = diff --git a/src/client/opamConfigCommand.mli b/src/client/opamConfigCommand.mli index a205bd376a5..d38f1a4b222 100644 --- a/src/client/opamConfigCommand.mli +++ b/src/client/opamConfigCommand.mli @@ -23,7 +23,7 @@ open OpamStateTypes val env: 'a global_state -> switch -> ?set_opamroot:bool -> ?set_opamswitch:bool -> - csh:bool -> sexp:bool -> fish:bool -> pwsh:bool -> cmd:bool -> + csh:bool -> sexp:bool -> fish:bool -> pwsh:bool -> cmd:bool -> nu:bool -> inplace_path:bool -> unit (** Ensures that the environment file exists in the given switch, regenerating @@ -32,7 +32,7 @@ val ensure_env: 'a global_state -> switch -> unit (** Like [env] but allows one to specify the precise env to print rather than compute it from a switch state *) -val print_eval_env: csh:bool -> sexp:bool -> fish:bool -> pwsh:bool -> cmd:bool -> env -> unit +val print_eval_env: csh:bool -> sexp:bool -> fish:bool -> pwsh:bool -> cmd:bool -> nu:bool -> env -> unit (** Display the content of all available packages variables *) val list: 'a switch_state -> name list -> unit diff --git a/src/core/opamStd.ml b/src/core/opamStd.ml index 226af7effb3..4d98aff95f7 100644 --- a/src/core/opamStd.ml +++ b/src/core/opamStd.ml @@ -1039,7 +1039,7 @@ module OpamSys = struct fun () -> Lazy.force os type powershell_host = Powershell_pwsh | Powershell - type shell = SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish + type shell = SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish | SH_nu | SH_pwsh of powershell_host | SH_cmd let all_shells = @@ -1047,6 +1047,7 @@ module OpamSys = struct SH_zsh; SH_csh; SH_fish; + SH_nu; SH_pwsh Powershell_pwsh; SH_pwsh Powershell; SH_cmd] @@ -1061,6 +1062,7 @@ module OpamSys = struct | "zsh" -> Some SH_zsh | "bash" -> Some SH_bash | "fish" -> Some SH_fish + | "nu" -> Some SH_nu | "pwsh" -> Some (SH_pwsh Powershell_pwsh) | "dash" | "sh" -> Some SH_sh @@ -1159,6 +1161,8 @@ module OpamSys = struct match shell with | SH_fish -> Some (List.fold_left Filename.concat (home ".config") ["fish"; "config.fish"]) + | SH_nu -> + Some (List.fold_left Filename.concat (home ".config") ["nushell"; "env.nu"]) | SH_zsh -> let zsh_home f = try Filename.concat (Env.get "ZDOTDIR") f diff --git a/src/core/opamStd.mli b/src/core/opamStd.mli index 74b06acb2de..41ad3fd6166 100644 --- a/src/core/opamStd.mli +++ b/src/core/opamStd.mli @@ -531,7 +531,7 @@ module Sys : sig (** The different families of shells we know about *) type powershell_host = Powershell_pwsh | Powershell - type shell = SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish + type shell = SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish | SH_nu | SH_pwsh of powershell_host | SH_cmd (** List of all supported shells *) diff --git a/src/format/opamTypes.mli b/src/format/opamTypes.mli index e7bf8036128..0b8f174f7f8 100644 --- a/src/format/opamTypes.mli +++ b/src/format/opamTypes.mli @@ -321,7 +321,7 @@ type pin_kind = [ `version | OpamUrl.backend ] (** Shell compatibility modes *) type powershell_host = OpamStd.Sys.powershell_host = Powershell_pwsh | Powershell type shell = OpamStd.Sys.shell = - | SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish | SH_pwsh of powershell_host + | SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish | SH_nu | SH_pwsh of powershell_host | SH_cmd (** {2 Generic command-line definitions with filters} *) diff --git a/src/format/opamTypesBase.ml b/src/format/opamTypesBase.ml index b74e32cd977..b5c0d9c0d93 100644 --- a/src/format/opamTypesBase.ml +++ b/src/format/opamTypesBase.ml @@ -42,6 +42,7 @@ let all_std_paths = let string_of_shell = function | SH_fish -> "fish" + | SH_nu -> "nu" | SH_csh -> "csh" | SH_zsh -> "zsh" | SH_sh -> "sh" diff --git a/src/state/opamEnv.ml b/src/state/opamEnv.ml index d47b7ce9ec0..eed6387465d 100644 --- a/src/state/opamEnv.ml +++ b/src/state/opamEnv.ml @@ -868,6 +868,8 @@ let opam_env_invocation ?root ?switch ?(set_opamswitch=false) shell = Printf.sprintf " \"--%s=%s\"" argname | SH_sh | SH_bash | SH_zsh | SH_csh | SH_fish -> Printf.sprintf " '--%s=%s'" argname + | SH_nu -> + Printf.sprintf " '--%s=%s'" argname in if filepath_needs_quote pathval then quoted pathval @@ -917,24 +919,25 @@ let eval_string gt ?(set_opamswitch=false) switch = (** The shells for which we generate init scripts (bash and sh are the same entry) *) -let shells_list = [ SH_sh; SH_zsh; SH_csh; SH_fish; SH_pwsh Powershell; SH_cmd ] +let shells_list = [ SH_sh; SH_zsh; SH_csh; SH_fish; SH_pwsh Powershell; SH_cmd ; SH_nu] let complete_file = function | SH_sh | SH_bash -> Some "complete.sh" | SH_zsh -> Some "complete.zsh" - | SH_csh | SH_fish | SH_pwsh _ | SH_cmd -> None + | SH_csh | SH_fish | SH_pwsh _ | SH_cmd | SH_nu-> None let env_hook_file = function | SH_sh | SH_bash -> Some "env_hook.sh" | SH_zsh -> Some "env_hook.zsh" | SH_csh -> Some "env_hook.csh" | SH_fish -> Some "env_hook.fish" - | SH_pwsh _ | SH_cmd -> None + | SH_pwsh _ | SH_cmd | SH_nu -> None let variables_file = function | SH_sh | SH_bash | SH_zsh -> "variables.sh" | SH_csh -> "variables.csh" | SH_fish -> "variables.fish" + | SH_nu -> "variables.nu" | SH_pwsh _ -> "variables.ps1" | SH_cmd -> "variables.cmd" @@ -943,13 +946,14 @@ let init_file = function | SH_zsh -> "init.zsh" | SH_csh -> "init.csh" | SH_fish -> "init.fish" + | SH_nu -> "init.nu" | SH_pwsh _ -> "init.ps1" | SH_cmd -> "init.cmd" let complete_script = function | SH_sh | SH_bash -> Some OpamScript.complete | SH_zsh -> Some OpamScript.complete_zsh - | SH_csh | SH_fish -> None + | SH_csh | SH_fish | SH_nu -> None | SH_pwsh _ | SH_cmd -> None let env_hook_script_base = function @@ -957,7 +961,7 @@ let env_hook_script_base = function | SH_zsh -> Some OpamScript.env_hook_zsh | SH_csh -> Some OpamScript.env_hook_csh | SH_fish -> Some OpamScript.env_hook_fish - | SH_pwsh _ | SH_cmd -> None + | SH_pwsh _ | SH_cmd | SH_nu -> None let export_in_shell shell = let make_comment comment_opt = @@ -993,6 +997,9 @@ let export_in_shell shell = Printf.sprintf "%sset -gx %s %s;\n" (make_comment comment) k v in + let nu (k,v,comment) = + Printf.sprintf "load-env (opam env %s %s %s)\n" (make_comment comment) k v + in let pwsh (k,v,comment) = Printf.sprintf "%s$env:%s=%s\n" (make_comment comment) k v in @@ -1005,6 +1012,7 @@ let export_in_shell shell = match shell with | SH_zsh | SH_bash | SH_sh -> sh | SH_fish -> fish + | SH_nu -> nu | SH_csh -> csh | SH_pwsh _ -> pwsh | SH_cmd -> cmd @@ -1030,6 +1038,8 @@ let source root shell f = | SH_fish -> let fname = unix_transform ~using_backslashes:true () in Printf.sprintf "test -r '%s' && source '%s' > /dev/null 2> /dev/null; or true\n" fname fname + | SH_nu -> + Printf.sprintf "%s:TODO" fname | SH_sh | SH_bash -> let fname = unix_transform () in Printf.sprintf "test -r '%s' && . '%s' > /dev/null 2> /dev/null || true\n" @@ -1065,6 +1075,8 @@ let if_interactive_script shell t e = Printf.sprintf "if ( $?prompt ) then\n %s%sendif\n" t @@ ielse e | SH_fish -> Printf.sprintf "if status is-interactive\n %s%send\n" t @@ ielse e + | SH_nu -> + Printf.sprintf "%sTODO%s" t @@ ielse e | SH_cmd -> Printf.sprintf "echo %%cmdcmdline%% | find /i \"%%~0\" >nul\nif errorlevel 1 (\n%s%s)\n" t @@ ielse_cmd e | SH_pwsh _ -> From 989ecbdf11849a523f32c07cac00553849ffc422 Mon Sep 17 00:00:00 2001 From: Benjamin Voisin Date: Tue, 10 Dec 2024 14:17:47 +0100 Subject: [PATCH 2/2] add changes to master_changes.md file --- master_changes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/master_changes.md b/master_changes.md index d8ccb0eaea4..edb8bc3a8d2 100644 --- a/master_changes.md +++ b/master_changes.md @@ -76,6 +76,7 @@ users) ## Clean ## Env + * [NEW] Add support for nushell in the opam env command ## Opamfile