Skip to content

Commit 5b8177d

Browse files
committed
Version 1.4.1:
refactor(dataclasses): remove enabled param from SearchWindowSettings class refactor: remove some comments with too obvious information
1 parent a502503 commit 5b8177d

File tree

9 files changed

+27
-49
lines changed

9 files changed

+27
-49
lines changed

CTkCodeBoxPlus/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
Homepage: https://github.com/KiTant/CTkCodeBoxPlus
77
"""
88

9-
__version__ = '1.4'
9+
__version__ = '1.4.1'
1010

1111
from .ctk_code_box import CTkCodeBox
1212
from .dataclasses import *
13+
from .constants import common_langs
1314
from .custom_exception_classes import *
1415
from .text_menu import TextMenu
1516
from .add_line_nums import AddLineNums
1617
from .keybinding import unregister_keybind, register_keybind
1718
from .search_replace_window import SearchReplaceWindow
1819

19-
__all__ = ["CTkCodeBox", "HistorySettings", "MenuSettings", "NumberingSettings", "ReplaceResult", "TextMenu",
20+
__all__ = ["CTkCodeBox", "HistorySettings", "MenuSettings", "SearchWindowSettings", "NumberingSettings",
2021
"AddLineNums", "unregister_keybind", "register_keybind", "CTkCodeBoxError", "KeybindingSettings",
2122
"LanguageNotAvailableError", "ThemeNotAvailableError", "LexerError", "ConfigureBadType",
22-
"SearchReplaceWindow"]
23+
"SearchReplaceWindow", "ReplaceResult", "TextMenu", "common_langs"]

CTkCodeBoxPlus/add_line_nums.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44

55
class AddLineNums(TkLineNumbers):
6-
"""
7-
Line numbers widget for CTkCodeBox (uses TkLineNumbers)
8-
"""
6+
"""Line numbers widget for CTkCodeBox (uses TkLineNumbers)"""
97
def __init__(self,
108
master,
119
text_color=None,

CTkCodeBoxPlus/ctk_code_box.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@
2222

2323
class CTkCodeBox(customtkinter.CTkTextbox):
2424
"""A code-oriented CTk textbox with syntax highlighting and UX helpers.
25-
2625
CTkCodeBox wraps a CTkTextbox to provide:
2726
- Pygments-based syntax highlighting with theme support
2827
- Optional line numbers, smarter selection, and current-line highlight
2928
- Indentation helpers (Tab/Shift+Tab, auto-indent on Return)
3029
- Simple history (Undo/Redo) with typing cooldown
3130
- Platform-aware keybindings (Cmd on macOS, Ctrl elsewhere)
32-
3331
Emits:
3432
<<ContentChanged>> on both the inner textbox and the wrapper whenever
3533
content changes via the provided APIs.
@@ -156,10 +154,8 @@ def __init__(self,
156154

157155
def check_lexer(self):
158156
"""Resolve and set the lexer.
159-
160157
If `language` is a string, pick a lexer from common languages.
161158
otherwise treat `language` as a Pygments lexer class.
162-
163159
Raises:
164160
LanguageNotAvailableError: When string language is unknown.
165161
"""
@@ -173,7 +169,6 @@ def check_lexer(self):
173169

174170
def configure_tags(self):
175171
"""Configure all syntax tags for the current Pygments theme.
176-
177172
Raises:
178173
ThemeNotAvailableError: If the requested theme is not installed.
179174
"""
@@ -220,7 +215,6 @@ def _select_all(self):
220215

221216
def insert(self, index, chars, push_history=True, *tags):
222217
"""Insert text and trigger a non-editing highlight update.
223-
224218
Mirrors tkinter.Text.insert signature to maintain API parity.
225219
"""
226220
if push_history:
@@ -231,7 +225,6 @@ def insert(self, index, chars, push_history=True, *tags):
231225

232226
def highlight_code(self, code):
233227
"""Tokenize code with Pygments and apply tags.
234-
235228
Raises:
236229
LexerError: If the provided lexer fails to tokenize the input.
237230
"""
@@ -958,7 +951,6 @@ def _on_backtick(self, event=None):
958951

959952
def _handle_chars_wrap(self, chars: str):
960953
"""Handle wrapping/insertion behavior for paired characters.
961-
962954
If text is selected, wraps it with the given pair. Otherwise inserts a
963955
paired sequence and places the caret between them.
964956
"""
@@ -1086,7 +1078,6 @@ def _on_triple_click(self, event):
10861078

10871079
def _expand_token_at_index(self, idx):
10881080
"""Return token span around index based on simple character classes.
1089-
10901081
Returns:
10911082
A tuple (start_index, end_index) or (None, None) when no token
10921083
can be expanded at the given index.

CTkCodeBoxPlus/dataclasses.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
@dataclass(frozen=True)
66
class SearchWindowSettings:
7-
enabled: bool = True
87
title: str = "Search & Replace"
98
width: int = 400
109
height: int = 250
@@ -34,7 +33,8 @@ class MenuSettings:
3433
commands: dict = field(default_factory=lambda: {
3534
# label: (special type for states or "", callable or attribute of codebox in str, displaying accelerator,
3635
# additional check (callable with return or attr of codebox in str for cget) or None)
37-
# or "separator": additional check (callable with return or attr of codebox in str for cget) or None
36+
# or
37+
# "separator": additional check (callable with return or attr of codebox in str for cget) or None
3838
"Copy": ("has_selection", "copy_text", "Ctrl+C", None),
3939
"Paste": ("has_clip", "paste_text", "Ctrl+V", None),
4040
"Cut": ("has_selection", "cut_text", "Ctrl+X", None),
@@ -75,7 +75,7 @@ class KeybindingSettings: # If you want to disable keybind just write ""
7575
R_open_search_window: str = "CmdOrCtrl+F"
7676
# Indentation keybinds
7777
R__on_tab: str = "TAB"
78-
# Use Shift-Tab for outdent;
78+
# Use Shift-Tab for outdent
7979
R__on_shift_tab: str = "Shift+TAB"
8080
R__on_return: str = "RETURN"
8181
# Quote wrapping on selection

CTkCodeBoxPlus/keybinding.py

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""
22
Keybinding system for customtkinter
3-
43
Provides layout-independent keyboard keybind registration that works across
54
platforms and keyboard layouts by physical keycode logic.
65
@@ -15,7 +14,6 @@
1514
from .keybinding import unregister_keybind
1615
unregister_keybind(root, "CmdOrCtrl+P") # remove all callbacks for this keybind on target
1716
unregister_keybind(entry, "Ctrl+Return", on_submit) # remove specific callback
18-
1917
Notes:
2018
- You can pass either a toplevel/root (tk.Tk, tk.Toplevel, CTk, CTkToplevel)
2119
or ANY Tk/CustomTkinter widget (e.g., CTkTextbox, CTkEntry).
@@ -68,7 +66,6 @@ def _get_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
6866

6967
def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
7068
"""Return (function_keys, special_keys) dicts for the current platform.
71-
7269
This centralizes platform keycodes to avoid duplication.
7370
"""
7471
if sys.platform == 'win32':
@@ -90,10 +87,10 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
9087
'ESCAPE': 27, 'ESC': 27,
9188
'SPACE': 32,
9289
'BACKSPACE': 8,
93-
'PLUS': 187, 'EQUAL': 187, '=': 187, # Main keyboard =/+ key
94-
'NUMPAD_PLUS': 107, 'NUMPAD_ADD': 107, # Numpad +
95-
'MINUS': 189, 'HYPHEN': 189, '-': 189, # Main keyboard -/_ key
96-
'NUMPAD_MINUS': 109, 'NUMPAD_SUBTRACT': 109, # Numpad -
90+
'PLUS': 187, 'EQUAL': 187, '=': 187,
91+
'NUMPAD_PLUS': 107, 'NUMPAD_ADD': 107,
92+
'MINUS': 189, 'HYPHEN': 189, '-': 189,
93+
'NUMPAD_MINUS': 109, 'NUMPAD_SUBTRACT': 109,
9794
'COMMA': 188, ',': 188,
9895
'PERIOD': 190, '.': 190
9996
}
@@ -106,7 +103,7 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
106103
}
107104
special_keys = {
108105
'DELETE': 117, 'DEL': 117, # Forward Delete (both unified)
109-
'BACKSPACE': 51, # Backspace key
106+
'BACKSPACE': 51,
110107
'INSERT': 114,
111108
'HOME': 115, 'END': 119,
112109
'PAGE_UP': 116, 'PAGEUP': 116, 'PGUP': 116,
@@ -116,10 +113,10 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
116113
'ENTER': 36, 'RETURN': 76, # keypad Enter = 76
117114
'ESCAPE': 53, 'ESC': 53,
118115
'SPACE': 49,
119-
'PLUS': 69, 'EQUAL': 69, '=': 69, # Main keyboard =/+ key
120-
'NUMPAD_PLUS': 78, 'NUMPAD_ADD': 78, # Numpad +
121-
'MINUS': 27, 'HYPHEN': 27, '-': 27, # Main keyboard -/_ key
122-
'NUMPAD_MINUS': 75, 'NUMPAD_SUBTRACT': 75, # Numpad -
116+
'PLUS': 69, 'EQUAL': 69, '=': 69,
117+
'NUMPAD_PLUS': 78, 'NUMPAD_ADD': 78,
118+
'MINUS': 27, 'HYPHEN': 27, '-': 27,
119+
'NUMPAD_MINUS': 75, 'NUMPAD_SUBTRACT': 75,
123120
'COMMA': 43, ',': 43,
124121
'PERIOD': 47, '.': 47
125122
}
@@ -142,10 +139,10 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
142139
'ESCAPE': 9, 'ESC': 9,
143140
'SPACE': 65,
144141
'BACKSPACE': 22,
145-
'PLUS': 21, 'EQUAL': 21, '=': 21, # Main keyboard =/+ key
146-
'NUMPAD_PLUS': 86, 'NUMPAD_ADD': 86, # Numpad +
147-
'MINUS': 20, 'HYPHEN': 20, '-': 20, # Main keyboard -/_ key
148-
'NUMPAD_MINUS': 82, 'NUMPAD_SUBTRACT': 82, # Numpad -
142+
'PLUS': 21, 'EQUAL': 21, '=': 21,
143+
'NUMPAD_PLUS': 86, 'NUMPAD_ADD': 86,
144+
'MINUS': 20, 'HYPHEN': 20, '-': 20,
145+
'NUMPAD_MINUS': 82, 'NUMPAD_SUBTRACT': 82,
149146
'COMMA': 59, ',': 59,
150147
'PERIOD': 60, '.': 60
151148
}
@@ -179,7 +176,6 @@ def _get_group_id(widget: Any) -> int:
179176

180177
def _parse_modifiers(mod_tokens: List[str]) -> Tuple[str, List[str]]:
181178
"""Normalize a list of modifier tokens into a canonical key and Tk names.
182-
183179
Returns:
184180
mods_key: canonical string like 'ctrl', 'ctrl+shift', or 'none'
185181
tk_mods: list of Tk modifier names like ['Control', 'Shift']
@@ -222,11 +218,9 @@ def _parse_modifiers(mod_tokens: List[str]) -> Tuple[str, List[str]]:
222218

223219
def register_keybind(widget_or_root: Any, keybind: str, callback: Callable, *, bind_scope: str = 'window') -> None:
224220
"""Register a keyboard keybind that works regardless of keyboard layout.
225-
226221
Supported Modifiers: Ctrl, Alt, Shift, Cmd (macOS)
227222
Supported Keys: A-Z, 0-9, F1-F12, Delete, Insert, Home, End, Page_Up, Page_Down, etc.
228223
Supports both single keys (F1, F2, Delete) and modified keys (Ctrl+S, Alt+F4)
229-
230224
Args:
231225
widget_or_root: Any Tk/CustomTkinter widget or a toplevel/root.
232226
keybind: Keybind string in format 'Modifier+Key' or just 'Key' (e.g., "Ctrl+S", "Alt+F4", "F1")
@@ -402,13 +396,11 @@ def _on_destroy(event, t_id=target_id, tgt=target):
402396

403397
def unregister_keybind(widget_or_root: Any, keybind: str, callback: Callable | None = None, *, bind_scope: str = 'window') -> bool:
404398
"""Unregister keybind from a window or a specific widget.
405-
406399
Args:
407400
widget_or_root: Any Tk/CustomTkinter widget or a toplevel/root.
408401
keybind: Keybind string 'Modifier+Key' or just 'Key'. Supports 'CmdOrCtrl'.
409402
callback: Optional specific callback to remove. If None, removes all callbacks for this keybind.
410403
bind_scope: 'window' to target the widget's toplevel, or 'widget' to target only the widget.
411-
412404
Returns:
413405
True if something was removed, False otherwise.
414406
"""

CTkCodeBoxPlus/text_menu.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,14 @@ def _update_states(self):
110110
except tkinter.TclError:
111111
has_redo = False
112112

113-
# Apply states
114113
def set_state(label, enabled):
115114
try:
116115
self.entryconfig(label, state=("normal" if enabled else "disabled"))
117116
except Exception:
118117
pass
119118

120-
states = {"has_selection": has_selection, "has_clip": has_clip, "has_text": has_text, "has_undo": has_undo, "has_redo": has_redo}
119+
states = {"has_selection": has_selection, "has_clip": has_clip, "has_text": has_text,
120+
"has_undo": has_undo, "has_redo": has_redo}
121121
for state, labels in self.labels_states.items():
122122
for label in labels:
123123
set_state(label, states[state])

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ root.mainloop()
9090
```python
9191
@dataclass(frozen=True)
9292
class SearchWindowSettings:
93-
enabled: bool = True
9493
title: str = "Search & Replace"
9594
width: int = 400
9695
height: int = 250
@@ -119,7 +118,8 @@ class MenuSettings:
119118
commands: dict = field(default_factory=lambda: {
120119
# label: (special type for states or "", callable or attribute of codebox in str, displaying accelerator,
121120
# additional check (callable with return or attr of codebox in str for cget) or None)
122-
# or "separator": additional check (callable with return or attr of codebox in str for cget) or None
121+
# or
122+
# "separator": additional check (callable with return or attr of codebox in str for cget) or None
123123
"Copy": ("has_selection", "copy_text", "Ctrl+C", None),
124124
"Paste": ("has_clip", "paste_text", "Ctrl+V", None),
125125
"Cut": ("has_selection", "cut_text", "Ctrl+X", None),
@@ -156,7 +156,7 @@ class KeybindingSettings: # If you want to disable keybind just write ""
156156
R_undo: str = "CmdOrCtrl+Z"
157157
# Indentation keybinds
158158
R__on_tab: str = "TAB"
159-
# Use Shift-Tab for outdent;
159+
# Use Shift-Tab for outdent
160160
R__on_shift_tab: str = "Shift+TAB"
161161
R__on_return: str = "RETURN"
162162
# Quote wrapping on selection

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "CTkCodeBoxPlus"
7-
version = "1.4"
7+
version = "1.4.1"
88
description = "A code editor widget for customtkinter with enhanced features"
99
readme = "README.md"
1010
license = {file = "LICENSE"}

theme_example.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import customtkinter
22
from CTkCodeBoxPlus import *
33

4-
# Create the main application window
54
app = customtkinter.CTk()
65
app.geometry("400x400")
76
app.title("CodeBox Themes")
87

9-
# Create a CTkLabel to display a title
108
title_label = customtkinter.CTkLabel(app, text="CodeBox Examples", font=("Helvetica", 16, "bold"))
119
title_label.pack()
1210

13-
# Create a CTkCodeBox with an initial theme
1411
codebox = CTkCodeBox(app, language="python", theme="solarized-light")
1512
codebox.pack(padx=10, pady=10, fill="both", expand=True)
1613
demo_code = """def is_prime(num):
@@ -32,7 +29,6 @@
3229
"""
3330
codebox.insert("0.0", demo_code, push_history=False)
3431

35-
# Create a CTkComboBox for theme selection
3632
theme_values = ['abap', 'arduino', 'autumn', 'borland',
3733
'colorful', 'default', 'dracula', 'emacs', 'friendly_grayscale',
3834
'friendly', 'fruity', 'github-dark', 'gruvbox-dark', 'gruvbox-light',

0 commit comments

Comments
 (0)