How do you fold code by indentation in sublime 3? - editor

In atom, the below is what you use to fold code by indent levels, but how do you do this in sublime?
Ctrl+k, then Ctrl+1 ... 9 Fold all code at indent level 1 ..

Same:
Ctrl + K, Ctrl + 1 to fold all code on indent 1.
To unfold all Ctrl + K, Ctrl + J.
Same procedure all the way to indent 9 (Ctrl + K, Ctrl + <number>). You can also fold by clicking on the side line number arrow:

CMD/CTRL + K, CMD/CTRL + <number>
for example, on MacOS, to fold to indent-level-1: CMD+K, CMD+1
Using menus: On MacOS: Edit > Code Folding > <level>

Sometimes code folding doesn't seem to work in Sublime3 especially if you've installed some package which have conflicts. You can try via the menu on MacOS: Edit > Code Folding > <level> to override or create your own key bindings via Sublime Text 3 -> Preferences -> Key Bindings and add something like the below. I've tried to replicate some of the key bindings from Intellij in the below settings, you can configure them as per your liking.
[{ "keys": ["super+shift+minus"], "command": "fold" },
{ "keys": ["super+shift+plus"], "command": "unfold" },
{ "keys": ["super+shift+1"], "command": "fold_by_level", "args": {"level": 1} },
{ "keys": ["super+shift+2"], "command": "fold_by_level", "args": {"level": 2} },
{ "keys": ["super+shift+3"], "command": "fold_by_level", "args": {"level": 3} },
{ "keys": ["super+shift+4"], "command": "fold_by_level", "args": {"level": 4} },
{ "keys": ["super+shift+5"], "command": "fold_by_level", "args": {"level": 5} },
{ "keys": ["super+shift+6"], "command": "fold_by_level", "args": {"level": 6} },
{ "keys": ["super+shift+7"], "command": "fold_by_level", "args": {"level": 7} },
{ "keys": ["super+shift+8"], "command": "fold_by_level", "args": {"level": 8} },
{ "keys": ["super+shift+9"], "command": "fold_by_level", "args": {"level": 9} },
{ "keys": ["super+shift+0"], "command": "unfold_all" },
{ "keys": ["super+shift+j"], "command": "unfold_all" },
{ "keys": ["super+shift+t"], "command": "fold_tag_attributes" },
]

Related

Electron build error: file not found in artifact

this is my first time building an electron app and I am getting confused about this error I got in my production package.
I've created my app using the electron-react-boilerplate, and I am running the package build with the default config.
"build": {
"productName": "App",
"appId": "org.erb.ElectronReact",
"asar": true,
"asarUnpack": "**\\*.{node,dll}",
"files": [
"dist",
"node_modules",
"package.json"
],
"afterSign": ".erb/scripts/notarize.js",
"mac": {
"target": {
"target": "default",
"arch": [
"arm64",
"x64"
]
},
"type": "distribution",
"hardenedRuntime": true,
"entitlements": "assets/entitlements.mac.plist",
"entitlementsInherit": "assets/entitlements.mac.plist",
"gatekeeperAssess": false
},
"dmg": {
"contents": [
{
"x": 130,
"y": 220
},
{
"x": 410,
"y": 220,
"type": "link",
"path": "/Applications"
}
]
},
"win": {
"target": [
"nsis"
]
},
"linux": {
"target": [
"AppImage"
],
"category": "Development"
},
"directories": {
"app": "release/app",
"buildResources": "assets",
"output": "release/build"
},
"extraResources": [
"./assets/**"
]
},
My preload.js file is requiring a module (module.umd.js) that is reading from three .trie files, so my folder structure looks like this:
Once builded, the app is not working and I see this error on the web console inspector:
Error: ENOENT, dist\main\data.trie not found in C:\Users\ivan\Desktop\app-electron\release\build\win-unpacked\resources\app.asar
So my question is: Do I have to somehow add those .trie files in app.asar in order to solve this problem?

cypher query to generate special path

I have a graph like this
O
|
A
|
B
/ \
C E
/ \
D F
I want to find the path from O to F. node F can contain an attribute call "non-direct". If this attribute is set false, then the path is
O-A-B-E-F
However, if it is set to true, the path is
O-A-B-C-D-C-B-E-F
I.e., the path first has to reach B which is a terminal node and then go back to the common parent between D and F, then walk to F.
How can I create a query to return these two path based on the attribute value?
Since Neo4j will not traverse back over the same relationship, you may need to create relationships in both direction on the branches. So something like this:
In addition, I would add some properties that indicate the toplogy, so for instance add a property on-branch for the nodes C and D.
Then you can run queries like this:
MATCH (f:Thing {name:'F'}), (o:Thing {name:'O'}), (d:Thing {name:'D'})
MATCH p = (o)-[:NEXT*]->(f)
WHERE ANY(node IN nodes(p) WHERE node.`on-branch`) = f.`non-direct`
AND (d IN nodes(p)) = f.`non-direct`
RETURN REDUCE(s='', node IN nodes(p) | s+ ' '+ node.name) AS nodes
The graph I tried this on can be created from this json:
{
"nodes": [
{
"id": 0,
"labels": [
"Thing"
],
"properties": {
"name": "O",
"on-branch": false
}
},
{
"id": 1,
"labels": [
"Thing"
],
"properties": {
"name": "A",
"on-branch": false
}
},
{
"id": 2,
"labels": [
"Thing"
],
"properties": {
"name": "B",
"on-branch": false
}
},
{
"id": 3,
"labels": [
"Thing"
],
"properties": {
"name": "C",
"on-branch": true
}
},
{
"id": 4,
"labels": [
"Thing"
],
"properties": {
"name": "D",
"on-branch": true
}
},
{
"id": 5,
"labels": [
"Thing"
],
"properties": {
"name": "E",
"on-branch": false
}
},
{
"id": 6,
"labels": [
"Thing"
],
"properties": {
"name": "F",
"non-direct": false,
"on-branch": false
}
}
],
"relations": [
{
"id": 0,
"source": 0,
"target": 1,
"type": "NEXT",
"properties": {}
},
{
"id": 1,
"source": 1,
"target": 2,
"type": "NEXT",
"properties": {}
},
{
"id": 2,
"source": 3,
"target": 2,
"type": "NEXT",
"properties": {}
},
{
"id": 3,
"source": 2,
"target": 3,
"type": "NEXT",
"properties": {}
},
{
"id": 4,
"source": 4,
"target": 3,
"type": "NEXT",
"properties": {}
},
{
"id": 5,
"source": 3,
"target": 4,
"type": "NEXT",
"properties": {}
},
{
"id": 6,
"source": 2,
"target": 5,
"type": "NEXT",
"properties": {}
},
{
"id": 7,
"source": 5,
"target": 6,
"type": "NEXT",
"properties": {}
}
]
}
The json above can be loaded with this cypher (in Neo4j with apoc):
CALL apoc.load.json([ url to the json]) YIELD value AS v
UNWIND v.nodes AS node
CALL apoc.merge.node(
node.labels,
{ _tempID : node.id},
node.properties,
{}
) YIELD node AS n
WITH DISTINCT v
UNWIND v.relations AS rel
MATCH (from {_tempID: rel.source})
MATCH (to {_tempID: rel.target})
CALL apoc.merge.relationship(
from,
rel.type,
{},
rel.properties,
to,
{}
) YIELD rel AS r
WITH DISTINCT v
MATCH (n) WHERE EXISTS(n._tempID)
REMOVE n._tempID

Twilio IVR Speech Recognition

I'm new to developing IVR with twilio studio so I started with the basic template and even that's not working.
This is the log:
LOG
Split Based On...
DETAIL
Input evaluated to 'Sales.' from '{{widgets.gather_input.SpeechResult}}'
Transitioning to 'say_play_1' because 'Sales.' did not match any expression
The split is set to "Equal to" sales which then connects the call to a number. It's obviously recognizing the correct speech input but still not working. Any ideas?
{
"description": "IVR",
"states": [
{
"name": "Trigger",
"type": "trigger",
"transitions": [
{
"event": "incomingMessage"
},
{
"next": "gather_input",
"event": "incomingCall"
},
{
"event": "incomingRequest"
}
],
"properties": {
"offset": {
"x": 250,
"y": 50
}
}
},
{
"name": "gather_input",
"type": "gather-input-on-call",
"transitions": [
{
"next": "split_key_press",
"event": "keypress"
},
{
"next": "split_speech_result",
"event": "speech"
},
{
"event": "timeout"
}
],
"properties": {
"voice": "alice",
"speech_timeout": "auto",
"offset": {
"x": 290,
"y": 250
},
"loop": 1,
"hints": "support,sales",
"finish_on_key": "",
"say": "Hello, how can we direct your call? Press 1 for sales, or say sales. To reach support, press 2 or say support.",
"language": "en",
"stop_gather": false,
"gather_language": "en-US",
"profanity_filter": "false",
"timeout": 5
}
},
{
"name": "split_key_press",
"type": "split-based-on",
"transitions": [
{
"event": "noMatch"
},
{
"next": "connect_call_to_sales",
"event": "match",
"conditions": [
{
"friendly_name": "1",
"arguments": [
"{{widgets.gather_input.Digits}}"
],
"type": "equal_to",
"value": "1"
}
]
},
{
"next": "connect_call_to_support",
"event": "match",
"conditions": [
{
"friendly_name": "2",
"arguments": [
"{{widgets.gather_input.Digits}}"
],
"type": "equal_to",
"value": "2"
}
]
}
],
"properties": {
"input": "{{widgets.gather_input.Digits}}",
"offset": {
"x": 100,
"y": 510
}
}
},
{
"name": "split_speech_result",
"type": "split-based-on",
"transitions": [
{
"next": "say_play_1",
"event": "noMatch"
},
{
"next": "connect_call_to_sales",
"event": "match",
"conditions": [
{
"friendly_name": "sales",
"arguments": [
"{{widgets.gather_input.SpeechResult}}"
],
"type": "equal_to",
"value": "sales"
}
]
},
{
"next": "connect_call_to_support",
"event": "match",
"conditions": [
{
"friendly_name": "support",
"arguments": [
"{{widgets.gather_input.SpeechResult}}"
],
"type": "equal_to",
"value": "support"
}
]
}
],
"properties": {
"input": "{{widgets.gather_input.SpeechResult}}",
"offset": {
"x": 510,
"y": 510
}
}
},
{
"name": "connect_call_to_sales",
"type": "connect-call-to",
"transitions": [
{
"event": "callCompleted"
}
],
"properties": {
"offset": {
"x": 100,
"y": 750
},
"caller_id": "{{contact.channel.address}}",
"noun": "number",
"to": "12222222",
"timeout": 30
}
},
{
"name": "connect_call_to_support",
"type": "connect-call-to",
"transitions": [
{
"event": "callCompleted"
}
],
"properties": {
"offset": {
"x": 520,
"y": 750
},
"caller_id": "{{contact.channel.address}}",
"noun": "number",
"to": "12222222",
"timeout": 30
}
},
{
"name": "say_play_1",
"type": "say-play",
"transitions": [
{
"next": "gather_input",
"event": "audioComplete"
}
],
"properties": {
"offset": {
"x": 710,
"y": 200
},
"loop": 1,
"say": "not valid choice."
}
}
],
"initial_state": "Trigger",
"flags": {
"allow_concurrent_calls": true
}
}
Twilio developer evangelist here.
That is weird behaviour, mainly because the log says "evaluated to 'Sales.'". Split widgets conditions are not case-sensitive and should trim leading and following white-space. For some reason this appears to have a capital "S" and a full-stop.
I would suggest a couple of things. Firstly, raise a ticket with Twilio support to look into why the condition didn't match correctly.
Then, try some of the other conditions. When I generate a new IVR template in Studio, the conditions use "Matches any of" instead of "Equal to". You might also try "Contains".
So, experiment with the ways you can match the operators, but get support involved to drill down into why it didn't work in the first place.
The period is needed after the word for some reason...I just put both, for example:
"1, 1., Uno, Uno., Una, Una., Uno, Uno., Español, Español., Español, Español., Español, Español."

How to Select multiple work items programmatically in Azure devops?

I am writing a Task Creator extension for ADO where we can create multiple tasks for multiple WITs.
Currently, I have a working extension where it allows to create multiple tasks on a single PBI.
This is how my manifest file looks
{
"manifestVersion": 1,
"id": "taskcreatortest",
"version": "1.0.24",
"name": "TaskCreator",
"description": "Create bulk tasks for a Work Item",
"publisher": "ZankhanaRana",
"galleryFlags": [
"Preview"
],
"icons": {
"default": "static/images/logo.png"
},
"scopes": [
"vso.work_write",
"vso.work",
"vso.code"
],
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"screenshots": [
{
"path": "static/images/menu.png"
},
{
"path": "static/images/createtaskform.png"
}
],
"demands": [
"api-version/3.0"
],
"tags": [
"TFS/VSTS Task Creator","Task"
],
"content": {
"details": {
"path": "overview.md"
},
"license": {
"path": "license.md"
}
},
"links": {
"getstarted": {
"uri": "https://bit.ly"
},
"support": {
"uri": "https://bit.ly"
},
"issues": {
"uri": "https://bit.ly"
}
},
"repository": {
"type": "git",
"uri": "https://bit.ly"
},
"branding": {
"color": "rgb(220, 235, 252)",
"theme": "light"
},
"files": [ ... ],
"categories": [
"Azure Test Plans"
],
"contributions": [
{
"id": "createtasks-context-menu",
"type": "ms.vss-web.action",
"description": "Toolbar item to create tasks for a work item",
"targets":[
"ms.vss-work-web.work-item-context-menu",
"ms.vss-work-web.work-item-toolbar-menu"
],
"properties": {
"uri": "static/index.html",
"text": "Create Tasks",
"title": "Create multiple tasks for a work item",
"toolbarText": "Create Tasks",
"groupId":"core"
}
},
{
"id": "createTasks-Form",
"type": "ms.vss-web.control",
"description": "Select task to create",
"targets": [ ],
"properties": {
"uri": "static/createTaskForm.html"
}
}
]
}
I am unable to select multiple work items, right-click and Create tasks.
An alert message 'Select only one item' pops up.
There are other custom extensions I installed, for example, Work Item Visualization by Microsoft Devlabs which allows multiple item selection. I think it has something to do with my configuration/manifest file.
Can someone point at what am I doing wrong?
I found the solution to this problem. Initially, I thought it has something to do with the extension configuration file (vss-extension.json); but I had a code in my script which checked for the number of items selected and if the number of items is greater than 1, it returned the alert box.
I changed that condition and everything run fine.
VSS.ready(function () {
VSS.register(VSS.getContribution().id, function (context) {
return {
execute: function (actionContext) {
if (actionContext.workItemDirty)
showDialog("Please save your work item first");
else if (actionContext.workItemIds && actionContext.workItemIds.length > 1)
showDialog("Select only one work item");
else {
var workItemType = getWorkItemType(actionContext)
if ($.inArray(workItemType, allowedWorkItemTypes) >= 0)
showPropertiesInDialog(actionContext, "Create Tasks");
else
showDialog("Not available for " + workItemType);
}
}
};
});
VSS.notifyLoadSucceeded();
});

How may I wrap a word in sublime text 3 with a $ sign

I am using latex on Sublime text 3; I would like to put $ sign in a wrap way around the highlighted text. For example, I have a character say
X_{d}
I would like it to do a keyboard shortcut that prints a $ sign before it and after it. How may I do so when I press on alt-shift-w I get
<p>X_{d}</p>
Is there a way to get $?
like $X_{d}$ rather than <p>
You can achieve this by adding the following to your User keybindings:
{ "keys": ["alt+shift+w"], "command": "insert_snippet", "args": { "contents": "\\$${1:$SELECTION}\\$" },
"context": [
{ "key": "selector", "operator": "equal", "operand": "text.tex" },
]
},
To make it reversible, you'll need to write a Python plugin, as the functionality isn't built in to ST:
Tools menu -> Developer -> New Plugin...
Select all and replace with the following
import sublime
import sublime_plugin
import re
class TextAroundSelectionEventListener(sublime_plugin.EventListener):
def on_query_context(self, view, key, operator, operand, match_all):
if key not in ('text_preceding_selection', 'text_following_selection'):
return None
match = False
for sel in view.sel():
line = view.line(sel)
before_sel = sublime.Region(line.begin(), sel.begin())
after_sel = sublime.Region(sel.end(), line.end())
check_region = before_sel if key == 'text_preceding_selection' else after_sel
if operator in (sublime.OP_EQUAL, sublime.OP_NOT_EQUAL):
match = view.substr(check_region) == operand
if operator == sublime.OP_NOT_EQUAL:
match = not match
else:
if operator in (sublime.OP_REGEX_MATCH, sublime.OP_NOT_REGEX_MATCH):
operand += r'$'
method = re.match if operator in (sublime.OP_REGEX_MATCH, sublime.OP_NOT_REGEX_MATCH) else re.search
try:
match = bool(method(operand, view.substr(check_region)))
except re.error as e:
print('error in keybinding context operand "' + str(operand) + '" for key "' + key + '":', e)
return None
if operator in (sublime.OP_NOT_REGEX_MATCH, sublime.OP_NOT_REGEX_CONTAINS):
match = not match
if match != match_all:
return match
return match
class TrimCharsAroundSelection(sublime_plugin.TextCommand):
def run(self, edit, **kwargs):
chars_to_trim = kwargs.get('chars_to_trim', 1)
for sel in reversed(self.view.sel()):
self.view.replace(edit, sublime.Region(sel.end(), sel.end() + chars_to_trim), '')
self.view.replace(edit, sublime.Region(sel.begin() - chars_to_trim, sel.begin()), '')
Save in the folder ST suggests (Packages/User/) as text_around_sel.py
Then, use the following keybindings:
{ "keys": ["alt+shift+w"], "command": "insert_snippet", "args": { "contents": "\\$${1:$SELECTION}\\$" },
"context": [
{ "key": "selector", "operator": "equal", "operand": "text.tex" },
{ "key": "text_preceding_selection", "operator": "not_regex_contains", "operand": "\\$$" },
{ "key": "text_following_selection", "operator": "not_regex_contains", "operand": "^\\$" },
]
},
{ "keys": ["alt+shift+w"], "command": "trim_chars_around_selection", "args": { "chars_to_trim": 1 },
"context": [
{ "key": "selector", "operator": "equal", "operand": "text.tex" },
{ "key": "text_preceding_selection", "operator": "regex_contains", "operand": "\\$$" },
{ "key": "text_following_selection", "operator": "regex_contains", "operand": "^\\$" },
]
},
Explanation and reasoning:
The preceding_text and following_text contexts that are built in to ST always include the selected text, no matter where the text selection caret is, making it no use for detecting text around/outside the selection.
(If the selection included the dollars at either end, it would be possible without creating any new context listeners, by using the text key, and ^ and $ anchors.)
Therefore, we need to write our own contexts that will correctly ignore the selection. Unfortunately, limitations in Sublime's (Find) API mean that we have to use Python's re module to do this, which is a much less powerful regex engine - though for the purposes of this question, it doesn't matter. (Probably there is a "hacky" way round it if needed, by copying the relevant contents of the line into a temporary hidden view (i.e. output panel) and using Sublime's find API on that to ensure the anchors work as expected etc., but that is out of scope for this task.)
The trim_chars_around_selection command then goes through all selections in reverse order (so the selection offsets from the beginning of the document don't change while the document is being modified by the plugin) and removes the specified number of characters from either end of the selection.
The code given by #Keith Hall could be further generalize to cut any and add any value. I will point this out here.
Suppose you want to wrap a latex file with a certain R and T that is by pressing on a combination of characters the selected string say Tamer would be RTamerT and when press on the key bindings once again it becomes Tamer.
{ "keys": ["alt+shift+q"], "command": "insert_snippet", "args": { "contents": "R${1:$SELECTION}T", "scope": "text.tex.latex"},
"context": [
{ "key": "selector", "operator": "equal", "operand": "text.tex" },
{ "key": "text_preceding_selection", "operator": "not_regex_contains", "operand": "R" },
{ "key": "text_following_selection", "operator": "not_regex_contains", "operand": "^T" },
]
},
{ "keys": ["alt+shift+q"], "command": "trim_chars_around_selection", "args": { "chars_to_trim": 1, "scope": "text.tex.latex" },
"context": [
{ "key": "selector", "operator": "equal", "operand": "text.tex" },
{ "key": "text_preceding_selection", "operator": "regex_contains", "operand": "R" },
{ "key": "text_following_selection", "operator": "regex_contains", "operand": "^T" },
]
},
I thought of sharing as I wanted to find a new kind of wrap that generalizes the code of Keith but do not know how to do the coding in sublime text. Trial and error have help me to find my way and thought of sharing it with you

Resources