Sublime Forum

How to print text on the output panel

#1

I’m developing a plug-in, and I need to print the log on the output panel. I’ve created and displayed an output panel, but I don’t know how to print the log on the created panel.

import sublime

win   = sublime.active_window()
panel = win.create_output_panel("panel")
win.run_command('show_panel',{"panel":"output.panel"})
0 Likes

#2

A panel is just a regular view, so in order to populate text into it you need to use a TextCommand to do it, since only a TextCommand has an edit object that can be used to modify the view.

The append command is generally what you want for this; it’s built in and does what you want without you having to do anything else. For example:

panel.run_command("append", {"characters": "Some text here"})
1 Like

#3

Hi @OdatNurd

How can we show list of messages for example, and add some action on message click?

0 Likes

#4

You can put whatever content you want into the panel using the append command as above; the characters argument can be any string of content you want, including multiple lines (if it includes \n characters in it to signal where lines end). You can also invoke it multiple times to append multiple messages.

What sort of action do you want to take on click?

0 Likes

#5

Thanks for reply!

I’m planning to display a list of errors, warnings and allow the user to go to the file that contains that error, by clicking on some action, hopefully.

0 Likes

#7

The easiest way to achieve this is to use the result_file_regex, result_line_regex and result_base_dir settings in your panel view. These are the settings that power the ability of a build system to navigate you to errors by double clicking in them in the build results.

If you’re unsure of how that works, see this page for details. The basic idea is that we tell Sublime how to recognize results, and it will automatically navigate there. Due to the way that the build system regex works, this requires your error output to always have data in the order of filename, line, column, message (though you really only need the first two). This might require you to format your data in such a way as to put the required data in the required format.

An example of a command that does this is below. It has hard coded examples that will try to open the named files in your home directory. When the file doesn’t exist, the tab will end up empty. However if you put some content into them first, double clicking the results in the panel after running the command will open the file and position the cursor there automatically.

Additionally, once you’ve clicked on one of the results, the menu items in Tools > Build Results will navigate you between the remaining results.

import sublime
import sublime_plugin

# So we can use os.path.expanduser below
import os


class ExampleCommand(sublime_plugin.WindowCommand):
    """
    Demonstrate how to use the result regex system (as used in build systems)
    to easily allow for the navigation of results in a panel.

    When executed the command will create an output panel and populate it with
    some fake messages. Double clicking on the messages will attempt to open
    the files and position the cursor at the given location.
    """
    def run(self):
        # Create a panel with the given name in the current window. The first
        # time this is executed in a window, a new view representing the panel
        # content is created and returned back, and has default settings.
        #
        # On subsequent calls, the same view is reused, and any settings that
        # have been applied remain. However, the content of the panel is erased
        # for you.
        #
        # The view (either newly created or existing) is returned back so that
        # you can interact with it.
        panel = self.window.create_output_panel("example_out")

        # When it's initially created, the panel gets the default settings any
        # new file would, so we can apply any settings desired here in order
        # to configure it as desired.
        #
        # For our example, we'll turn off the gutter so that line numbers
        # aren't visible. You can also change the color scheme, word wrap,
        # assign a new syntax, etc..
        panel.settings().set("gutter", False)

        # The settings result_file_regex and result_line_regex represent the
        # standard build system keys file_regex and line_regex; using them we
        # can tell Sublime how to recognize files and messages in the panel.
        #
        # In our example we're using just result_file_regex (file_regex); you
        # could also use the other, depending on how you are generating the
        # output.
        panel.settings().set("result_file_regex",
                             r"\w+: ([^,]+), line (\d+), col (\d+): (.*)")


        # In order for Sublime to be able to open the file, it has to know the
        # exact location on disk (like C:\users\youruser\file.txt or such) to
        # be able to find it.
        #
        # If the content you're displaying contains an absolute filename like
        # that, then everything will work as expected.
        #
        # In our example, we want just the names of files, so we use the
        # result_base_dir setting to tell Sublime what directory to look in for
        # any files that aren't absolute. Here we're assuming that's your home
        # directory, but you would set that as appropriate.
        panel.settings().set("result_base_dir", os.path.expanduser("~"))

        # Call create_output_panel a second time. This will recreate the panel
        # for us. This will keep the same view as was previously used, and the
        # settings will be retained; only the content will be cleared (although
        # currently it is still empty).
        #
        # This step is needed to allow Sublime to recognize the result regexes
        # we applied above so that it will capture messages when they appear.
        # If you don't take this step, that won't work as expected.
        self.window.create_output_panel("example_out")

        # A panel view is treated as a regular view, so the user is free to
        # click in it and type. To stop that from happening, we make the view
        # read-only after we insert the data below.
        #
        # Since the panel will be re-used the next time it is created, the
        # next time the command is executed although the content will be erased
        # the settings will remain, including the read-only state.
        #
        # So in order to be able to insert some data, we need to temporarily
        # make the panel editable.
        panel.set_read_only(False)

        # Add some content to the file.
        #
        # The append command adds text to the bottom of the file. Using \n
        # allows you to inject a new line, so you can put multiple lines in at
        # once. You can also just call the append command multiple times.
        panel.run_command("append", {"characters":
            "E: sample.txt, line 3, col 4: Well that was unexpected\n"})
        panel.run_command("append", {"characters":
            "W: other.txt, line 9, col 1: Something else\n"})

        # Now that the content is in the panel, we can make it read-only again
        # to stop the user from editing it.
        panel.set_read_only(True)

        # Get the window to run the command that will show our panel at the
        # bottom of the window. You could also bind this command to a key, add
        # it to the menu, or add it to the command palette.
        #
        # All panels  will appear in the panel switcher menu (icon in the
        # bottom left of the status bar in the menu) by name as well, and can
        # be chosen from there.
        self.window.run_command('show_panel', {"panel":"output.example_out"})
2 Likes