feat(cli): add doom.ps1 for Windows users

c9acdb7 removes doom.cmd because it was broken in most cases. This adds
doom.ps1; an alternative script for Windows+Powershell users, which
properly initializes the state it needs. Naturally, it requires
Powershell 3+ be installed on your systems, but it can be invoked from
either cmd.exe or PowerShell.exe.

This is the first powershell script I've ever written, so I expect edge
cases (for one, shell commands passed to `exit!` will need to be guarded
against the environment).

This also requires emacs.exe be your $PATH, however, unless you set
$EMACS to its path first. E.g.

  $env:EMACS = "C:\Program Files\Emacs\emacs-29.4\bin\emacs.exe"

That said, if you use WSL2, you're still far better off using the bash
script (bin/doom).

Ref: c9acdb72a4
This commit is contained in:
Henrik Lissner 2024-09-07 00:41:16 -04:00
parent 9753bfb775
commit 8d2cf32fef
No known key found for this signature in database
GPG key ID: B60957CA074D39A3
3 changed files with 80 additions and 20 deletions

View file

@ -1121,8 +1121,9 @@ Emacs' batch library lacks an implementation of the exec system call."
(error "__DOOMSTEP envvar missing; extended `exit!' functionality will not work"))
(let* ((pid (doom-cli-context-pid context))
(step (doom-cli-context-step context))
(shtype (or (getenv "__DOOMSH") "sh"))
(context-file (format (doom-path temporary-file-directory "doom.%s.%s.context") pid step))
(script-file (format (doom-path temporary-file-directory "doom.%s.%s.sh") pid step))
(script-file (format (doom-path temporary-file-directory "doom.%s.%s.%s") pid step shtype))
(command (if (listp args) (combine-and-quote-strings (remq nil args)) args))
(persistent-files
(combine-and-quote-strings (delq nil (list script-file context-file))))
@ -1154,24 +1155,40 @@ Emacs' batch library lacks an implementation of the exec system call."
newcontext))
(doom-log "restart: writing post-script to %s" script-file)
(doom-file-write
script-file `("#!/usr/bin/env sh\n"
"trap _doomcleanup EXIT\n"
"_doomcleanup() {\n rm -f " ,persistent-files "\n}\n"
"_doomrun() {\n " ,command "\n}\n"
,(string-join persisted-env " \\\n")
,(cl-loop for (envvar . val)
in `(("DOOMPROFILE" . ,(ignore-errors (doom-profile->id doom-profile)))
("EMACSDIR" . ,doom-emacs-dir)
("DOOMDIR" . ,doom-user-dir)
("DEBUG" . ,(if init-file-debug "1"))
("__DOOMSTEP" . ,(number-to-string (doom-cli-context-step context)))
("__DOOMCONTEXT" . ,context-file))
if val
concat (format "%s=%s \\\n" envvar (shell-quote-argument val)))
,(format "PATH=\"%s%s$PATH\" \\\n"
(doom-path doom-emacs-dir "bin")
path-separator)
"_doomrun \"$@\"\n")))
script-file
(let ((envvars `(("DOOMPROFILE" . ,(ignore-errors (doom-profile->id doom-profile)))
("EMACSDIR" . ,doom-emacs-dir)
("DOOMDIR" . ,doom-user-dir)
("DEBUG" . ,(if init-file-debug "1"))
("__DOOMPID" . ,(number-to-string (doom-cli-context-pid context)))
("__DOOMSTEP" . ,(number-to-string (doom-cli-context-step context)))
("__DOOMGEOM" . ,(number-to-string (doom-cli-context-step context)))
("__DOOMCONTEXT" . ,context-file))))
(pcase-exhaustive shtype
("sh" `("#!/usr/bin/env sh\n"
"trap _doomcleanup EXIT\n"
"_doomcleanup() {\n rm -f " ,persistent-files "\n}\n"
"_doomrun() {\n " ,command "\n}\n"
,(string-join persisted-env " \\\n")
,(cl-loop for (envvar . val) in envvars
if val
concat (format "%s=%s \\\n" envvar (shell-quote-argument val)))
,(format "PATH=\"%s%s$PATH\" \\\n"
(doom-path doom-emacs-dir "bin")
path-separator)
"_doomrun \"$@\"\n"))
("ps1" `("try {\n"
,(cl-loop for (envvar . val) in envvars
if val
concat (format " $__%s = $env:%s; $env:%s = %s\\\n " envvar envvar envvar (shell-quote-argument val)))
,command
"\n} finally {\n"
,(cl-loop for file in persistent-files
concat (format " Remote-Item -Path %S\n " file))
,(cl-loop for (envvar . val) in envvars
if val
concat (format " $env:%s = $__%s\\\n " envvar envvar))
"\n}"))))))
(doom-log "_doomrun: %s %s" (string-join persisted-env " ") command)
(doom-log "_doomcleanup: %s" persistent-files)
;; Error code 254 is special: it indicates to the caller that the
@ -1268,7 +1285,11 @@ Arguments don't have to be switches either."
ARGS are options passed to less. If DOOMPAGER is set, ARGS are ignored."
(let ((pager (or doom-cli-pager (getenv "DOOMPAGER"))))
(cond ((null (or pager (executable-find "less")))
(cond ((equal (getenv "__DOOMSH") "ps1")
;; Pager isn't supported in powershell
(doom-cli--exit 0 context))
((null (or pager (executable-find "less")))
(user-error "No pager set or available")
(doom-cli--exit 1 context))