Skip to content

Commit

Permalink
Add PowerShell filetype
Browse files Browse the repository at this point in the history
Windows PowerShell is a command-line shell and associated scripting language
which comes out of the box with Windows 7/Server 2008/8/Server 2012.

Original lexer from Scintilla is used.
  • Loading branch information
gentoo90 authored and codebrainz committed Aug 16, 2013
1 parent d44dfdb commit df589a9
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 1 deletion.
1 change: 1 addition & 0 deletions data/filetype_extensions.conf
Expand Up @@ -50,6 +50,7 @@ Perl=*.pl;*.perl;*.pm;*.agi;*.pod;
PHP=*.php;*.php3;*.php4;*.php5;*.phtml;
Po=*.po;*.pot;
Python=*.py;*.pyw;SConstruct;SConscript;wscript;
PowerShell=*.ps1;*.psm1;
reStructuredText=*.rest;*.reST;*.rst;
R=*.R;*.r;
Rust=*.rs
Expand Down
55 changes: 55 additions & 0 deletions data/filetypes.powershell
@@ -0,0 +1,55 @@
# For complete documentation of this file, please see Geany's main documentation
[styling]
# Edit these in the colorscheme .conf file instead
default=default
comment=comment
commentstream=comment_doc
string=string
character=character
number=number
variable=type
operator=operator
identifier=identifier
keyword=keyword
cmdlet=keyword_2
alias=keyword_2
function=keyword_2
user1=keyword_3

[keywords]
# all items must be in one line and in lowercase
keywords=begin break catch continue default do else elseif end filter finally for foreach function if in process return trap throw try switch until where while
cmdlets=add-computer add-content add-history add-member add-pssnapin add-type checkpoint-computer clear-content clear-eventlog clear-history clear-item clear-itemproperty clear-variable compare-object complete-transaction connect-pssession connect-wsman convert-path convertfrom-csv convertfrom-json convertfrom-securestring convertfrom-stringdata convertto-csv convertto-html convertto-json convertto-securestring convertto-xml copy-item copy-itemproperty debug-process disable-computerrestore disable-psbreakpoint disable-psremoting disable-pssessionconfiguration disable-wsmancredssp disconnect-pssession disconnect-wsman enable-computerrestore enable-psbreakpoint enable-psremoting enable-pssessionconfiguration enable-wsmancredssp enter-pssession exit-pssession export-alias export-cimcommand export-clixml export-console export-counter export-csv export-formatdata export-modulemember export-pssession foreach-object format-custom format-list format-table format-wide get-acl get-alias get-authenticodesignature get-childitem get-command get-computerrestorepoint get-content get-controlpanelitem get-counter get-credential get-culture get-date get-event get-eventlog get-eventsubscriber get-executionpolicy get-formatdata get-help get-history get-host get-hotfix get-item get-itemproperty get-job get-location get-member get-module get-pfxcertificate get-process get-psbreakpoint get-pscallstack get-psdrive get-psprovider get-pssession get-pssessionconfiguration get-pssnapin get-random get-service get-tracesource get-transaction get-typedata get-uiculture get-unique get-variable get-winevent get-wmiobject get-wsmancredssp get-wsmaninstance group-object import-alias import-clixml import-counter import-csv import-localizeddata import-module import-pssession invoke-command invoke-expression invoke-history invoke-item invoke-restmethod invoke-webrequest invoke-wmimethod invoke-wsmanaction join-path limit-eventlog measure-command measure-object move-item move-itemproperty new-alias new-event new-eventlog new-item new-itemproperty new-module new-modulemanifest new-object new-psdrive new-pssession new-pssessionconfigurationfile new-pssessionoption new-pstransportoption new-service new-timespan new-variable new-webserviceproxy new-winevent new-wsmaninstance new-wsmansessionoption out-default out-file out-gridview out-host out-null out-printer out-string pop-location push-location read-host receive-job receive-pssession register-engineevent register-jobevent register-objectevent register-pssessionconfiguration register-wmievent remove-computer remove-event remove-eventlog remove-item remove-itemproperty remove-job remove-module remove-psbreakpoint remove-psdrive remove-pssession remove-pssnapin remove-typedata remove-variable remove-wmiobject remove-wsmaninstance rename-computer rename-item rename-itemproperty reset-computermachinepassword resolve-path restart-computer restart-service restore-computer resume-job resume-service save-help select-object select-string select-xml send-mailmessage set-acl set-alias set-authenticodesignature set-content set-date set-executionpolicy set-item set-itemproperty set-location set-psbreakpoint set-psdebug set-pssessionconfiguration set-service set-strictmode set-tracesource set-variable set-wmiinstance set-wsmaninstance set-wsmanquickconfig show-command show-controlpanelitem show-eventlog sort-object split-path start-job start-process start-service start-sleep start-transaction start-transcript stop-computer stop-job stop-process stop-service stop-transcript suspend-job suspend-service tee-object test-computersecurechannel test-connection test-modulemanifest test-path test-pssessionconfigurationfile test-wsman trace-command unblock-file undo-transaction unregister-event unregister-pssessionconfiguration update-formatdata update-help update-list update-typedata use-transaction wait-event wait-job wait-process where-object write-debug write-error write-eventlog write-host write-output write-progress write-verbose write-warning
aliases=ac asnp cat cd chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp cvpa dbp del diff dir dnsn ebp echo epal epcsv epsn erase etsn exsn fc fl ft fw gal gbp gc gci gcm gcs gdr ghy gi gjb gl gm gmo gp gps group gsn gsnp gsv gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc select set si sl sleep sls sort sp spjb spps spsv start sujb sv swmi tee type wjb write
functions=clear-host get-verb help importsystemmodules mkdir more oss param parameter prompt psedit tabexpansion2
user1=

[settings]
# default extension used when saving files
extension=ps1

# the following characters are these which a "word" can contains, see documentation
#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

# single comments, like # in this file
comment_single=#
# multiline comments
comment_open=<#
comment_close=#>

# set to false if a comment character/string should start at column 0 of a line, true uses any
# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d
#command_example();
# setting to false would generate this
# command_example();
# This setting works only for single line comments
comment_use_indent=true

# context action command (please see Geany's main documentation for details)
context_action_cmd=

[build_settings]
# %f will be replaced by the complete filename
# %e will be replaced by the filename without extension
# (use only one of it at one time)
run_cmd=powershell -file "%f"
1 change: 1 addition & 0 deletions scintilla/Makefile.am
Expand Up @@ -31,6 +31,7 @@ lexers/LexNsis.cxx \
lexers/LexOthers.cxx \
lexers/LexPascal.cxx \
lexers/LexPerl.cxx \
lexers/LexPowerShell.cxx \
lexers/LexPython.cxx \
lexers/LexPO.cxx \
lexers/LexR.cxx \
Expand Down
201 changes: 201 additions & 0 deletions scintilla/lexers/LexPowerShell.cxx
@@ -0,0 +1,201 @@
// Scintilla source code edit control
/** @file LexPowerShell.cxx
** Lexer for PowerShell scripts.
**/
// Copyright 2008 by Tim Gerundt <tim@gerundt.de>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
}

static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {

WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];

styler.StartAt(startPos);

StyleContext sc(startPos, length, initStyle, styler);

for (; sc.More(); sc.Forward()) {

if (sc.state == SCE_POWERSHELL_COMMENT) {
if (sc.atLineEnd) {
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) {
if (sc.ch == '>' && sc.chPrev == '#') {
sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_STRING) {
// This is a doubles quotes string
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_CHARACTER) {
// This is a single quote string
if (sc.ch == '\'') {
sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_NUMBER) {
if (!IsADigit(sc.ch)) {
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_VARIABLE) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_OPERATOR) {
if (!isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_IDENTIFIER) {
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));

if (keywords.InList(s)) {
sc.ChangeState(SCE_POWERSHELL_KEYWORD);
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_POWERSHELL_CMDLET);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_POWERSHELL_ALIAS);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_POWERSHELL_FUNCTION);
} else if (keywords5.InList(s)) {
sc.ChangeState(SCE_POWERSHELL_USER1);
}
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
}

// Determine if a new state should be entered.
if (sc.state == SCE_POWERSHELL_DEFAULT) {
if (sc.ch == '#') {
sc.SetState(SCE_POWERSHELL_COMMENT);
} else if (sc.ch == '<' && sc.chNext == '#') {
sc.SetState(SCE_POWERSHELL_COMMENTSTREAM);
} else if (sc.ch == '\"') {
sc.SetState(SCE_POWERSHELL_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_POWERSHELL_CHARACTER);
} else if (sc.ch == '$') {
sc.SetState(SCE_POWERSHELL_VARIABLE);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_POWERSHELL_NUMBER);
} else if (isoperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_POWERSHELL_OPERATOR);
} else if (IsAWordChar(sc.ch)) {
sc.SetState(SCE_POWERSHELL_IDENTIFIER);
}
}
}
sc.Complete();
}

// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldPowerShellDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_POWERSHELL_OPERATOR) {
if (ch == '{') {
// Measure the minimum before a '{' to allow
// folding on "} else {"
if (levelMinCurrent > levelNext) {
levelMinCurrent = levelNext;
}
levelNext++;
} else if (ch == '}') {
levelNext--;
}
} else if (foldComment && style == SCE_POWERSHELL_COMMENTSTREAM) {
if (stylePrev != SCE_POWERSHELL_COMMENTSTREAM) {
levelNext++;
} else if (styleNext != SCE_POWERSHELL_COMMENTSTREAM) {
levelNext--;
}
}
if (!IsASpace(ch))
visibleChars++;
if (atEOL || (i == endPos-1)) {
int levelUse = levelCurrent;
if (foldAtElse) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
visibleChars = 0;
}
}
}

static const char * const powershellWordLists[] = {
"Commands",
"Cmdlets",
"Aliases",
"Functions",
"User1",
0
};

LexerModule lmPowerShell(SCLEX_POWERSHELL, ColourisePowerShellDoc, "powershell", FoldPowerShellDoc, powershellWordLists);

1 change: 1 addition & 0 deletions scintilla/makefile.win32
Expand Up @@ -75,6 +75,7 @@ LexOthers.o \
LexPascal.o \
LexPerl.o \
LexPO.o \
LexPowerShell.o \
LexPython.o \
LexSQL.o \
LexCaml.o \
Expand Down
2 changes: 1 addition & 1 deletion scintilla/scintilla_changes.patch
Expand Up @@ -111,7 +111,7 @@ index 84d003e..37b2a3c 100644
LINK_LEXER(lmPO);
- LINK_LEXER(lmPOV);
- LINK_LEXER(lmPowerPro);
- LINK_LEXER(lmPowerShell);
LINK_LEXER(lmPowerShell);
- LINK_LEXER(lmProgress);
LINK_LEXER(lmProps);
- LINK_LEXER(lmPS);
Expand Down
1 change: 1 addition & 0 deletions scintilla/src/Catalogue.cxx
Expand Up @@ -112,6 +112,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmPascal);
LINK_LEXER(lmPerl);
LINK_LEXER(lmPO);
LINK_LEXER(lmPowerShell);
LINK_LEXER(lmProps);
LINK_LEXER(lmPython);
LINK_LEXER(lmR);
Expand Down
6 changes: 6 additions & 0 deletions src/filetypes.c
Expand Up @@ -516,6 +516,12 @@ static void init_builtin_filetypes(void)
ft->name = g_strdup("Batch");
filetype_make_title(ft, TITLE_FILE);
ft->group = GEANY_FILETYPE_GROUP_SCRIPT;

#define POWERSHELL
ft = filetypes[GEANY_FILETYPES_POWERSHELL];
ft->name = g_strdup("PowerShell");
filetype_make_title(ft, TITLE_SOURCE_FILE);
ft->group = GEANY_FILETYPE_GROUP_SCRIPT;
}


Expand Down
1 change: 1 addition & 0 deletions src/filetypes.h
Expand Up @@ -93,6 +93,7 @@ typedef enum
GEANY_FILETYPES_ASCIIDOC,
GEANY_FILETYPES_ABAQUS,
GEANY_FILETYPES_BATCH,
GEANY_FILETYPES_POWERSHELL,
/* ^ append items here */
GEANY_MAX_BUILT_IN_FILETYPES /* Don't use this, use filetypes_array->len instead */
}
Expand Down
2 changes: 2 additions & 0 deletions src/highlighting.c
Expand Up @@ -1078,6 +1078,7 @@ void highlighting_init_styles(guint filetype_idx, GKeyFile *config, GKeyFile *co
init_styleset_case(PERL);
init_styleset_case(PHP);
init_styleset_case(PO);
init_styleset_case(POWERSHELL);
init_styleset_case(PYTHON);
init_styleset_case(R);
init_styleset_case(RUBY);
Expand Down Expand Up @@ -1159,6 +1160,7 @@ void highlighting_set_styles(ScintillaObject *sci, GeanyFiletype *ft)
styleset_case(PERL);
styleset_case(PHP);
styleset_case(PO);
styleset_case(POWERSHELL);
styleset_case(PYTHON);
styleset_case(R);
styleset_case(RUBY);
Expand Down
30 changes: 30 additions & 0 deletions src/highlightingmappings.h
Expand Up @@ -1156,6 +1156,36 @@ static const HLStyle highlighting_styles_PO[] =
#define highlighting_properties_PO EMPTY_PROPERTIES


/* PowerShell */
#define highlighting_lexer_POWERSHELL SCLEX_POWERSHELL
static const HLStyle highlighting_styles_POWERSHELL[] =
{
{ SCE_POWERSHELL_DEFAULT, "default", FALSE },
{ SCE_POWERSHELL_COMMENT, "comment", FALSE },
{ SCE_POWERSHELL_STRING, "string", FALSE },
{ SCE_POWERSHELL_CHARACTER, "character", FALSE },
{ SCE_POWERSHELL_NUMBER, "number", FALSE },
{ SCE_POWERSHELL_VARIABLE, "variable", FALSE },
{ SCE_POWERSHELL_OPERATOR, "operator", FALSE },
{ SCE_POWERSHELL_IDENTIFIER, "identifier", FALSE },
{ SCE_POWERSHELL_KEYWORD, "keyword", FALSE },
{ SCE_POWERSHELL_CMDLET, "cmdlet", FALSE },
{ SCE_POWERSHELL_ALIAS, "alias", FALSE },
{ SCE_POWERSHELL_FUNCTION, "function", FALSE },
{ SCE_POWERSHELL_USER1, "user1", FALSE },
{ SCE_POWERSHELL_COMMENTSTREAM, "commentstream", FALSE },
};
static const HLKeyword highlighting_keywords_POWERSHELL[] =
{
{ 0, "keywords", FALSE },
{ 1, "cmdlets", FALSE },
{ 2, "aliases", FALSE },
{ 3, "functions", FALSE },
{ 4, "user1", FALSE },
};
#define highlighting_properties_POWERSHELL EMPTY_PROPERTIES


/* Python */
#define highlighting_lexer_PYTHON SCLEX_PYTHON
static const HLStyle highlighting_styles_PYTHON[] =
Expand Down

0 comments on commit df589a9

Please sign in to comment.