vscode snippet - multiple regex transformation filepath+filename - regex

after 1 week of searching and try&error I'm creating this question in the hope of someone willing to help me out on this one:
My VsCode Snippet should transform the following:
D:\FolderX\FolderY\src\Folder1\Folder2\Folder3
into:
FOLDER1_FOLDER2_FOLDER3_FILENAMEBASE
Folder3 could be optional
what if come up so far is:
"body": [
"${TM_DIRECTORY/^.+(src\\\\)(.*)$/${2:/upcase}${3:/upcase}/g}_${TM_FILENAME_BASE/(.*)/${1:/upcase}/}",
],
and the result so far is:
FOLDER1\FODLER2\FOLDER3_FILENAMEBASE
so all I need to do now is change the \ to _ but I want that in one transformation if it's possible..
Anyone have an idea or better solution for my problem?
Thanks alot

You can use
"body": [
"${TM_DIRECTORY/^(?:.*\\\\)?src\\\\|([^\\\\]+)|(\\\\)/${1:/upcase}${2:+_}/g}_${TM_FILENAME_BASE/.+/${0:/upcase}/}",
],
Details:
^ - start of string
(?:.*\\\\)? - an optional sequence of any zero or more chars other than line break chars as many as possible and then
src\\\\ - src\ string
| - or
([^\\\\]+) - Group 2: one or more chars other than \
| - or
(\\\\) - Group 3: a \ char.
The ${1:/upcase}${2:+_} replacement means that Group 1 is always returned uppercased, and if Group 2 matches (a \ char), it is replaced with a _ char.
The ${TM_FILENAME_BASE/.+/${0:/upcase}/} is simplified as there is a $0 backreference to the whole match, no need to wrap the whole pattern with a capturing group.

This answer is not directly related to question, however, it is because of the answer from #Wiktor Stribiżew, that I managed to make my snippet work, after a couple of hours on this.
I am modifying the standard rfce snippet from dsznajder - ES7+ React/Redux/React-Native snippets.
I work with the following structure in my react dev:
src
|--components
|----NavBar
|------index.css
|------index.jsx
So, when creating the functional components, I need to create them with the actual name of the folder, and not the file name. Therefore, below is the full snippet, and I created this in the custom javascriptReact snippets:
{
"reactFunctionalExportComponent": {
"prefix": "rfce_",
"body": [
"import './index.css';",
"",
"function ${1:${TM_DIRECTORY/^(?:.*\\\\)/$1/g}}() {",
" return(",
" <div>",
" <h1>${1:${TM_DIRECTORY/^(?:.*\\\\)/$1/g}}</h1>",
" </div>",
" );",
"}",
"",
"export default ${1:${TM_DIRECTORY/^(?:.*\\\\)/$1/g}};",
""
],
"description": "Creates a React Functional Component with ES7 module system"
}
}
The result looks like this:
import "./index.css";
function NavBar() {
return (
<div>
<h1>NavBar</h1>
</div>
);
}
export default NavBar;
I have made similar changes for class components and also arrow functions.

Related

Regex function to look for a character just on part of the string

I need help to build a regex rule to find some [ on a text file.
Here is a sample of te text. It is a Json, but I can't use it as it is because of limitation of the program I'm using.
{
"event":[
"ONIMBOTMESSAGEADD"
],
"data[BOT][123][BOT_ID]":[
"123"
]
}
I need to find a regex that matches the line "data[BOT][123][BOT_ID]":[ and find all [ on it. The objectve is to replace it by an underscore so I would end up with something like this:
{
"event":[
"ONIMBOTMESSAGEADD"
],
"data_BOT_123_BOT_ID":[
"123"
]
}
I can't just remove all special characters because this would destroy the json structure.
I found a way to select each one of the lines that need to be corrected with the rule below, but I was not able to apply another rule over the result. I don't know how to do it.
pattern = (("data\[[a-zA-Z]+]\[[0-9]+]\[([a-zA-Z]+_[a-zA-Z]+)\]":\[)|("data\[[A-Z]+]\[([A-Z]+(_|)[A-Z]+)\]":\[)|("data\[[A-Z]+]\[([A-Z]+(_|)[A-Z]+(_|)[A-Z]+)\]":\[))
Any ideas on how to solve it? Thank you in advance.
Replacing weird data* key by only data:
jq '.["data"] = .[keys[0]] | del(.[keys[1]])' file
{
"event": [
"ONIMBOTMESSAGEADD"
],
"data": [
"123"
]
}

Visual Studio Snippet: Can I use TM_FILENAME to get a namespace from RELATIVE_FILEPATH?

I am toying with Visual Studio Snippets for a while now, and wonder if/how I can use TM_FILENAME to get a namespace from RELATIVE_FILEPATH. For example, I have:
RELATIVE_FILEPATH = src\model\RegisterModel.php
TM_FILENAME = RegisterModel.php
I want to strip the latter from the first, and the last \ as well, so I will end up with src\model
I can get it working if I use RegisterModel.php as a string, but not if I use TM_FILENAME as a variable. Is that even possible?
This is what works: ${RELATIVE_FILEPATH/(RegisterModel.php)//gi}
But I want something like this: ${RELATIVE_FILEPATH/(TM_FILENAME )//gi}
Thanks in advance!
This will get you what you want:
"filepath": {
"prefix": "rfp",
"body": [
"${RELATIVE_FILEPATH/(\\\\[^\\\\]*)$//i}", // with lots of escapes
],
"description": "directories of current file"
}
${RELATIVE_FILEPATH/${TM_FILENAME}//gi} will not work as according to the grammar only a regex can go into that ${TM_FILENAME} spot in the transform. See snippet grammar.
Relevant part of the grammar: transform ::= '/' regex '/' (format | text)+ '/' options
${RELATIVE_FILEPATH/[${TM_FILENAME}]//gi} results in:
src\od\Rgsrod.php because [${TM_FILENAME}] is treated as a regex (just a alternate list of those characters literally) and so each of those characters is removed from the RELATIVE_FILEPATH.
This is what I was trying to create. This snippet creates a php class template with the proper class name and namespace from the file name and location.
So, snippet
"php class": {
"prefix": "_pclass",
"body": "<?php\n\nnamespace app\\\\${RELATIVE_FILEPATH/(\\\\[^\\\\]*)$//i};\n\nclass $TM_FILENAME_BASE{\n\n\tpublic function __construct(){}\n\n\tpublic function $1($2){\n\n\t\t$3\n\t}\n}",
"description": "PHP class"
}
called in I:\xampp\htdocs\mvc2\src\core\form\Field.php creates
<?php
namespace app\src\core\form;
class Field{
public function __construct(){}
public function (){
}
}
with the cursor on the method name. Saves me quite a bit of time, hope it's just as helpful for others.

regex breaks when I use a colon(:)

I just started working with elastic search. By started working I mean I have to query an already running elastic database. Is there a good documentation of the regex they follow. I know about the one on their official site, but its not very helpful.
The more specific problem is that I want to query for lines of the sort:
10:02:37:623421|0098-TSOT {TRANSITION} {ID} {1619245525} {securityID} {} {fromStatus} {NOT_PRESENT} {toStatus} {WAITING}
or
01:01:36:832516|0058-CT {ADD} {0} {3137TTDR7} {23} {COM} {New} {0} {0} {52} {1}
and more of a similar structure. I don't want a generalized regex. If possible, could someone give me a regex expression for each of these that would run with elastic?
I noticed that it matches if the regexp matches with a substring too when I ran with:
query = {"query":
{"regexp":
{
"message": "[0-9]{2}"
}
},
"sort":
[
{"#timestamp":"asc"}
]
}
But it wont match anything if I use:
query = {"query":
{"regexp":
{
"message": "[0-9]{2}:.*"
}
},
"sort":
[
{"#timestamp":"asc"}
]
}
I want to write regex that are more specific and that are different for the two examples given near the top.
turns out my message is present in the tokenized form instead of the raw form, and : is one of the default delimiters of the tokenizer, in elastic. And as a reason, I can't use regexp query on the whole message because it matches it with each token individually.

How to get the module id from TM_FILEPATH in a vscode snippet?

Is there a way to convert the value of the TM_FILEPATH variable to a module id?
I would like to create a snippet that resolves the module id:
d:\myrepo\client\store\calc.ts => <amd-module name="store/calc" />
{
"prefix": "amd-module-name",
"body": [
"/// <amd-module name=\"${TM_FILEPATH/.*client\\\\(.*)\\..*$/$1/}\" />\n"
]
}
The snipped above gives me <amd-module name="store\calc" /> but how do I get rid of the back slash?
Try this:
"someName" : {
"prefix": "amd-module-name",
"body": [
"/// <amd-module name=\"${TM_DIRECTORY/(.*client[\\\\\\/])?([^\\/\\\\]*)([\\/\\\\])?/$2${3:+\/}/g}\/$TM_FILENAME_BASE\" />\n",
]
},
It is lengthy but fairly powerful (and all those necessary double-escapings!).
This will handle directories with \ or / path separators.
[\\\\\\/] means either a \ or a / (you just need 3 escaping backslashes before a \ in an vscode snippet and two before a /)!!
So [^\\/\\\\]* means get characters until you hit a slash.
This regex will work with any number of directories under "client". Thanks in part to the global regex modifier g .
d:\myrepo\client\store\subStore\calc.ts => <amd-module name="store/subStore/calc" />
This part is nice: $2${3:+\/} that means insert matching group 2 and only if there is a matching group 3 add a backslash /. This comes into play accounting for the last directory with the file in it and changing the captured group 3 \ to a / as you want.

Creating a specific Sublime Text's snippet, using Regular Expressions

Context
I have a process that envolves creating similar file/filename structures that have inside of it the name of itself, and things like that, i do this every day, and i see that is repetitive and have a pattern, then i got the idea of creating a Sublime Text's Snippet to generate the code for me, adding a significant improvement on my performance.
Example
There is a example of a complete "model" using the structure that i said:
Ext.define('App.model.geral.layouts.Layouts', {
extend: 'App.ux.model.base',
fields: [
{ name: 'Foo', type: 'string', fieldLabel: 'Foo' },
{ name: 'Bar', type: 'int', fieldLabel: 'Bar' },
{ name: 'FooTwo', type: 'boolean', fieldLabel: 'FooTwo' },
{ name: 'Date', type: 'date', fieldLabel: 'Date' },
],
proxy: Use.util.Model.getProxy({
controller: 'Layouts'
})
});
This is a simple and small sample of a file using mine structure. So that file, following the patterns will be placed at C:/Dev/Com/app/model/geral/layouts/Layouts.js, because models, are inside the folder model and geral is the module that the entity layouts belong to.
What i've tried
I tried various things and the most far i did go was that snippet file:
<snippet>
<content><![CDATA[
Ext.define('App.model.${TM_FILEPATH/.+(?:model\/)(.+)\.\w+/\l$1/}', {
extend: '',
fields: [ ],
proxy: ''
});
]]></content>
<tabTrigger>mitem</tabTrigger>
</snippet>
When i trigger that snippet on a empty file named and located in: C:/Dev/Com/app/model/geral/layouts/Layouts.js (as the pattern), it results:
Ext.define('App.model.geral/layouts/Layouts', {
extend: '',
fields: [ ],
proxy: ''
});
As you can see, i got 'App.model.geral/layouts/Layouts' instead of 'App.model.geral.layouts.Layouts' that is what i want. I am close to the final result that i want, as you can see on the complete model example, by the way i cannot go far than that, i dont have any knowledge of RegExp what i did was only researching and trying different things.
If helpful, there is a more complete info about Sublime Snippets that i found is:
$PARAM1 .. $PARAMn Arguments passed to the insert_snippet command. (Not covered here.)
$SELECTION The text that was selected when the snippet was triggered.
$TM_CURRENT_LINE Content of the cursor’s line when the snippet was triggered.
$TM_CURRENT_WORD Word under the cursor when the snippet was triggered.
$TM_FILENAME Name of the file being edited, including extension.
$TM_FILEPATH Path to the file being edited.
$TM_FULLNAME User’s user name.
$TM_LINE_INDEX Column where the snippet is being inserted, 0 based.
$TM_LINE_NUMBER Row where the snippet is being inserted, 1 based.
$TM_SELECTED_TEXT An alias for $SELECTION.
$TM_SOFT_TABS YES if translate_tabs_to_spaces is true, otherwise NO.
$TM_TAB_SIZE Spaces per-tab (controlled by the tab_size option).
I used that info to get the filepath, i tried using another variables like filename but did not get that far.
That will be very useful if someone can help me to get to the final result.
You can achieve what you want with the following:
<snippet>
<content><![CDATA[
Ext.define('App.model.${TM_FILEPATH/(^.+\/model\/)|(\w+)|(\.\w+$)|(\/)/(?2$2)(?4.)/g}', {
extend: '',
fields: [ ],
proxy: ''
});
]]></content>
<tabTrigger>mitem</tabTrigger>
</snippet>
Btw, I highly recommend installing the PackageDev package if you haven't already, to get some syntax highlighting on the snippet and regular expression/replacement.
How it works:
Match:
(^.+\/model\/) match from the beginning of the file path up to and including /model/, and store in capture group 1
| or
(\w+) match any sequence of word characters and store in capture group 2
| or
(\.\w+$) match the file extension and store in capture group 3
| or
(\/) match a / and store in capture group 4
Replacement:
(?2$2) if capture group 2 participated in the match, replace it with itself - i.e. keep it
(?4.) if capture group 4 participated in the match, replace it with a dot
Flags:
g global modifier to match as many times as possible
Arguably you don't need the capture groups 1 and 3, but I included them to make it easier to tell what is being matched.