1

1. Briefly

I don't find, how I can get output in new view, not in Sublime Text console.


2. Expected behavior

For example, I have countdown timer:

import time

seconds = 10

while seconds >= 0:
    time.sleep(1)
    if seconds == 5:
        print("5 seconds")
    elif seconds == 0:
        print("Time over!")
        time.sleep(5)
    else:
        print(seconds)
    seconds -= 1

Ctrl+Shift+P (⌘⇧p for Mac) → SublimeREPL: Python RUN current file → I get expected behavior:

Countdown timer


3. Actual behavior

Same countdown timer in Sublime Text plugin:

import time

import sublime_plugin

seconds = 10


class LovernaStandardCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        current_id = self.view.id()
        if current_id:
            global seconds
            while seconds >= 0:
                time.sleep(1)
                if seconds == 5:
                    print("5 seconds")
                elif seconds == 0:
                    print("Time over!")
                    time.sleep(5)
                else:
                    print(seconds)
                seconds -= 1

I run command loverna_standard → I see output in Sublime Text console, not in new view.


4. Not helped

  1. Python write() method works with files, not with unsaved buffers.
  2. I find in Sublime Text 3 API documentation, how I can open new view — sublime.active_window().new_file() — but I don't find, how I can print text in this view.
Саша Черных
  • 2,561
  • 4
  • 25
  • 71

1 Answers1

2

You can append text to a Sublime Text view by using the append command. For example, if you want the view to automatically scroll to the bottom when new text is added:

view.run_command('append', { 'characters': str(seconds) + '\n', 'scroll_to_end': True })

However, it is best to set up a callback every second than to sleep, otherwise ST will be unresponsive while the command is running.

import sublime
import sublime_plugin

class LovernaStandardCommand(sublime_plugin.TextCommand):

    def run(self, edit, seconds=10):
        self.print_seconds(sublime.active_window().new_file(), seconds)

    def print_seconds(self, view, seconds):
        text = ''
        if seconds > 0:
            text = str(seconds)
            if seconds == 5:
                text += ' seconds'
            sublime.set_timeout_async(lambda: self.print_seconds(view, seconds - 1), 1000) 
        else:
            text = 'Time over!'
        view.run_command('append', { 'characters': text + '\n', 'scroll_to_end': True })
Keith Hall
  • 15,362
  • 3
  • 53
  • 71
  • Keith Hall, I'm sorry, I don't understand, how I can delay between different actions in blocks of this code. [**Part of my code**](https://www.pastery.net/zfeqxj/). **Expected behavior**: `Time over!` print in new file → 5 seconds delay → file close. **Actual behavior**: 5 seconds delay → `Time over!` print in new file & file close at the same time. Thanks. – Саша Черных Apr 24 '17 at 09:57
  • 1
    you can use `sublime.set_timeout_async` to delay actions - to close the view 5 seconds after `Time over!` is written, you can add the following under `text = 'Time over!'` (with the same indentation level): `sublime.set_timeout_async(lambda: view.set_scratch(True) or view.window().run_command('close'), 5000)`. I'm not sure where your `force_quit` command is coming from, but you may be able to use that instead - `sublime.set_timeout_async(lambda: view.window().run_command('force_quit'), 5000)` – Keith Hall Apr 24 '17 at 10:04
  • KeithHall: I'm sorry. **1. Settings**: [**this project**](https://github.com/Kristinita/Sacagawea), I install and add to PATH environment variable [**mpg123**](https://www.mpg123.de/), **2. Expected behavior**: [**this Python code works for me**](https://www.pastery.net/eaqhcg/), I hear sounds., **3. Actual behavior**: if I run `sacagawea_standardo` command from my project, sounds doesn't play. In another my plugins I succesful use `subprocess.Popen`. What I do wrong? **4. Not helped**: if I use `os.system` instead of `subprocess.Popen`, I get actual behavior, not expected. // Thanks. – Саша Черных Apr 24 '17 at 18:08
  • 1
    most likely `mpg123` can't find the `mp3` files because they are not in the current working directory - try specifying the full path to the files in your `subprocess` call or [changing Python's current working directory](http://stackoverflow.com/questions/1810743/how-to-set-the-current-working-directory-in-python) before executing the `subprocess` call. You can also use `check=True` as an argument to ensure the process executes successfully. – Keith Hall Apr 25 '17 at 10:35
  • `'scroll_to_end': True` no effect for me. Scrollbars doesn't scroll to bottom with numbers. Thanks. – Саша Черных Apr 27 '17 at 09:58
  • weird, it works for me - maybe try also setting `'force': True`, in case that will help – Keith Hall Apr 27 '17 at 10:07