keymap to replace letter in Sublime text 3 - replace

I am trying to make a keymap to replace some letter combination to fix certain special Latin characters. Example:
I am trying to make a Spanish ñ with gn:
{ "keys": ["gn"], "command": "insert_snippet", "args": {"contents": "\\\~n"} },
My expected result with this is:
agno ---> a~no ----> año
but it lamentably doesn't work.
Do you know how to fix it?

This binding doesn't work because the keys key is not valid; it needs to be either a key on the keyboard, a key with modifiers, or a list of consecutive keys (with or without modifiers). With the binding as you have it currently, if you check the Sublime console (View > Show Console) you'll see a message like this every time you save the file as an indication of this:
Unknown key gn
Unable to parse binding {args: {contents: \~n}, command: insert_snippet, keys: [gn]}
Assuming the the idea is that you want the snippet to insert when you press those two keys in sequence, you can do that by specifying both keys one after the other:
{
"keys": ["g", "n"],
"command": "insert_snippet",
"args": {"contents": "\\~n"}
},
Something to keep in mind is that a binding like this will trigger every time these two characters are typed—unless you manually wait a bit before you press the second key; for example, you can't spell ignominious without pausing between the g and the n to let Sublime realize you mean the two keys should be considered to be distinct instead.
As a side note, I assume this sequence of keys (\~n) is what you'd manually type in order to generate the ñ character. If so, I'm not sure if this will do what you want; it may just insert those three literal characters. If that's the case, you can replace them with the ñ character you want to be inserted instead.

Related

Remove columns by name based on pattern

How can I remove a large number of columns by name based on a pattern?
A data set exported from Jira has a ton of extra columns that I've no interest in. 400 Log entries, 50 Comments, dozens of links or attachments. Problem is that they get random numbers assigned which means that removing them with hardcoded column names will not work. That would look like this and break as the numbers change:
= Table.RemoveColumns(#"Previous Step",{"Watchers", "Watchers_10", "Watchers_11", "Watchers_12", "Watchers_13", "Watchers_14", "Watchers_15", "Watchers_16", "Watchers_17", "Watchers_18", "Watchers_19", "Watchers_20", "Watchers_21", "Watchers_22", "Watchers_23", "Watchers_24", "Watchers_25", "Watchers_26", "Watchers_27", "Watchers_28", "Log Work", "Log Work_29", "Log Work_30", "Log Work_31", "Log Work_32", ...
How can I remove a large number of columns by using a pattern in the name? i.e. remove all "Log Work" columns.
The best way I've found is to use List.FindText on Table.ColumnNames to get a list of column names dynamically based on target string:
= Table.RemoveColumns(#"Previous Step", List.FindText(Table.ColumnNames(#"Previous Step"), "Log Work")
This works by first grabbing the full list of Column Names and keeping only the ones that match the search string. That's then sent to RemoveColumns as normal.
Limitation appears to be that FindText doesn't offer complex pattern matching.
Of course, when you want to remove a lot of different patterns, having individual steps isn't very interesting. A way to combine this is to use List.Combine to join the resulting column names together.
That becomes:
= Table.RemoveColumns(L, List.Combine({ List.FindText(Table.ColumnNames(L), "Watchers_"), List.FindText(Table.ColumnNames(L), "Log Work"), List.FindText(Table.ColumnNames(L), "Comment"), List.FindText(Table.ColumnNames(L), "issue link"), List.FindText(Table.ColumnNames(L), "Attachment")} ))
SO what's actually written there is:
Table.RemoveColumns(PreviousStep, List.Combine({ foundList1, foundlist2, ... }))
Note the { } that signifies a list! You need to use this as List.Combine only accepts a single argument which is itself already a List of lists. And the Combine call is required here.
Also note the L here instead of #"Previous Step". That's used to make the entire thing more readable. Achieved by inserting a step named "L" that just has = #"Promoted Headers".
This allows relatively maintainable removal of multiple columns by name, but it's far from perfect.

How to extract a column based on it's content in PowerBI

I have a column in my table which looks like below.
ResourceIdentifier
------------------
arn:aws:ec2:us-east-1:7XXXXXX1:instance/i-09TYTYTY79716
arn:aws:glue:us-east-1:5XXXXXX85:devEndpoint/etl-endpoint
i-075656565f7fea3
i-02c3434343f22
qa-271111145-us-east-1-raw
prod-95756565631-us-east-1-raw
prod-957454551631-us-east-1-isin-repository
i-02XXXXXXf0
I want a new column called 'Trimmed Resource Identifier' which looks at ResourceIdentifier and if the value starts with "arn", then returns value after last "/", else returns the whole string.
For eg.
arn:aws:ec2:us-east-1:7XXXXXX1:instance/i-09TYTYTY79716  ---> i-09TYTYTY797168
i-02XXXXXXf0 --> i-02XXXXXXf0
How do I do this ? I tried creating a new column called "first 3 letters" by extracting first 3 letters of the ResourceIdentifier column but I am getting stuck at the step of adding conditional column. Please see the image below.
Is there a way I can do all of this in one step using DAX instead of creating a new intermediate column ?
Many Thanks
The GUI is too simple to do exactly what you want but go ahead and use it to create the next step, which we can then modify to work properly.
Filling out the GUI like this
will produce a line of code that looks like this (turn on the Formula Bar under the View tab in the query editor if you don't see this formula).
= Table.AddColumn(#"Name of Previous Step Here", "Custom",
each if Text.StartsWith([ResourceIdentifier], "arn") then "output" else [ResourceIdentifier])
The first three letters bit is already handled with the operator I chose, so all that remains is to change the "output" placeholder to what we actually want. There's a handy Text.AfterDelimiter function we can use for this.
Text.AfterDelimiter([ResourceIdentifier], "/", {0, RelativePosition.FromEnd})
This tells it to take the text after the first / (starting from the end). Replace "output" with this expression and you should be good to go.

Parsing a name from a complex string in Tableau

I have a series of values in Tableau that are long strings intermixed with letters and numbers. I am unable to control the data output, but would like to parse the names from these strings. They follow the following format:
Potato 1TByte 4.5 NFA
Board 256GByte 553 NCA
Launch 4 512GByte 4.5 NFA
Launch 4S 512GByte 4.5 NCA
From each of these, I am attempting to capture the following:
"Potato"
"Board"
"Launch 4"
"Launch 4S"
Each string follows the same format: the name, followed by size, followed by some extra information we don't really care about.
I've tried to put together some text parsing strings, but am coming up short, and am still trying to learn regular expressions.
The Tableau calculated field I was trying to work with was something like the following:
LEFT([String], FIND([String], "Byte") - 2)
The issue is that the text and numbers preceding Byte can be anywhere from 4 to 2 characters and I need a way to identify the length of that.
Any help would be greatly appreciated!
One option which uses a regex replacement:
REGEXP_REPLACE('Launch 4 512GByte 4.5 NFA', ' \d+[A-Z]Byte .*$', '')
This strips off everything from the Byte term to the right, leaving us with only the product name.
You could try the following - this seems to work - Screenshot of Tableau output. Find below the formulas for the various derived columns you see in the screenshot (Your source column is called [Name])
Step1 = LEFT([Name],FIND([Name],"Byte")-1)
Step2 = LEN([Step1])-LEN(REPLACE([Step1]," ",""))
Step3 = FINDNTH([Step1]," ",[Step2])
Step4 = LEFT([Step1],[Step3]-1)
And of course you can nest all these in a single calculated field - kept them as separate columns for easier understanding

VS Code: How to convert snippet placeholder from camelCase to SCREAMING_SNAKE_CASE?

I'd like to create a VS Code snippet for creating redux reducers.
I would like to have a snippet with placeholder that expects camelCase and then transform a matching placeholder to SCREAMING_SNAKE_CASE.
Here's my attempted snippet, which is not working:
"test": {
"prefix": "test",
"body": "${1} -> ${1/([a-zA-Z])(?=[A-Z])/${1:/upcase}_/g}"
},
Which produces a non-desired result:
changeNetworkStatus -> changE_NetworK_Status
Desired Flow
type test (name of snippet)
hit tab to load the snippet.
type changeNetworkStatus to result in:
changeNetworkStatus -> changeNetworkStatus
hit tab to get expected result of:
changeNetworkStatus -> CHANGE_NETWORK_STATUS
How can I change my snippet code to get the desired result?
Here's a related solution which requires a different flow.
If you are starting with a non-camelCase input and want to get to SCREAMING_SNAKE_CASE, see https://stackoverflow.com/a/67008397/836330. The method there can handle input with spaces and hyphens.
Update: Keybinding version:
VScode is adding the editor.action.transformToSnakecase in v1.53 so the requested operation can be done easier without having to figure out the neccessary regex to make it work as shown in the previous answer. And because some people might find this question looking for snake case (snake-case) information.
What I show now is NOT a snippet however. You just type your text and then trigger the keybinding. The keybinding itself fires a macro extension command from the multi-command extension. In keybindings.json:
{
"key": "alt+3", // whatever keybinding you wish
"command": "extension.multiCommand.execute",
"args": {
"sequence": [
"cursorWordLeftSelect", // select word you just typed
"editor.action.transformToSnakecase",
"editor.action.transformToUppercase",
// "cursorLineEnd" // if you want this
]
},
"when": "editorTextFocus && !editorHasSelection"
},
Demo of keybinding version:
Snippet version:
"camelCaseModify": {
"prefix": "test",
"body": [
// first inefficient try, works for up to three words
// "${1} -> ${1/^([a-z]*)([A-Z])([a-z]+)*([A-Z])*([a-z]+)*/${1:/upcase}_$2${3:/upcase}${4:+_}$4${5:/upcase}/g}"
"${1} -> ${1/([a-z]*)(([A-Z])+([a-z]+))?/${1:/upcase}${2:+_}$3${4:/upcase}/g}",
// here is an especially gnarly version to handle edge cases like 'thisISABCTest' and trailing _'s
"${1} -> ${1/([a-z]+)(?=[A-Z])|([A-Z])(?=[A-Z])|([A-Z][a-z]+)(?=$)|([A-Z][a-z]+)|([a-z]+)(?=$)/${1:/upcase}${1:+_}$2${2:+_}${3:/upcase}${4:/upcase}${4:+_}${5:/upcase}/g}"
],
"description": "underscore separators"
},
This works with any number of camelCase words, from one to infinity...
The ${2:+_} means "if there is a capture group 2 then append an underscore." If there isn't a second word/capture group then groups 3 and 4 will be empty anyway because they are within capture group 2. Capture Group 2 is always the next Word (that starts with one capital and followed by at least one small letter).
for example, using changeNetworkStatus:
Match 1
Full match 0-13 `changeNetwork`
Group 1. 0-6 `change`
Group 2. 6-13 `Network`
Group 3. 6-7 `N`
Group 4. 7-13 `etwork`
Match 2
Full match 13-19 `Status`
Group 1. 13-13 ``
Group 2. 13-19 `Status`
Group 3. 13-14 `S`
Group 4. 14-19 `tatus`
Match 3
Full match 19-19 ``
Group 1. 19-19 ``
Sample Output:
abcd -> ABCD
twoFish -> TWO_FISH
threeFishMore -> THREE_FISH_MORE
fourFishOneMore -> FOUR_FISH_ONE_MORE
fiveFishTwoMoreFish -> FIVE_FISH_TWO_MORE_FISH
sixFishEelsSnakesDogsCatsMiceRatsClocksRocks -> SIX_FISH_EELS_SNAKES_DOGS_CATS_MICE_RATS_CLOCKS_ROCKS
Using regex101.com really helps to visualize what is going on!

Search while selection enabled in macro VS2015

On VAX/VMS (or OpenVMS Alpha and its other names) there was an editor called TPU. In TPU you could enable selection of text independently of holding a key down. You pressed SELECT and then any cursor movement you made selected text between the editing point and the new cursor location.
You could also record macros. So you could use this text selection feature to create macros like:
find "abc"
select
find "xyz"
cut
stop recording
So this macro would find any line with "abc" in it and then cut all text between "abc" and "xyz". Massive time saver.
Making sense? How can I do that in VS2015? I can't find a macro extension that provides the selection behaviour I need to do this.
Cheers,
.pd.
EDIT
It occurred to me this could be done with a regex but it seems like a pretty big ask.
#Html.DropDownListFor(m => m.Property, Model.SelectListProperty, htmlAttributes: new { #class="whatever" })
// the regex would replace this with
#Html.MyDropDownListFor(m => m.Property, Model.SelectListProperty, Model.Property, htmlAttributes: new { #class="whatever"})
So I would be looking for a regex to
- find #Html.DropDownList
- replace the token 1 of that line split by ',' with token 1 of token 0 split by '.' and prefixed with "Model."
Assuming Model.Property comes from m => m.Property.
Search for
#Html\.DropDownListFor\(((\w+)\s*=>\s*\2\.(\w+)),\s*(Model\.\w+)(,(?:[^(){}]|\{[^{}]*\})*)?\)
Replace with
#Html.MyDropDownListFor($1, $4, Model.$3$5)
Demo: http://regexr.com/3f3io