diff --git a/Makefile.dryice.js b/Makefile.dryice.js
index 6dcb6b18..7f9e1252 100755
--- a/Makefile.dryice.js
+++ b/Makefile.dryice.js
@@ -212,7 +212,7 @@ project.assumeAllFilesLoaded();
[
"css", "html", "javascript", "php", "python", "lua", "xml", "ruby", "java", "c_cpp",
"coffee", "perl", "csharp", "svg", "clojure", "scss", "json", "groovy",
- "ocaml", "scala", "textile", "scad", "markdown", "latex"
+ "ocaml", "scala", "textile", "scad", "markdown", "latex", "powershell"
].forEach(function(mode) {
console.log("mode " + mode);
copy({
diff --git a/demo/demo.js b/demo/demo.js
index 9811e9c6..cf5c9420 100644
--- a/demo/demo.js
+++ b/demo/demo.js
@@ -73,6 +73,7 @@ var TextMode = require("ace/mode/text").Mode;
var GroovyMode = require("ace/mode/groovy").Mode;
var ScalaMode = require("ace/mode/scala").Mode;
var LatexMode = require("ace/mode/latex").Mode;
+var PowershellMode = require("ace/mode/powershell").Mode;
var UndoManager = require("ace/undomanager").UndoManager;
var vim = require("ace/keyboard/keybinding/vim").Vim;
@@ -201,6 +202,10 @@ exports.launch = function(env) {
docs.latex.setMode(new LatexMode());
docs.latex.setUndoManager(new UndoManager());
+ docs.powershell = new EditSession(require("ace/requirejs/text!demo/docs/powershell.ps1"));
+ docs.powershell.setMode(new PowershellMode());
+ docs.powershell.setUndoManager(new UndoManager());
+
// Add a "name" property to all docs
for (var doc in docs) {
docs[doc].name = doc;
@@ -245,7 +250,8 @@ exports.launch = function(env) {
csharp: new CSharpMode(),
groovy: new GroovyMode(),
scala: new ScalaMode(),
- latex: new LatexMode()
+ latex: new LatexMode(),
+ powershell: new PowershellMode()
};
function getMode() {
@@ -352,6 +358,9 @@ exports.launch = function(env) {
else if (mode instanceof LatexMode) {
modeEl.value = "latex";
}
+ else if (mode instanceof PowershellMode) {
+ modeEl.value = "powershell";
+ }
else {
modeEl.value = "text";
}
diff --git a/demo/docs/powershell.ps1 b/demo/docs/powershell.ps1
new file mode 100644
index 00000000..f3a70bc1
--- /dev/null
+++ b/demo/docs/powershell.ps1
@@ -0,0 +1,24 @@
+# This is a simple comment
+function Hello($name) {
+ Write-host "Hello $name"
+}
+
+function add($left, $right=4) {
+ if ($right -ne 4) {
+ return $left
+ } elseif ($left -eq $null -and $right -eq 2) {
+ return 3
+ } else {
+ return 2
+ }
+}
+
+$number = 1 + 2;
+$number += 3
+
+Write-Host Hello -name "World"
+
+$an_array = @(1, 2, 3)
+$a_hash = @{"something" = "something else"}
+
+& notepad .\readme.md
diff --git a/kitchen-sink.html b/kitchen-sink.html
index 60c5433e..c8d80110 100644
--- a/kitchen-sink.html
+++ b/kitchen-sink.html
@@ -46,6 +46,7 @@
+
@@ -78,6 +79,7 @@
+
diff --git a/lib/ace/mode/powershell.js b/lib/ace/mode/powershell.js
new file mode 100644
index 00000000..ec2b6463
--- /dev/null
+++ b/lib/ace/mode/powershell.js
@@ -0,0 +1,56 @@
+define(function(require, exports, module) {
+
+var oop = require("pilot/oop");
+var TextMode = require("ace/mode/text").Mode;
+var Tokenizer = require("ace/tokenizer").Tokenizer;
+var PowershellHighlightRules = require("ace/mode/powershell_highlight_rules").PowershellHighlightRules;
+var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
+var CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour;
+
+var Mode = function() {
+ this.$tokenizer = new Tokenizer(new PowershellHighlightRules().getRules());
+ this.$outdent = new MatchingBraceOutdent();
+ this.$behaviour = new CstyleBehaviour();
+};
+oop.inherits(Mode, TextMode);
+
+(function() {
+
+ this.getNextLineIndent = function(state, line, tab) {
+ var indent = this.$getIndent(line);
+
+ var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
+ var tokens = tokenizedLine.tokens;
+ var endState = tokenizedLine.state;
+
+ if (tokens.length && tokens[tokens.length-1].type == "comment") {
+ return indent;
+ }
+
+ if (state == "start") {
+ var match = line.match(/^.*[\{\(\[]\s*$/);
+ if (match) {
+ indent += tab;
+ }
+ }
+
+ return indent;
+ };
+
+ this.checkOutdent = function(state, line, input) {
+ return this.$outdent.checkOutdent(line, input);
+ };
+
+ this.autoOutdent = function(state, doc, row) {
+ this.$outdent.autoOutdent(doc, row);
+ };
+
+
+ this.createWorker = function(session) {
+ return null;
+ };
+
+}).call(Mode.prototype);
+
+exports.Mode = Mode;
+});
diff --git a/lib/ace/mode/powershell_highlight_rules.js b/lib/ace/mode/powershell_highlight_rules.js
new file mode 100644
index 00000000..09402265
--- /dev/null
+++ b/lib/ace/mode/powershell_highlight_rules.js
@@ -0,0 +1,138 @@
+define(function(require, exports, module) {
+
+var oop = require("pilot/oop");
+var lang = require("pilot/lang");
+var DocCommentHighlightRules = require("ace/mode/doc_comment_highlight_rules").DocCommentHighlightRules;
+var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
+
+var PowershellHighlightRules = function() {
+
+ var keywords = lang.arrayToMap(
+ ("function|if|else|elseif|switch|while|default|for|do|until|break|continue|" +
+ "foreach|return|filter|in|trap|throw|param|begin|process|end").split("|")
+ );
+
+ var builtinFunctions = lang.arrayToMap(
+ ("Get-Alias|Import-Alias|New-Alias|Set-Alias|Get-AuthenticodeSignature|Set-AuthenticodeSignature|" +
+ "Set-Location|Get-ChildItem|Clear-Item|Get-Command|Measure-Command|Trace-Command|" +
+ "Add-Computer|Checkpoint-Computer|Remove-Computer|Restart-Computer|Restore-Computer|Stop-Computer|" +
+ "Reset-ComputerMachinePassword|Test-ComputerSecureChannel|Add-Content|Get-Content|Set-Content|Clear-Content|" +
+ "Get-Command|Invoke-Command|Enable-ComputerRestore|Disable-ComputerRestore|Get-ComputerRestorePoint|Test-Connection|" +
+ "ConvertFrom-CSV|ConvertTo-CSV|ConvertTo-Html|ConvertTo-Xml|ConvertFrom-SecureString|ConvertTo-SecureString|" +
+ "Copy-Item|Export-Counter|Get-Counter|Import-Counter|Get-Credential|Get-Culture|" +
+ "Get-ChildItem|Get-Date|Set-Date|Remove-Item|Compare-Object|Get-Event|" +
+ "Get-WinEvent|New-Event|Remove-Event|Unregister-Event|Wait-Event|Clear-EventLog|" +
+ "Get-Eventlog|Limit-EventLog|New-Eventlog|Remove-EventLog|Show-EventLog|Write-EventLog|" +
+ "Get-EventSubscriber|Register-EngineEvent|Register-ObjectEvent|Register-WmiEvent|Get-ExecutionPolicy|Set-ExecutionPolicy|" +
+ "Export-Alias|Export-Clixml|Export-Console|Export-Csv|ForEach-Object|Format-Custom|" +
+ "Format-List|Format-Table|Format-Wide|Export-FormatData|Get-FormatData|Get-Item|" +
+ "Get-ChildItem|Get-Help|Add-History|Clear-History|Get-History|Invoke-History|" +
+ "Get-Host|Read-Host|Write-Host|Get-HotFix|Import-Clixml|Import-Csv|" +
+ "Invoke-Command|Invoke-Expression|Get-Item|Invoke-Item|New-Item|Remove-Item|" +
+ "Set-Item|Clear-ItemProperty|Copy-ItemProperty|Get-ItemProperty|Move-ItemProperty|New-ItemProperty|" +
+ "Remove-ItemProperty|Rename-ItemProperty|Set-ItemProperty|Get-Job|Receive-Job|Remove-Job|" +
+ "Start-Job|Stop-Job|Wait-Job|Stop-Process|Update-List|Get-Location|" +
+ "Pop-Location|Push-Location|Set-Location|Send-MailMessage|Add-Member|Get-Member|" +
+ "Move-Item|Compare-Object|Group-Object|Measure-Object|New-Object|Select-Object|" +
+ "Sort-Object|Where-Object|Out-Default|Out-File|Out-GridView|Out-Host|" +
+ "Out-Null|Out-Printer|Out-String|Convert-Path|Join-Path|Resolve-Path|" +
+ "Split-Path|Test-Path|Get-Pfxcertificate|Pop-Location|Push-Location|Get-Process|" +
+ "Start-Process|Stop-Process|Wait-Process|Enable-PSBreakpoint|Disable-PSBreakpoint|Get-PSBreakpoint|" +
+ "Set-PSBreakpoint|Remove-PSBreakpoint|Get-PSDrive|New-PSDrive|Remove-PSDrive|Get-PSProvider|" +
+ "Set-PSdebug|Enter-PSSession|Exit-PSSession|Export-PSSession|Get-PSSession|Import-PSSession|" +
+ "New-PSSession|Remove-PSSession|Disable-PSSessionConfiguration|Enable-PSSessionConfiguration|Get-PSSessionConfiguration|Register-PSSessionConfiguration|" +
+ "Set-PSSessionConfiguration|Unregister-PSSessionConfiguration|New-PSSessionOption|Add-PsSnapIn|Get-PsSnapin|Remove-PSSnapin|" +
+ "Get-Random|Read-Host|Remove-Item|Rename-Item|Rename-ItemProperty|Select-Object|" +
+ "Select-XML|Send-MailMessage|Get-Service|New-Service|Restart-Service|Resume-Service|" +
+ "Set-Service|Start-Service|Stop-Service|Suspend-Service|Sort-Object|Start-Sleep|" +
+ "ConvertFrom-StringData|Select-String|Tee-Object|New-Timespan|Trace-Command|Get-Tracesource|" +
+ "Set-Tracesource|Start-Transaction|Complete-Transaction|Get-Transaction|Use-Transaction|Undo-Transaction|" +
+ "Start-Transcript|Stop-Transcript|Add-Type|Update-TypeData|Get-Uiculture|Get-Unique|" +
+ "Update-Formatdata|Update-Typedata|Clear-Variable|Get-Variable|New-Variable|Remove-Variable|" +
+ "Set-Variable|New-WebServiceProxy|Where-Object|Write-Debug|Write-Error|Write-Host|" +
+ "Write-Output|Write-Progress|Write-Verbose|Write-Warning|Set-WmiInstance|Invoke-WmiMethod|" +
+ "Get-WmiObject|Remove-WmiObject|Connect-WSMan|Disconnect-WSMan|Test-WSMan|Invoke-WSManAction|" +
+ "Disable-WSManCredSSP|Enable-WSManCredSSP|Get-WSManCredSSP|New-WSManInstance|Get-WSManInstance|Set-WSManInstance|" +
+ "Remove-WSManInstance|Set-WSManQuickConfig|New-WSManSessionOption").split("|"));
+
+ var binaryOperatorsRe = "eq|ne|ge|gt|lt|le|like|notlike|match|notmatch|replace|contains|notcontains|" +
+ "ieq|ine|ige|igt|ile|ilt|ilike|inotlike|imatch|inotmatch|ireplace|icontains|inotcontains|" +
+ "is|isnot|as|" +
+ "and|or|band|bor|not";
+
+ // regexp must not have capturing parentheses. Use (?:) instead.
+ // regexps are ordered -> the first match is used
+
+ this.$rules = {
+ "start" : [
+ {
+ token : "comment",
+ regex : "#.*$"
+ }, {
+ token : "string", // single line
+ regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
+ }, {
+ token : "string", // single line
+ regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
+ }, {
+ token : "constant.numeric", // hex
+ regex : "0[xX][0-9a-fA-F]+\\b"
+ }, {
+ token : "constant.numeric", // float
+ regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
+ }, {
+ token : "constant.language.boolean",
+ regex : "[$](?:[Tt]rue|[Ff]alse)\\b"
+ }, {
+ token : "constant.language",
+ regex : "[$][Nn]ull\\b"
+ }, {
+ token : "variable.instance",
+ regex : "[$][a-zA-Z][a-zA-Z0-9_]*\\b"
+ }, {
+ token : function(value) {
+ if (keywords.hasOwnProperty(value))
+ return "keyword";
+ else if (builtinFunctions.hasOwnProperty(value))
+ return "support.function";
+ else
+ return "identifier";
+ },
+ // TODO: Unicode escape sequences
+ // TODO: Unicode identifiers
+ regex : "[a-zA-Z_$][a-zA-Z0-9_$\\-]*\\b"
+ }, {
+ token : "keyword.operator",
+ regex : "\\-(?:" + binaryOperatorsRe + ")"
+ }, {
+ token : "keyword.operator",
+ regex : "&|\\*|\\+|\\-|\\=|\\+=|\\-="
+ }, {
+ token : "lparen",
+ regex : "[[({]"
+ }, {
+ token : "rparen",
+ regex : "[\\])}]"
+ }, {
+ token : "text",
+ regex : "\\s+"
+ }
+ ],
+ "comment" : [
+ {
+ token : "comment", // closing comment
+ regex : ".*?\\*\\/",
+ next : "start"
+ }, {
+ token : "comment", // comment spanning whole line
+ merge : true,
+ regex : ".+"
+ }
+ ]
+ };
+};
+
+oop.inherits(PowershellHighlightRules, TextHighlightRules);
+
+exports.PowershellHighlightRules = PowershellHighlightRules;
+});