/tortoisehg/hgqt/lexers.py

https://bitbucket.org/tortoisehg/hgtk/ · Python · 161 lines · 114 code · 29 blank · 18 comment · 20 complexity · 429fe578a7e936c75c30b4cfb2ab49be MD5 · raw file

  1. # lexers.py - select Qsci lexer for a filename and contents
  2. #
  3. # Copyright 2010 Steve Borho <steve@borho.org>
  4. #
  5. # This software may be used and distributed according to the terms of the
  6. # GNU General Public License version 2, incorporated herein by reference.
  7. import re
  8. from PyQt4 import Qsci
  9. from PyQt4.QtGui import *
  10. from tortoisehg.hgqt import qtlib
  11. class _LexerSelector(object):
  12. _lexer = None
  13. def match(self, filename, filedata):
  14. return False
  15. def lexer(self, parent):
  16. """
  17. Return a configured instance of the lexer
  18. """
  19. return self.cfg_lexer(self._lexer(parent))
  20. def cfg_lexer(self, lexer):
  21. font = qtlib.getfont('fontlog').font()
  22. lexer.setFont(font, -1)
  23. return lexer
  24. class _FilenameLexerSelector(_LexerSelector):
  25. """
  26. Base class for lexer selector based on file name matching
  27. """
  28. extensions = ()
  29. def match(self, filename, filedata):
  30. filename = filename.lower()
  31. for ext in self.extensions:
  32. if filename.endswith(ext):
  33. return True
  34. return False
  35. class _ScriptLexerSelector(_FilenameLexerSelector):
  36. """
  37. Base class for lexer selector based on content pattern matching
  38. """
  39. regex = None
  40. headersize = 3
  41. def match(self, filename, filedata):
  42. if super(_ScriptLexerSelector, self).match(filename, filedata):
  43. return True
  44. if self.regex and filedata:
  45. for line in filedata.splitlines()[:self.headersize]:
  46. if len(line)<1000 and self.regex.match(line):
  47. return True
  48. return False
  49. class PythonLexerSelector(_ScriptLexerSelector):
  50. extensions = ('.py', '.pyw')
  51. _lexer = Qsci.QsciLexerPython
  52. regex = re.compile(r'^#[!].*python')
  53. class BashLexerSelector(_ScriptLexerSelector):
  54. extensions = ('.sh', '.bash')
  55. _lexer = Qsci.QsciLexerBash
  56. regex = re.compile(r'^#[!].*sh')
  57. class PerlLexerSelector(_ScriptLexerSelector):
  58. extensions = ('.pl', '.perl')
  59. _lexer = Qsci.QsciLexerPerl
  60. regex = re.compile(r'^#[!].*perl')
  61. class RubyLexerSelector(_ScriptLexerSelector):
  62. extensions = ('.rb', '.ruby')
  63. _lexer = Qsci.QsciLexerRuby
  64. regex = re.compile(r'^#[!].*ruby')
  65. class LuaLexerSelector(_ScriptLexerSelector):
  66. extensions = ('.lua', )
  67. _lexer = Qsci.QsciLexerLua
  68. regex = None
  69. class CppLexerSelector(_FilenameLexerSelector):
  70. extensions = ('.c', '.cpp', '.cxx', '.h', '.hpp', '.hxx')
  71. _lexer = Qsci.QsciLexerCPP
  72. class CSSLexerSelector(_FilenameLexerSelector):
  73. extensions = ('.css',)
  74. _lexer = Qsci.QsciLexerCSS
  75. class HTMLLexerSelector(_FilenameLexerSelector):
  76. extensions = ('.htm', '.html', '.xhtml', '.xml')
  77. _lexer = Qsci.QsciLexerHTML
  78. class VerilogLexerSelector(_FilenameLexerSelector):
  79. extensions = ('.v', '.vh')
  80. _lexer = Qsci.QsciLexerVerilog
  81. class VHDLLexerSelector(_FilenameLexerSelector):
  82. extensions = ('.vhd', '.vhdl')
  83. _lexer = Qsci.QsciLexerVHDL
  84. class BatchLexerSelector(_FilenameLexerSelector):
  85. extensions = ('.cmd', '.bat')
  86. _lexer = Qsci.QsciLexerBatch
  87. class MakeLexerSelector(_FilenameLexerSelector):
  88. extensions = ('.mk', 'makefile')
  89. _lexer = Qsci.QsciLexerMakefile
  90. class SQLLexerSelector(_FilenameLexerSelector):
  91. extensions = ('.sql',)
  92. _lexer = Qsci.QsciLexerSQL
  93. class JSLexerSelector(_FilenameLexerSelector):
  94. extensions = ('.js',)
  95. _lexer = Qsci.QsciLexerJavaScript
  96. class JavaLexerSelector(_FilenameLexerSelector):
  97. extensions = ('.java',)
  98. _lexer = Qsci.QsciLexerJava
  99. class TeXLexerSelector(_FilenameLexerSelector):
  100. extensions = ('.tex', '.latex',)
  101. _lexer = Qsci.QsciLexerTeX
  102. class DiffLexerSelector(_ScriptLexerSelector):
  103. extensions = ()
  104. _lexer = Qsci.QsciLexerDiff
  105. regex = re.compile(r'^@@ [-]\d+,\d+ [+]\d+,\d+ @@$')
  106. def cfg_lexer(self, lexer):
  107. #lexer.setDefaultPaper(QtGui.QColor(cfg.getDiffBGColor()))
  108. #lexer.setColor(QtGui.QColor(cfg.getDiffFGColor()), -1)
  109. for label, i in (('diff.inserted', 6),
  110. ('diff.deleted', 5),
  111. ('diff.hunk', 4)):
  112. effect = qtlib.geteffect(label)
  113. for e in effect.split(';'):
  114. if e.startswith('color:'):
  115. lexer.setColor(QColor(e[7:]), i)
  116. font = qtlib.getfont('fontdiff').font()
  117. lexer.setFont(font, -1)
  118. return lexer
  119. lexers = []
  120. for clsname, cls in globals().items():
  121. if clsname.startswith('_'):
  122. continue
  123. if isinstance(cls, type) and issubclass(cls, _LexerSelector):
  124. #print clsname
  125. lexers.append(cls())
  126. def get_diff_lexer(parent):
  127. return DiffLexerSelector().lexer(parent)
  128. def get_lexer(filename, filedata, parent):
  129. for lselector in lexers:
  130. if lselector.match(filename, filedata):
  131. return lselector.lexer(parent)
  132. return None