Skip to content

Commit

Permalink
fix string literal in emit pragma colorization
Browse files Browse the repository at this point in the history
  • Loading branch information
jangko committed Jun 1, 2017
1 parent fe1f2bb commit 90f37b6
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 19 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ compatible with recent notepad++ in any language that can produce a DLL.

requirements(for notepad++ 32bit):
* Nim32/64bit
* MingW32 or VCC 32bit
* MinGW-w64 or MingGW32 ~~or VCC 32bit~~

(ironically, although VCC can compile this plugin, notepad++ reject it for some unknown reason)

how to compile:
* nim c -d:release nppnim

how to cross compile using 64bit Nim compiler:
* nim c -d:release --cpu:i386 nppnim
* nim c -d:release --cpu:i386 --passL:-m32 --passC:-m32 nppnim

how to test:
* put nppnim.dll in NPPINSTDIR\plugins
Expand Down
14 changes: 10 additions & 4 deletions leximpl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ proc GetWordType(L: ptr LexAccessor, start, stop: int): WordType =
if support.NimMagic.contains(kw): return WT_MAGIC
result = WT_IDENT

# this is Nim legacy
const
magicIdentSeparatorRuneByteWidth = 3

proc getSymbol(sc: var StyleContext) =
var pos = sc.currentPos
var styler = sc.styler
Expand All @@ -120,7 +124,9 @@ proc getSymbol(sc: var StyleContext) =
of 'a'..'z', '0'..'9', '\x80'..'\xFF':
if c == '\226' and
styler[][pos+1] == '\128' and
styler[][pos+2] == '\147': # It's a 'magic separator' en-dash Unicode
styler[][pos+2] == '\147':
# It's a 'magic separator' en-dash Unicode,
# not supported anymore since Nim 0.17.0
if styler[][pos + magicIdentSeparatorRuneByteWidth] notin SymChars:
break
inc(pos, magicIdentSeparatorRuneByteWidth)
Expand Down Expand Up @@ -169,7 +175,7 @@ proc getString(sc: var StyleContext, rawMode: bool) =
sc.getEscapedChar()
else:
sc.forward()
sc.setState(NIM_DEFAULT)
discard sc.popState()

template DEFAULT_STATE_BODY: typed =
case sc.ch
Expand Down Expand Up @@ -210,7 +216,7 @@ template DEFAULT_STATE_BODY: typed =
sc.getNumber()
continue
of '{':
if sc.chNext == '.': sc.setState(NIM_PRAGMA)
if sc.chNext == '.': sc.pushState(NIM_PRAGMA)
else:
sc.setState(NIM_BRACES)
sc.forward()
Expand All @@ -219,7 +225,7 @@ template DEFAULT_STATE_BODY: typed =
of '\"':
# check for extended raw string literal:
let rawMode = sc.currentPos > 0 and sc.chPrev in SymChars
sc.setState(NIM_STRING)
sc.pushState(NIM_STRING)
sc.getString(rawMode)
continue
of {'[', '(', '}', ']', ')'}:
Expand Down
26 changes: 19 additions & 7 deletions nppnim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#-----------------------------------------
import
winapi, scintilla, nppmsg, menucmdid, support,
lexaccessor, stylecontext, sets, etcpriv, utils, strutils
lexaccessor, stylecontext, sets, utils, strutils

{.link: "resource/resource.o".}

Expand Down Expand Up @@ -65,12 +65,18 @@ proc commandMenuCleanUp() =
discard

# this is needed to initialize GC, global variable initialization, etc
proc NimMain() {.cdecl, importc.}

when defined(vcc):
{.emit: "N_LIB_EXPORT N_CDECL(void, NimMain)(void);".}
else:
proc NimMain() {.cdecl, importc.}

proc DllMain(hModule: HANDLE, reasonForCall: DWORD, lpReserved: LPVOID): WINBOOL {.stdcall, exportc, dynlib.} =
case reasonForCall
of DLL_PROCESS_ATTACH:
NimMain()
when defined(vcc):
{.emit: "NimMain();".}
else:
NimMain()
pluginInit(hModule)
of DLL_PROCESS_DETACH:
commandMenuCleanUp()
Expand Down Expand Up @@ -176,18 +182,24 @@ proc Lex(x: pointer, startPos, docLen, initStyle: int, pAccess: IDocument) {.std
if sc.ch == '.' and sc.chNext == '}':
sc.forward()
sc.forward()
sc.setState(NIM_DEFAULT)
discard sc.popState()
continue
if sc.ch == '}':
sc.forward()
sc.setState(NIM_DEFAULT)
discard sc.popState()
if sc.ch == '\"':
# check for extended raw string literal:
let rawMode = sc.currentPos > 0 and sc.chPrev in SymChars
sc.pushState(NIM_STRING)
sc.getString(rawMode)
continue
of NIM_STRING_TRIPLE:
if sc.ch == '\\':
sc.forward()
elif sc.match "\"\"\"":
sc.forward()
sc.forward()
sc.forwardSetState(NIM_DEFAULT)
discard sc.popForwardState()
of NIM_DOC_BLOCK_COMMENT:
if sc.match "]##":
sc.forward()
Expand Down
30 changes: 28 additions & 2 deletions stylecontext.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#-----------------------------------------
import lexaccessor, scintilla

const maxState = 10

type
StyleContext* = object
styler*: ptr LexAccessor
Expand All @@ -23,13 +25,17 @@ type
lineStartNext: int
atLineStart: bool
atLineEnd: bool
state*: int
state*: int
chPrev*: char
ch*: char
width: int
chNext*: char
widthNext: int


# stateStack were added to cope with string/triple string in pragma
statePos: int
stateStack: array[0..maxState, int]

proc makeLowerCase(ch: char): char =
if (ch < 'A') or (ch > 'Z'): return ch
else: result = (ch.ord - 'A'.ord + 'a'.ord).chr
Expand Down Expand Up @@ -77,6 +83,8 @@ proc initStyleContext*(startPos, length, initStyle: int, styler: ptr LexAccessor
result.ch = result.chNext
result.width = result.widthNext
result.getNextChar()

result.statePos = 0

proc complete*(ctx: StyleContext) =
let x = if ctx.currentPos > ctx.lengthDocument: 2 else: 1
Expand Down Expand Up @@ -126,6 +134,24 @@ proc forwardSetState*(ctx: var StyleContext, state: int) =
ctx.styler[].colourTo(ctx.currentPos - x, ctx.state)
ctx.state = state

proc pushState*(ctx: var StyleContext, state: int) =
if ctx.statePos < maxState:
ctx.stateStack[ctx.statePos] = ctx.state
inc ctx.statePos
ctx.setState(state)

proc popState*(ctx: var StyleContext): int =
if ctx.statePos > 0:
result = ctx.stateStack[ctx.statePos - 1]
dec ctx.statePos
ctx.setState(result)

proc popForwardState*(ctx: var StyleContext): int =
if ctx.statePos > 0:
result = ctx.stateStack[ctx.statePos - 1]
dec ctx.statePos
ctx.forwardSetState(result)

proc lengthCurrent*(ctx: StyleContext): int =
result = ctx.currentPos - ctx.styler[].getStartSegment()

Expand Down
8 changes: 4 additions & 4 deletions winapi.nim
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ proc RegisterClassA*(lpWndClass: LPWNDCLASSA): ATOM {.stdcall, dynlib: "user32",
proc RegisterClassW*(lpWndClass: LPWNDCLASSW): ATOM {.stdcall, dynlib: "user32",
importc: "RegisterClassW".}

template registerClass*(wndClass: expr): ATOM =
template registerClass*(wndClass: typed): ATOM =
when defined(winUnicode): RegisterClassW(addr(wndClass))
else: RegisterClassA(addr(wndClass))

Expand All @@ -1001,20 +1001,20 @@ proc GetMessageA(lpMsg: LPMSG, wnd: HWND, wMsgFilterMin: WINUINT,
proc GetMessageW(lpMsg: LPMSG, wnd: HWND, wMsgFilterMin: WINUINT,
wMsgFilterMax: WINUINT): WINBOOL {.stdcall, dynlib: "user32", importc: "GetMessageW".}

template getMessage*(lpMsg: expr, wnd: HWND, wMsgFilterMin, wMsgFilterMax: WINUINT): expr =
template getMessage*(lpMsg: typed, wnd: HWND, wMsgFilterMin, wMsgFilterMax: WINUINT): untyped =
when defined(winUnicode): GetMessageW(addr(lpMsg), wnd, wMsgFilterMin, wMsgFilterMax) != 0
else: GetMessageA(addr(lpMsg), wnd, wMsgFilterMin, wMsgFilterMax) != 0

proc TranslateMessage(lpMsg: LPMSG): WINBOOL {.stdcall, dynlib: "user32",
importc: "TranslateMessage", discardable.}

template translateMessage*(lpMsg: expr): expr =
template translateMessage*(lpMsg: typed): untyped =
TranslateMessage(addr(lpMsg))

proc DispatchMessageA(lpMsg: LPMSG): int32 {.stdcall, dynlib: "user32", importc: "DispatchMessageA", discardable.}
proc DispatchMessageW(lpMsg: LPMSG): int32 {.stdcall, dynlib: "user32", importc: "DispatchMessageW", discardable.}

template dispatchMessage*(lpMsg: expr): expr =
template dispatchMessage*(lpMsg: typed): untyped =
when defined(winUnicode): DispatchMessageW(addr(lpMsg))
else: DispatchMessageA(addr(lpMsg))

Expand Down

0 comments on commit 90f37b6

Please sign in to comment.