Skip to content
This repository was archived by the owner on Jan 13, 2024. It is now read-only.

Commit b107018

Browse files
committed
Merge pull request #8 from kbilsted/topic/sync_scintillaiface
Topic/sync scintillaiface
2 parents d0ce01e + bb33564 commit b107018

File tree

7 files changed

+2424
-38
lines changed

7 files changed

+2424
-38
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,6 @@ UpgradeLog*.XML
105105
/.project
106106

107107
*.orig
108+
109+
*.pyc
110+
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Face.py - module for reading and parsing Scintilla.iface file
2+
# Implemented 2000 by Neil Hodgson neilh@scintilla.org
3+
# Released to the public domain.
4+
# Requires Python 2.5 or later
5+
6+
def sanitiseLine(line):
7+
if line[-1:] == '\n': line = line[:-1]
8+
if line.find("##") != -1:
9+
line = line[:line.find("##")]
10+
line = line.strip()
11+
return line
12+
13+
def decodeFunction(featureVal):
14+
retType, rest = featureVal.split(" ", 1)
15+
nameIdent, params = rest.split("(")
16+
name, value = nameIdent.split("=")
17+
params, rest = params.split(")")
18+
param1, param2 = params.split(",")
19+
return retType, name, value, param1, param2
20+
21+
def decodeEvent(featureVal):
22+
retType, rest = featureVal.split(" ", 1)
23+
nameIdent, params = rest.split("(")
24+
name, value = nameIdent.split("=")
25+
return retType, name, value
26+
27+
def decodeParam(p):
28+
param = p.strip()
29+
type = ""
30+
name = ""
31+
value = ""
32+
if " " in param:
33+
type, nv = param.split(" ")
34+
if "=" in nv:
35+
name, value = nv.split("=")
36+
else:
37+
name = nv
38+
return type, name, value
39+
40+
class Face:
41+
42+
def __init__(self):
43+
self.order = []
44+
self.features = {}
45+
self.values = {}
46+
self.events = {}
47+
48+
def ReadFromFile(self, name):
49+
currentCategory = ""
50+
currentComment = []
51+
currentCommentFinished = 0
52+
file = open(name)
53+
for line in file.readlines():
54+
line = sanitiseLine(line)
55+
if line:
56+
if line[0] == "#":
57+
if line[1] == " ":
58+
if currentCommentFinished:
59+
currentComment = []
60+
currentCommentFinished = 0
61+
currentComment.append(line[2:])
62+
else:
63+
currentCommentFinished = 1
64+
featureType, featureVal = line.split(" ", 1)
65+
if featureType in ["fun", "get", "set"]:
66+
try:
67+
retType, name, value, param1, param2 = decodeFunction(featureVal)
68+
except ValueError:
69+
print("Failed to decode %s" % line)
70+
raise
71+
p1 = decodeParam(param1)
72+
p2 = decodeParam(param2)
73+
self.features[name] = {
74+
"FeatureType": featureType,
75+
"ReturnType": retType,
76+
"Value": value,
77+
"Param1Type": p1[0], "Param1Name": p1[1], "Param1Value": p1[2],
78+
"Param2Type": p2[0], "Param2Name": p2[1], "Param2Value": p2[2],
79+
"Category": currentCategory, "Comment": currentComment
80+
}
81+
if value in self.values:
82+
raise Exception("Duplicate value " + value + " " + name)
83+
self.values[value] = 1
84+
self.order.append(name)
85+
elif featureType == "evt":
86+
retType, name, value = decodeEvent(featureVal)
87+
self.features[name] = {
88+
"FeatureType": featureType,
89+
"ReturnType": retType,
90+
"Value": value,
91+
"Category": currentCategory, "Comment": currentComment
92+
}
93+
if value in self.events:
94+
raise Exception("Duplicate event " + value + " " + name)
95+
self.events[value] = 1
96+
self.order.append(name)
97+
elif featureType == "cat":
98+
currentCategory = featureVal
99+
elif featureType == "val":
100+
try:
101+
name, value = featureVal.split("=", 1)
102+
except ValueError:
103+
print("Failure %s" % featureVal)
104+
raise Exception()
105+
self.features[name] = {
106+
"FeatureType": featureType,
107+
"Category": currentCategory,
108+
"Value": value }
109+
self.order.append(name)
110+
elif featureType == "enu" or featureType == "lex":
111+
name, value = featureVal.split("=", 1)
112+
self.features[name] = {
113+
"FeatureType": featureType,
114+
"Category": currentCategory,
115+
"Value": value }
116+
self.order.append(name)
117+
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#!/usr/bin/env python
2+
# FileGenerator.py - implemented 2013 by Neil Hodgson neilh@scintilla.org
3+
# Released to the public domain.
4+
5+
# Generate or regenerate source files based on comments in those files.
6+
# May be modified in-place or a template may be generated into a complete file.
7+
# Requires Python 2.5 or later
8+
# The files are copied to a string apart from sections between a
9+
# ++Autogenerated comment and a --Autogenerated comment which is
10+
# generated by the CopyWithInsertion function. After the whole string is
11+
# instantiated, it is compared with the target file and if different the file
12+
# is rewritten.
13+
14+
from __future__ import with_statement
15+
16+
import codecs, os, re, string, sys
17+
18+
lineEnd = "\r\n" if sys.platform == "win32" else "\n"
19+
20+
def UpdateFile(filename, updated):
21+
""" If the file contents are different to updated then copy updated into the
22+
file else leave alone so Mercurial and make don't treat it as modified. """
23+
newOrChanged = "Changed"
24+
try:
25+
with codecs.open(filename, "r", "utf-8") as infile:
26+
original = infile.read()
27+
if updated == original:
28+
# Same as before so don't write
29+
return
30+
os.unlink(filename)
31+
except IOError: # File is not there yet
32+
newOrChanged = "New"
33+
with codecs.open(filename, "w", "utf-8") as outfile:
34+
outfile.write(updated)
35+
print("%s %s" % (newOrChanged, filename))
36+
37+
# Automatically generated sections contain start and end comments,
38+
# a definition line and the results.
39+
# The results are replaced by regenerating based on the definition line.
40+
# The definition line is a comment prefix followed by "**".
41+
# If there is a digit after the ** then this indicates which list to use
42+
# and the digit and next character are not part of the definition
43+
# Backslash is used as an escape within the definition line.
44+
# The part between \( and \) is repeated for each item in the list.
45+
# \* is replaced by each list item. \t, and \n are tab and newline.
46+
# If there is no definition line than the first list is copied verbatim.
47+
# If retainDefs then the comments controlling generation are copied.
48+
def CopyWithInsertion(input, commentPrefix, retainDefs, lists):
49+
copying = 1
50+
generated = False
51+
listid = 0
52+
output = []
53+
for line in input.splitlines(0):
54+
isStartGenerated = line.lstrip().startswith(commentPrefix + "++Autogenerated")
55+
if copying and not isStartGenerated:
56+
output.append(line)
57+
if isStartGenerated:
58+
if retainDefs:
59+
output.append(line)
60+
copying = 0
61+
generated = False
62+
elif not copying and not generated:
63+
# Generating
64+
if line.startswith(commentPrefix + "**"):
65+
# Pattern to transform input data
66+
if retainDefs:
67+
output.append(line)
68+
definition = line[len(commentPrefix + "**"):]
69+
if (commentPrefix == "<!--") and (" -->" in definition):
70+
definition = definition.replace(" -->", "")
71+
listid = 0
72+
if definition[0] in string.digits:
73+
listid = int(definition[:1])
74+
definition = definition[2:]
75+
# Hide double slashes as a control character
76+
definition = definition.replace("\\\\", "\001")
77+
# Do some normal C style transforms
78+
definition = definition.replace("\\n", "\n")
79+
definition = definition.replace("\\t", "\t")
80+
# Get the doubled backslashes back as single backslashes
81+
definition = definition.replace("\001", "\\")
82+
startRepeat = definition.find("\\(")
83+
endRepeat = definition.find("\\)")
84+
intro = definition[:startRepeat]
85+
out = ""
86+
if intro.endswith("\n"):
87+
pos = 0
88+
else:
89+
pos = len(intro)
90+
out += intro
91+
middle = definition[startRepeat+2:endRepeat]
92+
for i in lists[listid]:
93+
item = middle.replace("\\*", i)
94+
if pos and (pos + len(item) >= 80):
95+
out += "\\\n"
96+
pos = 0
97+
out += item
98+
pos += len(item)
99+
if item.endswith("\n"):
100+
pos = 0
101+
outro = definition[endRepeat+2:]
102+
out += outro
103+
out = out.replace("\n", lineEnd) # correct EOLs in generated content
104+
output.append(out)
105+
else:
106+
# Simple form with no rule to transform input
107+
output.extend(lists[0])
108+
generated = True
109+
if line.lstrip().startswith(commentPrefix + "--Autogenerated") or \
110+
line.lstrip().startswith(commentPrefix + "~~Autogenerated"):
111+
copying = 1
112+
if retainDefs:
113+
output.append(line)
114+
output = [line.rstrip(" \t") for line in output] # trim trailing whitespace
115+
return lineEnd.join(output) + lineEnd
116+
117+
def GenerateFile(inpath, outpath, commentPrefix, retainDefs, *lists):
118+
"""Generate 'outpath' from 'inpath'.
119+
"""
120+
121+
try:
122+
with codecs.open(inpath, "r", "UTF-8") as infile:
123+
original = infile.read()
124+
updated = CopyWithInsertion(original, commentPrefix,
125+
retainDefs, lists)
126+
UpdateFile(outpath, updated)
127+
except IOError:
128+
print("Can not open %s" % inpath)
129+
130+
def Generate(inpath, outpath, commentPrefix, *lists):
131+
"""Generate 'outpath' from 'inpath'.
132+
"""
133+
GenerateFile(inpath, outpath, commentPrefix, inpath == outpath, *lists)
134+
135+
def Regenerate(filename, commentPrefix, *lists):
136+
"""Regenerate the given file.
137+
"""
138+
Generate(filename, filename, commentPrefix, *lists)
139+
140+
def UpdateLineInFile(path, linePrefix, lineReplace):
141+
lines = []
142+
updated = False
143+
with codecs.open(path, "r", "utf-8") as f:
144+
for l in f.readlines():
145+
l = l.rstrip()
146+
if not updated and l.startswith(linePrefix):
147+
lines.append(lineReplace)
148+
updated = True
149+
else:
150+
lines.append(l)
151+
contents = lineEnd.join(lines) + lineEnd
152+
UpdateFile(path, contents)
153+
154+
def ReplaceREInFile(path, match, replace):
155+
with codecs.open(path, "r", "utf-8") as f:
156+
contents = f.read()
157+
contents = re.sub(match, replace, contents)
158+
UpdateFile(path, contents)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Face
2+
from FileGenerator import Regenerate
3+
4+
def printLexCSFile(f):
5+
out = []
6+
for name in f.order:
7+
v = f.features[name]
8+
if v["FeatureType"] in ["fun", "get", "set"]:
9+
if "Comment" in v: out.extend([" /// " + line for line in v["Comment"]])
10+
featureDefineName = "SCI_" + name.upper()
11+
out.append(" " + featureDefineName + " = " + v["Value"] + ",")
12+
out.append("")
13+
elif v["FeatureType"] in ["evt"]:
14+
featureDefineName = "SCN_" + name.upper()
15+
if "Comment" in v: out.extend([" /// " + line for line in v["Comment"]])
16+
out.append(" " + featureDefineName + " = " + v["Value"] + ",")
17+
out.append("")
18+
elif v["FeatureType"] in ["val"]:
19+
if not ("SCE_" in name or "SCLEX_" in name):
20+
if "Comment" in v: out.extend([" /// " + line for line in v["Comment"]])
21+
out.append(" " + name + " = " + v["Value"] + ",")
22+
out.append("")
23+
out[-1] = out[-1][:-1] # drop the very last comma of the last line
24+
return out
25+
26+
def main():
27+
f = Face.Face()
28+
f.ReadFromFile("../../../notepad-plus-plus/scintilla/include/Scintilla.iface")
29+
Regenerate("../../Visual Studio Project Template C#/Integration/Scintilla_iface.cs", "/* ", printLexCSFile(f))
30+
31+
if __name__ == "__main__":
32+
main()

Visual Studio Project Template C#/Integration/MenuCmdID_h.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,11 @@ public enum NppMenuCmd : uint
355355
IDM_LANG_POWERSHELL = (IDM_LANG + 53),
356356
IDM_LANG_R = (IDM_LANG + 54),
357357
IDM_LANG_JSP = (IDM_LANG + 55),
358-
359358
IDM_LANG_EXTERNAL = (IDM_LANG + 65),
360359
IDM_LANG_EXTERNAL_LIMIT = (IDM_LANG + 79),
361-
362360
IDM_LANG_USER = (IDM_LANG + 80), //46080
363361
IDM_LANG_USER_LIMIT = (IDM_LANG + 110), //46110
364362

365-
366363
IDM_ABOUT = (IDM + 7000),
367364
IDM_HOMESWEETHOME = (IDM_ABOUT + 1),
368365
IDM_PROJECTPAGE = (IDM_ABOUT + 2),
@@ -373,7 +370,6 @@ public enum NppMenuCmd : uint
373370
IDM_WIKIFAQ = (IDM_ABOUT + 7),
374371
IDM_HELP = (IDM_ABOUT + 8),
375372

376-
377373
IDM_SETTING = (IDM + 8000),
378374
IDM_SETTING_TAB_SIZE = (IDM_SETTING + 1),
379375
IDM_SETTING_TAB_REPLCESPACE = (IDM_SETTING + 2),

Visual Studio Project Template C#/Integration/Msgs_h.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99

1010
namespace Kbg.NppPluginNET
1111
{
12-
public enum LangType
12+
class Constants
13+
{
14+
public const int WM_USER = 0x400;
15+
}
16+
17+
public enum LangType
1318
{
1419
L_TEXT, L_PHP, L_C, L_CPP, L_CS, L_OBJC, L_JAVA, L_RC,
1520
L_HTML, L_XML, L_MAKEFILE, L_PASCAL, L_BATCH, L_INI, L_ASCII, L_USER,
@@ -28,7 +33,7 @@ public enum LangType
2833
public enum NppMsg : uint
2934
{
3035
//Here you can find how to use these messages : http://notepad-plus.sourceforge.net/uk/plugins-HOWTO.php
31-
NPPMSG = (0x400/*WM_USER*/ + 1000),
36+
NPPMSG = (Constants.WM_USER + 1000),
3237

3338
NPPM_GETCURRENTSCINTILLA = (NPPMSG + 4),
3439
NPPM_GETCURRENTLANGTYPE = (NPPMSG + 5),
@@ -380,7 +385,7 @@ public enum NppMsg : uint
380385
// VOID NPPM_SAVEFILE(0, const TCHAR *fileNameToSave)
381386
// Save the file specified by fileNameToSave
382387

383-
RUNCOMMAND_USER = (0x400/*WM_USER*/ + 3000),
388+
RUNCOMMAND_USER = (Constants.WM_USER + 3000),
384389
NPPM_GETFULLCURRENTPATH = (RUNCOMMAND_USER + FULL_CURRENT_PATH),
385390
NPPM_GETCURRENTDIRECTORY = (RUNCOMMAND_USER + CURRENT_DIRECTORY),
386391
NPPM_GETFILENAME = (RUNCOMMAND_USER + FILE_NAME),
@@ -411,7 +416,7 @@ public enum NppMsg : uint
411416
CURRENT_LINE = 8,
412417
CURRENT_COLUMN = 9,
413418

414-
// Notification code
419+
// Notification codes
415420
NPPN_FIRST = 1000,
416421
NPPN_READY = (NPPN_FIRST + 1), // To notify plugins that all the procedures of launchment of notepad++ are done.
417422
//scnNotification->nmhdr.code = NPPN_READY;

0 commit comments

Comments
 (0)