Condense all my snippets into one file in Sublime Text 3 - sublimetext2

I have a multitude of snippets for each tag in the language I am currently programming in. I want to share these with some of my co-workers but I don't want to send them like 30 snippet files. Is there a way to condense these into one file (apart from zipping them, sending the zip and then having them unzip it).

You can use a .sublime-completions file. These are JSON-formatted files that contain the target scope at the top, then a series of completions with a trigger and contents. For example, the following snippet
<snippet>
<content><![CDATA[function ${1:function_name} (${2:argument}) {
${0:// body...}
}]]></content>
<tabTrigger>fun</tabTrigger>
<scope>source.js</scope>
<description>Function</description>
</snippet>
can be turned into this completion:
{
"scope": "source.js",
"completions":
[
{ "trigger": "fun", "contents": "function ${1:function_name} (${2:argument}) {\n ${0:// body...}\n}" }
]
}
Use \n for newlines and \t for tab characters in the "contents" section. Double quotes need to be escaped as well. Also, you can use \t to separate the trigger from a brief description on what the completion is about, it will be displayed right-aligned and slightly grayed and does not affect the trigger itself:
{ "trigger": "fun\tFunction", "contents": "function ${1:function_name} (${2:argument}) {\n ${0:// body...}\n}" }
Since this is JSON, to add multiple completions just put a comma , after the closing curly brace } of the completion, and put your next one on the next line. The final line should not have a final comma.
Good luck!

Related

How to convert lines of text to JSON Lines?

If you have a text file with many lines of text, is there a readily available way to convert it into the JSON Lines format?
Example text file contains:
This is the first line.
This is the "second" line.
This is the \third/ line.
This is the {fourth} line;
Example JSON Lines (.jsonl) file:
{"text": "This is the first line."}
{"text": "This is the \"second\" line."}
{"text": "This is the \\third\/ line."}
{"text": "This is the {fourth} line;"}
I was hoping there is a simple way to sort of linearly transform it like this, while escaping the special characters for JSON. Are there online or (CLI) tools for the Mac that can do this?
A browser is the most handy way to access an interpreter nowadays. Here's a quick solution based on that:
Copy and paste your lines into this page: https://codebeautify.org/javascript-escape-unescape
Then copy the escaped string, press F12 on a modern broser and paste the following code:
console.log(JSON.stringify("***PASTE HERE**".split("\n").map(x => ({text: x}))))
Then delete ***PASTE HERE*** and paste the escaped lines. Press enter and you'll have a JSON output similar to what you want.

VScode - replace captured group with the values

i have a bunch of strings in code such as:
<td style="background-color:#fdfdff"> </td>
and
<td> </td>
in one file.
The goal is to replace from first example with 0, while from second example with - (dash)
I'm using VScode regex, but I can't find the way to replace captured groups with specific values, as $1, $2 groups refer to original string groups.
This one is just example, how I'm trying to achieve this, but VScode don't ignore grouped regex.
An alternative process is to use a snippet which can do conditional replacements. With this snippet:
"replaceTDs": {
"prefix": "tdr", // whatever prefix you want
"body": [
"${TM_SELECTED_TEXT/(?<=\">)( )|( )/${1:+0}${2:+-}/g}",
]
}
The conditional replacements can be quite simple since you first find and select only the two alternative texts you are interested in. So
find: <td\s*(style="[^"]*"\s*)> </td>|<td> </td> old version
This simpler find will probably work for you:
<td\s*(style="[^"]*")?\s*> </td>
Don't replace, rather Control+Shift+L : selects all your two alternatives. Esc to focus on editor from the find widget.
Then apply your snippet, in this case type tdr+Tab
and all the changes are made. You just have to make the snippet one time and then do a single find.
This technique scales a little better than running as many find/replaces as you have replacements to do. Even with more conditional replacements it would probably be a simple change to the one snippet to add more replacements.
Also you can simplify this even more if you use a keybinding to trigger your snippet (you don't have to change focus from the find widget - or create the separate snippet). So with no snippet, but this keybinding:
{
"key": "alt+w",
"command": "editor.action.insertSnippet",
"args": {
"snippet": "${TM_SELECTED_TEXT/(?<=\">)( )|( )/${1:+0}${2:+-}/g}"
},
"when": "editorHasSelection"
}
now the same demo:
You can use
Search for (?<=<td\s+style="[^"]*">) (?=</td>) and replace with 0, and
Search for <td> </td> and replace with <td>-</td>, no need for a regex here.
Note that capturing groups are meant to keep captured substrings.
The first pattern matches
(?<=<td\s+style="[^"]*">) - a place in string that is immediately preceded with <td, one or more whitespaces, style=", any zero or more chars other than " and then a >
- a literal string
(?=</td>) - immediately to the right, there must be </td>.

How to match within two lines in JSON using REGEX?

So the JSON is like:
"foo": {
"points": 23.67
},
I'd like a regex to just match 23.67.
I've tried \"foo\":{\"points\":([^}"]*) but it doesn't work.
There are multiple lines which contain "points": so just \"points\":([^}"]*) won't work.
You are ignoring whitespace.
Try this instead:
\"foo\":\s*{\s*\"points\":\s*(\d+(?:\.\d+)?)\s*}
Demo
Your solution does not take into account a few details:
Between "foo": and { there can be spaces.
After { there can be a newline and spaces.
After "points": there can also be spaces.
Between the string to capture (capturing group and "terminating" '}'
there can also be a newline and spaces.
So, including the above missed details, and taking into account that \s
matches also newline, the whole regex can be as follows:
\"foo\":\s*{\s*\"points\":\s*([^}"]*)\s*}
Actually, your capturing group can be "more restrictive".
As the text to capture contains only digits and a dot,
it can be written as: [\d\.]+.
Note that I changed * to +, because the content cannot be empty.

Extract and Create Property in JSON file with RegEx

I have the following JSON file. Dotted across the file is the following:
"properties": {
"Name": "Darlington",
"Description": "<br><br><br> <table border=\"1\" padding=\"0\"> <tr><td>CCGcode</td><td>00C</td></tr> <tr><td>CCGname_short</td><td>Darlington</td></tr>"
}
Using RegEx, I would like to extract the CCG Code property and add it back in so that the above becomes:
"properties": {
"Name": "Darlington",
"CCGcode": "00C",
"Description": "<br><br><br> <table border=\"1\" padding=\"0\"> <tr><td>CCGcode</td><td>00C</td></tr> <tr><td>CCGname_short</td><td>Darlington</td></tr>"
}
I've tried all sorts and I just can't get it to work. I am using Sublime Text.
^("Description":").*?<td>CCGcode<\/td><td>([^<>\n]*).*$
The above selects the code, but not sure how I can get it to create the property.
Try this
( *)"Description".*?CCGcode.*?<td>([^<]+)
Regex demo
This one for sublimetext3
Find what:
( *)("Description".*?CCGcode.*?<td>)([^<]+)
Replace with:
\1"CCGcode": "\3",\n\1\2
Demo
There's a very simpel, but not so elegant, solution. Replace
"Description":.*?<td>CCGcode<\/td><td>([A-Z\d]*)<\/td>
with
"CCGCode":"\1",\n \0
Don't know how Sublime handles replacements, but you may have to change the replacing \0 and \1 to something else - e.g. $0 and $1.
What it does is to find the Description entry and the following CCGCode entry, capturing the code into capture group 1.
Then replace capture group 0 - the whole matched text, with the new CCGCode JSON tag plus the original text.
It's a pretty fragile solution, but it works for your sample case.
Check out example at regex101.
Regards

Underscore Snippet

Note: I have Emmet installed onto Sublime Text 2
In my workflow I have a lot of projects were I have to put underscores in between every word in a sentence. Is there a snippet I could build in sublime text 2 to do this for me with a tab trigger of some selected text?
You can easily create a snippet with this functionality by using regular expression–based snippet substitutions. The only code you need is this:
<snippet>
<content><![CDATA[
${SELECTION/\s/_/g}
]]></content>
</snippet>
You can then select a sentence, run this snippet from the command palette, and all of the spaces within will be substituted with underscores. You might have to adjust the regex (currently just \s) depending on what amount of whitespace you want to replace.
You can always use Find and Replace. Highlight the text you want and hit Ctrl-H (or Command-H on Mac) to open the Find and Replace box. Click the right-hand button on the top row to choose In Selection, and maybe the bottom right-hand button for Highlight matches if you want. Type a space in the Find What: box, an underscore in the Replace With: box, and hit Ctrl-Alt-Enter to Replace All (or Ctrl-Shift-H to Replace one at a time).
To use a snippet, do the following. Select Tools -> New Snippet... and put the following in it:
<snippet>
<content><![CDATA[${SELECTION/\s/_/g}]]></content>
</snippet>
Save it as Packages/User/replace_space_with_underscore.sublime-snippet. Then, open Preferences -> Key Bindings - User and put in the following:
[
{ "keys": ["ctrl+shift+-"], "command": "insert_snippet", "args": { "name": "Packages/User/replace_space_with_underscore.sublime-snippet" } }
]
(If you already have custom key bindings, just put in { "keys": ["ctrl+shift+-"], "command": "insert_snippet", "args": { "name": "Packages/User/replace_space_with_underscore.sublime-snippet" } } at the end, and remember to put a , after the one just above it.)
Save both files, and now you can highlight whatever text you want, hit Ctrl-Shift--, and replace the whitespace with underscores. If you just want spaces (no tabs or newlines), replace the "\s" with "\" (backslash space). This regex will replace multiple spaces with the same number of underscores. It gets a bit more complicated if you only want exactly one space, or exactly one underscore, but it's doable.