Sublime Forum

Dev Build 3156

#21

Never mind. Seems to be my whole system has clipboard messed up…sigh

0 Likes

#22

Thanks @wbond for corrections about Command Palette. In other news…

Have multiple cursors somehow changed? Seems like Alt-shift-up and -down aren’t working with this build with default keybindings. If I copy the default bindings to my user settings they do work.

Also, should I be creating actual issues for these things or is it okay to sound them out here in the release message thread?

0 Likes

#23

I don’t think anything has changed on them recently. Certainly not with build 3156.

0 Likes

#24

This is the symptom when some package is overriding your keybindings, as:

  1. Any package can override the default keybind
  2. The User .sublime-keymap file override all the packages key binds

Do help diagnose, you can enable/disable the Sublime Text logging with:

sublime.log_input(True); sublime.log_commands(True); sublime.log_result_regex(True)
sublime.log_input(False); sublime.log_commands(False); sublime.log_result_regex(False)

After enabling the log, press the keys and see if some command is issued on the Sublime Text console.

If it is a regression with this build, could post here or perhaps open a new issue, if you think is a too complicated/long discussion.

0 Likes

#25

It feels like I am blind. Maybe one of you can help me out.

I try to create a command which opens the new command pallet and lists all package settings files except existing syntax-settings. But somehow it keeps throwing an exception.

>>> sublime.run_command("my_input")
Traceback (most recent call last):
  File "C:\Apps\Sublime3\3156\sublime_plugin.py", line 934, in run_
    return self.run()
TypeError: run() missing 1 required positional argument: 'base_file'

It looks like the input() method of the MyInputCommand is not executed at all.

Not working piece of code

import re
import os

import sublime
import sublime_plugin

# import Default.settings

PACKAGES = "${packages}/"

# The pattern to extract the path and basename of a file without OS pattern.
SETTINGS_RE = re.compile(
    r"(?i)Packages/(.+/)(.+?)(?: \(.+\))?(\.sublime-settings)")
SYNTAX_RE = re.compile(
    r"(?i)Packages/(.+/)(.+?)(?: \(.+\))?(\.sublime-syntax)")


class BaseFileInputHandler(sublime_plugin.ListInputHandler):

    def name(self):
        return "base_file"

    def placeholder(self):
        return "Settings File"

    def preview(self, value):
        if value:
            return sublime.Html("<b>File:</b> " + value[len(PACKAGES):])
        else:
            return None

    def list_items(self):
        syntaxes = set()
        for f in sublime.find_resources('*.sublime-syntax'):
            _, name, _ = SYNTAX_RE.match(f).groups()
            syntaxes.add(name)

        items = set()
        for f in sublime.find_resources('*.sublime-settings'):
            path, name, ext = SETTINGS_RE.match(f).groups()
            if 'User' not in path and name not in syntaxes:
                items.add(("📑 " + name, "".join((PACKAGES, path, name, ext))))

        items = list(items)
        items.sort()
        return items


class MyInputCommand(sublime_plugin.ApplicationCommand):

    def input_description(self):
        return "Preferences"

    def input(self, args):
        if "base_file" not in args:
            return BaseFileInputHandler()
        else:
            return None

    def run(self, base_file):
        print(base_file)

There is another function to override the syntax specific settings which works fine.


class SyntaxSettingsInputHandler(sublime_plugin.ListInputHandler):

    def __init__(self, syntax):
        self.syntax = syntax

    def name(self):
        return "syntax"

    def placeholder(self):
        return "Syntax Name"

    def list_items(self):
        items = set()
        selected = None
        for f in sublime.find_resources('*.sublime-syntax'):
            path, name, ext = SYNTAX_RE.match(f).groups()
            if name == self.syntax:
                caption = "📑 " + name + " (this view)"
            else:
                caption = "📑 " + name
            item = (caption, name)
            if name == self.syntax:
                selected = item
            items.add(item)

        items = list(items)
        items.sort()
        return (items, items.index(selected)) if selected else items


class EditSyntaxSettingsCommand(Default.settings.EditSyntaxSettingsCommand):

    def input_description(self):
        return "Syntax Settings"

    def input(self, args):
        if "syntax" not in args:
            try:
                settings = self.window.active_view().settings()
                syntax, _ = os.path.splitext(os.path.basename(settings.get('syntax')))
            except:
                syntax = None
            return SyntaxSettingsInputHandler(syntax)
        else:
            return None

    def run(self, syntax):
        self.window.run_command(
            'edit_settings',
            {
                'base_file': '${packages}/Default/Preferences.sublime-settings',
                'user_file': os.path.join(sublime.packages_path(), 'User', syntax + '.sublime-settings'),
                'default': (
                    '// These settings override both User and Default settings '
                    'for the %s syntax\n{\n\t$0\n}\n') % syntax
            })

    def is_enabled(self):
        return True
0 Likes

#26

Yup, that was the problem. Thanks @addons_zz. Forgot I had installed Compare Side-By-Side right at the same time.

1 Like

#27

It does not work, because if I recall correctly, they do not implemented yet the ability to call the new input handlers outside the command palette as a command.

I made your example work, by creating a Default.sublime-command within:

  { "caption": "11111 My Input",
    "command": "my_input",
  },

Then, after opening the command palette and calling your command, it opened this:

0 Likes

#28

I believe that what @deathaxe is trying to do will work (that is, using run_command to run a command and have it prompt for input), but for it to work the command has to appear in the command palette as well.

0 Likes

#29

I just wanted to confirm this on Linux.

1 Like

#30

I believe this is the issue. The auto-fill input functionality only works if the command is in the command palette. This allows the user to back out of the command and then re-enter it, rather than backing out of a command and not being able to find it again.

1 Like

#31

After creating the Default.sublime-commands file within:

[
    { "caption": "My Input", "command": "my_input", },
]

I made your code working by using the https://github.com/randy3k/Keypress package:

class MyInputHelperCommand(sublime_plugin.WindowCommand):

    def run(self):
        self.window.run_command( "show_overlay", {"overlay": "command_palette"} )
        self.window.run_command( "select_all" )

        def press_enter():
            self.window.run_command( "keypress", {"key": "enter"} )

        self.window.run_command( "my_input_helper_hook")
        sublime.set_timeout_async( press_enter, 100 )


class MyInputHelperHookCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        selections = self.view.sel()
        self.view.erase( edit, selections[0] )

        self.view.run_command( "append", {"characters": "My Input"} )

Then you just need to call:

>>> window.run_command( "my_input_helper" )
0 Likes

#32

You don’t need an extra command. As long as your command appears in the command palette and has an input handler, you can just invoke it with run_command() and you will be promoted for input (assuming it is missing arguments).

1 Like

#33

That’s indeed the reason.

I originally tried to create a derived EditSettingsCommand class to just add the input handler and override the default one. But for some reason ST seems to keep using the original one. Therefore I tried to rename the command to MyInputCommand for debugging to avoid duplication, but missed to add the appropriate command pallet entry. After doing so it works well with all known kinds of calling commands.

Thanks for opening my eyes! :smile:

== [extended settings command with input handler ]==

import sublime
import sublime_plugin

import Default.settings

...

class EditSettingsCommand(Default.settings.EditSettingsCommand):

    def input_description(self):
        return "Preferences"

    def input(self, args):
        if "base_file" not in args:
            return BaseFileInputHandler()
        else:
            return None
1 Like

#34

Oh, I didn’t expect anyone could discover the Keypress package. I believe @wbond mentioned a while ago on discord that you could execute select command on the active view for simulating “enter” when command palette is up.

1 Like

#35

Well, I just googled, about on how to press keys with python, then I found your package. Thanks for writing it!

Indeed I just tried running window.run_command( "select" ) and it pressed enter. Here is a the updated code which opens the About dialog:

class MyInputHelperCommand(sublime_plugin.WindowCommand):

    def run(self):
        self.window.run_command( "show_overlay", {"overlay": "command_palette"} )
        self.window.run_command( "select_all" )

        self.window.run_command( "my_input_helper_hook")
        self.window.run_command( "select")

class MyInputHelperHookCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        selections = self.view.sel()
        self.view.erase( edit, selections[0] )
        self.view.run_command( "append", {"characters": "About"} )
0 Likes

#36

+1 Command Palette behavior is broken in this build. I believe the previous command text was preselected in the last 5 years.

0 Likes

#37

This will be fixed in the next build, see Dev Build 3156

0 Likes

#38

After restarting Sublime Text the command palette input text is lost. On build 3143, it is preserved.

1 Like

#39

The place holder in the new command panel seems not to be rendered at the correct vertical position. Is this something which can be tweaked by the theme or is it to be optimized by the core?

animation

Would be nice, if pasting the placeholder’s text would only cause the color to change, not the text to move down by about 2 or 3 pixels.

3 Likes

#40

@addons_zz could you please release it on PackageControl.io? I tried to run your plugin code, but It did not work. And this issue driving me crazy.

0 Likes