I'm using this two bindings for auto complete:
{
"keys": ["tab"],
"command": "move",
"args": {"by": "lines", "forward": true},
"context":
[
{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
]
},
{
"keys": ["shift+tab"],
"command": "move",
"args": {"by": "lines", "forward": false},
"context":
[
{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
]
},
I would like to add "commit_completion" command to space key:
"keys": ["space"],
"command": "commit_completion",
"context":
[
{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
]
},
But it's not binding, when I press space it acts as normal space(it makes space xD). I'm able to bind it to any other key but not space. What am I missing?
There's not a key code for the space bar that you can bind like that; if you want to bind something to space, you need to use a literal space character:
{
"keys": [" "],
"command": "commit_completion",
"context": [
{ "key": "auto_complete_visible", "operator": "equal", "operand": true }
]
},
This is visible in the Sublime console by using sublime.log_input(True) to turn on input logging and then pressing the key; the only thing that gets logged is a character event, and not a key event.
It's also important to note that you never want to bind anything to a character like this unless you're using a context to constrain when the binding applies, or you lose the ability to type that character.
Related
The linked chart contains only a legend and the legend works as follows:
clicking on a fruit name toggles it on and off
shift-clicking on a fruit name switches it ON and switches OFF all other fruit names
Legend display is controlled by two entities:
data set SELECTED remembers selected items
signal FILTERMODE toggles the type of the filter between include and exclude
Currently, if only one fruit name is ON, then a click on it switches it OFF (so all fruit names become OFF).
I would like to modify this behavior so that a click on the last enabled fruit name would switch everything ON.
(In other words - it would not be possible to deselect everything.)
In order to switch everything ON I only need to change the value of signal FILTERMODE to exclude. This is where I hit a snag.
I have tried the following in the signal definition:
"update": "event.shiftKey? 'include' : (length(data('selected'))? filtermode : 'exclude')",
This does not work. I am fairly sure this happens because of a race condition.
When I check for the length of data('source'), it is still non-empty.
So the sequence of events is the following:
click
update signal FILTERMODE (check if the data set SELECTED is empty - it is not)
update data set SELECTED (only now it has become empty)
What would be the most elegant work-around?
Try this instead. It is the same as your code but also checks the length of the array which your single line doesn't currently do.
You can now shift click melon and then click it normally and the filter mode will switch.
Editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A scatter plot example with interactive legend and x-axis.",
"width": 200,
"height": 200,
"padding": 5,
"autosize": "pad",
"signals": [
{
"name": "shift",
"value": false,
"on": [
{
"events": "#legendSymbol:click, #legendLabel:click",
"update": "event.shiftKey",
"force": true
}
]
},
{
"name": "clicked",
"value": null,
"on": [
{
"events": "#legendSymbol:click, #legendLabel:click",
"update": "{value: datum.value}",
"force": true
}
]
},
{
"name": "filtermode",
"value": "exclude",
"on": [
{
"events": "#legendSymbol:click, #legendLabel:click",
"update": "event.shiftKey? 'include' : (length(data('selected') == 0)? filtermode : 'exclude')",
"force": true
}
]
}
],
"data": [
{
"name": "source",
"values": [
{"fruit": "apple"},
{"fruit": "plum"},
{"fruit": "pear"},
{"fruit": "melon"},
{"fruit": "grape"},
{"fruit": "strawberry"}
]
},
{
"name": "selected",
"on": [
{"trigger": "clicked && (event.shiftKey)", "remove": true},
{"trigger": "clicked && (event.shiftKey)", "insert": "clicked"},
{"trigger": "clicked && (!event.shiftKey)", "toggle": "clicked"}
]
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"range": {"scheme": "category10"},
"domain": {"data": "source", "field": "fruit"}
}
],
"legends": [
{
"stroke": "color",
"title": "Fruit",
"encode": {
"symbols": {
"name": "legendSymbol",
"interactive": true,
"update": {
"fill": {"value": "transparent"},
"strokeWidth": {"value": 2},
"opacity": [
{
"test": "filtermode == 'exclude' && !indata('selected', 'value', datum.value)",
"value": 1
},
{
"test": "filtermode == 'include' && indata('selected', 'value', datum.value)",
"value": 1
},
{"value": 0.15}
],
"size": {"value": 64}
}
},
"labels": {
"name": "legendLabel",
"interactive": true,
"update": {
"opacity": [
{
"test": "filtermode == 'exclude' && !indata('selected', 'value', datum.value)",
"value": 1
},
{
"test": "filtermode == 'include' && indata('selected', 'value', datum.value)",
"value": 1
},
{"value": 0.25}
]
}
}
}
}
]
}
Are you checking the length of the correct array? It is hard to understand precisely what the desired behaviour is but if I add the code (depending on whether filter mode is include or exclude)
length(data('selected')) == 6
or
length(data('selected')) == 0
then it seems to work.
Editor
Is there a way how to set in key-binding file new rule, that when I type character which is already right after the cursor, it will be overridden.
To clarify what I would like to have:
if (ABC === XYZ) { // when I place cursor right after "XYZ" and type ")" mark, it will not be inserted and cursor jump right after the ")" which is already there
echo "equals"; // when I place cursor right ater "equals" and type ";" mark, it will not be inserted and cursor jump right after the semicolon which is already there. When I type it again then, it will be inserted as usual
}
Yes, this is possible - when you press the key you want to skip, check if the character immediately to the right of the caret is the same as the key you pressed, and move over it if so. Here is the concrete bindings for semi-colon and closing paren: (unforunately it involves a bit of repetition because the context can't take a parameter based on which key was pressed without writing some plugin code)
{ "keys": [";"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
[
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "following_text", "operator": "regex_contains", "operand": "^;", "match_all": true },
]
},
{ "keys": [")"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
[
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "following_text", "operator": "regex_contains", "operand": "^\\)", "match_all": true },
]
},
I'm trying to set my Sublime Text 3, but I'm not able to do my desired settings (which was worked in ST2 on my old computer).
What I need
When I type in CSS, I type eg. color: and I'd like to have autocomplete to color: |; (where | is a cursor).
What I have so far
I've found an advice to add
{ "keys": [":"], "command": "insert", "args": {"characters": ": ;"}}
into sublime-keymap. It partially works, it add space and semicolon but cursor if after, not inside.
When I googled, I had 99% of results for ST2 not ST3.
Any idea? Thanks.
The insert command just inserts exactly the text that you give it, as if you typed it yourself. If you want to do something like insert text and specify the location at which the cursor ends up, you want insert_snippet instead.
The default key bindings have several examples of keys bound using insert_snippet as the command that demonstrate this. For example:
// Auto-pair single quotes
{ "keys": ["'"], "command": "insert_snippet", "args": {"contents": "'$0'"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "following_text", "operator": "regex_contains", "operand": "^(?:\t| |\\)|]|\\}|>|$)", "match_all": true },
{ "key": "preceding_text", "operator": "not_regex_contains", "operand": "['a-zA-Z0-9_]$", "match_all": true },
{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.single - punctuation.definition.string.end", "match_all": true }
]
},
As noted here, the insert_snippet command takes as one of its arguments contents, which specifies the text of the snippet to insert, and this text can contain things like snippet fields and the like just as a sublime-snippet file can. The special field $0 specifies where the cursor should be placed.
This particular example also contains context items that define exactly in what situations this binding should be active.
As outlined in your question, your binding will trigger every time you type a colon, which stops you from ever being able to just type a single colon. So, you may want to add context to your key as well if you haven't already done so.
As an aside, one of the features of Sublime Text 4 is that it will automatically inject a snippet just like this one when entering CSS properties.
I had my terminal set up with two panes. Like this:
[A|B]
I accidentally Ctrl+C'd a process running in the pane to the left, which results in the pane getting closed. When I split again, my new pane comes to the right. So that my setup becomes:
[B|A]
Is there anyway to restore the setup I had initially without cancelling the process running in B?
When you asked, this wasn't possible.
With Windows Terminal 1.12 however, this is possible with the swapPane actions. For more details, see: https://learn.microsoft.com/en-us/windows/terminal/panes#swapping-panes-preview
The syntax for these actions is:
{ "command": { "action": "swapPane", "direction": "down" } },
{ "command": { "action": "swapPane", "direction": "left" } },
{ "command": { "action": "swapPane", "direction": "right" } },
{ "command": { "action": "swapPane", "direction": "up" } },
{ "command": { "action": "swapPane", "direction": "previous" } },
{ "command": { "action": "swapPane", "direction": "previousInOrder" } },
{ "command": { "action": "swapPane", "direction": "nextInOrder" } }
But they should also be bound by default in the Command Palette, under the names "Swap Pane..."
In Sublime Text 3, I am trying to alternate a setting's value using the same shortcut, but with differing contexts. Basically, I want to alternate the draw_white_space setting between its three possible values: none, selection, and all.
I change the setting easily enough with three separate shortcuts/keymaps. Here is that code (working):
{
"keys": ["ctrl+e", "ctrl+w"],
"command": "set_setting",
"args": {
"setting": "draw_white_space",
"value": "all",
}
},
{
"keys": ["ctrl+e", "ctrl+q"],
"command": "set_setting",
"args": {
"setting": "draw_white_space",
"value": "none",
}
},
{
"keys": ["ctrl+e", "ctrl+s"],
"command": "set_setting",
"args": {
"setting": "draw_white_space",
"value": "selection",
}
}
But, what I would really like is to be able to press ["ctrl+e", "ctrl+w"] and have it alternate through each possible value. Yes, it is a Visual Studio shortcut that I'm used to!
I created what looks to me like it should work, but it doesn't. At least not how I want it to. Here is that code (broken):
{
"keys": ["ctrl+e", "ctrl+w"],
"command": "set_setting",
"args": {
"setting": "draw_white_space",
"value": "none",
},
"context": [
{ "key": "setting.draw_white_space",
"operator": "equal", "operand": "all" }
]
},
{
"keys": ["ctrl+e", "ctrl+w"],
"command": "set_setting",
"args": {
"setting": "draw_white_space",
"value": "selection",
},
"context": [
{ "key": "setting.draw_white_space",
"operator": "equal", "operand": "none" }
]
},
{
"keys": ["ctrl+e", "ctrl+w"],
"command": "set_setting",
"args": {
"setting": "draw_white_space",
"value": "all",
},
"context": [
{ "key": "setting.draw_white_space",
"operator": "equal", "operand": "selection" }
]
}
I have tested out my contexts, so I know they work. For instance, I can manually set all in my settings file, then the shortcut that checks for all will work the first time only. It nor the others will work after that.
Another thing I noticed is that my settings file does not change the draw_white_space value when the shortcut does work (including the three separate shortcuts). I assumed that might be default behavior - the settings changes may be per session - and that would be fine. But, I removed the setting completely and it is still the same behavior.
I am changing the file opened via the Preferences | Key Bindings - User menu, which opened the <Sublime Text>\Data\Packages\User\Default (Windows).sublime-keymap file.
Any ideas? Am I doing something wrong or missing something?
Maybe not what you want, but you can get that behavior with a pretty simple plugin.
import sublime
import sublime_plugin
class CycleDrawWhiteSpaceCommand(sublime_plugin.TextCommand):
def run(self, edit):
view = self.view
white_space_type = view.settings().get("draw_white_space")
if white_space_type == "all":
view.settings().set("draw_white_space", "none")
elif white_space_type == "none":
view.settings().set("draw_white_space", "selection")
else:
view.settings().set("draw_white_space", "all")
After you save the plugin, bind your key binding to cycle_draw_white_space