1 ;; powershell.el, version 0.1
4 ;; Thu, 10 Apr 2008 11:10
6 ;; Run Windows PowerShell v1.0 as an inferior shell within emacs. Tested with
10 ;; - test what happens when you expand the window size beyond the
11 ;; maxWindowWidth for the RawUI
12 ;; - make everything configurable (Powershell exe, initial args, powershell
14 ;; - implement powershell launch hooks
15 ;; - prevent backspace from deleting the powershell prompt? (do other shells
22 (defun powershell-gen-window-width-string ()
23 (concat "$a = (Get-Host).UI.RawUI\n"
24 "$b = $a.WindowSize\n"
25 "$b.Width = " (number-to-string (window-width)) "\n"
26 "$a.BufferSize = $b\n"
31 (defvar powershell-prompt-pattern
"PS [^#$%>]+>"
32 "Regexp for powershell prompt. This isn't really used, because I couldn't figure out how to get it to work."
35 (defgroup powershell nil
36 "Running shell from within Emacs buffers."
41 (defcustom powershell-need-rawui-resize t
42 "set when powershell needs to be resized"
47 (defun powershell (&optional buffer
)
48 "Run an inferior powershell, by invoking the shell function. See the help for shell for more details.
49 \(Type \\[describe-mode] in the shell buffer for a list of commands.)"
52 (and current-prefix-arg
53 (read-buffer "Shell buffer: "
54 (generate-new-buffer-name "*PowerShell*")))))
55 ; get a name for the buffer
56 (setq buffer
(get-buffer-create (or buffer
"*PowerShell*")))
59 (tmp-shellfile explicit-shell-file-name
)
61 ; set arguments for the powershell exe.
62 ; This needs to be tunable.
63 (setq explicit-shell-file-name
"c:\\windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe")
64 (setq explicit-powershell.exe-args
'("-Command" "-" )) ; interactive, but no command prompt
69 ; restore the original shell
70 (if explicit-shell-file-name
71 (setq explicit-shell-file-name tmp-shellfile
)
76 (proc (get-buffer-process buffer
))
79 ; This sets up the powershell RawUI screen width. By default,
80 ; the powershell v1.0 assumes terminal width of 80 chars.
81 ;This means input gets wrapped at the 80th column. We reset the
82 ; width of the PS terminal to the window width.
83 (add-hook 'window-size-change-functions
'powershell-window-size-changed
)
85 (powershell-window-size-changed)
87 ; ask for initial prompt
88 (comint-simple-send proc
"prompt")
91 ; hook the kill-buffer action so we can kill the inferior process?
92 (add-hook 'kill-buffer-hook
'powershell-delete-process
)
94 ; wrap the comint-input-sender with a PS version
95 ; must do this after launching the shell!
96 (make-local-variable 'comint-input-sender
)
97 (setq comint-input-sender
'powershell-simple-send
)
99 ; set a preoutput filter for powershell. This will trim newlines after the prompt.
100 (add-hook 'comint-preoutput-filter-functions
'powershell-preoutput-filter-for-prompt
)
102 ;(run-hooks 'powershell-launch-hook)
104 ; return the buffer created
109 (defun powershell-window-size-changed (&optional frame
)
110 ; do not actually resize here. instead just set a flag.
111 (setq powershell-need-rawui-resize t
)
116 (defun powershell-delete-process (&optional proc
)
118 (setq proc
(get-buffer-process (current-buffer))))
120 (delete-process proc
))
125 ;; This function trims the newline from the prompt that we
126 ;; get back from powershell. It is set into the preoutput
127 ;; filters, so the newline is trimmed before being put into
128 ;; the output buffer.
129 (defun powershell-preoutput-filter-for-prompt (string)
131 ; not sure why, but I have not succeeded in using a variable here???
132 ;(string-match powershell-prompt-pattern string)
134 (string-match "PS [^#$%>]+>" string
)
135 (substring string
0 -
1)
144 (defun powershell-simple-send (proc string
)
145 "Override of the comint-simple-send function, specific for powershell.
146 This just sends STRING, plus the prompt command. Normally powershell is in
147 noninteractive model when run as an inferior shell with stdin/stdout
148 redirected, which is the case when running as a shell within emacs.
149 This function insures we get and display the prompt. "
150 ; resize if necessary. We do this by sending a resize string to the shell,
151 ; before sending the actual command to the shell.
152 (if powershell-need-rawui-resize
154 (comint-simple-send proc
(powershell-gen-window-width-string))
155 (setq powershell-need-rawui-resize nil
)
158 (comint-simple-send proc string
)
159 (comint-simple-send proc
"prompt")