This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
5.8 KiB

  1. import sys
  2. import textwrap
  3. import re
  4. from PyQt5.Qt import * # noqa
  5. from PyQt5.Qsci import QsciScintilla
  6. from PyQt5.Qsci import QsciLexerCustom
  7. from lark import Lark, inline_args, Transformer
  8. class LexerJson(QsciLexerCustom):
  9. def __init__(self, parent=None):
  10. super().__init__(parent)
  11. self.create_grammar()
  12. self.create_styles()
  13. def create_styles(self):
  14. deeppink = QColor(249, 38, 114)
  15. khaki = QColor(230, 219, 116)
  16. mediumpurple = QColor(174, 129, 255)
  17. mediumturquoise = QColor(81, 217, 205)
  18. yellowgreen = QColor(166, 226, 46)
  19. lightcyan = QColor(213, 248, 232)
  20. darkslategrey = QColor(39, 40, 34)
  21. styles = {
  22. 0: mediumturquoise,
  23. 1: mediumpurple,
  24. 2: yellowgreen,
  25. 3: deeppink,
  26. 4: khaki,
  27. 5: lightcyan
  28. }
  29. for style, color in styles.items():
  30. self.setColor(color, style)
  31. self.setPaper(darkslategrey, style)
  32. self.setFont(self.parent().font(), style)
  33. self.token_styles = {
  34. "__COLON": 5,
  35. "__COMMA": 5,
  36. "__LBRACE": 5,
  37. "__LSQB": 5,
  38. "__RBRACE": 5,
  39. "__RSQB": 5,
  40. "FALSE": 0,
  41. "NULL": 0,
  42. "TRUE": 0,
  43. "STRING": 4,
  44. "NUMBER": 1,
  45. }
  46. def create_grammar(self):
  47. grammar = '''
  48. anons: ":" "{" "}" "," "[" "]"
  49. TRUE: "true"
  50. FALSE: "false"
  51. NULL: "NULL"
  52. %import common.ESCAPED_STRING -> STRING
  53. %import common.SIGNED_NUMBER -> NUMBER
  54. %import common.WS
  55. %ignore WS
  56. '''
  57. self.lark = Lark(grammar, parser=None, lexer='standard')
  58. # All tokens: print([t.name for t in self.lark.parser.lexer.tokens])
  59. def defaultPaper(self, style):
  60. return QColor(39, 40, 34)
  61. def language(self):
  62. return "Json"
  63. def description(self, style):
  64. return {v: k for k, v in self.token_styles.items()}.get(style, "")
  65. def styleText(self, start, end):
  66. self.startStyling(start)
  67. text = self.parent().text()[start:end]
  68. last_pos = 0
  69. try:
  70. for token in self.lark.lex(text):
  71. ws_len = token.pos_in_stream - last_pos
  72. if ws_len:
  73. self.setStyling(ws_len, 0) # whitespace
  74. token_len = len(bytearray(token, "utf-8"))
  75. self.setStyling(
  76. token_len, self.token_styles.get(token.type, 0))
  77. last_pos = token.pos_in_stream + token_len
  78. except Exception as e:
  79. print(e)
  80. class EditorAll(QsciScintilla):
  81. def __init__(self, parent=None):
  82. super().__init__(parent)
  83. # Set font defaults
  84. font = QFont()
  85. font.setFamily('Consolas')
  86. font.setFixedPitch(True)
  87. font.setPointSize(8)
  88. font.setBold(True)
  89. self.setFont(font)
  90. # Set margin defaults
  91. fontmetrics = QFontMetrics(font)
  92. self.setMarginsFont(font)
  93. self.setMarginWidth(0, fontmetrics.width("000") + 6)
  94. self.setMarginLineNumbers(0, True)
  95. self.setMarginsForegroundColor(QColor(128, 128, 128))
  96. self.setMarginsBackgroundColor(QColor(39, 40, 34))
  97. self.setMarginType(1, self.SymbolMargin)
  98. self.setMarginWidth(1, 12)
  99. # Set indentation defaults
  100. self.setIndentationsUseTabs(False)
  101. self.setIndentationWidth(4)
  102. self.setBackspaceUnindents(True)
  103. self.setIndentationGuides(True)
  104. # self.setFolding(QsciScintilla.CircledFoldStyle)
  105. # Set caret defaults
  106. self.setCaretForegroundColor(QColor(247, 247, 241))
  107. self.setCaretWidth(2)
  108. # Set selection color defaults
  109. self.setSelectionBackgroundColor(QColor(61, 61, 52))
  110. self.resetSelectionForegroundColor()
  111. # Set multiselection defaults
  112. self.SendScintilla(QsciScintilla.SCI_SETMULTIPLESELECTION, True)
  113. self.SendScintilla(QsciScintilla.SCI_SETMULTIPASTE, 1)
  114. self.SendScintilla(
  115. QsciScintilla.SCI_SETADDITIONALSELECTIONTYPING, True)
  116. lexer = LexerJson(self)
  117. self.setLexer(lexer)
  118. EXAMPLE_TEXT = textwrap.dedent("""\
  119. {
  120. "_id": "5b05ffcbcf8e597939b3f5ca",
  121. "about": "Excepteur consequat commodo esse voluptate aute aliquip ad sint deserunt commodo eiusmod irure. Sint aliquip sit magna duis eu est culpa aliqua excepteur ut tempor nulla. Aliqua ex pariatur id labore sit. Quis sit ex aliqua veniam exercitation laboris anim adipisicing. Lorem nisi reprehenderit ullamco labore qui sit ut aliqua tempor consequat pariatur proident.",
  122. "address": "665 Malbone Street, Thornport, Louisiana, 243",
  123. "age": 23,
  124. "balance": "$3,216.91",
  125. "company": "BULLJUICE",
  126. "email": "elisekelley@bulljuice.com",
  127. "eyeColor": "brown",
  128. "gender": "female",
  129. "guid": "d3a6d865-0f64-4042-8a78-4f53de9b0707",
  130. "index": 0,
  131. "isActive": false,
  132. "isActive2": true,
  133. "latitude": -18.660714,
  134. "longitude": -85.378048,
  135. "name": "Elise Kelley",
  136. "phone": "+1 (808) 543-3966",
  137. "picture": "http://placehold.it/32x32",
  138. "registered": "2017-09-30T03:47:40 -02:00",
  139. "tags": [
  140. "et",
  141. "nostrud",
  142. "in",
  143. "fugiat",
  144. "incididunt",
  145. "labore",
  146. "nostrud"
  147. ]
  148. }\
  149. """)
  150. def main():
  151. app = QApplication(sys.argv)
  152. ex = EditorAll()
  153. ex.setWindowTitle(__file__)
  154. ex.setText(EXAMPLE_TEXT)
  155. ex.resize(800, 600)
  156. ex.show()
  157. sys.exit(app.exec_())
  158. if __name__ == "__main__":
  159. main()