When editing a markdown file, I would like to make asterisks and backticks behave like parentheses. For instance, I have made a selection and I press *, I would like the selection to be enclosed within two * characters.
How do I do this in Sublime Text 3?
From the Preferences menu, choose Keybindings and paste in the following:
{ "keys": ["*"], "command": "insert_snippet", "args": {"contents": "*${0:$SELECTION}*"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true },
]
},
{ "keys": ["`"], "command": "insert_snippet", "args": {"contents": "`${0:$SELECTION}`"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true },
]
},
This is just a modified version of the Default keybinding for (, with the additional restriction that it will only apply to Markdown files.
Auto-pairing is implemented as key binding in sublime you can find it in
sublime > preferences > key Binding
here is an example of how it works:
{ "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 }
]
}
when "(" is pressed insert the snippet ($0) open parentheses then the first "data to enter"/cursor then closing parentheses but ensure the following criteria
auto_match_enabled => auto match is enabled
selection_empty(true) => you don't have a selection
following_text => the next text is something matches "^(?:\t|
|\)|]|;|\}|$)"
another one:
{ "keys": ["("], "command": "insert_snippet", "args": {"contents": "(${0:$SELECTION})"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
]
}
when "(" is pressed insert the snippet (${0:$SELECTION}) open parentheses then the selected text then closing parentheses but ensure the following criteria
auto_match_enabled => auto match is enabled
selection_empty(false) => you have a selection
and the others work in the same manner for pressing the closing parentheses that move the cursor right and for deleting an empty parentheses pair
so what you need is
{ "keys": ["*"], "command": "insert_snippet", "args": {"contents": "*${0:$SELECTION}*"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
]
},
{ "keys": ["`"], "command": "insert_snippet", "args": {"contents": "`${0:$SELECTION}`"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true }
]
}
To make a back-tick (`) behave in completely the same way as other matching characters, i.e. add closing pair, enclose selection, delete the closing pair when the opening back-tick is backspaced, add this to the user's pane in Sublime > Preferences > Key Binding:
{ "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.double - punctuation.definition.string.end", "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["`"], "command": "insert_snippet", "args": {"contents": "`${0:$SELECTION}`"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": false, "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["`"], "command": "move", "args": {"by": "characters", "forward": true}, "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": "^`", "match_all": true },
{ "key": "selector", "operator": "not_equal", "operand": "punctuation.definition.string.begin", "match_all": true },
{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
},
{ "keys": ["backspace"], "command": "run_macro_file", "args": {"file": "res://Packages/Default/Delete Left Right.sublime-macro"}, "context":
[
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "preceding_text", "operator": "regex_contains", "operand": "`$", "match_all": true },
{ "key": "following_text", "operator": "regex_contains", "operand": "^`", "match_all": true },
{ "key": "selector", "operator": "not_equal", "operand": "punctuation.definition.string.begin", "match_all": true },
{ "key": "eol_selector", "operator": "not_equal", "operand": "string.quoted.double - punctuation.definition.string.end", "match_all": true },
{ "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true }
]
}
I copied this code from Sublime's default key bindings for double-quote ("), replacing "\"" with "`".
The settings will only affect markdown. To address JavaScript files, for example, you would replace "text.html.markdown" with "source.js".
Related
I used to be able to type div and then press tab and sublime would autocomplete and output <div></div>. The same thing with components. I would type MyComponent and press tab and sublime would autocomplete <MyComponent></MyComponent>. Since today this no longer works for me. Any ideas why?
I tried finding a solution, but have been unsuccessful. Below is a keybinding that I have tried, but it does not work.
{ "keys": ["tab"], "command": "expand_abbreviation_by_tab", "context":
[
{ "operand": "source.js", "operator": "equal", "match_all": true, "key": "selector" },
{ "match_all": true, "key": "selection_empty" },
{ "operator": "equal", "operand": false, "match_all": true, "key": "has_next_field" },
{ "operand": false, "operator": "equal", "match_all": true, "key": "auto_complete_visible" },
{ "match_all": true, "key": "is_abbreviation" }
]
}
Turns out the Emmet package was updated to Emmet2 today and the above key bind needs to be adjusted slightly. The command property should be emmet_expand_abbreviation instead of expand_abbreviation_by_tab and Emmet2 now displays a popup while you type so the last 2 lines need to be commented out.
Here what works for me:
{ "keys": ["tab"], "command": "emmet_expand_abbreviation", "context":
[
{ "operand": "source.js", "operator": "equal", "match_all": true, "key": "selector" },
{ "match_all": true, "key": "selection_empty" },
{ "operator": "equal", "operand": false, "match_all": true, "key": "has_next_field" },
// { "operand": false, "operator": "equal", "match_all": true, "key": "auto_complete_visible" },
// { "match_all": true, "key": "is_abbreviation" }
]
}
I tried to set the shortcut of Reindent in Sublime using the following approach:
{ "keys": ["ctrl+alt+i"], "command": "reindent", "context":
[
{ "key": "setting.auto_indent", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "preceding_text", "operator": "regex_match", "operand": "^$", "match_all": true },
{ "key": "following_text", "operator": "regex_match", "operand": "^$", "match_all": true }
]
},
So, now I would expect the Ctrl+Alt+i to Reindent the selected code. I checked that the file with keybindings is saved by reopening it.
But when I select all and press Ctrl+Alt+i re indentation does not happen.
Also I checked that the keybinding does not appear on the Reindent button.
I tried to restart the editor, but neither did this help.
What can I do about the issue? Thank you.
I'm working with sublime 3 (build: 3143) and I experience a really annoying issue since a long time.
Whenever I type a backtick
`
it is automatically completed to a pair of quotes
`'
this is annoying especially when I want only one of the two symbols, and I'm not able to find what I did or wasn't able to prevent in order to obtain this higly undesirable behaviour.
I suspect this is something LaTeXTools is doing; no clue of what I shall disable (auto-completion? But then I'd lose autocompletions I need, and like, too).
Any help is welcome!
You're right, this is a keybinding from LaTeXTools:
// autopair quotation marks (`')
{ "keys": ["`"], "command": "insert_snippet", "args": {"contents": "`$0'"}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.tex.latex"},
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
]
},
To remove this behavior, as there is no LaTeXTools preference for it, one can simply add a new keybinding in the User keybindings file to override it, that will simply insert a backtick:
{ "keys": ["`"], "command": "insert", "args": {"characters": "`"}, "context":
[
{ "key": "selector", "operator": "equal", "operand": "text.tex.latex"},
{ "key": "setting.auto_match_enabled", "operator": "equal", "operand": true },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }
]
},
Whenever I type ' in sublime it adds the terminating quote ' and places the cursor in the middle like this: '|'
Same goes for " that gets expanded into "|".
This is unwanted behavior for me, the only way I found to turn it off is by setting:
"auto_indent": false,
However, this makes it cumbersome to write indented code.
Is there anyway to get Sublime to not complete string literals and keep auto_indent?
I tested this on Sublime 3 Build 3114 on Windows and Sublime 3 Build 3083 on Linux.
The name of the setting should be auto_match_enabled as you see in definition in the default keybindings:
// Auto-pair 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.double - punctuation.definition.string.end", "match_all": true }
]
},
I have the following command in my sublime-keymap:
{
"keys": ["tab"],
"command": "insert_snippet",
"args": { "contents": "${1:key}: ${0:'value'}" },
"context": [
{ "key": "selector", "operator": "equal", "operand": "source.js" },
{ "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true },
{ "key": "preceding_text", "operator": "regex_contains", "operand": "\\{\\s*$" },
{ "key": "preceding_text", "operator": "not_regex_contains", "operand": "\\)\\s*\\{\\s*$" }
]
},
This matches the following text just fine (pipe = insertion point):
{ |
…but not this:
{
|
…because preceding_text only seems to include the preceding text on the same line. Is there any way to match on more than one line here?