I am working on a tm language project for vscode and I'm wondering what the captures property on a pattern does exactly.
I can't seem to figure out what the indexes of the captures object stand for and I can't find any information on it online.
Example:
{
"match": "(group 1)(group2)"
"captures": {
"0": {
"name": "Name of first capture group? What does 0 mean here?"
}
}
}
The "captures" key is documented here, in the "Rule Keys" section (12.3):
https://macromates.com/manual/en/language_grammars
The name is not the name of the first capture group. It is just a string that specifies the name of the style to apply to the characters that were matched by that capture group. When I say "capture group", I am referring to a matching left paren and right paren in your regular expression.
Using the "captures" key is a relatively complex way to assign style names to characters in the document. It allows you to specify different styles to different portions of the text matched by the regular expression. A simpler way is to just use the "name" key, which will apply the style to all of the matched text.
Related
I would love to set my 'tranformTOLowerCase' and 'tranformToUpperCase' to the same keybind, and use the when clause option that vs code has, but I can't find the right property to rely on,
I'v looked in the vsCode documentation under when contexts and didn't find a solution,
Does anyone know any different way?
I don't think there is any keybinding context key that will help to differentiate between text that is uppercase and text that is lowercase.
But you can use an extension that I wrote to do this: Find and Transform.
Create this keybinding in your keybindings.json:
{
"key": "alt+d", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "((([a-z])|([A-Z]))(.*))", // is the first letter upper of lowercase?
"replace": "${3:+${1:/upcase}}${4:+${1:/downcase}}",
"isRegex": true,
"matchCase": true, // this must be set to true to distinguish cases
"restrictFind": "selections", // works on your selection(s), one or many
}
}
As you can see, it tests the first letter. If it is lowercase a-z, then the selection is uppercased. And vice-versa, if the first letter is [A-Z], then the selection is lowercased.
If you can have digits, underscores or other non-alphabetic characters as the first character, this simple first-letter matching won't work and you would have to keep testing characters which would make for a messy regex, but could probably be done. [Let me know if you need that, I think I know how it can be done, although it is a different approach.]
The replacement:
"replace": ${3:+${1:/upcase}}${4:+${1:/downcase}}
is pretty interesting. The $n's refer to capture groups from the find regex. ${3:+${1:/upcase}} means if there is a capture group 3 (the first letter is [a-z], then upcase all of capture group 1.
And similarly if the first letter is [A-Z], so there is a capture group 4, then it and the rest of the selection, capture group 1, will be lowercased.
In a normal vscode snippet or keybinding you can not embed a capture group inside a conditional like ${3:+${1:/upcase}}. ${3:+text to add here if group 3} normally takes only text and cannot resolve variables or capture groups, much less transform their case like ${1:/upcase} inside the conditional - but the extension can.
I have multiple .xml files in which I have a repeating string pattern. I want to replace each instance of that pattern with an integer starting with "1".
e.g.
Input:
APPLE is my favorite fruit. APPLE is red in color.
Expected Output:
1 is my favorite fruit. 2 is red in color.
For simple incrementing integers from 1, 2, 3, ... (or 0, 1, 2, ...) you can use the new snippet variables $CURSOR_NUMBER or $CURSOR_INDEX respectively.
You would still have to find a way to select all the find matches you want to replace (and so I think the extension below is better). You could use Ctrl+D to progressively select the occurrences you want or using the Find Widget:
Find: APPLE
and then Alt+Enter to select all matches and then insert a snippet like:
"Increment integer": {
"prefix": "i++",
"body": [
"${CURSOR_NUMBER}",
]
},
by typing its trigger prefix i++ and voila, all the APPLE instances are replaced by increasing integers.
I am sure there are other extensions that can do this, but using one that I wrote this is very easy: Find and Transform.
Create this keybinding (in your keybindings.json):
{
"key": "alt+y", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
// "find": "APPLE", // actually not necessary
"replace": "${matchNumber}",
"matchCase": true // match only APPLE, not Apple
}
}
That will replace whatever word your cursor is on with the matchNumber starting at 1. If you wanted to start at 0, use ${matchIndex}.
If you need to specify a more complicated regex find, you can do that too.
With Regex Text Generator you can do this.
select all the APPLE instances you want, any way you like, Ctrl+D, Selet All Occurrences, Alt+Enter from Find dialog
execute command Generate Text based on regular expression
as match expression use: .*
as generator expression use: {{=i+1}}
I am following this link(https://code.visualstudio.com/api/language-extensions/snippet-guide) to develop the code snippet function of my vscode exetension.
I want my code snippets not distinguish between uppercase and lowercase letters. For example, "Enum"/"ENUM"/"enum"/"eNum"/"eNUm"/...and so on is all I need, how should I configure my "prefix" field(like using regex?)?
You can define multiple prefixes, choose the ones that are the most likely
{
"Enum snip": {
"prefix": ["enum", "ENUM", "Enum"],
"body": ["MyEnum {}"],
"description": "Enum foo bar."
}
}
Or you can write a CompletionItemProvider and analyze the text before the cursor with a regex and create a snippet completion item.
"Heading 2" style in French is "Titre 2": how to get "Titre 2" knowing "Heading 2" ?
I searched on Google and found this
https://msdn.microsoft.com/en-us/vba/word-vba/articles/style-namelocal-property-word
Unfortunately that's not what I want.
When working with the built-in styles always use the enumeration. The code below will print the localized name of Heading 2 to the Immediate window.
Debug.Print ActiveDocument.Styles(wdStyleHeading2).NameLocal
https://msdn.microsoft.com/en-us/vba/word-vba/articles/wdbuiltinstyle-enumeration-word
Also, when your document is going international, and you are using chapter names in the header or footer, don't use
{ StyleRef "Heading 1" }
because when the document is shown in a German MS Word, it wouldn't understand "Heading" but expect "Überschrift" instead.
However, there's an international version, too. Just use
{ StyleRef 1 }
without quotes around the heading number.
You can't reference "Titre 2" as "Heading 2". Instead, see 'WdBuiltinStyle Enumeration'. Knowing these constants for the most part means you don't need to know the local names and, when you do, you can retrieve them via .NameLocal.
See also 'WdListNumberStyle Enumeration', 'WdCaptionNumberStyle Enumeration', 'WdNoteNumberStyle Enumeration', 'WdApplyQuickStyleSets Enumeration', and 'WdStyleType Enumeration' in the Word VBA help file.
I have defined some keywords for a proprietary language I use at work:
{ "match": "\\b(util.tickettimelimit|util.user_ip|util.server_name|util.today)\\b",
"name": "keyword.source.GTX2",
"comment": "Tags"
}
I also have a completion file:
{
"scope": "source.GTX2",
"completions":
[
"util.server_name",
"util.tickettimelimit",
"util.today",
"util.user_ip"
]
}
When I start typing "util" I see the correct autocomplete options:
But as soon as I enter the "."(dot) autocomplete options go away:
Is there a way to change this behavior? I just want the keywords to be trated as a whole thing and ignore the dots.
Thanks!
I've looked everywhere I can, and it seems the auto-complete code is embedded within the executable itself (at least on Windows, I haven't checked my Mac yet), and not in one of the numerous external .py files scattered around, so I can't even see the parameters for how auto-completion is performed. I looked through the default Packages/Default/Preferences.sublime-settings file and while there are several options relating to auto-complete, there are none relating to what we're looking for. While looking through the Default (Windows).sublime-keymap file in the same directory, I tried adding the following:
{ "keys": ["."], "command": "hide_auto_complete", "context":
[
{ "key": "auto_complete_visible", "operator": "equal", "operand": false }
]
},
but alas it didn't work. There are a number of auto_complete commands there, and while this looked the most promising I haven't tried the rest.
I haven't exhaustively looked through the source and config files for the nifty SublimeCodeIntel plugin (also available through Package Control), so it's possible you might be able to find an option there. You'd probably have to completely disable the built-in auto-complete functionality first, so it doesn't override SCI.
So, I guess for now there's not much you can do. You can always leave a feature request and see if it makes it into Sublime Text 3, or search/open a thread on the Sublime Text Forum and see if anyone else has any suggestions. Good luck!
What I think #Ashish is alluding to is the word_separators setting. You will want to create a syntax specific preference (Preferences -> Settings - More -> Syntax Specific - User). Create a word_separators entry with the dot removed (Copy from the default preferences as the base). This will give you the behavior you want but there are some things to note. The dot, obviously, will not be treated as a word separator, which will change some behavior.
I'll use java as an example. If I had a variable foo, with some method bar, I could enter foo.b and bar would be shown as a completion. Without the dot as a separator, you will not see this.
Another example, perhaps easier to understand is when selecting words. If you use ctrl/cmd + d to select the word, it selects words, bound by word separators. So if I had foo.ba|r, where the | represents the cursor position and used ctrl/cmd+d it would select bar. With the dot removed as a word separator, foo.bar would be selected.
Let me know if I can clarify anything.
It's a little late but I hope this can help, create a new plugin and add this code:
import re
myObjects = {"util": ["server", "tickettimelimit", "today", "user_ip"]}
class CustomAutocomplete(sublime_plugin.EventListener):
def on_query_completions(self, view, prefix, locations):
if not view.match_selector(0, "source.GTX2"):
return
if prefix == "":
# get the last word in the current line
currentposition = view.sel()[0].begin()
currentline = view.full_line(currentposition)
text = view.substr(currentline)
words = re.findall("\w+", text)
lastword = words[-1]
if lastword in myObjects.keys():
# return a list of tuples, it represents snippets
# the first element is the trigger and the second one
# is the content
return [(x, x) for x in myObjects[lastword]]
return []
And add the next key in the user settings:
"auto_complete_triggers":
[
{
"characters": ".",
"selector": "source.GTX2"
}
]
Don't press . (dot) else you will need to type at least one character after dot so list can appear again. Using Brackets or Dot tells Sublime Text 2 that user has completed typing.
example: if I type for then sublime will show dropdown list but if I type for( list will disappear.
Click on Preferences > Settings - User, then copy and paste the following
// Characters that are considered to separate words – does not include periods.
// Place comma at the end of the line if there are multiple keybindings.
"word_separators": "/\\()\"‘-:,;~!##$%^&*|+=[]{}`~?"
From this webpage:
http://tomschenkjr.net/using-sublime-text-2-for-r/