Skip to content

Commit

Permalink
Change language mode from statusbar
Browse files Browse the repository at this point in the history
Merge pull request #140 from billyeatcookies/change_language_mode
  • Loading branch information
tomlin7 authored Oct 16, 2023
2 parents 002dc2c + 5c4d87e commit 9a38016
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 22 deletions.
54 changes: 41 additions & 13 deletions biscuit/core/components/editors/texteditor/highlighter.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
from __future__ import annotations

import os
import threading
import tkinter as tk
import typing

from pygments import lex
from pygments.lexers import get_lexer_by_name, get_lexer_for_filename

if typing.TYPE_CHECKING:
from .text import Text

class Highlighter:
def __init__(self, master, language=None, *args, **kwargs) -> None:
self.master = master
self.base = master.base
def __init__(self, text: Text, language: str=None, *args, **kwargs) -> None:
"""Highlighter based on pygments lexers
If language is not given, it will try to detect the language from the file extension.
If the file extension is not recognized, it will default to plain text.
Attributes
----------
text : Text
Text widget to highlight
language : str, optional
Language to highlight, by default None
"""

self.text = master
self.base = master.base
self.text: Text = text
self.base = text.base
self.language = language

if language:
Expand All @@ -25,10 +40,10 @@ def __init__(self, master, language=None, *args, **kwargs) -> None:
return
else:
try:
if os.path.basename(master.path).endswith("txt"):
if os.path.basename(text.path).endswith("txt"):
raise Exception()

self.lexer = get_lexer_for_filename(os.path.basename(master.path), encoding=master.encoding)
self.lexer = get_lexer_for_filename(os.path.basename(text.path), encoding=text.encoding)
self.text.language = self.lexer.name
except:
self.lexer = None
Expand All @@ -39,7 +54,16 @@ def __init__(self, master, language=None, *args, **kwargs) -> None:
self.tag_colors = self.base.theme.syntax
self.setup_highlight_tags()

def change_language(self, language):
def change_language(self, language: str) -> None:
"""Change the language of the highlighter
If language is not given, it will try to detect the language from the file extension.
If the file extension is not recognized, it will default to plain text.
Parameters
----------
language : str
Language to highlight
"""
if language:
try:
self.lexer = get_lexer_by_name(language)
Expand All @@ -51,22 +75,26 @@ def change_language(self, language):
return
else:
try:
if os.path.basename(self.master.path).endswith("txt"):
if os.path.basename(self.text.path).endswith("txt"):
raise Exception()

self.lexer = get_lexer_for_filename(os.path.basename(self.master.path), encoding=self.master.encoding)
self.lexer = get_lexer_for_filename(os.path.basename(self.text.path), encoding=self.text.encoding)
self.text.language = self.lexer.name
except:
self.lexer = None
self.text.language = "Plain Text"
self.base.notifications.info("No lexers are available for opened file type.")
return

def setup_highlight_tags(self):

threading.Thread(target=self.text.refresh, daemon=True).start()

def setup_highlight_tags(self) -> None:
"Setup the tags for highlighting"
for token, color in self.tag_colors.items():
self.text.tag_configure(str(token), foreground=color)

def highlight(self):
def highlight(self) -> None:
"Highlights the text content of attached Editor instance"
if not self.lexer:
return

Expand Down
1 change: 1 addition & 0 deletions biscuit/core/components/floating/palette/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def __init__(self, master, items=None, width=60, *args, **kwargs) -> None:
self.configure_bindings()

def register_actionset(self, actionset: ActionSet) -> None:
"Expects a lambda returning the actionset instead of the actionset itself"
self.actionsets.append(actionset)

def generate_help_actionset(self) -> None:
Expand Down
26 changes: 17 additions & 9 deletions biscuit/core/layout/statusbar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import tkinter as tk
import typing

from pygments.lexers._mapping import LEXERS

from biscuit.core.components import ActionSet
from biscuit.core.components.utils import Frame

Expand All @@ -28,7 +30,13 @@ class Statusbar(Frame):
"""
Status bar holds various widgets that are used to display information about the current file
and the current state of the editor.
Attributes
----------
base : Root
Root window
"""

def __init__(self, master: Root, *args, **kwargs) -> None:
super().__init__(master, *args, **kwargs)
self.config(bg=self.base.theme.layout.statusbar.background)
Expand Down Expand Up @@ -84,21 +92,21 @@ def __init__(self, master: Root, *args, **kwargs) -> None:
self.eol = SButton(self, text="CRLF", function=lambda: self.base.palette.show_prompt('eol:'), description="Select End of Line sequence")
self.eol.set_pack_data(side=tk.RIGHT)

# TODO use pygments to list out?
self.filetype_actionset = ActionSet(
"FILETYPE", "syntax:",
[("Plain Text", lambda e=None: print("filetype Plain Text", e)),
("python", lambda e=None: print("filetype python", e)),
("c++", lambda e=None: print("filetype c++", e))],
# language mode
items = [(aliases[0], lambda _, lang=aliases[0]: self.base.editorsmanager.active_editor.content.text.highlighter.change_language(lang)) for _, _, aliases, _, _ in LEXERS.values() if aliases]
self.language_actionset = ActionSet(
"Change Language Mode", "language:", items
)
self.base.palette.register_actionset(lambda: self.filetype_actionset)
self.file_type = SButton(self, text="Plain Text", function=lambda: self.base.palette.show_prompt('syntax:'), description="Select Language Mode")
self.base.palette.register_actionset(lambda: self.language_actionset)
self.file_type = SButton(self, text="Plain Text", function=lambda: self.base.palette.show_prompt('language:'), description="Select Language Mode")
self.file_type.set_pack_data(side=tk.RIGHT)

# show/hide notifications
self.notif = SButton(self, icon="bell", function=self.base.notifications.show, description="No notifications")
self.notif.pack(side=tk.RIGHT, padx=(0, 10))

self.filetype_actionset = ActionSet(
# clock
self.time_actionset = ActionSet(
"Configure clock format", "time:",
[("12 hours", lambda e=None: print("time 12 hours", e)),
("24 hours", lambda e=None: print("time 24 hours", e)),],
Expand Down
3 changes: 3 additions & 0 deletions biscuit/core/layout/statusbar/utils/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ def change_description(self, text: str) -> None:

def change_icon(self, icon: str) -> None:
self.icon_label.config(text=get_codicon(icon))

def change_function(self, function: typing.Callable) -> None:
self.function = function

def set_pack_data(self, **kwargs) -> None:
self.pack_data = kwargs
Expand Down

0 comments on commit 9a38016

Please sign in to comment.