Beispiel #1
0
    def set_object_info(self, object_info, label):
        assert "elements" in object_info

        self.elements_have_indices = object_info["type"] in (repr(tuple),
                                                             repr(list))
        self._update_columns()

        self._clear_tree()
        index = 0
        # TODO: don't show too big number of elements
        for element in object_info["elements"]:
            node_id = self.tree.insert("", "end")
            if self.elements_have_indices:
                self.tree.set(node_id, "index", index)
            else:
                self.tree.set(node_id, "index", "")

            self.tree.set(node_id, "id", format_object_id(element["id"]))
            self.tree.set(
                node_id, "value",
                shorten_repr(element["repr"], MAX_REPR_LENGTH_IN_GRID))
            index += 1

        count = len(object_info["elements"])
        self.tree.config(height=min(count, 10))

        label.configure(text=("%d element" if count == 1 else "%d elements") %
                        count)
Beispiel #2
0
    def _replace(self, focus, value):
        start_mark = self._get_mark_name(focus.lineno, focus.col_offset)
        end_mark = self._get_mark_name(focus.end_lineno, focus.end_col_offset)

        self.delete(start_mark, end_mark)

        id_str = memory.format_object_id(value.id)
        if get_workbench().in_heap_mode():
            value_str = id_str
        else:
            value_str = shorten_repr(value.repr, 100)

        object_tag = "object_" + str(value.id)
        self.insert(start_mark, value_str, ("value", object_tag))
        if misc_utils.running_on_mac_os():
            sequence = "<Command-Button-1>"
        else:
            sequence = "<Control-Button-1>"
        self.tag_bind(
            object_tag,
            sequence,
            lambda _: get_workbench().event_generate(
                "ObjectSelect", object_id=value.id
            ),
        )
Beispiel #3
0
    def handle_vm_message(self, msg):
        debug("ExpressionView.handle_vm_message %s", (msg.state, msg.focus))
        
        if msg.state in ("before_expression", "before_expression_again"):
            # (re)load stuff
            if self._main_range is None or msg.focus.not_smaller_eq_in(self._main_range):
                self._load_expression(msg.filename, msg.focus)
                self._update_position(msg.focus)
                self._update_size()
                
            self._highlight_range(msg.focus, msg.state)
            
        
        elif msg.state == "after_expression":
            debug("EV: after_expression %s", msg)
            
            self.tag_configure('after', background="#BBEDB2", borderwidth=1, relief=tk.FLAT)
            start_mark = self._get_mark_name(msg.focus.lineno, msg.focus.col_offset)
            end_mark = self._get_mark_name(msg.focus.end_lineno, msg.focus.end_col_offset)
            
            if hasattr(msg, "value"):
                debug("EV: replacing expression with value")
                #print("del", start_mark, end_mark)
                self.delete(start_mark, end_mark)
                
                id_str = memory.format_object_id(msg.value.id)
                if self._workbench.get_option("view.values_in_heap"):
                    value_str = id_str
                else:
                    value_str = shorten_repr(msg.value.repr, 100)
                
                #print("ins", start_mark, value_str)
                object_tag = "object_" + str(msg.value.id)
                self.insert(start_mark, value_str, ('value', 'after', object_tag))
                if misc_utils.running_on_mac_os():
                    sequence = "<Command-Button-1>"
                else:
                    sequence = "<Control-Button-1>"
                self.tag_bind(object_tag, sequence,
                              lambda _: self._workbench.event_generate("ObjectSelect", object_id=msg.value.id))
                    
                self._update_size()
                
            else:
                debug("EV: got exc: %s", msg)
                "TODO: make it red"
                
        elif (msg.state == "before_statement_again"
              and self._main_range is not None # TODO: shouldn't need this 
              and self._main_range.is_smaller_eq_in(msg.focus)):
            # we're at final stage of executing parent statement 
            # (eg. assignment after the LHS has been evaluated)
            # don't close yet
            self.tag_configure('after', background="#DCEDF2", borderwidth=1, relief=tk.FLAT)   
        else:
            # hide and clear on non-expression events
            self.clear_debug_view()

        if hasattr(msg, "focus"):
            self._last_focus = msg.focus
Beispiel #4
0
 def _update_data(self, data):
     self._clear_tree()
     for value_id in sorted(data.keys()):
         node_id = self.tree.insert("", "end")
         self.tree.set(node_id, "id", format_object_id(value_id))
         self.tree.set(
             node_id, "value", shorten_repr(data[value_id].repr, MAX_REPR_LENGTH_IN_GRID)
         )
Beispiel #5
0
    def _handle_toplevel_response(self, msg: ToplevelResponse) -> None:
        if msg.get("error"):
            self._insert_text_directly(msg["error"] + "\n",
                                       ("toplevel", "stderr"))
            self._ensure_visible()

        if "user_exception" in msg:
            self._show_user_exception(msg["user_exception"])
            self._ensure_visible()

        welcome_text = msg.get("welcome_text")
        if welcome_text and welcome_text != self._last_welcome_text:
            self._insert_text_directly(welcome_text, ("comment", ))
            self._last_welcome_text = welcome_text

        if "value_info" in msg:
            num_stripped_question_marks = getattr(
                msg, "num_stripped_question_marks", 0)
            if num_stripped_question_marks > 0:
                # show the value in object inspector
                get_workbench().event_generate("ObjectSelect",
                                               object_id=msg["value_info"].id)
            else:
                # show the value in shell
                value_repr = shorten_repr(msg["value_info"].repr, 10000)
                if value_repr != "None":
                    if get_workbench().in_heap_mode():
                        value_repr = memory.format_object_id(
                            msg["value_info"].id)
                    object_tag = "object_" + str(msg["value_info"].id)
                    self._insert_text_directly(
                        value_repr + "\n", ("toplevel", "value", object_tag))
                    if running_on_mac_os():
                        sequence = "<Command-Button-1>"
                    else:
                        sequence = "<Control-Button-1>"
                    self.tag_bind(
                        object_tag,
                        sequence,
                        lambda _: get_workbench().event_generate(
                            "ObjectSelect", object_id=msg["value_info"].id),
                    )

                    self.active_object_tags.add(object_tag)

        self.mark_set("output_end", self.index("end-1c"))
        self._discard_old_content()
        self._update_visible_io(None)
        self._reset_ansi_attributes()
        self._io_cursor_offset = 0
        self._insert_prompt()
        self._try_submit_input(
        )  # Trying to submit leftover code (eg. second magic command)
        self.see("end")
Beispiel #6
0
    def set_object_info(self, object_info, label):
        assert "entries" in object_info

        self._clear_tree()
        # TODO: don't show too big number of elements
        for key, value in object_info["entries"]:
            node_id = self.tree.insert("", "end")
            self.tree.set(node_id, "key_id", format_object_id(key["id"]))
            self.tree.set(node_id, "key",
                          shorten_repr(key["repr"], MAX_REPR_LENGTH_IN_GRID))
            self.tree.set(node_id, "id", format_object_id(value["id"]))
            self.tree.set(node_id, "value",
                          shorten_repr(value["repr"], MAX_REPR_LENGTH_IN_GRID))

        count = len(object_info["entries"])
        self.tree.config(height=min(count, 10))

        label.configure(text=("%d entry" if count == 1 else "%d entries") %
                        count)

        self.update_memory_model()
Beispiel #7
0
    def _show_object_by_id(self, object_id, via_navigation=False):

        if self.winfo_ismapped() and self.object_id != object_id:
            if not via_navigation and self.object_id is not None:
                if self.object_id in self.back_links:
                    self.back_links.remove(self.object_id)
                self.back_links.append(self.object_id)
                del self.forward_links[:]

            self.object_id = object_id
            update_entry_text(self.id_entry, format_object_id(object_id))
            self.set_object_info(None)
            self.request_object_info()
Beispiel #8
0
    def _handle_toplevel_result(self, msg):
        self["font"] = get_workbench().get_font("EditorFont")
        self._before_io = True
        if hasattr(msg, "error"):
            self._insert_text_directly(msg.error + "\n", ("toplevel", "error"))

        if hasattr(msg, "welcome_text"):
            configuration = get_workbench().get_option(
                "run.backend_configuration")
            welcome_text = msg.welcome_text
            if hasattr(
                    msg, "executable"
            ) and msg.executable != thonny.running.get_private_venv_executable(
            ):
                welcome_text += " (" + msg.executable + ")"
            if (configuration != self._last_configuration
                    and not (self._last_configuration is None
                             and not configuration)):
                self._insert_text_directly(welcome_text, ("welcome", ))

            self._last_configuration = get_workbench().get_option(
                "run.backend_configuration")

        if hasattr(msg, "value_info"):
            value_repr = shorten_repr(msg.value_info["repr"], 10000)
            if value_repr != "None":
                if get_workbench().in_heap_mode():
                    value_repr = memory.format_object_id(msg.value_info["id"])
                object_tag = "object_" + str(msg.value_info["id"])
                self._insert_text_directly(value_repr + "\n",
                                           ("toplevel", "value", object_tag))
                if running_on_mac_os():
                    sequence = "<Command-Button-1>"
                else:
                    sequence = "<Control-Button-1>"
                self.tag_bind(
                    object_tag, sequence,
                    lambda _: get_workbench().event_generate(
                        "ObjectSelect", object_id=msg.value_info["id"]))

                self.active_object_tags.add(object_tag)

        self.mark_set("output_end", self.index("end-1c"))
        self._insert_prompt()
        self._try_submit_input(
        )  # Trying to submit leftover code (eg. second magic command)
        self.see("end")
Beispiel #9
0
    def update_expression(self, msg, frame_info):
        focus = frame_info.last_event_focus
        event = frame_info.last_event
        
        if event in ("before_expression", "before_expression_again"):
            # (re)load stuff
            if self._main_range is None or focus.not_smaller_eq_in(self._main_range):
                self._load_expression(frame_info.filename, focus)
                self._update_position(focus)
                self._update_size()
                
            self._highlight_range(focus, event, msg.exception)
            
        
        elif event == "after_expression":
            debug("EV: after_expression %s", msg)
            
            self.tag_configure('after', background="#BBEDB2", borderwidth=1, relief=tk.FLAT)
            start_mark = self._get_mark_name(focus.lineno, focus.col_offset)
            end_mark = self._get_mark_name(focus.end_lineno, focus.end_col_offset)
            
            assert hasattr(msg, "value")
            debug("EV: replacing expression with value")

            original_focus_text = self.get(start_mark, end_mark)
            self.delete(start_mark, end_mark)
            
            id_str = memory.format_object_id(msg.value.id)
            if get_workbench().in_heap_mode():
                value_str = id_str
            elif "StringLiteral" in frame_info.last_event_args["node_tags"]:
                # No need to show Python replacing double quotes with single quotes
                value_str = original_focus_text
            else:
                value_str = shorten_repr(msg.value.repr, 100)
            
            object_tag = "object_" + str(msg.value.id)
            self.insert(start_mark, value_str, ('value', 'after', object_tag))
            if misc_utils.running_on_mac_os():
                sequence = "<Command-Button-1>"
            else:
                sequence = "<Control-Button-1>"
            self.tag_bind(object_tag, sequence,
                          lambda _: get_workbench().event_generate("ObjectSelect", object_id=msg.value.id))
                
            self._update_size()
                
            
                
        elif (event == "before_statement_again"
              and self._main_range is not None # TODO: shouldn't need this 
              and self._main_range.is_smaller_eq_in(focus)):
            # we're at final stage of executing parent statement 
            # (eg. assignment after the LHS has been evaluated)
            # don't close yet
            self.tag_configure('after', background="#DCEDF2", borderwidth=1, relief=tk.FLAT)
        
        elif event == "exception":
            "TODO:"   
        
        else:
            # hide and clear on non-expression events
            self.clear_debug_view()

        self._last_focus = focus
Beispiel #10
0
 def _handle_vm_message(self, msg):
     if isinstance(msg, InputRequest):
         self.text_mode = "io"
         self.text["font"] = self._workbench.get_font("IOFont") # otherwise the cursor is of toplevel size
         self.text.focus_set()
         self.text.mark_set("insert", "end")
         self.text.tag_remove("sel", "1.0", tk.END)
         self._try_submit_input() # try to use leftovers from previous request
         self.text.see("end")
         
     elif isinstance(msg, OutputEvent):
         self.text_mode = "io"
         self.text["font"] = self._workbench.get_font("IOFont")
         
         # mark first line of io
         if self._before_io:
             self._insert_text_directly(msg.data[0], ("io", msg.stream_name, "vertically_spaced"))
             self._before_io = False
             self._insert_text_directly(msg.data[1:], ("io", msg.stream_name))
         else:
             self._insert_text_directly(msg.data, ("io", msg.stream_name))
         
         self.text.mark_set("output_end", self.text.index("end-1c"))
         self.text.see("end")
         
     elif isinstance(msg, ToplevelResponse):
         
         self.text_mode = "toplevel"
         self.text["font"] = self._workbench.get_font("EditorFont")
         self._before_io = True
         if hasattr(msg, "error"):
             self._insert_text_directly(msg.error + "\n", ("toplevel", "error"))
             
         if hasattr(msg, "value_info"):
             value_repr = shorten_repr(msg.value_info.repr, 10000)
             if value_repr != "None":
                 if self._workbench.in_heap_mode():
                     value_repr = memory.format_object_id(msg.value_info.id)
                 object_tag = "object_" + str(msg.value_info.id)
                 self._insert_text_directly(value_repr + "\n", ("toplevel",
                                                                "value",
                                                                object_tag))
                 if running_on_mac_os():
                     sequence = "<Command-Button-1>"
                 else:
                     sequence = "<Control-Button-1>"
                 self.text.tag_bind(object_tag, sequence,
                                    lambda _: self._workbench.event_generate(
                                         "ObjectSelect", object_id=msg.value_info.id))
                 
                 self.active_object_tags.add(object_tag)
         
         self.text.mark_set("output_end", self.text.index("end-1c"))
         self._insert_prompt()
         self._try_submit_input()
         self.text.see("end")
         
         # TODO: show cwd if it has changed
         """
         if hasattr(msg, "event") and msg.event == "reset":
             # make current dir visible (again)
             self.submit_magic_command("%cd " + self._workbench.get_runner().get_cwd() + "\n")
         """
         
     else:
         pass
Beispiel #11
0
 def _update_data(self, data):
     self._clear_tree()
     for value_id in sorted(data.keys()):
         node_id = self.tree.insert("", "end")
         self.tree.set(node_id, "id", format_object_id(value_id))
         self.tree.set(node_id, "value", shorten_repr(data[value_id].repr, MAX_REPR_LENGTH_IN_GRID))