class AssistantConfigPage(ConfigurationPage):
    def __init__(self, master):
        super().__init__(master)

        ui_utils.create_url_label(
            self,
            "https://github.com/thonny/thonny/wiki/Friendly-traceback",
            text=_("Friendly traceback level"),
        ).grid(row=1, column=0, sticky="w")

        self.add_combobox(
            "assistance.friendly_traceback_level",
            values=[0, 1, 2, 3, 4, 5, 6, 7, 9],
            row=1,
            column=1,
            width=3,
            padx=5,
        )

        self.add_checkbox(
            "assistance.open_assistant_on_errors",
            _("Open Assistant automatically when program crashes with an exception"
              ),
            row=2,
            columnspan=2,
        )

        self.add_checkbox(
            "assistance.open_assistant_on_warnings",
            _("Open Assistant automatically when it has warnings for your code"
              ),
            row=3,
            columnspan=2,
        )

        if get_workbench().get_option("assistance.use_pylint",
                                      "missing") != "missing":
            self.add_checkbox("assistance.use_pylint",
                              _("Perform selected Pylint checks"),
                              row=4,
                              columnspan=2)

        if get_workbench().get_option("assistance.use_mypy",
                                      "missing") != "missing":
            self.add_checkbox("assistance.use_mypy",
                              _("Perform MyPy checks"),
                              row=5,
                              columnspan=2)

        disabled_checks_label = ttk.Label(
            self, text=_("Disabled checks (one id per line)"))
        disabled_checks_label.grid(row=8,
                                   sticky="nw",
                                   pady=(10, 0),
                                   columnspan=2)

        self.disabled_checks_box = TextFrame(
            self,
            vertical_scrollbar_style=scrollbar_style("Vertical"),
            horizontal_scrollbar_style=scrollbar_style("Horizontal"),
            horizontal_scrollbar_class=ui_utils.AutoScrollbar,
            wrap="word",
            font="TkDefaultFont",
            # cursor="arrow",
            padx=5,
            pady=5,
            height=4,
            borderwidth=1,
            relief="groove",
        )
        self.disabled_checks_box.grid(row=9,
                                      sticky="nsew",
                                      pady=(0, 10),
                                      columnspan=2)
        self.disabled_checks_box.text.insert(
            "1.0", "\n".join(
                get_workbench().get_option("assistance.disabled_checks")))

        self.columnconfigure(1, weight=1)
        self.rowconfigure(9, weight=1)

    def apply(self):
        disabled_checks_str = (self.disabled_checks_box.text.get(
            "1.0",
            "end").replace("\r", "").replace('"', "").replace("'", "").strip())
        get_workbench().set_option("assistance.disabled_checks",
                                   disabled_checks_str.splitlines())
Exemplo n.º 2
0
class AssistantConfigPage(ConfigurationPage):
    def __init__(self, master):
        super().__init__(master)

        self.add_checkbox(
            "assistance.open_assistant_on_errors",
            "Open Assistant automatically when program crashes with an exception",
            row=1,
        )

        self.add_checkbox(
            "assistance.open_assistant_on_warnings",
            "Open Assistant automatically when it has warnings for your code",
            row=2,
        )

        if get_workbench().get_option("assistance.use_pylint",
                                      "missing") != "missing":
            self.add_checkbox(
                "assistance.use_pylint",
                "Perform selected Pylint checks",
                row=3,
            )

        if get_workbench().get_option("assistance.use_mypy",
                                      "missing") != "missing":
            self.add_checkbox(
                "assistance.use_mypy",
                "Perform MyPy checks",
                row=4,
            )

        disabled_checks_label = ttk.Label(
            self, text="Disabled checks (one id per line)")
        disabled_checks_label.grid(row=8, sticky="nw", pady=(10, 0))

        self.disabled_checks_box = TextFrame(
            self,
            vertical_scrollbar_style=scrollbar_style("Vertical"),
            horizontal_scrollbar_style=scrollbar_style("Horizontal"),
            horizontal_scrollbar_class=ui_utils.AutoScrollbar,
            wrap="word",
            font="TkDefaultFont",
            # cursor="arrow",
            padx=5,
            pady=5,
            height=4,
            borderwidth=1,
            relief="groove",
        )
        self.disabled_checks_box.grid(row=9, sticky="nsew", pady=(0, 10))
        self.disabled_checks_box.text.insert(
            "1.0", "\n".join(
                get_workbench().get_option("assistance.disabled_checks")))

        self.columnconfigure(0, weight=1)
        self.rowconfigure(9, weight=1)

    def apply(self):
        disabled_checks_str = (self.disabled_checks_box.text.get(
            "1.0",
            "end").replace("\r", "").replace('"', "").replace("'", "").strip())
        get_workbench().set_option("assistance.disabled_checks",
                                   disabled_checks_str.splitlines())
Exemplo n.º 3
0
import tkinter as tk
from thonny.tktextext import TextFrame, TweakableText

root = tk.Tk()
frame = TextFrame(root,
                  read_only=False,
                  wrap=tk.NONE,
                  line_numbers=True,
                  line_length_margin=13,
                  text_class=TweakableText)
frame.grid()
text = frame.text

text.direct_insert("1.0", "Essa\n    'tessa\nkossa\nx=34+(45*89*(a+45)")
text.tag_configure('string', background='yellow')
text.tag_add("string", "2.0", "3.0")

text.tag_configure('paren', underline=True)
text.tag_add("paren", "4.6", "5.0")

root.mainloop()
Exemplo n.º 4
0
class SqueezedTextDialog(tk.Toplevel):
    def __init__(self, master, button):
        super().__init__(master)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.button = button
        self.content = button.contained_text
        self.shell_text = master

        padding = 20

        mainframe = ttk.Frame(self)
        mainframe.grid(row=0, column=0, sticky="nsew")
        mainframe.columnconfigure(0, weight=1)
        mainframe.rowconfigure(2, weight=1)

        explanation_label = ttk.Label(
            mainframe,
            text="For performance reasons, Shell avoids showing " +
            "very long lines in full (see Tools => Options => Shell).\n" +
            "Here you can interact with the original text fragment.")
        explanation_label.grid(row=0,
                               column=0,
                               sticky="nsew",
                               padx=padding,
                               pady=padding)

        self._wrap_var = tk.BooleanVar(False)
        self.wrap_checkbox = ttk.Checkbutton(mainframe,
                                             text="Wrap text (may be slow)",
                                             variable=self._wrap_var,
                                             onvalue=True,
                                             offvalue=False,
                                             command=self._on_wrap_changed)
        self.wrap_checkbox.grid(row=1,
                                padx=padding,
                                pady=(0, padding // 2),
                                sticky="w")

        self.text_frame = TextFrame(mainframe,
                                    text_class=TweakableText,
                                    height=10,
                                    width=80,
                                    relief="sunken",
                                    borderwidth=1,
                                    wrap="none")
        self.text_frame.grid(row=2, column=0, padx=padding)
        self.text_frame.text.insert("1.0", button.contained_text)
        self.text_frame.text.set_read_only(True)

        button_frame = ttk.Frame(mainframe)
        button_frame.grid(row=3,
                          column=0,
                          padx=padding,
                          pady=padding,
                          sticky="nswe")
        button_frame.columnconfigure(2, weight=1)

        copy_caption = "Copy to clipboard"
        copy_button = ttk.Button(button_frame,
                                 text=copy_caption,
                                 width=len(copy_caption),
                                 command=self._on_copy)
        copy_button.grid(row=0, column=1, sticky="w", padx=(0, padding))

        expand_caption = "Expand in Shell"
        expand_button = ttk.Button(button_frame,
                                   text=expand_caption,
                                   width=len(expand_caption),
                                   command=self._on_expand)
        expand_button.grid(row=0, column=2, sticky="e", padx=padding)

        close_button = ttk.Button(button_frame,
                                  text="Close",
                                  command=self._on_close)
        close_button.grid(row=0, column=3, sticky="e")

        self.bind("<Escape>", self._on_close, True)
        self.protocol("WM_DELETE_WINDOW", self._on_close)
        self.title("Squeezed text (%d characters)" % len(self.content))

    def _on_wrap_changed(self):
        if self._wrap_var.get():
            self.text_frame.text.configure(wrap="word")
        else:
            self.text_frame.text.configure(wrap="none")

    def _on_expand(self):
        index = self.shell_text.index(self.button)
        self.shell_text.direct_delete(index, index + " +1 chars")
        self.shell_text.direct_insert(index, self.content,
                                      tuple(self.button.tags))
        self.destroy()

        # looks like the widgets are not fully GC-d.
        # At least avoid leaking big chunks of texts
        self.button.contained_text = None
        self.button.destroy()

    def _on_copy(self):
        self.clipboard_clear()
        self.clipboard_append(self.content)

    def _on_close(self, event=None):
        self.destroy()
Exemplo n.º 5
0
class DocuBoxBase(EditorInfoBox):
    def __init__(self, show_vertical_scrollbar: bool):
        super().__init__()
        self.text_frame = TextFrame(
            master=self,
            horizontal_scrollbar=False,
            vertical_scrollbar=show_vertical_scrollbar,
            read_only=True,
            height=7,
            width=40,
            font="TkDefaultFont",
            wrap="word",
        )
        self.text_frame.grid()
        self.text = self.text_frame.text

        self._update_theme()

    def _update_theme(self, event=None):
        super()._update_theme(event)
        comment_opts = get_syntax_options_for_tag("comment")
        gutter_opts = get_syntax_options_for_tag("GUTTER")
        text_opts = get_syntax_options_for_tag("TEXT")
        self.text["background"] = gutter_opts["background"]
        self.text["foreground"] = text_opts["foreground"]
        self.text.tag_configure("prose", font="TkDefaultFont")
        self.text.tag_configure("active", font="BoldTkDefaultFont")
        self.text.tag_configure("annotation", **comment_opts)
        self.text.tag_configure("default", **comment_opts)
        self.text.tag_configure("marker", **comment_opts)

    def _append_chars(self, chars, tags=()):
        self.text.direct_insert("end", chars, tags=tuple(tags))

    def render_signatures(self,
                          signatures: List[SignatureInfo],
                          only_params=False) -> None:
        for i, sig in enumerate(signatures):
            if i > 0:
                self._append_chars("\n")
            self.render_signature(sig, only_params)

    def render_signature(self, sig: SignatureInfo, only_params) -> None:
        if not only_params:
            self._append_chars(sig.name)

        self._append_chars("(")

        is_positional = False
        is_kw_only = False

        for i, param in enumerate(sig.params):
            if i > 0:
                self._append_chars(", ")
            if len(sig.params) > 20:
                self._append_chars("\n    ")

            is_positional |= param.kind == "POSITIONAL_ONLY"
            if is_positional and param.kind != "POSITIONAL_ONLY":
                self._append_chars("/, ", ["marker"])
                is_positional = False

            if param.kind == "VAR_POSITIONAL":
                is_kw_only = True
            elif param.kind == "KEYWORD_ONLY" and not is_kw_only:
                self._append_chars("*, ", ["marker"])
                is_kw_only = True

            is_active_parameter = sig.current_param_index == i
            self.render_parameter(param, is_active_parameter)

        if is_positional:
            self._append_chars(", /", ["marker"])

        self._append_chars(")")

        if sig.return_type and not only_params:
            self._append_chars(" -> ", ["marker"])
            self._append_chars(sig.return_type, ["annotation"])

    def render_parameter(self, param: SignatureParameter,
                         active: bool) -> None:

        if active:
            base_tags = ["active"]
        else:
            base_tags = []

        if param.kind == "VAR_POSITIONAL":
            self._append_chars("*", base_tags)
        elif param.kind == "VAR_KEYWORD":
            self._append_chars("**", base_tags)

        self._append_chars(param.name, base_tags)

        if param.annotation:
            self._append_chars(":\u00A0" + param.annotation,
                               base_tags + ["annotation"])

        if param.default:
            self._append_chars("=" + param.default, base_tags + ["default"])

    def format_signature(self, s: str) -> str:
        s = s.replace(": ", ":\u00A0")
        if len(s) > self.text["width"] * 1.8 and s.count("(") and s.count(")"):
            args_index = s.index("(") + 1
            suffix_index = s.rindex(")")
            prefix = s[:args_index]
            args = s[args_index:suffix_index].split(", ")
            suffix = s[suffix_index:]
            s = prefix + "\n  " + ",\n  ".join(args) + "\n" + suffix
            # don't keep / and * alone on a line
            s = (s.replace("\n  /,", " /,").replace("\n  *,", " *,").replace(
                "\n  /\n)", " /\n)").replace("\n  *\n)", " *\n)"))
            return s
        else:
            return s