def test(self): lexer = BasicLexer() listing='10 PRINT"FOO"' tokensource = lexer.get_tokens(listing) self.assertEqual(list(tokensource), [ (Token.Name.Label, '10'), (Token.Text, ' '), (Token.Name.Builtin, 'PRINT'), (Token.Literal.String, '"FOO"'), (Token.Text, '\n') ])
def __init__(self, editor): super(TkTextHighlighting, self).__init__(editor) self.lexer = BasicLexer() self.machine_api = editor.machine_api self.tags = self.create_tags() self.existing_tags = tuple(self.tags.values()) # TODO: Add a bind callback list # see: http://www.python-forum.de/viewtopic.php?f=18&t=35275 (de) # self.editor.root.bind("<KeyRelease>", self.update) # self.editor.root.bind("<KeyRelease>", self.force_update) self.old_pos=None self.__update_interval()
class TkTextHighlighting(BaseExtension): """ code based on idlelib.ColorDelegator.ColorDelegator """ after_id = None TAG_LINE_NUMBER = "lineno" TAG_JUMP_ADDESS = "jump" def __init__(self, editor): super(TkTextHighlighting, self).__init__(editor) self.lexer = BasicLexer() self.machine_api = editor.machine_api self.tags = self.create_tags() self.existing_tags = tuple(self.tags.values()) # TODO: Add a bind callback list # see: http://www.python-forum.de/viewtopic.php?f=18&t=35275 (de) # self.editor.root.bind("<KeyRelease>", self.update) # self.editor.root.bind("<KeyRelease>", self.force_update) self.old_pos=None self.__update_interval() def __update_interval(self): """ highlight the current line """ self.update() self.after_id = self.text.after(250, self.__update_interval) def force_update(self, event): print("force update") self.update(event, force=True) def update(self, event=None, force=False): pos = self.text.index(tkinter.INSERT) # print("update %s" % pos) if not force and pos == self.old_pos: # print("Skip") return self.recolorize() self.old_pos = pos # --------------------------------------------------------------------------------------- def create_tags(self): tags={} bold_font = font.Font(self.text, self.text.cget("font")) bold_font.configure(weight=font.BOLD) italic_font = font.Font(self.text, self.text.cget("font")) italic_font.configure(slant=font.ITALIC) bold_italic_font = font.Font(self.text, self.text.cget("font")) bold_italic_font.configure(weight=font.BOLD, slant=font.ITALIC) style = get_style_by_name("default") for ttype, ndef in style: # print(ttype, ndef) tag_font = None if ndef["bold"] and ndef["italic"]: tag_font = bold_italic_font elif ndef["bold"]: tag_font = bold_font elif ndef["italic"]: tag_font = italic_font if ndef["color"]: foreground = "#%s" % ndef["color"] else: foreground = None tags[ttype]=str(ttype) self.text.tag_configure(tags[ttype], foreground=foreground, font=tag_font) # self.text.tag_configure(str(ttype), foreground=foreground, font=tag_font) return tags def recolorize(self): # print("recolorize") listing = self.text.get("1.0", "end-1c") destinations = self.machine_api.renum_tool.get_destinations(listing) tokensource = self.lexer.get_tokens(listing) start_line=1 start_index = 0 end_line=1 end_index = 0 for ttype, value in tokensource: if "\n" in value: end_line += value.count("\n") end_index = len(value.rsplit("\n",1)[1]) else: end_index += len(value) if value not in (" ", "\n"): index1 = "%s.%s" % (start_line, start_index) index2 = "%s.%s" % (end_line, end_index) for tagname in self.text.tag_names(index1): # FIXME # print("remove %s" % tagname) if tagname not in self.existing_tags: # Don"t remove e.g.: "current line"-tag # print("Skip...") continue self.text.tag_remove(tagname, index1, index2) # Mark used line numbers extra: if start_index==0 and ttype==pygments.token.Name.Label: if int(value) in destinations: ttype = pygments.token.Name.Tag self.text.tag_add(self.tags[ttype], index1, index2) start_line = end_line start_index = end_index