Permalink
Browse files

More lexer work.

  • Loading branch information...
cmrazek committed Jul 8, 2012
1 parent 5422b12 commit ec14f4e99696b2b84e02c6d8fd5b72cabde416c0
View
@@ -36,7 +36,7 @@ namespace NppSharp
return ret;
}
- String^ NativeUtf8ToClrString(void* buf, int len)
+ String^ NativeUtf8ToClrString(const void* buf, int len)
{
array<unsigned char>^ arr = gcnew array<unsigned char>(len);
for (int i = 0; i < len; i++) arr[i] = *(((unsigned char*)buf) + i);
View
@@ -23,7 +23,7 @@ namespace NppSharp
{
wstring ClrStringToWString(String^ str);
string ClrStringToAString(String^ str);
- String^ NativeUtf8ToClrString(void *buf, int len);
+ String^ NativeUtf8ToClrString(const void *buf, int len);
void NativeWToBufA(const wchar_t *wide, StringBufA &buf);
void NativeWToUtf8BufA(const wchar_t* wide, StringBufA &buf);
String^ GetLastErrorClrString();
View
@@ -0,0 +1,130 @@
+// NppSharp - C#/.NET Scripting Plugin for Notepad++
+// Copyright (C) 2012 Chris Mrazek
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include "StdAfx.h"
+#include "LexerLine.h"
+
+namespace NppSharp
+{
+ LexerLine::LexerLine()
+ : _text(nullptr)
+ , _styles(nullptr)
+ , _len(0)
+ , _pos(0)
+ {
+ }
+
+ String^ LexerLine::Text::get()
+ {
+ return _text;
+ }
+
+ void LexerLine::Start(String^ str)
+ {
+ _text = str;
+ _len = str->Length;
+ _pos = 0;
+
+ if (_styles == nullptr || _styles->Length < _len) _styles = gcnew array<byte>(_len);
+ for (int i = 0; i < _len; ++i) _styles[i] = 0;
+ }
+
+ array<byte>^ LexerLine::StylesBuf::get()
+ {
+ return _styles;
+ }
+
+
+ int LexerLine::Length::get()
+ {
+ return _text->Length;
+ }
+
+ int LexerLine::Position::get()
+ {
+ return _pos;
+ }
+
+ void LexerLine::Position::set(int pos)
+ {
+ if (pos < 0) _pos = 0;
+ else if (pos > _len) _pos = _len;
+ else _pos = pos;
+ }
+
+ bool LexerLine::EOL::get()
+ {
+ return _pos >= _len;
+ }
+
+ void LexerLine::Style(LexerStyle^ style)
+ {
+ byte styleNum = style != nullptr ? style->Index : 0;
+
+ if (_pos < _len) _styles[_pos++] = styleNum;
+ }
+
+ void LexerLine::Style(LexerStyle^ style, int length)
+ {
+ byte styleNum = style != nullptr ? style->Index : 0;
+
+ for (int i = 0; i < length; ++i)
+ {
+ if (_pos >= _len) return;
+ _styles[_pos++] = styleNum;
+ }
+ }
+
+ void LexerLine::StyleRemainder(LexerStyle^ style)
+ {
+ byte styleNum = style != nullptr ? style->Index : 0;
+
+ while (_pos < _len) _styles[_pos++] = styleNum;
+ }
+
+ void LexerLine::StyleRange(LexerStyle^ style, int startPos, int length)
+ {
+ byte styleNum = style != nullptr ? style->Index : 0;
+
+ if (startPos < 0)
+ {
+ length += startPos;
+ startPos = 0;
+ }
+ else if (startPos > _len) startPos = _len;
+
+ if (length < 0) length = 0;
+ else if (startPos + length > _len) length = _len - startPos;
+
+ for (int i = 0; i < length; ++i)
+ {
+ _styles[startPos + i] = styleNum;
+ }
+ _pos = startPos + length;
+ }
+
+ String^ LexerLine::Peek(int length)
+ {
+ if (_pos + length > _len) length = _len - _pos;
+ return _text->Substring(_pos, length);
+ }
+
+ wchar_t LexerLine::NextChar::get()
+ {
+ if (_pos >= _len) return L'\0';
+ return _text[_pos];
+ }
+}
View
@@ -0,0 +1,47 @@
+// NppSharp - C#/.NET Scripting Plugin for Notepad++
+// Copyright (C) 2012 Chris Mrazek
+//
+// This program 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.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+#pragma once
+
+namespace NppSharp
+{
+ ref class LexerLine : public ILexerLine
+ {
+ public:
+ LexerLine();
+
+ property bool EOL { virtual bool get(); }
+ property int Length { virtual int get(); }
+ property wchar_t NextChar { virtual wchar_t get(); }
+ property int Position { virtual int get(); virtual void set(int); }
+ property String^ Text { virtual String^ get(); }
+
+ virtual String^ Peek(int length);
+ virtual void Style(LexerStyle^ style);
+ virtual void Style(LexerStyle^ style, int length);
+ virtual void StyleRemainder(LexerStyle^ style);
+ virtual void StyleRange(LexerStyle^ style, int startPos, int length);
+
+ void Start(String^ text);
+ property array<byte>^ StylesBuf { array<byte>^ get(); }
+
+ private:
+ String^ _text;
+ array<byte>^ _styles;
+ int _len;
+ int _pos;
+ };
+}
View
@@ -16,6 +16,9 @@
#include "StdAfx.h"
#include "LexerWrapper.h"
+#include "Main.h"
+#include "ClrUtil.h"
+#include "LexerLine.h"
namespace NppSharp
{
@@ -69,12 +72,112 @@ namespace NppSharp
void LexerWrapper::Lex(unsigned int startPos, int lengthDoc, int initStyle, npp::IDocument *pAccess)
{
- // TODO
+ try
+ {
+ _doc = pAccess;
+
+ const char* pszBuf = _doc->BufferPointer();
+ const char* pszPos = pszBuf + startPos;
+ const char* pszEnd = pszPos + (unsigned int)lengthDoc;
+ const char* pszLineStart = pszPos;
+ const char* pszLineEnd;
+ int line = _doc->LineFromPosition(startPos);
+ int lineLen;
+ int state = line > 0 ? _doc->GetLineState(line - 1) : 0;
+ int codePage = _doc->CodePage();
+ LexerLine^ lineObj = gcnew LexerLine();
+
+ while (pszPos < pszEnd)
+ {
+ _doc->StartStyling(pszPos - pszBuf, 31);
+ pszLineEnd = pszBuf + _doc->LineStart(line + 1);
+ lineLen = pszLineEnd - pszPos;
+
+ // Get the line text as a CLR string.
+ String^ lineStr;
+ if (codePage == SC_CP_UTF8)
+ {
+ lineStr = NativeUtf8ToClrString(pszPos, lineLen);
+ }
+ else
+ {
+ lineStr = gcnew String(pszPos, 0, lineLen);
+ }
+
+ // Tell script to style the line.
+ lineObj->Start(lineStr);
+ try
+ {
+ state = _clrLexer->StyleLine(lineObj, state);
+ }
+ catch (Exception^ ex)
+ {
+ NppSharp::WriteOutputLine(NppSharp::OutputStyle::Error, String::Concat("Exception in lexer:\r\n", ex));
+ }
+
+ // Apply the styles
+ // CLR styler uses unicode chars, but Scintilla uses ANSI or UTF-8.
+ // Need to adjust for multi-byte chars.
+ array<byte>^ styles = lineObj->StylesBuf;
+ if (codePage == SC_CP_UTF8)
+ {
+ byte ch;
+ int charIndex = 0;
+ for (int bufIndex = 0; bufIndex < lineLen; ++bufIndex)
+ {
+ ch = (byte)pszPos[bufIndex];
+ if (ch & 0x80)
+ {
+ // Char is spread across multiple bytes.
+ // All lead bytes will be given same style as the final byte.
+
+ // Lead-bytes
+ while (ch & 0x40)
+ {
+ _doc->SetStyleFor(1, styles[charIndex]);
+ ch <<= 1;
+ bufIndex++;
+ }
+
+ // Final-byte
+ _doc->SetStyleFor(1, styles[charIndex++]);
+ }
+ else
+ {
+ // Single-byte char
+ _doc->SetStyleFor(1, styles[charIndex++]);
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0; i < lineLen; ++i)
+ {
+ _doc->SetStyleFor(1, styles[i]);
+ }
+ }
+
+ // Advance to next line.
+ _doc->SetLineState(line++, state);
+ pszPos = pszLineEnd;
+ }
+ }
+ catch (Exception^ ex)
+ {
+ NppSharp::WriteOutputLine(NppSharp::OutputStyle::Error, String::Concat("CLR exception in lexer:\r\n", ex));
+ }
+ catch (exception ex)
+ {
+ NppSharp::WriteOutputLine(NppSharp::OutputStyle::Error, String::Concat("STD exception in lexer:\r\n", gcnew String(ex.what())));
+ }
+ catch (...)
+ {
+ NppSharp::WriteOutputLine(NppSharp::OutputStyle::Error, "Unknown exception in lexer.");
+ }
}
void LexerWrapper::Fold(unsigned int startPos, int lengthDoc, int initStyle, npp::IDocument *pAccess)
{
- // TODO
}
void* LexerWrapper::PrivateCall(int operation, void *pointer)
View
@@ -38,10 +38,23 @@ namespace NppSharp
virtual void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, npp::IDocument *pAccess);
virtual void * SCI_METHOD PrivateCall(int operation, void *pointer);
- String^ GetName() { return _clrLexer->Name; }
- String^ GetDescription() { return _clrLexer->Description; }
+ NppSharp::ILexer^ GetLexer() { return _clrLexer; }
private:
gcroot<NppSharp::ILexer^> _clrLexer;
+ npp::IDocument* _doc;
+ };
+
+ ref class LexerInfo
+ {
+ public:
+ Type^ type;
+ String^ name;
+ String^ description;
+ NppSharp::ILexer^ instance;
+
+ // Config file customizations
+ String^ addExt;
+ List<LexerStyle^>^ styles;
};
}
View
@@ -302,6 +302,7 @@ namespace NppSharp
{
try
{
+ g.npp->GenerateLexerConfigFile();
return g.npp->GetLexerCount();
}
catch (Exception^ ex)
@@ -411,4 +412,17 @@ namespace NppSharp
return NULL;
}
}
+
+ void WriteOutputLine(String^ message)
+ {
+ g.npp->WriteOutputLine(message);
+ }
+
+ void WriteOutputLine(OutputStyle style, String^ message)
+ {
+ OutputStyle oldStyle = style;
+ g.npp->OutputStyle = style;
+ g.npp->WriteOutputLine(message);
+ g.npp->OutputStyle = oldStyle;
+ }
}
View
@@ -29,4 +29,7 @@ namespace NppSharp
void OnGetLexerName(int num, char *buf, int bufLen);
void OnGetLexerStatusText(int num, wchar_t *buf, int bufLen);
LexerFactoryFunction OnGetLexerFactory(int index);
+
+ void WriteOutputLine(String^ message);
+ void WriteOutputLine(OutputStyle style, String^ message);
}
@@ -33,6 +33,8 @@ namespace NppSharp
, _funcItems(NULL)
, _numFuncItems(0)
, _dockWindows(gcnew List<DockWindow^>())
+ , _lexers(gcnew List<LexerInfo^>())
+ , _lexerFileCreated(false)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Oops, something went wrong.

0 comments on commit ec14f4e

Please sign in to comment.