Some tweaks

This commit is contained in:
John Doty 2012-10-06 16:49:27 -07:00
parent 79f0af91c0
commit 92130e2524
4 changed files with 230 additions and 187 deletions

View file

@ -317,6 +317,8 @@
(interactive) (interactive)
(indent-region (point-min) (point-max) nil)) (indent-region (point-min) (point-max) nil))
;; (global-set-key (read-kbd-macro "C-i") 'indent-buffer)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; C# Mode support ;;; C# Mode support
;;; ;;;

View file

@ -71,3 +71,17 @@ function prompt
return ' ' return ' '
} }
function Get-APFile($Path, $Cockpit="BLUINFDPXYIH802:80")
{
$localFile = join-path $pwd (split-path -leaf $Path)
$uri = "http://$Cockpit/files?cmd=get&path=$Path"
Write-Host "Getting $Path to $localFile via $uri"
(New-Object System.Net.Webclient).DownloadFile($uri, $localFile)
}
function Get-Url($Url)
{
(New-Object System.Net.Webclient).DownloadString($Url)
}

View file

@ -1,213 +1,240 @@
;; powershell-mode.el, version 0.5jd ;;; powershell-mode.el --- Mode for editing Powershell scripts
;;
;; Author: John Doty (http://friendlyhedgehog.com) ;; Copyright (C) 2009, 2010 Frédéric Perrin
;; Based on the work by Vivek Sharma (http://www.viveksharma.com/techlog)
;; Provides: Major mode for editing PS (PowerShell) scripts ;; Author: Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>
;; Last Updated: 04/29/11 ;; Keywords: Powershell, Monad, MSH
;;
;; DONE ;; This file is free software: you can redistribute it and/or modify
;; - Indentation support (done) ;; it under the terms of the GNU General Public License as published
;; - support here strings (done) ;; 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/>.
;;; Comment:
;; This is still WIP.
;; ;;
;; TODO ;; This was written from scratch, without using Vivek Sharma's code:
;; - C# class support ;; it had issues I wanted to correct, but unfortunately there were no
;; - PowerShell v2 support ;; licence indication, and Vivek didn't answered my mails.
;; ;;
;; CHANGES ;; This is still pretty basic: there is indentation, syntax
;; 0.1 - initial version with text highlighting support and indenting ;; hilighting, speedbar/imenu support. The indentation is pretty naïve
;; 0.2 - fixed file based on feedback to handle xemacs and syntax file changes ;; but robust, and sufficient for my current needs.
;; 0.3 - updated to reflect Monad --> PowerShell name change
;; 0.4 - added manual indentation support, not totally what I'd like, but good enough
;; 0.5 - update from Richard Bielawski (email address excluded till he grants permission to
;; include it :) - Many thanks Richard! Fixes: indenting fixed, elseif keyword added,
;; visiting file bug fixed, standard comment support added. I only tested with latest
;; EmacsWin32, YMMV
;; 0.5jd - JohnDoty started to work on this; nothing quite yet.
;; custom hooks (setq debug-on-error t)
(defvar powershell-mode-hook nil)
;; default mode map, really simple (defvar powershell-indent 4
(defvar powershell-mode-map "Amount of horizontal space to indent after, for instance, an
(let ((powershell-mode-map (make-keymap))) opening brace")
;; (define-key powershell-mode-map "\r" 'powershell-indent-line)
(define-key powershell-mode-map "\t" 'powershell-indent-line)
;; (define-key powershell-mode-map "{" 'powershell-electric-brace)
;; (define-key powershell-mode-map "}" 'powershell-electric-brace)
powershell-mode-map)
"Keymap for PS major mode")
(defvar powershell-indent-width 4) (defvar powershell-continuation-indent 2
"Amount of horizontal space to indent a continuation line")
;; make braces indent properly (defvar powershell-continued-regexp ".*\\(|[\\t ]*\\|`\\)$"
(defun powershell-electric-brace (arg) "Regexp matching a continued line (ending either with an
"Correct indentation for squigly brace" explicit backtick, or with a pipe).")
(interactive "P")
(self-insert-command (prefix-numeric-value arg))
(unless
(save-excursion
(beginning-of-line)
(or
;; (looking-at "$\w+") ;Don't do this in a variable
(looking-at "{\s*|[^}]") ;Don't do this in an open procedure block
(looking-at "\"[^\"]*$")) ;Don't do this in a open string
)
(powershell-indent-line)
(forward-char 1)
)
)
;(add-to-list 'auto-mode-alist '("\\.ps1\\'" . powershell-mode)) (defun powershell-continuation-line-p ()
"Returns t is the current line is a continuation line (i.e. the
previous line is a continued line, ending with a backtick or a pipe"
(interactive)
(save-excursion
(forward-line -1)
(looking-at powershell-continued-regexp)))
;; Function to control indenting. (defun powershell-indent-line-amount ()
(defun powershell-indent-line () "Returns the column to which the current line ought to be indented."
"Indent current PowerShell script line" (interactive)
(interactive) (beginning-of-line)
(let ((closing-paren (looking-at "[\t ]*[])}]")))
;; a very simple indentation method: if on a continuation line (i.e. the
;; previous line ends with a trailing backtick or pipe), we indent relative
;; to the continued line; otherwise, we indent relative to the ([{ that
;; opened the current block.
(if (powershell-continuation-line-p)
(progn
(while (powershell-continuation-line-p)
(forward-line -1))
(+ (current-indentation) powershell-continuation-indent))
(condition-case nil
(progn
(backward-up-list)
;; indentation relative to the opening paren: if there is text (no
;; comment) after the opening paren, vertically align the block
;; with this text; if we were looking at the closing paren, reset
;; the indentation; otherwise, indent the block by powershell-indent.
(cond ((not (looking-at ".[\t ]*\\(#.*\\)?$"))
(forward-char)
(skip-chars-forward " \t")
(current-column))
(closing-paren
(current-indentation))
(t
(+ (current-indentation) powershell-indent))))
(scan-error ;; most likely, we are at the top-level
0)))))
;; Set the point to beginning of line. (defun powershell-indent-line ()
(beginning-of-line) "Indent the current line of powershell mode, leaving the point
(if (bobp) in place if it is inside the meat of the line"
(indent-line-to 0) (interactive)
(let ((savep (> (current-column) (current-indentation)))
(amount (save-excursion (powershell-indent-line-amount))))
(if savep
(save-excursion (indent-line-to amount))
(indent-line-to amount))))
(let ((not-indented t) (lines-back 0) cur-indent)
(if (looking-at "^[ \t]*}") ; Check for closing brace ;; Taken from <http://www.manning.com/payette/AppCexcerpt.pdf> which seems the
(progn ;; closest to a grammar definition for powershell. It is not complete, and
(save-excursion ;; contains some inaccuracies (e.g. it says that variables match \$[:alnum:]+,
(forward-line -1) ;; so $_ is not a variable it seems...)
(setq lines-back (+ lines-back 1))
(if (looking-at "^[ \t]*{") ; If now looking at opening block
(setq cur-indent (current-indentation)) ;; duplicate indent
(setq cur-indent (- (current-indentation) powershell-indent-width)))
)
;; Safety check to make sure we don't indent negative. (defvar powershell-keywords
(if (< cur-indent 0) (regexp-opt '("begin" "break" "catch" "continue" "data" "do" "dynamicparam"
(setq cur-indent 0))) "else" "elseif" "end" "exit" "filter" "finally" "for" "foreach"
"from" "function" "if" "in" "param" "process" "return"
"switch" "throw" "trap" "try" "until" "while"))
"Powershell keywords")
(save-excursion (defvar powershell-operators
(if (looking-at "^[ \t]*{") ; Opening block (regexp-opt '("and" "as" "band" "bnot" "bor" "bxor" "casesensitive"
(progn "ccontains" "ceq" "cge" "cgt" "cle" "clike" "clt" "cmatch"
(forward-line -1) "cne" "cnotcontains" "cnotlike" "cnotmatch" "contains"
(setq lines-back (+ lines-back 1)) "creplace" "eq" "exact" "f" "file" "ge" "gt" "icontains"
(setq cur-indent (current-indentation)) "ieq" "ige" "igt" "ile" "ilike" "ilt" "imatch" "ine"
(setq not-indented nil)) "inotcontains" "inotlike" "inotmatch" "ireplace" "is"
"isnot" "le" "like" "lt" "match" "ne" "not" "notcontains"
"notlike" "notmatch" "or" "replace" "wildcard"))
"Powershell operators")
(while not-indented (defvar powershell-scope-names
(forward-line -1) (regexp-opt
(setq lines-back (+ lines-back 1)) '("env" "function" "global" "local" "private" "script" "variable"))
(if (looking-at "^[ \t]*}") ; Closing block "Names of scopes in Powershell mode.")
(progn
(setq cur-indent (current-indentation))
(setq not-indented nil))
(if (looking-at "^[ \t]*{") ; Opening block ;; Taken from Get-Variable on a fresh shell, merged with man
(progn ;; about_automatic_variables
(setq cur-indent (+ (current-indentation) powershell-indent-width)) (defvar powershell-builtin-variables
(setq not-indented nil)) (regexp-opt
'("^" "_" "$" "?" "Args" "ConfirmPreference" "ConsoleFileName"
"DebugPreference" "Error" "ErrorActionPreference" "ErrorView"
"ExecutionContext" "foreach" "FormatEnumerationLimit" "HOME" "Host"
"Input" "LASTEXITCODE" "MaximumAliasCount" "MaximumDriveCount"
"MaximumErrorCount" "MaximumFunctionCount" "MaximumHistoryCount"
"MaximumVariableCount" "MyInvocation" "NestedPromptLevel" "OFS"
"OutputEncoding" "PID" "PROFILE" "PSHOME" "PWD" "ProgressPreference"
"ReportErrorShowExceptionClass" "ReportErrorShowInnerException"
"ReportErrorShowSource" "ReportErrorShowStackTrace" "ShellId"
"ShouldProcessPreference" "ShouldProcessReturnPreference" "StackTrace"
"VerbosePreference" "WarningPreference" "WhatIfPreference" "false"
"input" "lastWord" "line" "null" "true" ))
"Names of the built-in Powershell variables. They are hilighted
differently from the other variables.")
(if (looking-at "^[ \t]*\\(if\\|for\\|foreach\\|function\\|filter\\|else\\|do\\|while\\)\\>") (defvar powershell-font-lock-keywords-1
(progn `(;; Type annotations
(setq cur-indent (current-indentation)) ("\\[\\([[:word:].]+\\(\\[\\]\\)?\\)\\]" 1 font-lock-type-face)
(forward-line 1) ;; syntaxic keywords
(setq lines-back (- lines-back 1)) (,(concat "\\<" powershell-keywords "\\>") . font-lock-keyword-face)
(if (looking-at "^[ \t]*{") ; Has block ;; operators
(setq not-indented nil) (,(concat "\\<-" powershell-operators "\\>") . font-lock-builtin-face)
(if (equal lines-back 0) ; No block ;; the REQUIRES mark
(progn ("^#\\(REQUIRES\\)" 1 font-lock-warning-face t))
(setq cur-indent (+ cur-indent powershell-indent-width)) "Keywords for the first level of font-locking in Powershell mode.")
(setq not-indented nil))
(setq not-indented nil)))
)
(if (bobp) (defvar powershell-font-lock-keywords-2
(setq not-indented nil))))))))) (append
(if cur-indent powershell-font-lock-keywords-1
(indent-line-to cur-indent) `(;; Built-in variables
(indent-line-to 0))))) (,(concat "\\$\\(" powershell-builtin-variables "\\)\\>")
1 font-lock-builtin-face t)))
;; only defined one keyword list right now "Keywords for the second level of font-locking in Powershell mode.")
(defconst powershell-font-lock-keywords-3 (defvar powershell-font-lock-keywords-3
(list (append
'("\\<\\(d\\(?:o\\|efault\\)\\|else\\(if\\)?\\|f\\(?:oreach\\|unction\\|ilter\\)\\|if\\|switch\\|t\\(?:hrow\\|rap\\)\\|w\\(?:here\\|hile\\)\\)\\>" . font-lock-keyword-face) powershell-font-lock-keywords-2
'("$[a-zA-Z0-9_\\.:{}]+\\>" . font-lock-variable-name-face) `(;; Variables in curly brackets
'("\\<\\w+-\\w+\\>" . font-lock-function-name-face) ("\\${\\([^}]+\\)}" 1 font-lock-variable-name-face)
'("\\<-\\w+\\>" . font-lock-builtin-face) ;; Variables, with a scope
'("@'[A-z0-9\n\t ]+'@" . font-lock-string-face) (,(concat "\\$\\(" powershell-scope-names "\\):"
'("@\"[A-z0-9\n\t ]+\"@" . font-lock-string-face) "\\([[:alnum:]_]+\\)")
'("\\(-\\)\\([a-z][a-zA-Z0-9]+\\)" . font-lock-type-face)) (1 (cons font-lock-type-face '(underline)))
"Maximum highlighting for PowerShell major mode") (2 font-lock-variable-name-face))
;; Variables, without a scope. XXX: unify this with the
;; previous rule?
("\\$\\([[:alnum:]_]+\\)" 1 font-lock-variable-name-face)
;; hilight properties, but not the methods (personnal preference)
("\\.\\([[:alnum:]_.]+\\)\\>\\s *[^(]" 1 font-lock-variable-name-face)))
"Keywords for the maximum level of font-locking in Powershell mode.")
(defvar powershell-mode-syntax-table (make-syntax-table)
"Syntax table for Powershell mode")
(defvar powershell-font-lock-keywords powershell-font-lock-keywords-3 (modify-syntax-entry ?# "<" powershell-mode-syntax-table)
"Maximum highlighting for PowerShell major mode") (modify-syntax-entry ?\n ">" powershell-mode-syntax-table)
;; Powershell uses a backtick as its escape character.
(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)
(defvar powershell-imenu-expression
`(("Functions" "function \\(\\w+\\)" 1)
("Top variables" ,(concat "^\\$\\(" powershell-scope-names "\\)?:?"
"\\([[:alnum:]_]+\\)")
2))
"List of regexps matching important expressions, for speebar & imenu.")
;; is adding punctuation to word syntax appropriate?? (if (require 'speedbar nil t)
(speedbar-add-supported-extension ".ps1?"))
(defvar powershell-mode-syntax-table (require 'compile nil t)
(let ((powershell-mode-syntax-table (make-syntax-table))) ;; A better command would be something like "powershell.exe -NoLogo
(modify-syntax-entry ?. "_" powershell-mode-syntax-table) ;; -NonInteractive -Command & (buffer-file-name)". But it will just
(modify-syntax-entry ?: "_" powershell-mode-syntax-table) ;; sit there waiting... The following will only work when .ps1 files
(modify-syntax-entry ?\\ "_" powershell-mode-syntax-table) ;; are associated with powershell.exe. And if they don't contain spaces.
(modify-syntax-entry ?{ "(}" powershell-mode-syntax-table) (defvar powershell-compile-command
(modify-syntax-entry ?} "){" powershell-mode-syntax-table) '(buffer-file-name)
(modify-syntax-entry ?[ "(]" powershell-mode-syntax-table) "Default command used to invoke a powershell script")
(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 ?\n ">" powershell-mode-syntax-table)
(modify-syntax-entry ?' "\"" powershell-mode-syntax-table)
powershell-mode-syntax-table)
"Syntax for PowerShell major mode")
;; 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))
(defvar powershell-imenu-expressions
'((nil "^\\(?:function\\|Add-Class\\)\\s-+\\([-a-z0-9A-Z_^:.]+\\)[^-a-z0-9A-Z_^:.]" 1)) ;; the hook is automatically run by derived-mode
"alist of regexp identifying the start of powershell definitions" (defvar powershell-mode-hook '(imenu-add-menubar-index)
) "Hook run after the initialization of Powershell mode.")
(defun powershell-setup-imenu () (define-derived-mode powershell-mode fundamental-mode "PS"
"Installs powershell-imenu-expression." "A major mode for editing Powershell script files."
(require 'imenu t) (set (make-local-variable 'indent-line-function) 'powershell-indent-line)
;; imenu doc says these 3 are buffer-local by default
(setq imenu-generic-expression powershell-imenu-expressions)
(imenu-add-menubar-index)
(require 'which-func t)
(which-function-mode t)
)
(defun powershell-mode ()
"Major mode for editing PowerShell files"
(interactive)
(kill-all-local-variables)
(setq major-mode 'powershell-mode)
(setq mode-name "PS")
(set-syntax-table powershell-mode-syntax-table)
(use-local-map powershell-mode-map)
(set (make-local-variable 'font-lock-defaults) (set (make-local-variable 'font-lock-defaults)
'(powershell-font-lock-keywords)) '((powershell-font-lock-keywords-1
powershell-font-lock-keywords-2
powershell-font-lock-keywords-3)
nil t))
(set (make-local-variable 'comment-start) "# ")
(set (make-local-variable 'comment-start-skip) "#+\\s*")
;; not sure why this is not the default
(set (make-local-variable 'parse-sexp-ignore-comments) t)
(set-syntax-table powershell-mode-syntax-table)
(set (make-local-variable 'imenu-generic-expression)
powershell-imenu-expression)
(set (make-local-variable 'imenu-case-fold-search) nil)
(set (make-local-variable 'compile-command) powershell-compile-command))
(make-local-variable 'compile-command) (provide 'powershell-mode)
(if buffer-file-name
(setq compile-command (format "PowerShell -noprofile -nologo -command %s"
(expand-file-name buffer-file-name))))
; Here we register our line indentation function with Emacs. Now Emacs will
; call our function every time line indentation is required (like when the
; user calls indent-region).
;; (make-local-variable 'indent-line-function)
;; (setq indent-line-function 'powershell-indent-line)
; Set indentation defaults.
(make-local-variable 'powershell-indent-width)
(set (make-local-variable 'comment-start) "#")
(powershell-setup-imenu)
(run-hooks 'powershell-mode-hook))
(provide 'powershell-mode)