def button_handler_for_magiccmd_on_current_file():
        # generate a magic command to submit to shell (shell will execute it)
        get_runner().execute_current(magiccmd)

        # hack to get a newline after magic command is done
        if get_runner().get_state() == "waiting_toplevel_command":
            get_workbench().get_view("ShellView").submit_command("\n")
Exemple #2
0
 def send_command(self, cmd):
     if self._proxy is None:
         return
     
     if not self._state_is_suitable(cmd):
         if isinstance(cmd, DebuggerCommand) and self.get_state() == "running":
             # probably waiting behind some InlineCommand
             self._postpone_command(cmd)
             return
         elif isinstance(cmd, InlineCommand):
             self._postpone_command(cmd)
             return
         else:
             raise AssertionError("Trying to send " + str(cmd) + " in state " + self.get_state())
     
     if cmd.command in ("Run", "Debug", "Reset"):
         get_workbench().event_generate("BackendRestart")
     
     accepted = self._proxy.send_command(cmd)
     
     if (accepted and isinstance(cmd, (ToplevelCommand, DebuggerCommand, InlineCommand))):
         self._set_state("running")
         self._current_command = cmd
         if isinstance(cmd, ToplevelCommand):
             self._current_toplevel_command = cmd
Exemple #3
0
 def remember_recent_file(self, filename):
     recents = get_workbench().get_option("file.recent_files")
     if filename in recents:
         recents.remove(filename)
     recents.insert(0, filename)
     existing_recents = [name for name in recents if os.path.exists(name)]
     get_workbench().set_option("file.recent_files", existing_recents[:10])
Exemple #4
0
 def create_new_file(self):
     selected_path = self.get_selected_path()
     
     if not selected_path:
         return
     
     if os.path.isdir(selected_path):
         parent_path = selected_path
     else:
         parent_path = os.path.dirname(selected_path)
     
     
     initial_name = self.get_proposed_new_file_name(parent_path, ".py")
     name = askstring("File name",
                     "Provide filename",
                     initialvalue=initial_name,
                     #selection_range=(0, len(initial_name)-3)
                     )
     
     if not name:
         return
                     
     path = os.path.join(parent_path, name)
     
     if os.path.exists(path):
         showerror("Error", "The file '"+path+"' already exists")
     else:
         open(path, 'w').close()
     
     self.open_path_in_browser(path, True)
     get_workbench().get_editor_notebook().show_file(path)
Exemple #5
0
 def do_kill():
     self._proc.kill()
     get_workbench().event_generate(
         "ProgramOutput",
         stream_name="stderr",
         data="KeyboardInterrupt: Forced reset")
     get_runner().reset_backend()
Exemple #6
0
 def on_double_click(self, event):
     path = self.get_selected_path()
     if os.path.isfile(path):
         get_workbench().get_editor_notebook().show_file(path)
         self.save_current_folder()
     elif os.path.isdir(path):
         self.refresh_tree(self.get_selected_node(), True)
Exemple #7
0
    def execute_script(self,
                       script_path,
                       args,
                       working_directory=None,
                       command_name="Run"):
        if (working_directory is not None
                and self._proxy.cwd != working_directory):
            # create compound command
            # start with %cd
            cmd_line = "%cd " + shlex.quote(working_directory) + "\n"
            next_cwd = working_directory
        else:
            # create simple command
            cmd_line = ""
            next_cwd = self._proxy.cwd

        # append main command (Run, run, Debug or debug)
        rel_filename = os.path.relpath(script_path, next_cwd)
        cmd_line += "%" + command_name + " " + shlex.quote(rel_filename)

        # append args
        for arg in args:
            cmd_line += " " + shlex.quote(arg)

        cmd_line += "\n"

        # submit to shell (shell will execute it)
        get_workbench().get_view("ShellView").submit_command(cmd_line)
Exemple #8
0
def load_plugin():
    get_workbench().add_view(HelpView, "Help", "ne")
    get_workbench().add_command("help_contents",
                                "help",
                                "Help contents",
                                open_help,
                                group=30)
Exemple #9
0
 def reset_backend(self):
     self.kill_backend()
     configuration = get_workbench().get_option("run.backend_configuration")
     backend_name, configuration_option = parse_configuration(configuration)
     backend_class = get_workbench().get_backends()[backend_name]
     self._proxy = backend_class(configuration_option)
     self.send_command(ToplevelCommand(command="Reset"))
Exemple #10
0
    def _perform_replace(self):

        #nothing is currently in found status
        if self.active_found_tag == None:
            return

        #get the found word bounds
        del_start = self.active_found_tag[0]
        del_end = self.active_found_tag[1]

        #erase all tags - these would not be correct anyway after new word is inserted
        self._remove_all_tags()
        toreplace = self.replace_entry.get().strip()
        #get the text to replace

        #delete the found word
        self.codeview.text.delete(del_start, del_end)
        #insert the new word
        self.codeview.text.insert(del_start, toreplace)
        #mark the inserted word boundaries
        self.last_processed_indexes = (del_start,
                                       self.codeview.text.index(
                                           "%s+%dc" %
                                           (del_start, len(toreplace))))

        get_workbench().event_generate("Replace",
                                       widget=self.codeview.text,
                                       old_text=self.codeview.text.get(
                                           del_start, del_end),
                                       new_text=toreplace)
Exemple #11
0
 def handle_execute_from_shell(self, cmd_line):
     """
     Handles all commands that take a filename and 0 or more extra arguments.
     Passes the command to backend.
     
     (Debugger plugin may also use this method)
     """
     command, args = parse_shell_command(cmd_line)
     
     if len(args) >= 1:
         get_workbench().get_editor_notebook().save_all_named_editors()
         cmd = ToplevelCommand(command=command,
                            filename=args[0],
                            args=args[1:])
         
         if os.path.isabs(cmd.filename):
             cmd.full_filename = cmd.filename
         else:
             cmd.full_filename = os.path.join(self.get_cwd(), cmd.filename)
             
         if command in ["Run", "run", "Debug", "debug"]:
             with tokenize.open(cmd.full_filename) as fp:
                 cmd.source = fp.read()
             
         self.send_command(cmd)
     else:
         raise CommandSyntaxError("Command '%s' takes at least one argument", command)
Exemple #12
0
 def __init__(self, configuration_option):
     if configuration_option == DEFAULT_CPYTHON_INTERPRETER:
         self._prepare_private_venv()
         self._executable = get_private_venv_executable()
     else:
         self._executable = configuration_option
         
         # Rembember the usage of this non-default interpreter
         used_interpreters = get_workbench().get_option("run.used_interpreters")
         print(used_interpreters)
         if self._executable not in used_interpreters:
             used_interpreters.append(self._executable)
         get_workbench().set_option("run.used_interpreters", used_interpreters)
         
     
     cwd = get_workbench().get_option("run.working_directory")
     if os.path.exists(cwd):
         self.cwd = cwd
     else:
         self.cwd = os.path.expanduser("~")
         
     self._proc = None
     self._message_queue = None
     self._sys_path = []
     self._gui_update_loop_id = None
     self.in_venv = None
     
     self._start_new_process()
Exemple #13
0
    def __init__(self, master, **kw):
        ttk.Frame.__init__(self, master, **kw)

        self.vert_scrollbar = ttk.Scrollbar(self, orient=tk.VERTICAL)
        self.vert_scrollbar.grid(row=0, column=2, sticky=tk.NSEW)
        self.text = ShellText(
            self,
            font=get_workbench().get_font("EditorFont"),
            #foreground="white",
            #background="#666666",
            highlightthickness=0,
            #highlightcolor="LightBlue",
            borderwidth=0,
            yscrollcommand=self.vert_scrollbar.set,
            padx=4,
            insertwidth=2,
            height=10,
            undo=True)

        get_workbench().event_generate("ShellTextCreated",
                                       text_widget=self.text)
        get_workbench().add_command("clear_shell",
                                    "edit",
                                    "Clear shell",
                                    self.clear_shell,
                                    group=200)

        self.text.grid(row=0, column=1, sticky=tk.NSEW)
        self.vert_scrollbar['command'] = self.text.yview
        self.columnconfigure(1, weight=1)
        self.rowconfigure(0, weight=1)
Exemple #14
0
 def interrupt(self):
     if self._proc is not None and self._proc.poll() is None:
         command_to_interrupt = get_runner().get_current_toplevel_command()
         if running_on_windows():
             try:
                 os.kill(self._proc.pid, signal.CTRL_BREAK_EVENT)  # @UndefinedVariable
             except:
                 logging.exception("Could not interrupt backend process")
         else:
             self._proc.send_signal(signal.SIGINT)
     
         # Tkinter programs can't be interrupted so easily:
         # http://stackoverflow.com/questions/13784232/keyboardinterrupt-taking-a-while
         # so let's chedule a hard kill in case the program refuses to be interrupted
         def go_hard():
             if (get_runner().get_state() != "waiting_toplevel_command"
                 and get_runner().get_current_toplevel_command() == command_to_interrupt): # still running same command
                 self._proc.kill()
                 get_workbench().event_generate("ProgramOutput",
                                                stream_name="stderr",
                                                data="KeyboardInterrupt: Forced reset")
                 get_runner().reset_backend()
         
         # 100 ms was too little for Mac
         # 250 ms was too little for one of the Windows machines
         get_workbench().after(500, go_hard)
Exemple #15
0
    def execute_current(self, command_name, always_change_to_script_dir=False):
        """
        This method's job is to create a command for running/debugging
        current file/script and submit it to shell
        """
        
        editor = get_workbench().get_current_editor()
        if not editor:
            return

        filename = editor.get_filename(True)
        if not filename:
            return
        
        if editor.is_modified():
            filename = editor.save_file()
            if not filename:
                return 
            
        
        # changing dir may be required
        script_dir = os.path.realpath(os.path.dirname(filename))
        
        if (get_workbench().get_option("run.auto_cd") 
            and command_name[0].isupper() or always_change_to_script_dir):
            working_directory = script_dir
        else:
            working_directory = None
        
        self.execute_script(filename, [], working_directory, command_name)
Exemple #16
0
    def load_startup_files(self):
        """If no filename was sent from command line
        then load previous files (if setting allows)"""

        cmd_line_filenames = [
            name for name in sys.argv[1:] if os.path.exists(name)
        ]

        if len(cmd_line_filenames) > 0:
            filenames = cmd_line_filenames
        elif get_workbench().get_option("file.reopen_all_files"):
            filenames = get_workbench().get_option("file.open_files")
        elif get_workbench().get_option("file.current_file"):
            filenames = [get_workbench().get_option("file.current_file")]
        else:
            filenames = []

        if len(filenames) > 0:
            for filename in filenames:
                if os.path.exists(filename):
                    self.show_file(filename)

            cur_file = get_workbench().get_option("file.current_file")
            # choose correct active file
            if len(cmd_line_filenames) > 0:
                self.show_file(cmd_line_filenames[0])
            elif cur_file and os.path.exists(cur_file):
                self.show_file(cur_file)
            else:
                self._cmd_new_file()
        else:
            self._cmd_new_file()

        self._remember_open_files()
Exemple #17
0
 def __init__(self, master, frame_info):
     tk.Toplevel.__init__(self, master)
     
     self.transient(master)
     if misc_utils.running_on_windows():
         self.wm_attributes('-toolwindow', 1)
     
     
     # TODO: take size from prefs
     editor_notebook = get_workbench().get_editor_notebook()
     if master.winfo_toplevel() == get_workbench():
         position_reference = editor_notebook
     else:
         # align to previous frame
         position_reference = master.winfo_toplevel()
         
     self.geometry("{}x{}+{}+{}".format(editor_notebook.winfo_width(),
                                        editor_notebook.winfo_height()-20,
                                        position_reference.winfo_rootx(),
                                        position_reference.winfo_rooty()))
     self.protocol("WM_DELETE_WINDOW", self._on_close)
     
     self._init_layout_widgets(master, frame_info)
     FrameVisualizer.__init__(self, self._text_frame, frame_info)
     
     self._load_code(frame_info)
     self._text_frame.text.focus()
Exemple #18
0
 def set_colorer(self):
     # TODO: some problem when doing fast rewind
     return
 
     self.colorer = SyntaxColorer(self.code_view.text,
                                  get_workbench().get_font("EditorFont"),
                                  get_workbench().get_font("BoldEditorFont"))
Exemple #19
0
 def go_hard():
     if (get_runner().get_state() != "waiting_toplevel_command"
         and get_runner().get_current_toplevel_command() == command_to_interrupt): # still running same command
         self._proc.kill()
         get_workbench().event_generate("ProgramOutput",
                                        stream_name="stderr",
                                        data="KeyboardInterrupt: Forced reset")
         get_runner().reset_backend()
Exemple #20
0
 def apply(self):
     if not self._configuration_variable.modified:
         return
     
     configuration = self._configuration_variable.get()
     get_workbench().set_option("run.backend_configuration", configuration)
     
     get_runner().reset_backend()
Exemple #21
0
 def _init_commands(self):
     get_workbench().add_command(
         "export_usage_logs",
         "tools",
         "Export usage logs...",
         self._cmd_export,
         group=110
     )
Exemple #22
0
def load_plugin():
    def open_about(*args):
        AboutDialog(get_workbench(), get_workbench().get_version())

    get_workbench().add_command("about", "help", "About Thonny", open_about)

    # For Mac
    get_workbench().createcommand("tkAboutDialog", open_about)
def get_credentials():

    credentials = {
        'address': get_workbench().get_option("ev3.ip"),
        'username': get_workbench().get_option("ev3.username"),
        'password': get_workbench().get_option("ev3.password")
    }
    return  AttrDict(credentials)
Exemple #24
0
 def _load_file(self, filename):
     source, self.file_encoding = misc_utils.read_python_file(
         filename)  # TODO: support also text files
     self._filename = filename
     get_workbench().event_generate("Open", editor=self, filename=filename)
     self._code_view.set_content(source)
     self._code_view.focus_set()
     self.master.remember_recent_file(filename)
Exemple #25
0
 def _create_private_venv(self, path, description, clear=False, upgrade=False):
     base_exe = sys.executable
     if sys.executable.endswith("thonny.exe"):
         # assuming that thonny.exe is in the same dir as "python.exe"
         base_exe = sys.executable.replace("thonny.exe", "python.exe")
     
     
     # Don't include system site packages
     # This way all students will have similar configuration
     # independently of system Python (if Thonny is used with system Python)
     
     # NB! Cant run venv.create directly, because in Windows 
     # it tries to link venv to thonny.exe.
     # Need to run it via proper python
     cmd = [base_exe, "-m", "venv"]
     if clear:
         cmd.append("--clear")
     if upgrade:
         cmd.append("--upgrade")
     
     try:
         import ensurepip  # @UnusedImport
     except ImportError:
         cmd.append("--without-pip")
         
     cmd.append(path)
     startupinfo = None
     if running_on_windows():
         startupinfo = subprocess.STARTUPINFO()
         startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
     proc = subprocess.Popen(cmd, startupinfo=startupinfo,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT,
                             universal_newlines=True)
          
     from thonny.ui_utils import SubprocessDialog
     dlg = SubprocessDialog(get_workbench(), proc, "Preparing the backend", long_description=description)
     try:
         get_workbench().wait_window(dlg)
     except:
         # if using --without-pip the dialog may close very quickly 
         # and for some reason wait_window would give error then
         logging.exception("Problem with waiting for venv creation dialog")
     get_workbench().become_topmost_window() # Otherwise focus may get stuck somewhere
     
     bindir = os.path.dirname(get_private_venv_executable())
     # create private env marker
     marker_path = os.path.join(bindir, "is_private")
     with open(marker_path, mode="w") as fp:
         fp.write("# This file marks Thonny-private venv")
     
     # Create recommended pip conf to get rid of list deprecation warning
     # https://github.com/pypa/pip/issues/4058
     pip_conf = "pip.ini" if running_on_windows() else "pip.conf"
     with open(os.path.join(path, pip_conf), mode="w") as fp:
         fp.write("[list]\nformat = columns")
     
     assert os.path.isdir(path)
Exemple #26
0
def load_plugin():

    get_workbench().add_command("autocomplete",
                                "edit",
                                "Auto-complete",
                                handle_autocomplete_request,
                                default_sequence="<Control-space>"
                                # TODO: tester
                                )
Exemple #27
0
 def _advance_background_tk_mainloop(self):
     """Enables running Tkinter programs which doesn't call mainloop. 
     
     When mainloop is omitted, then program can be interacted with
     from the shell after it runs to the end.
     """
     if self._proxy.get_state() == "waiting_toplevel_command":
         self._proxy.send_command(InlineCommand("tkupdate"))
     get_workbench().after(50, self._advance_background_tk_mainloop)
Exemple #28
0
    def _load_file(self, filename):
        with tokenize.open(filename) as fp:  # TODO: support also text files
            source = fp.read()

        self._filename = filename
        get_workbench().event_generate("Open", editor=self, filename=filename)
        self._code_view.set_content(source)
        self._code_view.focus_set()
        self.master.remember_recent_file(filename)
Exemple #29
0
 def destroy(self):
     try:
         # Not sure if editor notebook is still living
         get_workbench().get_editor_notebook().unbind(
             "<<NotebookTabChanged>>", self._tab_changed_binding)
     except:
         pass
     self.vert_scrollbar["command"] = None
     ttk.Frame.destroy(self)
Exemple #30
0
 def _ok(self, event=None):
     for title in sorted(self._pages):
         try:
             page = self._pages[title]
             if page.apply() == False:
                 return
         except:
             get_workbench().report_exception("Error when applying options in " + title)
          
     self.destroy()