Search code examples
python-3.xtkintertkinter-text

how can I add an auto indent feature after colon in tkinter gui in python?


I am making a text editor it has all the features but not an auto-indent feature which can automatically add spaces after loops or conditions. Please tell me how can I make, and please try to give a code which can do it. I am making this in Tkinter and want this function in the text widget. I had made this text editor.enter image description here

I made this in Tkinter so please help me to give a code for auto-indent. I had tried for firing events whenever a user presses ':' button to give an indent in the next line but it does not follow the pattern of multilevel indenting. like


    for i in range(100):
        if i==5:
            break
        else:
            print('got till '+str(i))

but my code does not follow like this it only adds space in the first line so the code looks like.


   for i in range(100):
      if i==5:
      break
   else:
      print('got till '+str(i))

so it is a bit tricky. Please comment for any related info or question but please answer me.


Solution

  • You just need to get the indentation from the current line and add the new level of indentation.

    Here's a complete working example:

    import tkinter as tk
    import re
    
    root = tk.Tk()
    text = tk.Text(root)
    text.pack(fill="both", expand=True)
    
    def autoindent(event):
        # the text widget that received the event
        widget = event.widget
    
        # get current line
        line = widget.get("insert linestart", "insert lineend")
    
        # compute the indentation of the current line
        match = re.match(r'^(\s+)', line)
        current_indent = len(match.group(0)) if match else 0
    
        # compute the new indentation
        new_indent = current_indent + 4
    
        # insert the character that triggered the event,
        # a newline, and then new indentation
        widget.insert("insert", event.char + "\n" + " "*new_indent)
    
        # return 'break' to prevent the default behavior
        return "break"
    
    text.bind(":", autoindent)
    
    root.mainloop()