1+ from __future__ import annotations
2+
13import ntkutils , tkinter
2- from tkinter import ttk , filedialog
4+ from tkinter import PhotoImage , ttk , filedialog , Event
35from pygments .lexers import get_lexer_for_filename
46import pygments .lexers
7+ import pyautogui
58
69import vars as v
710import filetype as f
811
9- tabbuttons = []
10- cbuttons = []
1112tabs = [["Untitled" , "" , "unsaved" , "*" ]]
1213
13-
14- def update (file ):
14+ def updatetab (file ):
1515 tabs [v .tabselected ][0 ] = file .name .split ("/" )[- 1 ]
1616 tabs [v .tabselected ][2 ] = file .name
17- tabs [v .tabselected ][3 ] = ""
17+ tabs [v .tabselected ][3 ] = ""
1818
1919def updatetitle (): v .root .title ("txt2 - {} {}" .format (tabs [v .tabselected ][0 ], tabs [v .tabselected ][3 ]))
2020
21- def _open ( x ):
21+ def new ( ):
2222 tabs [v .tabselected ][1 ] = v .textwidget .text .get ("1.0" , "end" )
23- v .tabselected = tabbuttons .index (x )
24-
2523 v .textwidget .text .delete ("1.0" , "end" )
26- v .textwidget .text .insert ("1.0" , tabs [v .tabselected ][1 ])
27- v .textwidget .text .delete ("end-1c" , "end" )
28-
29- v .filedir .configure (text = tabs [v .tabselected ][2 ])
24+ tabs .append (["Untitled" , "" , "unsaved" , "*" ])
25+ v .filedir .configure (text = "unsaved" )
26+ v .tabselected = v .tabselected + 1
3027
31- buildtabs ()
32- updatetitle ()
33- setlexer ()
34-
35- def close (e , x ):
36- if not v .tabselected == cbuttons .index (x ):
37- tabs .pop (cbuttons .index (x ))
38- if cbuttons .index (x ) < v .tabselected : v .tabselected = v .tabselected - 1
39-
40- buildtabs ()
41- else :
42- if len (cbuttons ) > 1 :
43- tabs .pop (v .tabselected )
44- v .tabselected = v .tabselected - 1
28+ try : v .textwidget .redraw ()
29+ except : pass
4530
46- buildtabs ()
31+ v .tabbar .add (tkinter .Frame (), text = tabs [v .tabselected ][0 ], image = v .closeimg , compound = "right" )
32+ v .tabbar .select (v .tabselected )
4733
48- v .textwidget .text .delete ("1.0" , "end" )
49- v .textwidget .text .insert ("1.0" , tabs [v .tabselected ][1 ])
50- updatetitle ()
51- v .filedir .configure (text = tabs [v .tabselected ][2 ])
52- else :
53- v .root .destroy ()
54-
55- def new ():
56- if not len (tabs ) == 10 :
57- tabs [v .tabselected ][1 ] = v .textwidget .text .get ("1.0" , "end" )
58- v .textwidget .text .delete ("1.0" , "end" )
59- tabs .append (["Untitled" , "" , "unsaved" , "*" ])
60- v .filedir .configure (text = "unsaved" )
61- v .tabselected = len (tabbuttons )
62-
63- buildtabs ()
64- updatetitle ()
65- if v .cfg ["syntax-highlighting" ]: v .textwidget .text ._set_lexer (pygments .lexers .TextLexer )
66- else : print ("Tab limit reached" )
34+ updatetitle ()
35+ if v .cfg ["syntax-highlighting" ]: v .textwidget .text ._set_lexer (pygments .lexers .TextLexer )
6736
6837def save (e = "" , saveas = False ):
6938 if tabs [v .tabselected ][2 ] == "unsaved" or saveas :
7039 file = filedialog .asksaveasfile ()
7140 if file == None : return
7241 else : file = open (tabs [v .tabselected ][2 ], "w" )
73-
42+
7443 if file != None :
7544 file .write (v .textwidget .text .get ("1.0" , "end" ))
7645
77- update (file )
46+ updatetab (file )
7847 v .filedir .configure (text = file .name )
7948
8049 file .close ()
8150
82- buildtabs ()
8351 updatetitle ()
8452 setlexer ()
8553
8654def openfile (e = "" ):
87- if not len (tabs ) == 10 :
88- file = filedialog .askopenfile ()
89- content = file .read ()
90-
91- if not v .textwidget .text .get ("1.0" , "end" ).replace ("\n " , "" ) == "" : new ()
92-
93- update (file )
55+ file = filedialog .askopenfile ()
56+ content = file .read ()
9457
95- file .close ()
96-
97- v .textwidget .text .insert ("1.0" , content )
98- v .filedir .configure (text = tabs [v .tabselected ][2 ])
99-
100- buildtabs ()
101- updatetitle ()
102- setlexer ()
103- else :
104- print ("Tab limit reached" )
58+ if v .textwidget .text .get ("1.0" , "end" ).replace ("\n " , "" ) != "" :
59+ new ()
10560
106- def changetype ():
107- if tabs [v .tabselected ][2 ] == "unsaved" : save ()
108- else :
109- result = f .get (tabs [v .tabselected ][2 ])
110- tabs [v .tabselected ][2 ] = result
111- tabs [v .tabselected ][0 ] = result .split ("/" )[- 1 ]
112- v .filedir .configure (text = result )
61+ updatetab (file )
11362
114- buildtabs ()
115- updatetitle ()
116- setlexer ()
63+ file .close ()
11764
118- def on_enters (e , x ): x .configure (bg = v .selected_hover )
119- def on_leaves (e , x ): x .configure (bg = v .selected )
120- def on_enter (e , x ): x .configure (bg = v .normal_hover )
121- def on_leave (e , x ): x .configure (bg = v .normal )
65+ v .tabbar .tab (v .tabselected , text = tabs [v .tabselected ][0 ], image = v .closeimg , compound = "right" )
66+ v .textwidget .text .insert ("1.0" , content )
67+ v .filedir .configure (text = tabs [v .tabselected ][2 ])
12268
123- def buildtabs ():
124- ntkutils .clearwin (v .tabbar )
125- tabbuttons .clear ()
126- cbuttons .clear ()
69+ updatetitle ()
70+ setlexer ()
12771
128- for i in tabs :
129- button = ttk .Button (v .tabbar , text = i [0 ] + " " , image = v .closeimg , compound = "right" )
130- button .pack (side = "left" , padx = 10 )
131- button .configure (command = lambda x = button : _open (x ))
132- button .update ()
72+ def opentab (event , tabdeleted = False ):
73+ if not tabdeleted : tabs [v .tabselected ][1 ] = v .textwidget .text .get ("1.0" , "end" )
13374
134- cbutton = tkinter .Label (v .tabbar , font = ("" , 15 ), image = v .closeimg , bg = v .normal )
135- cbutton .place (x = button .winfo_x () + button .winfo_width () - 37 , y = 23 )
136- cbutton .bind ("<1>" , lambda event , x = cbutton :close (event , x )) # Execute closetab on click
75+ v .tabselected = v .tabbar .index (v .tabbar .select ())
13776
138- tabbuttons .append (button )
139- cbuttons .append (cbutton )
77+ v .textwidget .text .delete ("1.0" , "end" )
78+ v .textwidget .text .insert ("1.0" , tabs [v .tabselected ][1 ])
79+ v .textwidget .text .delete ("end-1c" , "end" )
14080
141- tabbuttons [ v . tabselected ] .configure (style = "Accent.TButton" )
81+ v . filedir .configure (text = tabs [ v . tabselected ][ 2 ] )
14282
143- # This makes the background change to the hover color when hovering over the button
144- for i in tabbuttons :
145- if tabbuttons .index (i ) == v .tabselected :
146- i .bind ("<Enter>" , lambda event , x = cbuttons [v .tabselected ]: on_enters (event , x ))
147- i .bind ("<Leave>" , lambda event , x = cbuttons [v .tabselected ]: on_leaves (event , x ))
148- else :
149- i .bind ("<Enter>" , lambda event , x = cbuttons [tabbuttons .index (i )]: on_enter (event , x ))
150- i .bind ("<Leave>" , lambda event , x = cbuttons [tabbuttons .index (i )]: on_leave (event , x ))
83+ try : v .textwidget .redraw ()
84+ except : pass
15185
152- cbuttons [v .tabselected ].configure (bg = v .selected , image = v .closeimg2 )
86+ updatetitle ()
87+ setlexer ()
15388
15489def setlexer ():
15590 if v .cfg ["syntax-highlighting" ]:
15691 try : lexer = get_lexer_for_filename (tabs [v .tabselected ][0 ])
15792 except pygments .util .ClassNotFound : lexer = pygments .lexers .TextLexer
158- lexer = "pygments.lexers." + str (lexer ).split ("." )[- 1 ].removesuffix (">" )
93+ lexer = "pygments.lexers." + str (lexer ).split ("." )[- 1 ].removesuffix (">" ). removesuffix ( "'" )
15994 v .textwidget .text ._set_lexer (eval (lexer ))
16095 try : v .textwidget .redraw ()
161- except : pass
96+ except : pass
97+
98+ # The following two functions contain code copied from https://github.com/Akuli/porcupine
99+
100+ def closetab (event ):
101+ before = v .tabbar .index (f"@{ event .x } ,{ event .y } " )
102+ after = before + 1
103+
104+ if v .tabbar .index (v .tabbar .tabs ()[before :after ][0 ]) < v .tabselected :
105+ v .tabselected = v .tabselected - 1
106+
107+ tabs .pop (v .tabbar .index (v .tabbar .tabs ()[before :after ][0 ]))
108+ v .tabbar .forget (v .tabbar .tabs ()[before :after ][0 ])
109+ opentab (event , True )
110+
111+ def click (event ) -> None :
112+ if event .widget .identify (event .x , event .y ) == "label" :
113+ # find the right edge of the top label (including close button)
114+ right = event .x
115+ while event .widget .identify (right , event .y ) == "label" :
116+ right += 1
117+
118+ if event .x >= right - v .closeimg .width ():
119+ if event .widget .index ("end" ) != 1 :
120+ closetab (event )
121+ else :
122+ v .root .destroy ()
123+ else :
124+ opentab (event )
125+ else :
126+ opentab (event )
127+
128+ def changetype ():
129+ if tabs [v .tabselected ][2 ] == "unsaved" : save ()
130+ else :
131+ result = f .get (tabs [v .tabselected ][2 ])
132+ tabs [v .tabselected ][2 ] = result
133+ tabs [v .tabselected ][0 ] = result .split ("/" )[- 1 ]
134+ v .filedir .configure (text = result )
135+
136+ updatetitle ()
137+ setlexer ()
0 commit comments