qscilexerpython.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. // This module implements the QsciLexerPython class.
  2. //
  3. // Copyright (c) 2017 Riverbank Computing Limited <info@riverbankcomputing.com>
  4. //
  5. // This file is part of QScintilla.
  6. //
  7. // This file may be used under the terms of the GNU General Public License
  8. // version 3.0 as published by the Free Software Foundation and appearing in
  9. // the file LICENSE included in the packaging of this file. Please review the
  10. // following information to ensure the GNU General Public License version 3.0
  11. // requirements will be met: http://www.gnu.org/copyleft/gpl.html.
  12. //
  13. // If you do not wish to use this file under the terms of the GPL version 3.0
  14. // then you may purchase a commercial license. For more information contact
  15. // info@riverbankcomputing.com.
  16. //
  17. // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
  18. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19. #include "Qsci/qscilexerpython.h"
  20. #include <qcolor.h>
  21. #include <qfont.h>
  22. #include <qsettings.h>
  23. // The list of Python keywords that can be used by other friendly lexers.
  24. const char *QsciLexerPython::keywordClass =
  25. "and as assert break class continue def del elif else except exec "
  26. "finally for from global if import in is lambda None not or pass "
  27. "print raise return try while with yield";
  28. // The ctor.
  29. QsciLexerPython::QsciLexerPython(QObject *parent)
  30. : QsciLexer(parent),
  31. fold_comments(false), fold_compact(true), fold_quotes(false),
  32. indent_warn(NoWarning), strings_over_newline(false), v2_unicode(true),
  33. v3_binary_octal(true), v3_bytes(true), highlight_subids(true)
  34. {
  35. }
  36. // The dtor.
  37. QsciLexerPython::~QsciLexerPython()
  38. {
  39. }
  40. // Returns the language name.
  41. const char *QsciLexerPython::language() const
  42. {
  43. return "Python";
  44. }
  45. // Returns the lexer name.
  46. const char *QsciLexerPython::lexer() const
  47. {
  48. return "python";
  49. }
  50. // Return the view used for indentation guides.
  51. int QsciLexerPython::indentationGuideView() const
  52. {
  53. return QsciScintillaBase::SC_IV_LOOKFORWARD;
  54. }
  55. // Return the set of character sequences that can separate auto-completion
  56. // words.
  57. QStringList QsciLexerPython::autoCompletionWordSeparators() const
  58. {
  59. QStringList wl;
  60. wl << ".";
  61. return wl;
  62. }
  63. // Return the list of characters that can start a block.
  64. const char *QsciLexerPython::blockStart(int *style) const
  65. {
  66. if (style)
  67. *style = Operator;
  68. return ":";
  69. }
  70. // Return the number of lines to look back when auto-indenting.
  71. int QsciLexerPython::blockLookback() const
  72. {
  73. // This must be 0 otherwise de-indenting a Python block gets very
  74. // difficult.
  75. return 0;
  76. }
  77. // Return the style used for braces.
  78. int QsciLexerPython::braceStyle() const
  79. {
  80. return Operator;
  81. }
  82. // Returns the foreground colour of the text for a style.
  83. QColor QsciLexerPython::defaultColor(int style) const
  84. {
  85. switch (style)
  86. {
  87. case Default:
  88. return QColor(0x80,0x80,0x80);
  89. case Comment:
  90. return QColor(0x00,0x7f,0x00);
  91. case Number:
  92. return QColor(0x00,0x7f,0x7f);
  93. case DoubleQuotedString:
  94. case SingleQuotedString:
  95. return QColor(0x7f,0x00,0x7f);
  96. case Keyword:
  97. return QColor(0x00,0x00,0x7f);
  98. case TripleSingleQuotedString:
  99. case TripleDoubleQuotedString:
  100. return QColor(0x7f,0x00,0x00);
  101. case ClassName:
  102. return QColor(0x00,0x00,0xff);
  103. case FunctionMethodName:
  104. return QColor(0x00,0x7f,0x7f);
  105. case Operator:
  106. case Identifier:
  107. break;
  108. case CommentBlock:
  109. return QColor(0x7f,0x7f,0x7f);
  110. case UnclosedString:
  111. return QColor(0x00,0x00,0x00);
  112. case HighlightedIdentifier:
  113. return QColor(0x40,0x70,0x90);
  114. case Decorator:
  115. return QColor(0x80,0x50,0x00);
  116. }
  117. return QsciLexer::defaultColor(style);
  118. }
  119. // Returns the end-of-line fill for a style.
  120. bool QsciLexerPython::defaultEolFill(int style) const
  121. {
  122. if (style == UnclosedString)
  123. return true;
  124. return QsciLexer::defaultEolFill(style);
  125. }
  126. // Returns the font of the text for a style.
  127. QFont QsciLexerPython::defaultFont(int style) const
  128. {
  129. QFont f;
  130. switch (style)
  131. {
  132. case Comment:
  133. #if defined(Q_OS_WIN)
  134. f = QFont("Comic Sans MS",9);
  135. #elif defined(Q_OS_MAC)
  136. f = QFont("Comic Sans MS", 12);
  137. #else
  138. f = QFont("Bitstream Vera Serif",9);
  139. #endif
  140. break;
  141. case DoubleQuotedString:
  142. case SingleQuotedString:
  143. case UnclosedString:
  144. #if defined(Q_OS_WIN)
  145. f = QFont("Courier New",10);
  146. #elif defined(Q_OS_MAC)
  147. f = QFont("Courier", 12);
  148. #else
  149. f = QFont("Bitstream Vera Sans Mono",9);
  150. #endif
  151. break;
  152. case Keyword:
  153. case ClassName:
  154. case FunctionMethodName:
  155. case Operator:
  156. f = QsciLexer::defaultFont(style);
  157. f.setBold(true);
  158. break;
  159. default:
  160. f = QsciLexer::defaultFont(style);
  161. }
  162. return f;
  163. }
  164. // Returns the set of keywords.
  165. const char *QsciLexerPython::keywords(int set) const
  166. {
  167. if (set != 1)
  168. return 0;
  169. return keywordClass;
  170. }
  171. // Returns the user name of a style.
  172. QString QsciLexerPython::description(int style) const
  173. {
  174. switch (style)
  175. {
  176. case Default:
  177. return tr("Default");
  178. case Comment:
  179. return tr("Comment");
  180. case Number:
  181. return tr("Number");
  182. case DoubleQuotedString:
  183. return tr("Double-quoted string");
  184. case SingleQuotedString:
  185. return tr("Single-quoted string");
  186. case Keyword:
  187. return tr("Keyword");
  188. case TripleSingleQuotedString:
  189. return tr("Triple single-quoted string");
  190. case TripleDoubleQuotedString:
  191. return tr("Triple double-quoted string");
  192. case ClassName:
  193. return tr("Class name");
  194. case FunctionMethodName:
  195. return tr("Function or method name");
  196. case Operator:
  197. return tr("Operator");
  198. case Identifier:
  199. return tr("Identifier");
  200. case CommentBlock:
  201. return tr("Comment block");
  202. case UnclosedString:
  203. return tr("Unclosed string");
  204. case HighlightedIdentifier:
  205. return tr("Highlighted identifier");
  206. case Decorator:
  207. return tr("Decorator");
  208. }
  209. return QString();
  210. }
  211. // Returns the background colour of the text for a style.
  212. QColor QsciLexerPython::defaultPaper(int style) const
  213. {
  214. if (style == UnclosedString)
  215. return QColor(0xe0,0xc0,0xe0);
  216. return QsciLexer::defaultPaper(style);
  217. }
  218. // Refresh all properties.
  219. void QsciLexerPython::refreshProperties()
  220. {
  221. setCommentProp();
  222. setCompactProp();
  223. setQuotesProp();
  224. setTabWhingeProp();
  225. setStringsOverNewlineProp();
  226. setV2UnicodeProp();
  227. setV3BinaryOctalProp();
  228. setV3BytesProp();
  229. setHighlightSubidsProp();
  230. }
  231. // Read properties from the settings.
  232. bool QsciLexerPython::readProperties(QSettings &qs,const QString &prefix)
  233. {
  234. int rc = true;
  235. fold_comments = qs.value(prefix + "foldcomments", false).toBool();
  236. fold_compact = qs.value(prefix + "foldcompact", true).toBool();
  237. fold_quotes = qs.value(prefix + "foldquotes", false).toBool();
  238. indent_warn = (IndentationWarning)qs.value(prefix + "indentwarning", (int)NoWarning).toInt();
  239. strings_over_newline = qs.value(prefix + "stringsovernewline", false).toBool();
  240. v2_unicode = qs.value(prefix + "v2unicode", true).toBool();
  241. v3_binary_octal = qs.value(prefix + "v3binaryoctal", true).toBool();
  242. v3_bytes = qs.value(prefix + "v3bytes", true).toBool();
  243. highlight_subids = qs.value(prefix + "highlightsubids", true).toBool();
  244. return rc;
  245. }
  246. // Write properties to the settings.
  247. bool QsciLexerPython::writeProperties(QSettings &qs,const QString &prefix) const
  248. {
  249. int rc = true;
  250. qs.setValue(prefix + "foldcomments", fold_comments);
  251. qs.setValue(prefix + "foldcompact", fold_compact);
  252. qs.setValue(prefix + "foldquotes", fold_quotes);
  253. qs.setValue(prefix + "indentwarning", (int)indent_warn);
  254. qs.setValue(prefix + "stringsovernewline", strings_over_newline);
  255. qs.setValue(prefix + "v2unicode", v2_unicode);
  256. qs.setValue(prefix + "v3binaryoctal", v3_binary_octal);
  257. qs.setValue(prefix + "v3bytes", v3_bytes);
  258. qs.setValue(prefix + "highlightsubids", highlight_subids);
  259. return rc;
  260. }
  261. // Set if comments can be folded.
  262. void QsciLexerPython::setFoldComments(bool fold)
  263. {
  264. fold_comments = fold;
  265. setCommentProp();
  266. }
  267. // Set the "fold.comment.python" property.
  268. void QsciLexerPython::setCommentProp()
  269. {
  270. emit propertyChanged("fold.comment.python",(fold_comments ? "1" : "0"));
  271. }
  272. // Set if folds are compact.
  273. void QsciLexerPython::setFoldCompact(bool fold)
  274. {
  275. fold_compact = fold;
  276. setCompactProp();
  277. }
  278. // Set the "fold.compact" property.
  279. void QsciLexerPython::setCompactProp()
  280. {
  281. emit propertyChanged("fold.compact",(fold_compact ? "1" : "0"));
  282. }
  283. // Set if quotes can be folded.
  284. void QsciLexerPython::setFoldQuotes(bool fold)
  285. {
  286. fold_quotes = fold;
  287. setQuotesProp();
  288. }
  289. // Set the "fold.quotes.python" property.
  290. void QsciLexerPython::setQuotesProp()
  291. {
  292. emit propertyChanged("fold.quotes.python",(fold_quotes ? "1" : "0"));
  293. }
  294. // Set the indentation warning.
  295. void QsciLexerPython::setIndentationWarning(QsciLexerPython::IndentationWarning warn)
  296. {
  297. indent_warn = warn;
  298. setTabWhingeProp();
  299. }
  300. // Set the "tab.timmy.whinge.level" property.
  301. void QsciLexerPython::setTabWhingeProp()
  302. {
  303. emit propertyChanged("tab.timmy.whinge.level", QByteArray::number(indent_warn));
  304. }
  305. // Set if string literals can span newlines.
  306. void QsciLexerPython::setStringsOverNewlineAllowed(bool allowed)
  307. {
  308. strings_over_newline = allowed;
  309. setStringsOverNewlineProp();
  310. }
  311. // Set the "lexer.python.strings.u" property.
  312. void QsciLexerPython::setStringsOverNewlineProp()
  313. {
  314. emit propertyChanged("lexer.python.strings.over.newline", (strings_over_newline ? "1" : "0"));
  315. }
  316. // Set if v2 unicode string literals are allowed.
  317. void QsciLexerPython::setV2UnicodeAllowed(bool allowed)
  318. {
  319. v2_unicode = allowed;
  320. setV2UnicodeProp();
  321. }
  322. // Set the "lexer.python.strings.u" property.
  323. void QsciLexerPython::setV2UnicodeProp()
  324. {
  325. emit propertyChanged("lexer.python.strings.u", (v2_unicode ? "1" : "0"));
  326. }
  327. // Set if v3 binary and octal literals are allowed.
  328. void QsciLexerPython::setV3BinaryOctalAllowed(bool allowed)
  329. {
  330. v3_binary_octal = allowed;
  331. setV3BinaryOctalProp();
  332. }
  333. // Set the "lexer.python.literals.binary" property.
  334. void QsciLexerPython::setV3BinaryOctalProp()
  335. {
  336. emit propertyChanged("lexer.python.literals.binary", (v3_binary_octal ? "1" : "0"));
  337. }
  338. // Set if v3 bytes string literals are allowed.
  339. void QsciLexerPython::setV3BytesAllowed(bool allowed)
  340. {
  341. v3_bytes = allowed;
  342. setV3BytesProp();
  343. }
  344. // Set the "lexer.python.strings.b" property.
  345. void QsciLexerPython::setV3BytesProp()
  346. {
  347. emit propertyChanged("lexer.python.strings.b",(v3_bytes ? "1" : "0"));
  348. }
  349. // Set if sub-identifiers are highlighted.
  350. void QsciLexerPython::setHighlightSubidentifiers(bool enabled)
  351. {
  352. highlight_subids = enabled;
  353. setHighlightSubidsProp();
  354. }
  355. // Set the "lexer.python.keywords2.no.sub.identifiers" property.
  356. void QsciLexerPython::setHighlightSubidsProp()
  357. {
  358. emit propertyChanged("lexer.python.keywords2.no.sub.identifiers",
  359. (highlight_subids ? "0" : "1"));
  360. }