commit 027b8ee690d89f3c8dac0c0984448e6d6c5c68b7
parent 8a94ae4094a779a57c3d4d55073f67916bdb5701
Author: Lukas Henkel <lh@entf.net>
Date: Sat, 8 Oct 2022 10:56:40 +0200
Add powershell stuff
Diffstat:
7 files changed, 1551 insertions(+), 1 deletion(-)
diff --git a/elpa/ob-powershell-20220314.1359/ob-powershell-autoloads.el b/elpa/ob-powershell-20220314.1359/ob-powershell-autoloads.el
@@ -0,0 +1,28 @@
+;;; ob-powershell-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+
+;;; Generated autoloads from ob-powershell.el
+
+(register-definition-prefixes "ob-powershell" '("ob-powershell-" "org-babel-"))
+
+;;; End of scraped data
+
+(provide 'ob-powershell-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; ob-powershell-autoloads.el ends here
diff --git a/elpa/ob-powershell-20220314.1359/ob-powershell-pkg.el b/elpa/ob-powershell-20220314.1359/ob-powershell-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from ob-powershell.el -*- no-byte-compile: t -*-
+(define-package "ob-powershell" "20220314.1359" "Run Powershell from org mode source blocks" '((emacs "26.1")) :commit "f351429590ed68b26a9c8f9847066ca4205e524b" :authors '(("Rob Kiggen" . "robby.kiggen@essential-it.be")) :maintainer '("Mois Moshev" . "mois.moshev@bottleshipvfx.com") :keywords '("powershell" "shell" "execute" "outlines" "processes") :url "https://github.com/rkiggen/ob-powershell")
diff --git a/elpa/ob-powershell-20220314.1359/ob-powershell.el b/elpa/ob-powershell-20220314.1359/ob-powershell.el
@@ -0,0 +1,68 @@
+;;; ob-powershell.el --- Run Powershell from org mode source blocks
+;;; SPDX-License-Identifier: MIT
+
+;; Copyright (C) 2022 Rob Kiggen
+
+;; Author: Rob Kiggen <robby.kiggen@essential-it.be>
+;; Maintainer: Mois Moshev <mois.moshev@bottleshipvfx.com>
+;; Version: 1.0
+;; Package-Version: 20220314.1359
+;; Package-Commit: f351429590ed68b26a9c8f9847066ca4205e524b
+;; Package-Requires: ((emacs "26.1"))
+;; Keywords: powershell, shell, execute, outlines, processes
+;; URL: https://github.com/rkiggen/ob-powershell
+
+;;; Commentary:
+
+;; Currently this only supports the external compilation and execution
+;; of Powershell code blocks (i.e., no session support).
+;;; Code:
+
+(require 'ob)
+
+(defvar org-babel-tangle-lang-exts)
+(add-to-list 'org-babel-tangle-lang-exts '("powershell" . "ps1"))
+
+(defcustom ob-powershell-powershell-command "powershell"
+ "Name of command used to evaluate powershell blocks."
+ :group 'org-babel
+ :version "24.3"
+ :type 'string)
+
+
+(defun org-babel-execute:powershell (body params)
+ "Execute a block of Powershell code BODY with Babe passing PARAMS.
+This function is called by `org-babel-execute-src-block'."
+ (let ((scriptfile (org-babel-temp-file "powershell-script-" ".ps1"))
+ (full-body (org-babel-expand-body:generic
+ body params (org-babel-variable-assignments:powershell params))))
+ (message full-body)
+ (with-temp-file scriptfile (insert full-body))
+ (org-babel-eval (concat ob-powershell-powershell-command " " scriptfile) "")))
+
+(defun org-babel-variable-assignments:powershell (params)
+ "Return a list of Powershell statements parsed from PARAMS, assigning the block's variables."
+ (mapcar
+ (lambda (pair)
+ (format "$env:%s=%s"
+ (car pair)
+ (ob-powershell-var-to-powershell (cdr pair))))
+ (org-babel--get-vars params)))
+
+(defun ob-powershell-var-to-powershell (var)
+ "Convert :var into a powershell variable.
+Convert an elisp value, VAR, into a string of poershell source code
+specifying a variable of the same value."
+ (if (listp var)
+ (concat "[" (mapconcat #'ob-powershell-var-to-powershell var ", ") "]")
+ (format "$%S" var)))
+
+(defun org-babel-prep-session:powershell (session params)
+ "Return an error because Powershell does not support sessions.
+SESSION refers to the babel session.
+PARAMS are the passed parameters."
+ (error "Sessions are not (yet) supported for Powershell"))
+
+
+(provide 'ob-powershell)
+;;; ob-powershell.el ends here
diff --git a/elpa/powershell-20220805.1712/powershell-autoloads.el b/elpa/powershell-20220805.1712/powershell-autoloads.el
@@ -0,0 +1,56 @@
+;;; powershell-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+
+;;; Generated autoloads from powershell.el
+
+(add-to-list 'auto-mode-alist '("\\.ps[dm]?1\\'" . powershell-mode))
+(autoload 'powershell-mode "powershell" "\
+Major mode for editing PowerShell scripts.
+
+\\{powershell-mode-map}
+Entry to this mode calls the value of `powershell-mode-hook' if
+that value is non-nil.
+
+(fn)" t nil)
+(autoload 'powershell "powershell" "\
+Run an inferior PowerShell.
+If BUFFER is non-nil, use it to hold the powershell
+process. Defaults to *PowerShell*.
+
+Interactively, a prefix arg means to prompt for BUFFER.
+
+If BUFFER exists but the shell process is not running, it makes a
+new shell.
+
+If BUFFER exists and the shell process is running, just switch to
+BUFFER.
+
+If PROMPT-STRING is non-nil, sets the prompt to the given value.
+
+See the help for `shell' for more details. (Type
+\\[describe-mode] in the shell buffer for a list of commands.)
+
+(fn &optional BUFFER PROMPT-STRING)" t nil)
+(register-definition-prefixes "powershell" '("explicit-powershell.exe-args" "powershell-"))
+
+;;; End of scraped data
+
+(provide 'powershell-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; powershell-autoloads.el ends here
diff --git a/elpa/powershell-20220805.1712/powershell-pkg.el b/elpa/powershell-20220805.1712/powershell-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from powershell.el -*- no-byte-compile: t -*-
+(define-package "powershell" "20220805.1712" "Mode for editing PowerShell scripts" '((emacs "24")) :commit "f2da15857e430206e215a3c65289b4058ae3c976" :authors '(("Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>")) :maintainer '("Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>") :keywords '("powershell" "languages") :url "http://github.com/jschaf/powershell.el")
diff --git a/elpa/powershell-20220805.1712/powershell.el b/elpa/powershell-20220805.1712/powershell.el
@@ -0,0 +1,1394 @@
+;;; powershell.el --- Mode for editing PowerShell scripts -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2009, 2010 Frédéric Perrin
+;; Copyright (C) 2012 Richard Bielawski rbielaws-at-i1-dot-net
+;; http://www.emacswiki.org/emacs/Rick_Bielawski
+
+;; Author: Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>
+;; URL: http://github.com/jschaf/powershell.el
+;; Package-Version: 20220805.1712
+;; Package-Commit: f2da15857e430206e215a3c65289b4058ae3c976
+;; Version: 0.3
+;; Package-Requires: ((emacs "24"))
+;; Keywords: powershell, languages
+
+;; This file is NOT part of GNU Emacs.
+
+;; This file is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Installation:
+
+;; Place powershell.el on your `load-path' by adding the following
+;; code to your `user-init-file', which is usually ~/.emacs.d/init.el
+;; or ~/.emacs.
+;;
+;; (add-to-list 'load-path "~/path/to/powershell")
+;;
+
+;;; Commentary:
+
+;; powershell.el is a combination of powershell.el by Dino Chiesa
+;; <dpchiesa@hotmail.com> and powershell-mode.el by Frédéric Perrin
+;; and Richard Bielawski. Joe Schafer combined the work into a single
+;; file.
+
+;;; Frédéric Perrin Comments:
+;;
+;; The original powershell-mode.el was written from scratch, without
+;; using Vivek Sharma's code: it had issues I wanted to correct, but
+;; unfortunately there were no licence indication, and Vivek didn't
+;; answered my mails.
+;;
+;;; Rick Bielawski Comments 2012/09/28:
+;;
+;; On March 31, 2012 Frédéric gave me permission to take over support
+;; for powershell-mode.el. I've added support for multi-line comments
+;; and here-strings as well as enhancement/features such as: Functions
+;; to quote, unquote and escape a selection, and one to wrap a
+;; selection in $(). Meanwhile I hope I didn't break anything.
+;;
+;; Joe Schafer Comments 2013-06-06:
+;;
+;; I combined powershell.el and powershell-mode.el. Since
+;; powershell.el was licensed with the new BSD license I combined the
+;; two files using the more restrictive license, the GPL. I also
+;; cleaned up the documentation and reorganized some of the code.
+
+;;; Updates:
+
+;; 2012/10/01 Fixed several bugs in highlighting variables and types.
+;; Renamed some variables to be more descriptive.
+;; 2012/10/02 Enhanced PowerShell-mode indenting & syntax table.
+;; Fixed dangling parens and re-indented the elisp itself.
+;; 2012/10/05 Added eldoc support. Fixed bug where indent could loop.
+;; See comment below on how to generate powershell-eldoc.el
+;; 2013/06/06 Merged powershell.el and powershell-mode.el
+
+;;; Code:
+
+(eval-when-compile (require 'thingatpt))
+(require 'shell)
+(require 'compile)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.ps[dm]?1\\'" . powershell-mode))
+
+
+;; User Variables
+
+(defgroup powershell nil
+ "Customization of PowerShell mode."
+ :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
+ :group 'languages)
+
+(defcustom powershell-indent 4
+ "Amount of horizontal space to indent.
+After, for instance, an opening brace"
+ :type 'integer
+ :group 'powershell)
+
+(defcustom powershell-continuation-indent 2
+ "Amount of horizontal space to indent a continuation line."
+ :type 'integer
+ :group 'powershell)
+
+(defcustom powershell-continued-regexp ".*\\(|[\\t ]*\\|`\\)$"
+ "Regexp matching a continued line.
+Ending either with an explicit backtick, or with a pipe."
+ :type 'integer
+ :group 'powershell)
+
+;; Note: There are no explicit references to the variable
+;; `explicit-powershell.exe-args'. It is used implicitly by M-x shell
+;; when the shell is `powershell.exe'. See
+;; http://blogs.msdn.com/b/dotnetinterop/archive/2008/04/10/run-powershell-as-a-shell-within-emacs.aspx
+;; for details.
+(defcustom explicit-powershell.exe-args '("-Command" "-" )
+ "Args passed to inferior shell by \\[shell], if the shell is powershell.exe.
+Value is a list of strings, which may be nil."
+ :type '(repeat (string :tag "Argument"))
+ :group 'powershell)
+
+(defun powershell-continuation-line-p ()
+ "Return t is the current line is a continuation line.
+The current line is a continued line when the previous line ends
+with a backtick or a pipe"
+ (interactive)
+ (save-excursion
+ (forward-line -1)
+ (looking-at powershell-continued-regexp)))
+
+;; Rick added significant complexity to Frédéric's original version
+(defun powershell-indent-line-amount ()
+ "Return the column to which the current line ought to be indented."
+ (interactive)
+ (save-excursion
+ (beginning-of-line)
+ (if (powershell-continuation-line-p)
+ ;; on a continuation line (i.e. prior line ends with backtick
+ ;; or pipe), indent relative to the continued line.
+ (progn
+ (while (and (not (bobp))(powershell-continuation-line-p))
+ (forward-line -1))
+ (+ (current-indentation) powershell-continuation-indent))
+ ;; otherwise, indent relative to the block's opening char ([{
+ ;; \\s- includes newline, which make the line right before closing paren not indented
+ (let ((closing-paren (looking-at "[ \t]*\\s)"))
+ new-indent
+ block-open-line)
+ (condition-case nil
+ (progn
+ (backward-up-list) ;when at top level, throw to no-indent
+ (setq block-open-line (line-number-at-pos))
+ ;; We're in a block, calculate/return indent amount.
+ (if (not (looking-at "\\s(\\s-*\\(#.*\\)?$"))
+ ;; code (not comments) follow the block open so
+ ;; vertically align the block with the code.
+ (if closing-paren
+ ;; closing indent = open
+ (setq new-indent (current-column))
+ ;; block indent = first line of code
+ (forward-char)
+ (skip-syntax-forward " ")
+ (setq new-indent (current-column)))
+ ;; otherwise block open is at eol so indent is relative to
+ ;; bol or another block open on the same line.
+ (if closing-paren ; this sets the default indent
+ (setq new-indent (current-indentation))
+ (setq new-indent (+ powershell-indent (current-indentation))))
+ ;; now see if the block is nested on the same line
+ (when (condition-case nil
+ (progn
+ (backward-up-list)
+ (= block-open-line (line-number-at-pos)))
+ (scan-error nil))
+ (forward-char)
+ (skip-syntax-forward " ")
+ (if closing-paren
+ (setq new-indent (current-column))
+ (setq new-indent (+ powershell-indent (current-column))))))
+ new-indent)
+ (scan-error ;; most likely, we are at the top-level
+ 0))))))
+
+(defun powershell-indent-line ()
+ "Indent the current line of powershell mode.
+Leave the point in place if it is inside the meat of the line"
+ (interactive)
+ (let ((savep (> (current-column) (current-indentation)))
+ (amount (powershell-indent-line-amount)))
+ (if savep
+ (save-excursion (indent-line-to amount))
+ (indent-line-to amount))))
+
+(defun powershell-quote-selection (beg end)
+ "Quotes the selection between BEG and END.
+Quotes with single quotes and doubles embedded single quotes."
+ (interactive `(,(region-beginning) ,(region-end)))
+ (if (not mark-active)
+ (error "Command requires a marked region"))
+ (goto-char beg)
+ (while (re-search-forward "'" end t)
+ (replace-match "''")(setq end (1+ end)))
+ (goto-char beg)
+ (insert "'")
+ (setq end (1+ end))
+ (goto-char end)
+ (insert "'"))
+
+(defun powershell-unquote-selection (beg end)
+ "Unquotes the selected text between BEG and END.
+Remove doubled single quotes as we go."
+ (interactive `(,(region-beginning) ,(region-end)))
+ (if (not mark-active)
+ (error "Command requires a marked region"))
+ (goto-char beg)
+ (cond ((looking-at "'")
+ (goto-char end)
+ (when (looking-back "'" nil)
+ (delete-char -1)
+ (setq end (1- end))
+ (goto-char beg)
+ (delete-char 1)
+ (setq end (1- end))
+ (while (search-forward "'" end t)
+ (delete-char -1)
+ (forward-char)
+ (setq end (1- end)))))
+ ((looking-at "\"")
+ (goto-char end)
+ (when (looking-back "\"" nil)
+ (delete-char -1)
+ (setq end (1- end))
+ (goto-char beg)
+ (delete-char 1)
+ (setq end (1- end))
+ (while (search-forward "\"" end t)
+ (delete-char -1)
+ (forward-char)
+ (setq end (1- end)))
+ (while (search-forward "`" end t)
+ (delete-char -1)
+ (forward-char)
+ (setq end (1- end)))))
+ (t (error "Must select quoted text exactly"))))
+
+(defun powershell-escape-selection (beg end)
+ "Escape variables between BEG and END.
+Also extend existing escapes."
+ (interactive `(,(region-beginning) ,(region-end)))
+ (if (not mark-active)
+ (error "Command requires a marked region"))
+ (goto-char beg)
+ (while (re-search-forward "`" end t)
+ (replace-match "```")(setq end (+ end 2)))
+ (goto-char beg)
+ (while (re-search-forward "\\(?:\\=\\|[^`]\\)[$]" end t)
+ (goto-char (car (cdr (match-data))))
+ (backward-char)
+ (insert "`")
+ (forward-char)
+ (setq end (1+ end))))
+
+(defun powershell-doublequote-selection (beg end)
+ "Quotes the text between BEG and END with double quotes.
+Embedded quotes are doubled."
+ (interactive `(,(region-beginning) ,(region-end)))
+ (if (not mark-active)
+ (error "Command requires a marked region"))
+ (goto-char beg)
+ (while (re-search-forward "\"" end t)
+ (replace-match "\"\"")(setq end (1+ end)))
+ (goto-char beg)
+ (while (re-search-forward "`'" end t)
+ (replace-match "```")(setq end (+ 2 end)))
+ (goto-char beg)
+ (insert "\"")
+ (setq end (1+ end))
+ (goto-char end)
+ (insert "\""))
+
+(defun powershell-dollarparen-selection (beg end)
+ "Wraps the text between BEG and END with $().
+The point is moved to the closing paren."
+ (interactive `(,(region-beginning) ,(region-end)))
+ (if (not mark-active)
+ (error "Command requires a marked region"))
+ (save-excursion
+ (goto-char end)
+ (insert ")")
+ (goto-char beg)
+ (insert "$("))
+ (forward-char))
+
+(defun powershell-regexp-to-regex (beg end)
+ "Turn the text between BEG and END into a regex.
+The text is assumed to be `regexp-opt' output."
+ (interactive `(,(region-beginning) ,(region-end)))
+ (if (not mark-active)
+ (error "Command requires a marked region"))
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\(" nil t)
+ (replace-match "("))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\)" nil t)
+ (replace-match ")"))
+ (goto-char (point-min))
+ (while (re-search-forward "\\\\|" nil t)
+ (replace-match "|"))))
+
+
+;; Taken from About_Keywords
+(defvar powershell-keywords
+ (concat "\\_<"
+ (regexp-opt
+ '("begin" "break" "catch" "class" "continue" "data" "define" "do" "default"
+ "dynamicparam" "else" "elseif" "end" "enum" "exit" "filter" "finally"
+ "for" "foreach" "from" "function" "hidden" "if" "in" "param" "process"
+ "return" "static" "switch" "throw" "trap" "try" "until" "using" "var" "where" "while"
+ ;; Questionable, specific to workflow sessions
+ "inlinescript")
+ t)
+ "\\_>")
+ "PowerShell keywords.")
+
+;; Taken from About_Comparison_Operators and some questionable sources :-)
+(defvar powershell-operators
+ (concat "\\_<"
+ (regexp-opt
+ '("-eq" "-ne" "-gt" "-ge" "-lt" "-le"
+ ;; case sensitive versions
+ "-ceq" "-cne" "-cgt" "-cge" "-clt" "-cle"
+ ;; explicitly case insensitive
+ "-ieq" "-ine" "-igt" "-ige" "-ilt" "-ile"
+ "-band" "-bor" "-bxor" "-bnot"
+ "-and" "-or" "-xor" "-not" "!"
+ "-like" "-notlike" "-clike" "-cnotlike" "-ilike" "-inotlike"
+ "-match" "-notmatch" "-cmatch" "-cnotmatch" "-imatch" "-inotmatch"
+ "-contains" "-notcontains" "-ccontains" "-cnotcontains"
+ "-icontains" "-inotcontains"
+ "-replace" "-creplace" "-ireplace"
+ "-is" "-isnot" "-as" "-f"
+ "-in" "-cin" "-iin" "-notin" "-cnotin" "-inotin"
+ "-split" "-csplit" "-isplit"
+ "-join"
+ "-shl" "-shr"
+ ;; Questionable --> specific to certain contexts
+ "-casesensitive" "-wildcard" "-regex" "-exact" ;specific to case
+ "-begin" "-process" "-end" ;specific to scriptblock
+ ) t)
+ "\\_>")
+ "PowerShell operators.")
+
+(defvar powershell-scope-names
+ '("global" "local" "private" "script" )
+ "Names of scopes in PowerShell mode.")
+
+(defvar powershell-variable-drive-names
+ (append '("env" "function" "variable" "alias" "hklm" "hkcu" "wsman") powershell-scope-names)
+ "Names of scopes in PowerShell mode.")
+
+(defconst powershell-variables-regexp
+ ;; There are 2 syntaxes detected: ${[scope:]name} and $[scope:]name
+ ;; Match 0 is the entire variable name.
+ ;; Match 1 is scope when the former syntax is found.
+ ;; Match 2 is scope when the latter syntax is found.
+ (concat
+ "\\_<$\\(?:{\\(?:" (regexp-opt powershell-variable-drive-names t)
+ ":\\)?[^}]+}\\|"
+ "\\(?:" (regexp-opt powershell-variable-drive-names t)
+ ":\\)?[a-zA-Z0-9_]+\\_>\\)")
+ "Identifies legal powershell variable names.")
+
+(defconst powershell-function-names-regex
+ ;; Syntax detected is [scope:]verb-noun
+ ;; Match 0 is the entire name.
+ ;; Match 1 is the scope if any.
+ ;; Match 2 is the function name (which must exist)
+ (concat
+ "\\_<\\(?:" (regexp-opt powershell-scope-names t) ":\\)?"
+ "\\([A-Z][a-zA-Z0-9]*-[A-Z0-9][a-zA-Z0-9]*\\)\\_>")
+ "Identifies legal function & filter names.")
+
+(defconst powershell-object-types-regexp
+ ;; Syntax is \[name[.name]\] (where the escaped []s are literal)
+ ;; Only Match 0 is returned.
+ "\\[\\(?:[a-zA-Z_][a-zA-Z0-9]*\\)\\(?:\\.[a-zA-Z_][a-zA-Z0-9]*\\)*\\]"
+ "Identifies object type references. I.E. [object.data.type] syntax.")
+
+(defconst powershell-function-switch-names-regexp
+ ;; Only Match 0 is returned.
+ "\\_<-[a-zA-Z][a-zA-Z0-9]*\\_>"
+ "Identifies function parameter names of the form -xxxx.")
+
+;; Taken from Get-Variable on a fresh shell, merged with man
+;; about_automatic_variables
+(defvar powershell-builtin-variables-regexp
+ (regexp-opt
+ '("$" "?"
+ "^" "_"
+ "args" "ConsoleFileName"
+ "Error" "Event"
+ "EventArgs"
+ "EventSubscriber" "ExecutionContext"
+ "false" "Foreach"
+ "HOME" "Host"
+ "input" "lsCoreCLR"
+ "lsLinux" "lsMacOS"
+ "lsWindows" "LASTEXITCODE"
+ "Matches" "MyInvocation"
+ "NestedPromptLevel" "null"
+ "PID" "PROFILE"
+ "PSBoundParameters" "PSCmdlet"
+ "PSCommandPath"
+ "PSCulture" "PSDebugContext"
+ "PSHOME" "PSITEM"
+ "PSScriptRoot" "PSSenderInfo"
+ "PSUICulture" "PSVersionTable"
+ "PWD" "ReportErrorShowExceptionClass"
+ "ReportErrorShowInnerException" "ReportErrorShowSource"
+ "ReportErrorShowStackTrace" "Sender"
+ "ShellId" "SourceArgs"
+ "SourceEventArgs" "StackTrace"
+ "this" "true" ) t)
+ "The names of the built-in PowerShell variables.
+They are highlighted differently from the other variables.")
+
+(defvar powershell-config-variables-regexp
+ (regexp-opt
+ '("ConfirmPreference" "DebugPreference"
+ "ErrorActionPreference" "ErrorView"
+ "FormatEnumerationLimit" "InformationPreference"
+ "LogCommandHealthEvent"
+ "LogCommandLifecycleEvent" "LogEngineHealthEvent"
+ "LogEngineLifecycleEvent" "LogProviderHealthEvent"
+ "LogProviderLifecycleEvent" "MaximumAliasCount"
+ "MaximumDriveCount" "MaximumErrorCount"
+ "MaximumFunctionCount" "MaximumHistoryCount"
+ "MaximumVariableCount" "OFS"
+ "OutputEncoding" "ProgressPreference"
+ "PSDefaultParameterValues" "PSEmailServer"
+ "PSModuleAutoLoadingPreference" "PSSessionApplicationName"
+ "PSSessionConfigurationName" "PSSessionOption"
+ "VerbosePreference" "WarningPreference"
+ "WhatIfPreference" ) t)
+ "Names of variables that configure powershell features.")
+
+
+(defun powershell-find-syntactic-comments (limit)
+ "Find PowerShell comment begin and comment end characters.
+Returns match 1 and match 2 for <# #> comment sequences respectively.
+Returns match 3 and optionally match 4 for #/eol comments.
+Match 4 is returned only if eol is found before LIMIT"
+ (when (search-forward "#" limit t)
+ (cond
+ ((looking-back "<#" nil)
+ (set-match-data (list (match-beginning 0) (1+ (match-beginning 0))
+ (match-beginning 0) (1+ (match-beginning 0)))))
+ ((looking-at ">")
+ (set-match-data (list (match-beginning 0) (match-end 0)
+ nil nil
+ (match-beginning 0) (match-end 0)))
+ (forward-char))
+ (t
+ (let ((start (point)))
+ (if (search-forward "\n" limit t)
+ (set-match-data (list (1- start) (match-end 0)
+ nil nil nil nil
+ (1- start) start
+ (match-beginning 0) (match-end 0)))
+ (set-match-data (list start (match-end 0)
+ nil nil nil nil
+ (1- start) start))))))
+ t))
+
+(defun powershell-find-syntactic-quotes (limit)
+ "Find PowerShell hear string begin and end sequences upto LIMIT.
+Returns match 1 and match 2 for @' '@ sequences respectively.
+Returns match 3 and match 4 for @\" \"@ sequences respectively."
+ (when (search-forward "@" limit t)
+ (cond
+ ((looking-at "'$")
+ (set-match-data (list (match-beginning 0) (1+ (match-beginning 0))
+ (match-beginning 0) (1+ (match-beginning 0))))
+ (forward-char))
+ ((looking-back "^'@" nil)
+ (set-match-data (list (1- (match-end 0)) (match-end 0)
+ nil nil
+ (1- (match-end 0)) (match-end 0))))
+ ((looking-at "\"$")
+ (set-match-data (list (match-beginning 0) (1+ (match-beginning 0))
+ nil nil
+ nil nil
+ (match-beginning 0) (1+ (match-beginning 0))))
+ (forward-char))
+ ((looking-back "^\"@" nil)
+ (set-match-data (list (1- (match-end 0)) (match-end 0)
+ nil nil
+ nil nil
+ nil nil
+ (1- (match-end 0)) (match-end 0)))))
+ t))
+(defvar powershell-font-lock-syntactic-keywords
+ `((powershell-find-syntactic-comments (1 "!" t t) (2 "!" t t)
+ (3 "<" t t) (4 ">" t t))
+ (powershell-find-syntactic-quotes (1 "|" t t) (2 "|" t t)
+ (3 "|" t t) (4 "|" t t)))
+ "A list of regexp's or functions.
+Used to add `syntax-table' properties to
+characters that can't be set by the `syntax-table' alone.")
+
+
+(defvar powershell-font-lock-keywords-1
+ `( ;; Type annotations
+ (,powershell-object-types-regexp . font-lock-type-face)
+ ;; syntaxic keywords
+ (,powershell-keywords . font-lock-keyword-face)
+ ;; operators
+ (,powershell-operators . font-lock-builtin-face)
+ ;; the REQUIRES mark
+ ("^#\\(REQUIRES\\)" 1 font-lock-warning-face t))
+ "Keywords for the first level of font-locking in PowerShell mode.")
+
+(defvar powershell-font-lock-keywords-2
+ (append
+ powershell-font-lock-keywords-1
+ `( ;; Built-in variables
+ (,(concat "\\$\\(" powershell-builtin-variables-regexp "\\)\\>")
+ 0 font-lock-builtin-face t)
+ (,(concat "\\$\\(" powershell-config-variables-regexp "\\)\\>")
+ 0 font-lock-builtin-face t)))
+ "Keywords for the second level of font-locking in PowerShell mode.")
+
+(defvar powershell-font-lock-keywords-3
+ (append
+ powershell-font-lock-keywords-2
+ `( ;; user variables
+ (,powershell-variables-regexp
+ (0 font-lock-variable-name-face)
+ (1 (cons font-lock-type-face '(underline)) t t)
+ (2 (cons font-lock-type-face '(underline)) t t))
+ ;; function argument names
+ (,powershell-function-switch-names-regexp
+ (0 font-lock-constant-face)
+ (1 (cons font-lock-type-face '(underline)) t t)
+ (2 (cons font-lock-type-face '(underline)) t t))
+ ;; function names
+ (,powershell-function-names-regex
+ (0 font-lock-function-name-face)
+ (1 (cons font-lock-type-face '(underline)) t t))))
+ "Keywords for the maximum level of font-locking in PowerShell mode.")
+
+
+(defun powershell-setup-font-lock ()
+ "Set up the buffer local value for `font-lock-defaults'."
+ ;; I use font-lock-syntactic-keywords to set some properties and I
+ ;; don't want them ignored.
+ (set (make-local-variable 'parse-sexp-lookup-properties) t)
+ ;; This is where all the font-lock stuff actually gets set up. Once
+ ;; font-lock-defaults has its value, setting font-lock-mode true should
+ ;; cause all your syntax highlighting dreams to come true.
+ (setq font-lock-defaults
+ ;; The first value is all the keyword expressions.
+ '((powershell-font-lock-keywords-1
+ powershell-font-lock-keywords-2
+ powershell-font-lock-keywords-3)
+ ;; keywords-only means no strings or comments get fontified
+ nil
+ ;; case-fold (t ignores case)
+ t
+ ;; syntax-alist nothing special here
+ nil
+ ;; syntax-begin - no function defined to move outside syntactic block
+ nil
+ ;; font-lock-syntactic-keywords
+ ;; takes (matcher (match syntax override lexmatch) ...)...
+ (font-lock-syntactic-keywords
+ . powershell-font-lock-syntactic-keywords))))
+
+(defvar powershell-mode-syntax-table
+ (let ((powershell-mode-syntax-table (make-syntax-table)))
+ (modify-syntax-entry ?$ "_" powershell-mode-syntax-table)
+ (modify-syntax-entry ?: "_" powershell-mode-syntax-table)
+ (modify-syntax-entry ?- "_" powershell-mode-syntax-table)
+ (modify-syntax-entry ?^ "_" powershell-mode-syntax-table)
+ (modify-syntax-entry ?\\ "_" powershell-mode-syntax-table)
+ (modify-syntax-entry ?\{ "(}" powershell-mode-syntax-table)
+ (modify-syntax-entry ?\} "){" powershell-mode-syntax-table)
+ (modify-syntax-entry ?\[ "(]" powershell-mode-syntax-table)
+ (modify-syntax-entry ?\] ")[" powershell-mode-syntax-table)
+ (modify-syntax-entry ?\( "()" powershell-mode-syntax-table)
+ (modify-syntax-entry ?\) ")(" powershell-mode-syntax-table)
+ (modify-syntax-entry ?` "\\" powershell-mode-syntax-table)
+ (modify-syntax-entry ?_ "w" powershell-mode-syntax-table)
+ (modify-syntax-entry ?= "." powershell-mode-syntax-table)
+ (modify-syntax-entry ?| "." powershell-mode-syntax-table)
+ (modify-syntax-entry ?+ "." powershell-mode-syntax-table)
+ (modify-syntax-entry ?* "." powershell-mode-syntax-table)
+ (modify-syntax-entry ?/ "." powershell-mode-syntax-table)
+ (modify-syntax-entry ?' "\"" powershell-mode-syntax-table)
+ (modify-syntax-entry ?# "<" powershell-mode-syntax-table)
+ powershell-mode-syntax-table)
+ "Syntax for PowerShell major mode.")
+
+(defvar powershell-mode-map
+ (let ((powershell-mode-map (make-keymap)))
+ ;; (define-key powershell-mode-map "\r" 'powershell-indent-line)
+ (define-key powershell-mode-map (kbd "M-\"")
+ 'powershell-doublequote-selection)
+ (define-key powershell-mode-map (kbd "M-'") 'powershell-quote-selection)
+ (define-key powershell-mode-map (kbd "C-'") 'powershell-unquote-selection)
+ (define-key powershell-mode-map (kbd "C-\"") 'powershell-unquote-selection)
+ (define-key powershell-mode-map (kbd "M-`") 'powershell-escape-selection)
+ (define-key powershell-mode-map (kbd "C-$")
+ 'powershell-dollarparen-selection)
+ powershell-mode-map)
+ "Keymap for PS major mode.")
+
+(defun powershell-setup-menu ()
+ "Add a menu of PowerShell specific functions to the menu bar."
+ (define-key (current-local-map) [menu-bar powershell-menu]
+ (cons "PowerShell" (make-sparse-keymap "PowerShell")))
+ (define-key (current-local-map) [menu-bar powershell-menu doublequote]
+ '(menu-item "DoubleQuote Selection" powershell-doublequote-selection
+ :key-sequence(kbd "M-\"")
+ :help
+ "DoubleQuotes the selection escaping embedded double quotes"))
+ (define-key (current-local-map) [menu-bar powershell-menu quote]
+ '(menu-item "SingleQuote Selection" powershell-quote-selection
+ :key-sequence (kbd "M-'")
+ :help
+ "SingleQuotes the selection escaping embedded single quotes"))
+ (define-key (current-local-map) [menu-bar powershell-menu unquote]
+ '(menu-item "UnQuote Selection" powershell-unquote-selection
+ :key-sequence (kbd "C-'")
+ :help "Un-Quotes the selection un-escaping any escaped quotes"))
+ (define-key (current-local-map) [menu-bar powershell-menu escape]
+ '(menu-item "Escape Selection" powershell-escape-selection
+ :key-sequence (kbd "M-`")
+ :help (concat "Escapes variables in the selection"
+ " and extends existing escapes.")))
+ (define-key (current-local-map) [menu-bar powershell-menu dollarparen]
+ '(menu-item "DollarParen Selection" powershell-dollarparen-selection
+ :key-sequence (kbd "C-$")
+ :help "Wraps the selection in $()")))
+
+
+;;; Eldoc support
+
+(defcustom powershell-eldoc-def-files nil
+ "List of files containing function help strings used by function `eldoc-mode'.
+These are the strings function `eldoc-mode' displays as help for
+functions near point. The format of the file must be exactly as
+follows or who knows what happens.
+
+ (set (intern \"<fcn-name1>\" powershell-eldoc-obarray) \"<helper string1>\")
+ (set (intern \"<fcn-name2>\" powershell-eldoc-obarray) \"<helper string2>\")
+...
+
+Where <fcn-name> is the name of the function to which <helper string> applies.
+ <helper-string> is the string to display when point is near <fcn-name>."
+ :type '(repeat string)
+ :group 'powershell)
+
+(defvar powershell-eldoc-obarray ()
+ "Array for file entries by the function `eldoc'.
+`powershell-eldoc-def-files' entries are added into this array.")
+
+(defun powershell-eldoc-function ()
+ "Return a documentation string appropriate for the current context or nil."
+ (let ((word (thing-at-point 'symbol)))
+ (if word
+ (eval (intern-soft word powershell-eldoc-obarray)))))
+
+(defun powershell-setup-eldoc ()
+ "Load the function documentation for use with eldoc."
+ (when (not (null powershell-eldoc-def-files))
+ (set (make-local-variable 'eldoc-documentation-function)
+ 'powershell-eldoc-function)
+ (unless (vectorp powershell-eldoc-obarray)
+ (setq powershell-eldoc-obarray (make-vector 41 0))
+ (condition-case var (mapc 'load powershell-eldoc-def-files)
+ (error (message "*** powershell-setup-eldoc ERROR *** %s" var))))))
+;;; Note: You can create quite a bit of help with these commands:
+;;
+;; function Get-Signature ($Cmd) {
+;; if ($Cmd -is [Management.Automation.PSMethod]) {
+;; $List = @($Cmd)}
+;; elseif ($Cmd -isnot [string]) {
+;; throw ("Get-Signature {<method>|<command>}`n" +
+;; "'$Cmd' is not a method or command")}
+;; else {$List = @(Get-Command $Cmd -ErrorAction SilentlyContinue)}
+;; if (!$List[0] ) {
+;; throw "Command '$Cmd' not found"}
+;; foreach ($O in $List) {
+;; switch -regex ($O.GetType().Name) {
+;; 'AliasInfo' {
+;; Get-Signature ($O.Definition)}
+;; '(Cmdlet|ExternalScript)Info' {
+;; $O.Definition} # not sure what to do with ExternalScript
+;; 'F(unction|ilter)Info'{
+;; if ($O.Definition -match '^param *\(') {
+;; $t = [Management.Automation.PSParser]::tokenize($O.Definition,
+;; [ref]$null)
+;; $c = 1;$i = 1
+;; while($c -and $i++ -lt $t.count) {
+;; switch ($t[$i].Type.ToString()) {
+;; GroupStart {$c++}
+;; GroupEnd {$c--}}}
+;; $O.Definition.substring(0,$t[$i].start + 1)} #needs parsing
+;; else {$O.Name}}
+;; 'PSMethod' {
+;; foreach ($t in @($O.OverloadDefinitions)) {
+;; while (($b=$t.IndexOf('`1[[')) -ge 0) {
+;; $t=$t.remove($b,$t.IndexOf(']]')-$b+2)}
+;; $t}}}}}
+;; get-command|
+;; ?{$_.CommandType -ne 'Alias' -and $_.Name -notlike '*:'}|
+;; %{$_.Name}|
+;; sort|
+;; %{("(set (intern ""$($_.Replace('\','\\'))"" powershell-eldoc-obarray)" +
+;; " ""$(Get-Signature $_|%{$_.Replace('\','\\').Replace('"','\"')})"")"
+;; ).Replace("`r`n"")",""")")} > .\powershell-eldoc.el
+
+
+(defvar powershell-imenu-expression
+ `(("Functions" ,(concat "function " powershell-function-names-regex) 2)
+ ("Filters" ,(concat "filter " powershell-function-names-regex) 2)
+ ("Top variables"
+ , (concat "^\\(" powershell-object-types-regexp "\\)?\\("
+ powershell-variables-regexp "\\)\\s-*=")
+ 2))
+ "List of regexps matching important expressions, for speebar & imenu.")
+
+(defun powershell-setup-imenu ()
+ "Install `powershell-imenu-expression'."
+ (when (require 'imenu nil t)
+ ;; imenu doc says these are buffer-local by default
+ (setq imenu-generic-expression powershell-imenu-expression)
+ (setq imenu-case-fold-search nil)
+ (imenu-add-menubar-index)))
+
+(defun powershell-setup-speedbar ()
+ "Install `speedbar-add-supported-extension'."
+ (when (require 'speedbar nil t)
+ (speedbar-add-supported-extension ".ps1?")))
+
+;; A better command would be something like "powershell.exe -NoLogo
+;; -NonInteractive -Command & (buffer-file-name)". But it will just
+;; sit there waiting... The following will only work when .ps1 files
+;; are associated with powershell.exe. And if they don't contain spaces.
+(defvar powershell-compile-command
+ '(buffer-file-name)
+ "Default command used to invoke a powershell script.")
+
+;; The column number will be off whenever tabs are used. Since this is
+;; the default in this mode, we will not capture the column number.
+(setq compilation-error-regexp-alist
+ (cons '("At \\(.*\\):\\([0-9]+\\) char:\\([0-9]+\\)" 1 2)
+ compilation-error-regexp-alist))
+
+
+(add-hook 'powershell-mode-hook #'imenu-add-menubar-index)
+
+;;;###autoload
+(define-derived-mode powershell-mode prog-mode "PS"
+ "Major mode for editing PowerShell scripts.
+
+\\{powershell-mode-map}
+Entry to this mode calls the value of `powershell-mode-hook' if
+that value is non-nil."
+ (powershell-setup-font-lock)
+ (setq-local indent-line-function 'powershell-indent-line)
+ (setq-local compile-command powershell-compile-command)
+ (setq-local comment-start "#")
+ (setq-local comment-start-skip "#+\\s*")
+ (setq-local parse-sexp-ignore-comments t)
+ ;; Support electric-pair-mode
+ (setq-local electric-indent-chars
+ (append "{}():;," electric-indent-chars))
+ (powershell-setup-imenu)
+ (powershell-setup-speedbar)
+ (powershell-setup-menu)
+ (powershell-setup-eldoc))
+
+;;; PowerShell inferior mode
+
+;;; Code:
+(defcustom powershell-location-of-exe
+ (or (executable-find "pwsh") (executable-find "powershell"))
+ "A string providing the location of the powershell executable. Since
+the newer PowerShell Core (pwsh.exe) does not replace the older Windows
+PowerShell (powershell.exe) when installed, this attempts to find the
+former first, and only if it doesn't exist, falls back to the latter."
+ :group 'powershell
+ :type 'string)
+
+(defcustom powershell-log-level 3
+ "The current log level for powershell internal operations.
+0 = NONE, 1 = Info, 2 = VERBOSE, 3 = DEBUG."
+ :group 'powershell
+ :type 'integer)
+
+(defcustom powershell-squish-results-of-silent-commands t
+ "The function `powershell-invoke-command-silently' returns the results
+of a command in a string. PowerShell by default, inserts newlines when
+the output exceeds the configured width of the powershell virtual
+window. In some cases callers might want to get the results with the
+newlines and formatting removed. Set this to true, to do that."
+ :group 'powershell
+ :type 'boolean)
+
+(defvar powershell-prompt-regex "PS [^#$%>]+> "
+ "Regexp to match the powershell prompt.
+powershell.el uses this regex to determine when a command has
+completed. Therefore, you need to set this appropriately if you
+explicitly change the prompt function in powershell. Any value
+should include a trailing space, if the powershell prompt uses a
+trailing space, but should not include a trailing newline.
+
+The default value will match the default PowerShell prompt.")
+
+(defvar powershell-command-reply nil
+ "The reply of powershell commands.
+This is retained for housekeeping purposes.")
+
+(defvar powershell--max-window-width 0
+ "The maximum width of a powershell window.
+You shouldn't need to ever set this. It gets set automatically,
+once, when the powershell starts up.")
+
+(defvar powershell-command-timeout-seconds 12
+ "The timeout for a powershell command.
+powershell.el will wait this long before giving up.")
+
+(defvar powershell--need-rawui-resize t
+ "No need to fuss with this. It's intended for internal use
+only. It gets set when powershell needs to be informed that
+emacs has resized its window.")
+
+(defconst powershell--find-max-window-width-command
+ (concat
+ "function _Emacs_GetMaxPhsWindowSize"
+ " {"
+ " $rawui = (Get-Host).UI.RawUI;"
+ " $mpws_exists = ($rawui | Get-Member | Where-Object"
+ " {$_.Name -eq \"MaxPhysicalWindowSize\"});"
+ " if ($mpws_exists -eq $null) {"
+ " 210"
+ " } else {"
+ " $rawui.MaxPhysicalWindowSize.Width"
+ " }"
+ " };"
+ " _Emacs_GetMaxPhsWindowSize")
+ "The powershell logic to determine the max physical window width.")
+
+(defconst powershell--set-window-width-fn-name "_Emacs_SetWindowWidth"
+ "The name of the function this mode defines in PowerShell to
+set the window width. Intended for internal use only.")
+
+(defconst powershell--text-of-set-window-width-ps-function
+ ;; see
+ ;; http://blogs.msdn.com/lior/archive/2009/05/27/ResizePowerShellConsoleWindow.aspx
+ ;;
+ ;; When making the console window narrower, you mus set the window
+ ;; size first. When making the console window wider, you must set the
+ ;; buffer size first.
+
+ (concat "function " powershell--set-window-width-fn-name
+ "([string] $pswidth)"
+ " {"
+ " $rawui = (Get-Host).UI.RawUI;"
+ " $bufsize = $rawui.BufferSize;"
+ " $winsize = $rawui.WindowSize;"
+ " $cwidth = $winsize.Width;"
+ " $winsize.Width = $pswidth;"
+ " $bufsize.Width = $pswidth;"
+ " if ($cwidth -lt $pswidth) {"
+ " $rawui.BufferSize = $bufsize;"
+ " $rawui.WindowSize = $winsize;"
+ " }"
+ " elseif ($cwidth -gt $pswidth) {"
+ " $rawui.WindowSize = $winsize;"
+ " $rawui.BufferSize = $bufsize;"
+ " };"
+ " Set-Variable -name rawui -value $null;"
+ " Set-Variable -name winsize -value $null;"
+ " Set-Variable -name bufsize -value $null;"
+ " Set-Variable -name cwidth -value $null;"
+ " }")
+
+ "The text of the powershell function that will be used at runtime to
+set the width of the virtual Window in PowerShell, as the Emacs window
+gets resized.")
+
+(defun powershell-log (level text &rest args)
+ "Log a message at level LEVEL.
+If LEVEL is higher than `powershell-log-level', the message is
+ignored. Otherwise, it is printed using `message'.
+TEXT is a format control string, and the remaining arguments ARGS
+are the string substitutions (see `format')."
+ (if (<= level powershell-log-level)
+ (let* ((msg (apply 'format text args)))
+ (message "%s" msg))))
+
+;; (defun dino-powershell-complete (arg)
+;; "do powershell completion on the given STRING. Pop up a buffer
+;; with the completion list."
+;; (interactive
+;; (list (read-no-blanks-input "\
+;; Stub to complete: ")))
+
+;; (let ((proc
+;; (get-buffer-process (current-buffer))))
+;; (comint-proc-query proc (concat "Get-Command " arg "*\n"))
+;; )
+;; )
+
+;; (defun dino-powershell-cmd-complete ()
+;; "try to get powershell completion to work."
+;; (interactive)
+;; (let ((proc
+;; (get-buffer-process (current-buffer))))
+;; ;; (comint-proc-query proc "Get-a\t")
+;; ;; (comint-simple-send proc "Get-a\t")
+;; (comint-send-string proc "Get-a\t\n")
+;; ;; (process-send-eof)
+;; )
+;; )
+
+(defun powershell--define-set-window-width-function (proc)
+ "Sends a function definition to the PowerShell instance
+identified by PROC. The function sets the window width of the
+PowerShell virtual window. Later, the function will be called
+when the width of the emacs window changes."
+ (if proc
+ (progn
+ ;;process-send-string
+ (comint-simple-send
+ proc
+ powershell--text-of-set-window-width-ps-function))))
+
+(defun powershell--get-max-window-width (buffer-name)
+ "Gets the maximum width of the virtual window for PowerShell running
+in the buffer with name BUFFER-NAME.
+
+In PowerShell 1.0, the maximum WindowSize.Width for
+PowerShell is 210, hardcoded, I believe. In PowerShell 2.0, the max
+windowsize.Width is provided in the RawUI.MaxPhysicalWindowSize
+property.
+
+This function does the right thing, and sets the buffer-local
+`powershell--max-window-width' variable with the correct value."
+ (let ((proc (get-buffer-process buffer-name)))
+
+ (if proc
+ (with-current-buffer buffer-name
+ (powershell-invoke-command-silently
+ proc
+ powershell--find-max-window-width-command
+ 0.90)
+
+ ;; store the retrieved width
+ (setq powershell--max-window-width
+ (if (and (not (null powershell-command-reply))
+ (string-match
+ "\\([1-9][0-9]*\\)[ \t\f\v\n]+"
+ powershell-command-reply))
+ (string-to-number (match-string 1 powershell-command-reply))
+ 200)))))) ;; could go to 210, but let's use 200 to be safe
+
+(defun powershell--set-window-width (proc)
+ "Run the PowerShell function that sets the RawUI width
+appropriately for a PowerShell shell.
+
+This is necessary to get powershell to do the right thing, as far
+as text formatting, when the emacs window gets resized.
+
+The function gets defined in powershell upon powershell startup."
+ (let ((ps-width
+ (number-to-string (min powershell--max-window-width (window-width)))))
+ (progn
+ ;;(process-send-string
+ (comint-simple-send
+ proc
+ (concat powershell--set-window-width-fn-name
+ "('" ps-width "')")))))
+
+;;;###autoload
+(defun powershell (&optional buffer prompt-string)
+ "Run an inferior PowerShell.
+If BUFFER is non-nil, use it to hold the powershell
+process. Defaults to *PowerShell*.
+
+Interactively, a prefix arg means to prompt for BUFFER.
+
+If BUFFER exists but the shell process is not running, it makes a
+new shell.
+
+If BUFFER exists and the shell process is running, just switch to
+BUFFER.
+
+If PROMPT-STRING is non-nil, sets the prompt to the given value.
+
+See the help for `shell' for more details. \(Type
+\\[describe-mode] in the shell buffer for a list of commands.)"
+ (interactive
+ (list
+ (and current-prefix-arg
+ (read-buffer "Shell buffer: "
+ (generate-new-buffer-name "*PowerShell*")))))
+
+ (setq buffer (get-buffer-create (or buffer "*PowerShell*")))
+ (powershell-log 1 "powershell starting up...in buffer %s" (buffer-name buffer))
+ (let ((explicit-shell-file-name (if (and (eq system-type 'cygwin)
+ (fboundp 'cygwin-convert-file-name-from-windows))
+ (cygwin-convert-file-name-from-windows powershell-location-of-exe)
+ powershell-location-of-exe)))
+ ;; set arguments for the powershell exe.
+ ;; Does this need to be tunable?
+
+ (shell buffer))
+
+ ;; (powershell--get-max-window-width "*PowerShell*")
+ ;; (powershell-invoke-command-silently (get-buffer-process "*csdeshell*")
+ ;; "[Ionic.Csde.Utilities]::Version()" 2.9)
+
+ ;; (comint-simple-send (get-buffer-process "*csdeshell*") "prompt\n")
+
+ (let ((proc (get-buffer-process buffer)))
+
+ (make-local-variable 'powershell-prompt-regex)
+ (make-local-variable 'powershell-command-reply)
+ (make-local-variable 'powershell--max-window-width)
+ (make-local-variable 'powershell-command-timeout-seconds)
+ (make-local-variable 'powershell-squish-results-of-silent-commands)
+ (make-local-variable 'powershell--need-rawui-resize)
+ (make-local-variable 'comint-prompt-read-only)
+
+ ;; disallow backspace over the prompt:
+ (setq comint-prompt-read-only t)
+
+ ;; We need to tell powershell how wide the emacs window is, because
+ ;; powershell pads its output to the width it thinks its window is.
+ ;;
+ ;; The way it's done: every time the width of the emacs window changes, we
+ ;; set a flag. Then, before sending a powershell command that is
+ ;; typed into the buffer, to the actual powershell process, we check
+ ;; that flag. If it is set, we resize the powershell window appropriately,
+ ;; before sending the command.
+
+ ;; If we didn't do this, powershell output would get wrapped at a
+ ;; column width that would be different than the emacs buffer width,
+ ;; and everything would look ugly.
+
+ ;; get the maximum width for powershell - can't go beyond this
+ (powershell--get-max-window-width buffer)
+
+ ;; define the function for use within powershell to resize the window
+ (powershell--define-set-window-width-function proc)
+
+ ;; add the hook that sets the flag
+ (add-hook 'window-size-change-functions
+ #'(lambda (&rest _)
+ (setq powershell--need-rawui-resize t)))
+
+ ;; set the flag so we resize properly the first time.
+ (setq powershell--need-rawui-resize t)
+
+ (if prompt-string
+ (progn
+ ;; This sets up a prompt for the PowerShell. The prompt is
+ ;; important because later, after sending a command to the
+ ;; shell, the scanning logic that grabs the output looks for
+ ;; the prompt string to determine that the output is complete.
+ (comint-simple-send
+ proc
+ (concat "function prompt { '" prompt-string "' }"))
+
+ (setq powershell-prompt-regex prompt-string)))
+
+ ;; hook the kill-buffer action so we can kill the inferior process?
+ (add-hook 'kill-buffer-hook 'powershell-delete-process)
+
+ ;; wrap the comint-input-sender with a PS version
+ ;; must do this after launching the shell!
+ (make-local-variable 'comint-input-sender)
+ (setq comint-input-sender 'powershell-simple-send)
+
+ ;; set a preoutput filter for powershell. This will trim newlines
+ ;; after the prompt.
+ (add-hook 'comint-preoutput-filter-functions
+ 'powershell-preoutput-filter-for-prompt)
+
+ ;; send a carriage-return (get the prompt)
+ (comint-send-input)
+ (accept-process-output proc))
+
+ ;; The launch hooks for powershell has not (yet?) been implemented
+ ;;(run-hooks 'powershell-launch-hook)
+
+ ;; return the buffer created
+ buffer)
+
+;; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+;; Using powershell on emacs23, I get an error:
+;;
+;; ansi-color-process-output: Marker does not point anywhere
+;;
+;; Here's what's happening.
+;;
+;; In order to be able to read the output from powershell, this shell
+;; starts powershell.exe in "interactive mode", using the -i
+;; option. This which has the curious side-effect of turning off the
+;; prompt in powershell. Normally powershell will return its results,
+;; then emit a prompt to indicate that it is ready for more input. In
+;; interactive mode it doesn't emit the prompt. To work around this,
+;; this code (powershell.el) sends an explicit `prompt` command after
+;; sending any user-entered command to powershell. This tells powershell
+;; to explicitly return the prompt, after the results of the prior
+;; command. The prompt then shows up in the powershell buffer. Lovely.
+;;
+;; But, `ansi-color-apply-on-region` gets called after every command
+;; gets sent to powershell. It gets called with args `(begin end)`,
+;; which are both markers. Turns out the very first time this fn is
+;; called, the position for the begin marker is nil.
+;;
+;; `ansi-color-apply-on-region` calls `(goto-char begin)` (effectively),
+;; and when the position on the marker is nil, the call errors with
+;; "Marker does not point anywhere."
+;;
+;; The following advice suppresses the call to
+;; `ansi-color-apply-on-region` when the begin marker points
+;; nowhere.
+(defadvice ansi-color-apply-on-region (around
+ powershell-throttle-ansi-colorizing
+ (begin end)
+ compile)
+ (progn
+ (let ((start-pos (marker-position begin)))
+ (cond
+ (start-pos
+ (progn
+ ad-do-it))))))
+
+(defun powershell--silent-cmd-filter (process result)
+"A process filter that captures output from a shell and stores it
+to `powershell-command-reply', rather than allowing the output to
+be displayed in the shell buffer.
+
+This function is intended for internal use only."
+ (let ((end-of-result
+ (string-match (concat ".*\n\\(" powershell-prompt-regex "\\)[ \n]*\\'")
+ result)))
+ (if (and end-of-result (numberp end-of-result))
+
+ (progn
+ ;; Store everything except the follow-on prompt.
+ ;; The result probably includes a final newline!
+ (setq result (substring result 0 (match-beginning 1)))
+
+ (if powershell-squish-results-of-silent-commands
+ (setq result
+ (replace-regexp-in-string "\n" "" result)))
+
+ (setq powershell-command-reply
+ (concat powershell-command-reply result)))
+
+ (progn
+ (if powershell-squish-results-of-silent-commands
+ (setq result
+ (replace-regexp-in-string "\n" "" result)))
+
+ (setq powershell-command-reply
+ (concat powershell-command-reply result))
+
+ ;; recurse. For very very long output, the recursion can
+ ;; cause stack overflow. Careful!
+ (accept-process-output process powershell-command-timeout-seconds)))))
+
+(defun powershell-invoke-command-silently (proc command
+ &optional timeout-seconds)
+ "In the PowerShell instance PROC, invoke COMMAND silently.
+Neither the COMMAND is echoed nor the results to the associated
+buffer. Use TIMEOUT-SECONDS as the timeout, waiting for a
+response. The COMMAND should be a string, and need not be
+terminated with a newline.
+
+This is helpful when, for example, doing setup work. Or other sneaky
+stuff, such as resetting the size of the PowerShell virtual window.
+
+Returns the result of the command, a string, without the follow-on
+command prompt. The result will probably end in a newline. This result
+is also stored in the buffer-local variable `powershell-command-reply'.
+
+In some cases the result can be prepended with the command prompt, as
+when, for example, several commands have been send in succession and the
+results of the prior command were not fully processed by the application.
+
+If a PowerShell buffer is not the current buffer, this function
+should be invoked within a call to `with-current-buffer' or
+similar in order to insure that the buffer-local values of
+`powershell-command-reply', `powershell-prompt-regex', and
+`powershell-command-timeout-seconds' are used.
+
+Example:
+
+ (with-current-buffer powershell-buffer-name
+ (powershell-invoke-command-silently
+ proc
+ command-string
+ 1.90))"
+
+ (let ((old-timeout powershell-command-timeout-seconds)
+ (original-filter (process-filter proc)))
+
+ (setq powershell-command-reply nil)
+
+ (if timeout-seconds
+ (setq powershell-command-timeout-seconds timeout-seconds))
+
+ (set-process-filter proc 'powershell--silent-cmd-filter)
+
+ ;; Send the command plus the "prompt" command. The filter
+ ;; will know the command is finished when it sees the command
+ ;; prompt.
+ ;;
+ (process-send-string proc (concat command "\nprompt\n"))
+
+ (accept-process-output proc powershell-command-timeout-seconds)
+
+ ;; output of the command is now available in powershell-command-reply
+
+ ;; Trim prompt from the beginning of the output.
+ ;; this can happen for the first command through
+ ;; the shell. I think there's a race condition.
+ (if (and powershell-command-reply
+ (string-match (concat "^" powershell-prompt-regex "\\(.*\\)\\'")
+ powershell-command-reply))
+ (setq powershell-command-reply
+ (substring powershell-command-reply
+ (match-beginning 1)
+ (match-end 1))))
+
+ ;; restore the original filter
+ (set-process-filter proc original-filter)
+
+ ;; restore the original timeout
+ (if timeout-seconds
+ (setq powershell-command-timeout-seconds old-timeout))
+
+ ;; the result:
+ powershell-command-reply))
+
+(defun powershell-delete-process (&optional proc)
+ "Delete the current buffer process or PROC."
+ (or proc
+ (setq proc (get-buffer-process (current-buffer))))
+ (and (processp proc)
+ (delete-process proc)))
+
+(defun powershell-preoutput-filter-for-prompt (string)
+ "Trim the newline from STRING, the prompt that we get back from
+powershell. This fn is set into the preoutput filters, so the
+newline is trimmed before being put into the output buffer."
+ (if (string-match (concat powershell-prompt-regex "\n\\'") string)
+ (substring string 0 -1) ;; remove newline
+ string))
+
+(defun powershell-simple-send (proc string)
+ "Override of the comint-simple-send function, with logic
+specifically designed for powershell. This just sends STRING,
+plus the prompt command.
+
+When running as an inferior shell with stdin/stdout redirected,
+powershell is in noninteractive mode. This means no prompts get
+emitted when a PS command completes. This makes it difficult for
+a comint mode to determine when the command has completed.
+Therefore, we send an explicit request for the prompt, after
+sending the actual (primary) command. When the primary command
+completes, PowerShell then responds to the \"prompt\" command,
+and emits the prompt.
+
+This insures we get and display the prompt."
+ ;; Tell PowerShell to resize its virtual window, if necessary. We do
+ ;; this by calling a resize function in the PowerShell, before sending
+ ;; the user-entered command to the shell.
+ ;;
+ ;; PowerShell keeps track of its \"console\", and formats its output
+ ;; according to the width it thinks it is using. This is true even when
+ ;; powershell is invoked with the - argument, which tells it to use
+ ;; stdin as input.
+
+ ;; Therefore, if the user has resized the emacs window since the last
+ ;; PowerShell command, we need to tell PowerShell to change the size
+ ;; of its virtual window. Calling that function does not change the
+ ;; size of a window that is visible on screen - it only changes the
+ ;; size of the virtual window that PowerShell thinks it is using. We
+ ;; do that by invoking the PowerShell function that this module
+ ;; defined for that purpose.
+ ;;
+ (if powershell--need-rawui-resize
+ (progn
+ (powershell--set-window-width proc)
+ (setq powershell--need-rawui-resize nil)))
+ (comint-simple-send proc (concat string "\n"))
+ (comint-simple-send proc "prompt\n"))
+
+;; Notes on TAB for completion.
+;; -------------------------------------------------------
+;; Emacs calls comint-dynamic-complete when the TAB key is pressed in a shell.
+;; This is set up in shell-mode-map.
+;;
+;; comint-dynamic-complete calls the functions in
+;; comint-dynamic-complete-functions, until one of them returns
+;; non-nil.
+;;
+;; comint-dynamic-complete-functions is a good thing to set in the mode hook.
+;;
+;; The default value for that var in a powershell shell is:
+;; (comint-replace-by-expanded-history
+;; shell-dynamic-complete-environment-variable
+;; shell-dynamic-complete-command
+;; shell-replace-by-expanded-directory
+;; comint-dynamic-complete-filename)
+
+;; (defun powershell-dynamic-complete-command ()
+;; "Dynamically complete the command at point. This function is
+;; similar to `comint-dynamic-complete-filename', except that it
+;; searches the commands from powershell and then the `exec-path'
+;; (minus the trailing Emacs library path) for completion candidates.
+
+;; Completion is dependent on the value of
+;; `shell-completion-execonly', plus those that effect file
+;; completion. See `powershell-dynamic-complete-as-command'.
+
+;; Returns t if successful."
+;; (interactive)
+;; (let ((filename (comint-match-partial-filename)))
+;; (if (and filename
+;; (save-match-data (not (string-match "[~/]" filename)))
+;; (eq (match-beginning 0)
+;; (save-excursion (shell-backward-command 1) (point))))
+;; (prog2 (message "Completing command name...")
+;; (powershell-dynamic-complete-as-command)))))
+
+;; (defun powershell-dynamic-complete-as-command ()
+;; "Dynamically complete at point as a command.
+;; See `shell-dynamic-complete-filename'. Returns t if successful."
+;; (let* ((filename (or (comint-match-partial-filename) ""))
+;; (filenondir (file-name-nondirectory filename))
+;; (path-dirs (cdr (reverse exec-path)))
+;; (cwd (file-name-as-directory (expand-file-name default-directory)))
+;; (ignored-extensions
+;; (and comint-completion-fignore
+;; (mapconcat (function (lambda (x) (concat (regexp-quote x) "$")))
+;; comint-completion-fignore "\\|")))
+;; (dir "") (comps-in-dir ())
+;; (file "") (abs-file-name "") (completions ()))
+
+;; ;; Go thru each cmd in powershell's lexicon, finding completions.
+
+;; ;; Go thru each dir in the search path, finding completions.
+;; (while path-dirs
+;; (setq dir (file-name-as-directory (comint-directory (or (car path-dirs) ".")))
+;; comps-in-dir (and (file-accessible-directory-p dir)
+;; (file-name-all-completions filenondir dir)))
+;; ;; Go thru each completion found, to see whether it should be used.
+;; (while comps-in-dir
+;; (setq file (car comps-in-dir)
+;; abs-file-name (concat dir file))
+;; (if (and (not (member file completions))
+;; (not (and ignored-extensions
+;; (string-match ignored-extensions file)))
+;; (or (string-equal dir cwd)
+;; (not (file-directory-p abs-file-name)))
+;; (or (null shell-completion-execonly)
+;; (file-executable-p abs-file-name)))
+;; (setq completions (cons file completions)))
+;; (setq comps-in-dir (cdr comps-in-dir)))
+;; (setq path-dirs (cdr path-dirs)))
+;; ;; OK, we've got a list of completions.
+;; (let ((success (let ((comint-completion-addsuffix nil))
+;; (comint-dynamic-simple-complete filenondir completions))))
+;; (if (and (memq success '(sole shortest)) comint-completion-addsuffix
+;; (not (file-directory-p (comint-match-partial-filename))))
+;; (insert " "))
+;; success)))
+
+(provide 'powershell)
+
+;;; powershell.el ends here
diff --git a/init.el b/init.el
@@ -303,7 +303,7 @@
("melpa-stable" . "https://stable.melpa.org/packages/")
("melpa" . "https://melpa.org/packages/")))
'(package-selected-packages
- '(web-mode lexic csharp-mode editorconfig forge elfeed-tube-mpv elfeed-tube cider restclient-jq graphviz-dot-mode consult-eglot jq-mode multiple-cursors ob-restclient restclient vterm deadgrep helpful pdf-tools paredit-menu paredit corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-roam org-contrib org ace-window expand-region consult marginalia uuidgen request diminish which-key))
+ '(ob-powershell powershell web-mode lexic csharp-mode editorconfig forge elfeed-tube-mpv elfeed-tube cider restclient-jq graphviz-dot-mode consult-eglot jq-mode multiple-cursors ob-restclient restclient vterm deadgrep helpful pdf-tools paredit-menu paredit corfu sly eglot aggressive-indent project nov nhexl-mode elfeed magit yaml-mode json-mode lua-mode go-mode geiser-guile geiser org-roam org-contrib org ace-window expand-region consult marginalia uuidgen request diminish which-key))
'(pcomplete-ignore-case t t)
'(pixel-scroll-precision-mode t)
'(read-buffer-completion-ignore-case t)