Sublime Forum

Page-up/down in autocomplete popup and command palette?

#1

Is there a way to use the pageup / pagedown keys to move the scrollbar by “pages” in an autocomplete popup or the command palette?

I’ve tried to setup a keybinding for it, but instead of the content in the popup, the cursor in the buffer is moved…

[code] { “keys”: “pagedown”], “command”: “scroll_lines”, “args”: {“amount”: 3.0 }, “context”:

		{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
	]
},[/code]

Are there any other working methods or at least a plugin that could help?

1 Like

#2

Not possible?

0 Likes

#3

No, it is.

Since I’m too lazy to see if there’s a proper way of doing this…

Use

"""
Based off of https://forum.sublimetext.com/t/run-multiple-commands-command/6848/1,
and I see no license there so AFAIK you need to ask there any time you
even think about doing anything to this source. Or you can just duck
and hope, like I have.

My changes are hereby released completely and irrevocably into the
Public Domain. THE ORIGINAL CODE MAY NOT BE PUBLIC DOMAIN AND THUS
THIS CODE SHOULD NOT BE THOUGHT OF AS PUBLIC DOMAIN.

- Joshua Landau <joshua@landau.ws>
"""

import sublime, sublime_plugin

class RunMultipleCommandsCommand(sublime_plugin.TextCommand):
	"""
	"args" for this takes _either_ "command" or "commands", where
	"commands" is a list of what "command" takes. "args" also takes
	an optional "times" parameter, and just runs itself that many
	times.

	"command" takes either a string (such as "store_selections") or
	a dictionary with a "command" attribute, an optional "args"
	attribute and an optional "context" attribute.

	In the above, the "command" and "args" attribute are as expected,
	and the "context" attribute is one of "window", "app" and "text".
	"""
	def run(self, edit, commands=None, command=None, times=1):
		if commands is None:
			commands = [command] if command is not None else ]

		for _ in range(times):
			for command in commands:
				self.exec_command(command)


	def exec_command(self, command):
		# Shortcut for simple command described by one string
		if not "command" in command:
			if isinstance(command, str):
				command = {"command": command}

			else:
				raise ValueError("No command name provided.")

		args = command.get("args")

		contexts = {"window": self.view.window(), "app": sublime, "text": self.view}
		context = contexts[command.get("context", "text")]

		context.run_command(command"command"], args)

as a plugin and then use this key-binding:

	{
		"keys": "pageup"],
		"command": "run_multiple_commands",
		"args": { "command": { "command": "move", "args": {"by": "lines", "forward": false } }, "times": 8 },
		"context": 
			{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
		]
	},
	{
		"keys": "pagedown"],
		"command": "run_multiple_commands",
		"args": { "command": { "command": "move", "args": {"by": "lines", "forward": true  } }, "times": 8 },
		"context": 
			{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
		]
	},

This has unfortunate characteristics if you “run out” of autocompletes (the cursor just keeps moving when in the real buffer) but I’m not going to solve that right now…

0 Likes

#4

Thank you Veedrac!

Unfortunately I get an error in the console, after pressing pagedown in an autocomplete popup (with enough entries, that pagedown “makes sense”):

command: run_multiple_commands {"command": {"args": {"by": "lines", "forward": true}, "command": "move"}, "times": 8} Traceback (most recent call last): File "D:\Tools\Sublime Text\sublime_plugin.py", line 543, in run_ return self.run(edit, **args) TypeError: run() got an unexpected keyword argument 'times'

0 Likes

#5

What is this file?

0 Likes

#6

It exists on every installation / portable version of ST3 (under Windows) and contains definitions for api commands.

Line 543 is:

return self.run(edit, **args)

Context:

[code]class TextCommand(Command):
def init(self, view):
self.view = view

def run_(self, edit_token, args):
    if args:
        if 'event' in args:
            del args'event']

        edit = self.view.begin_edit(edit_token, self.name(), args)
        try:
            return self.run(edit, **args)
        finally:
            self.view.end_edit(edit)
    else:
        edit = self.view.begin_edit(edit_token, self.name())
        try:
            return self.run(edit)
        finally:
            self.view.end_edit(edit)

def run(self, edit):
    pass

[/code]

0 Likes

#7

I think I know what’s happened - you haven’t installed the plugin I said to.

If you do “Tools > New Plugin…” and replace the text with the below and then save to the default place with a good name, it should work.

"""
Based off of https://forum.sublimetext.com/t/run-multiple-commands-command/6848/1,
and I see no license there so AFAIK you need to ask there any time you
even think about doing anything to this source. Or you can just duck
and hope, like I have.

My changes are hereby released completely and irrevocably into the
Public Domain. THE ORIGINAL CODE MAY NOT BE PUBLIC DOMAIN AND THUS
THIS CODE SHOULD NOT BE THOUGHT OF AS PUBLIC DOMAIN.

- Joshua Landau <joshua@landau.ws>
"""

import sublime, sublime_plugin

class RunMultipleCommandsCommand(sublime_plugin.TextCommand):
   """
   "args" for this takes _either_ "command" or "commands", where
   "commands" is a list of what "command" takes. "args" also takes
   an optional "times" parameter, and just runs itself that many
   times.

   "command" takes either a string (such as "store_selections") or
   a dictionary with a "command" attribute, an optional "args"
   attribute and an optional "context" attribute.

   In the above, the "command" and "args" attribute are as expected,
   and the "context" attribute is one of "window", "app" and "text".
   """
   def run(self, edit, commands=None, command=None, times=1):
      if commands is None:
         commands = [command] if command is not None else ]

      for _ in range(times):
         for command in commands:
            self.exec_command(command)


   def exec_command(self, command):
      # Shortcut for simple command described by one string
      if not "command" in command:
         if isinstance(command, str):
            command = {"command": command}

         else:
            raise ValueError("No command name provided.")

      args = command.get("args")

      contexts = {"window": self.view.window(), "app": sublime, "text": self.view}
      context = contexts[command.get("context", "text")]

      context.run_command(command"command"], args)
0 Likes

#8

I had… Saved it in the packages\user folder as “ScrollInPopup.py”. Restarted ST3 afterwards and it was loaded successfully but I got nothing apart from that error that I posted.

I’ve just deleted the .py file and tried it again. Different name (“PageDownInPopup.py”). Restart and… it works…

I’m unable to explain this behavior^^

Thank you Veedrac.

0 Likes

#9

This works great for me on autocomplete, but does anybody know how to do the same thing with overlays? (specifically Go To Anything)

I have tried

{ "keys": "pageup"], "command": "run_multiple_commands", "args": { "command": { "command": "move", "args": {"by": "lines", "forward": false } }, "times": 8 }, "context": { "key": "overlay_visible", "operator": "equal", "operand": true } ] }, { "keys": "pagedown"], "command": "run_multiple_commands", "args": { "command": { "command": "move", "args": {"by": "lines", "forward": true } }, "times": 8 }, "context": { "key": "overlay_visible", "operator": "equal", "operand": true } ] },

but it doesn’t seem like the overlay receives the move command. I have also tried with a run_macro_file command calling a macro with 8 moves and this doesn’t work either. Strangely simply using the move command once does work.

0 Likes

Page Down and Page Up in Popup lists and Overlay lists
#10

Navigation in autocomplete with PageUp / PageDown

{ "keys": ["pageup"], "command": "move", "args": {"by": "lines", "forward": false},
    "context":[{"key": "auto_complete_visible", "operator": "equal", "operand": true },]
    },
{ "keys": ["pagedown"], "command": "move", "args": {"by": "lines", "forward": true},
    "context":[{"key": "auto_complete_visible", "operator": "equal", "operand": true },]
    },

If it doesn’t work, maybe these keys are still being used somewhere below, then you need to resolve these conflicts

A convenient way to configure hotkeys is to take an action and see what command was used in the console.

View → Show console, Enter this:
sublime.log_commands(True)

And documentation
Context https://www.sublimetext.com/docs/key_bindings.html#context-key

Examples
Show/Hide panel Find by pressing single key

{"keys": ["f1"], "command": "show_panel", "args": {"panel": "find"}},
{"keys": ["f1"], "command": "hide_panel", "args": {"panel": "find"}, "context": [ {"key": "panel", "operand": "find" } ] },

Useful contexts: Last command, Settings

{"keys": ["ctrl+space"], "command": "hide_auto_complete", "context":
   [
      {"key": "auto_complete_visible", "operator": "equal", "operand": true },
      {"key": "last_command", "operator": "equal", "operand": "commit_completion" },
      {"key": "setting.tab_completion", "operator": "equal", "operand": true }
   ]
},
0 Likes