Search code examples
sublimetext3sublimetextsublime-text-plugin

Difference between "view.window().run_command" and "view.run_command"


What is the practical difference between view.window().run_command(...) and view.run_command(...)?

Here are two versions of the same plugin, with two minor changes:

(It will convert tabs to spaces on save. You need "expand_tabs_on_save": true in preferences).

One:

# https://coderwall.com/p/zvyg7a/convert-tabs-to-spaces-on-file-save
import sublime, sublime_plugin, os

class ExpandTabsOnSave(sublime_plugin.EventListener):
  def on_pre_save(self, view):
    if view.settings().get('expand_tabs_on_save') == 1:
      view.window().run_command('expand_tabs')

Two:

# https://github.com/bubenkoff/ExpandTabsOnSave-SublimeText
import sublime_plugin # <---------- `sublime` and `os` removed

class ExpandTabsOnSave(sublime_plugin.EventListener):
  def on_pre_save(self, view):
    if view.settings().get('expand_tabs_on_save') == 1:
      view.run_command('expand_tabs') # <--------- `window()` removed

What have changed in it's behaviour with these changes?


Solution

  • In Sublime Text, commands can be defined to operate at an Application level (ApplicationCommand), a Window level (WindowCommand), or a View level (TextCommand).

    Typically only TextCommands modify the buffer, or settings which only affect the current buffer, WindowCommands the current window layout or other related settings, and ApplicationCommands global preferences etc.

    In my experience, executing a WindowCommand on a View object does nothing. Example:

    view.run_command('set_layout', {"cells": [[0, 0, 1, 1], [1, 0, 2, 1]], "cols": [0.0, 0.5, 1.0], "rows": [0.0, 1.0]})
    

    But executing a TextCommand on a Window object implicitly targets that window's currently active view. When executed from the ST console, it will affect the ST console's input text area.

    window.run_command('insert', { 'characters': 'testing123' })
    

    So, the answer is that there could be a difference depending on the type of command, and whether the View you want to execute the command on is the active one or not.


    In terms of the imports removed, there is no effect as those imports were not used in the plugin.