SublimeText completion using .sublime-completions file fails to work on HTML attribute, inside the quotes. Typing the trigger (test in the example below) inside the alt="" attribute does not insert the completion. It does outside the image tag without problems. Any suggestions why?
Scope inside the quotes is matching the definition in the html-attr.sublime-completions file below: text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html.
<body>
<img src="/images/poster.jpg" alt="">
</body>
I am using .sublime-completions file:
// html-attr.sublime-completions
{
"scope": "text.html.basic meta.tag.inline.any.html string.quoted.double.html punctuation.definition.string.end.html",
"completions":
[
{
"trigger": "test",
"contents": "test ok"
}
]
}
Other installed packages include Emmet, HTML5, Better Completion, HTMLAttributes and SublimeCodeIntel, but disabling them all does not help the situation.
// Preferences.sublime-settings
{
"auto_complete": true,
}
Update:
Emmet could have been a culprit, but not my case. Emmet overrides completions defined by .sublime-completions files, unless Emmet's tab_abbreviation is disabled for the corresponding scope:
// Emmet.sublime-settings
"disable_tab_abbreviations_for_scopes": "text.html.basic"
I solved the problem temporarily by using .sublime-snippet, but it didn't work on the XML files so well. Still looking for an answer to the question above.
<!-- html-attr.sublime-snippet -->
<snippet>
<content>test ok</content>
<tabTrigger>test</tabTrigger>
<scope>text.html.basic</scope>
<description>html-attr.sublime-completion does not work</description>
</snippet>
Related
I found that when you type.print at the end of the line in pycharm, it will automatically convert this line to print(line). So I want to know whether vscode can achieve such a function with snippet.
I have written a snippet after googling.
"print": {
"prefix": "print",
"body": "\nprint(${TM_CURRENT_LINE-})"
}
However, there is a problem in this snippet: the prefix will be added during conversion. Besides, it only adds an additional line instead of changing the current line.
demonstration of snippet now
you can do it like this:
".print": {
"prefix": ".print",
"body": ["\nprint(${TM_CURRENT_LINE/(^.+)(\\..+)/$1/g})"],
}
How can I change the color of the HTML open/close tags in VScode to match the image below? I have tried using the Highlight Matching Tag extension and the following settings, but this only works on selecting (onFocus) of the tags. I want the actual font color for open tags to be different than all the closing tags. Thank you!
"highlight-matching-tag.styles": {
"opening": {
"name": {
"custom": {
"color": "#007fff",
}
}
},
"closing": {
"name": {
"custom": {
"color": "#F02931"
}
}
}
},
You can do this by customizing the VS Code theme that you are currently using (see the end result on the last image).
CUTOMIZING THE THEME
In the VSCode open the Command Palette by pressing Ctrl + Shift + P, and type/select Preferences: Open Settings (JSON).
This will open the editor Settings .json file.
Set/add new rules for the editor token color customization.
Adding the below snippet to the settings.json will change the color of the closing tags (name) in JSX, for the theme Dark (Visual Studio).
TL;DR
Paste the below snippet to your editor settings JSON, to enable the color > rules for a particular theme.
settings.json
"editor.tokenColorCustomizations": {
"[Visual Studio Dark]": { // Name of the theme that we want to customize, same as the value from "workbench.colorTheme"
"textMateRules": [ // TextMate grammars tokenization settings
{
"name": "Opening JSX tags",
"scope": [
"entity.name.tag.open.jsx", // HTML opening tags (in JSX)
"support.class.component.open.jsx", // JSX Component opening tags
],
"settings": {
"foreground": "#007fff",
}
},
{
"name": "Closing JSX tags",
"scope": [
"entity.name.tag.close.jsx", // HTML closing tags (in JSX)
"support.class.component.close.jsx", // JSX Component closing tags
],
"settings": {
"foreground": "#F02931",
}
},
]
}
}
SETTING ADDITIONAL SCOPES:
Additionally you can inspect the particular token (e.g. tag) in order to see the name of the scope that you want to style.
In the the Command Palette Ctrl + Shift + P open the Developer: Inspect Editor Tokens and Scopes to see the TextMate scope names of the parts (opening tag, closing tag, etc.) that you want to modify.
For a more advanced matching and going beyond jsx you may want to reference the TextMate grammars
How do I create a custom snippet that will automatically enter a variable's value that I type into its prefix?
I want a snippet that will create a html start-end tag comment block. For example if I type /se hello I want the result to be
<!-- $var start-->
<!-- $var end-->
Where $var is replaced with "hello". Thank you for reading!
As the VSCode snippet docs says, it uses TextMate to power its snippets. TextMate uses variables of the form $name and ${name:default}, and luckily supplies $TM_CURRENT_WORD which may be sufficient for your needs. However there is no built in variable to get multiple arguments directly after the snippet name i.e. $arg1 and $arg2 as variables. Thought you could do a similar effect with interpolated shell code, but unfortunately:
The snippet syntax follows the TextMate snippet syntax with the exceptions of 'interpolated shell code' and the use of \u; both are not supported.
Emphasis mine
However for this simple example, the following indexed variable example is probably sufficient.
<!-- $1 start-->
$0
<!-- $1 end-->
$i gives you a value to fill in, you can go between each one with tabbing. The $0 is where the cursor goes at the end(the end of the snippet by default). Optionally you can do something like:
<!-- ${1: default text} start-->
$0
<!-- $1 end-->
and it'll start looking like:
<!-- default text start-->
<!-- default text end-->
with both of the defaults selected to edit.
This all put together would look like this together in the snippets.json file:
{
"se": {
"scope": "html",
"prefix": "se",
"body": [
"<!-- ${1:default text} start-->",
"\t$0",
"<!--$1 end-->"
]
}
}
As #Mark pointed out, if you want it to work for more than just HTML you can use $BLOCK_COMMENT_START and $BLOCK_COMMENT_END which will vary for each language. The snippet would then look like this:
{
"se": {
// Leaving scope off will make it a global snippet
"prefix": "se",
"body": [
"$BLOCK_COMMENT_START ${1:default text} start $BLOCK_COMMENT_END",
"\t$0",
"$BLOCK_COMMENT_START$1 end $BLOCK_COMMENT_END"
]
}
}
Is there a tool or task runner that can take an HTML document in one language, parse out the content in general/specific HTML tags, run that content through Google translate, then put it back into the markup in the right place in new files? Basically, digest one source file and output multiple variations in different (non-computer) languages.
What I'm hoping for is:
index.html
<!DOCTYPE html>
<html>
<body>
привет мир!
</body>
</html>
Gets compiled to:
en/index.html
<!DOCTYPE html>
<html>
<body>
Hello World!
</body>
</html>
ru/index.html
<!DOCTYPE html>
<html>
<body>
привет мир!
</body>
</html>
ch/index.html
<!DOCTYPE html>
<html>
<body>
你好世界!
</body>
</html>
I obviously don't mind setting up some sort of Gruntfile or whatever that dictates the languages, destinations, etc.
Take a look at get-translation or grunt-google-translate. Also Google Translate has simple REST API, you can write your own plugin from the scratch or use something like grunt-restful.
I was able to piece together a solution using Ruby and Grunt. This could be refactored to be more robust, but it was a working solution, so I ran with it. Keep in mind, the translating script overwrites the source files. Only the Grunt starts making duplicates in new destinations.
Using the easy_translate Rub gem I wrote this script:
#!/usr/bin/ruby
require 'easy_translate'
EasyTranslate.api_key = '' # Get from google
target_path = '' # path to translate
Dir.glob(target_path) do |item|
next if item == '.' or item == '..' or item == '.svn'
contents = ""
update = ""
File.open(item, "r") do |file|
contents += file.read
update += EasyTranslate.translate(contents, :from => :russian, :to => :en)
end
File.open(item, "w"){ }
File.open(item, "w") do |file|
file.write(update)
end
end
Walking through this, each file in the target_path is checked if it’s a worthwhile item we make variables contents and update we’ll use to place in the old and new versions of the contents of the file, respectively. Then we open the file and fill up those variable. On line 20 we empty the file, then in the last block on lines 22-24 we write the update string into the file. I used File.open(item, "w") {} instead of .truncate(0) because I was getting random Unicode characters added to the contents of the file with the latter option. Again, overwriting the files in the translation process is not ideal. It'd be better to make a copy in a new destination, but I didn't do that.
The Ruby script returned a single line of minified HTML and broke Smarty templating, so I used used grunt-prettify and grunt-text-replace to prettify the HTML for ease of use and to make the Smarty stuff work again. The Gruntfile looks like this:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
'prettify': {
options: {
indent: 4,
indent_char: ' ',
wrap_line_length: 0,
brace_style: 'expand',
"unformatted": [
"a",
"code",
"pre"
]
},
all: {
expand: true,
cwd: 'static_ugly',
ext: '.html',
src: ['*.html'],
dest: 'static_pretty'
}
},
'replace': {
fix_smarty: {
src: ['static_pretty/*.html'],
overwrite: true,
replacements: [{
from: '{/ Strip',
to: '{/strip'
},{
from: '{$ This-> setLayout ',
to: '{$this->setLayout'
},{
from: '{$ this- > setPageTitle ',
to: '{$this->setPageTitle'
},{
from: '$ this-> setPageTitle ',
to: '$this->setPageTitle'
},{
from: '{$ smarty.block.footer ',
to: '{$smarty.block.footer'
}]
}
}
});
grunt.loadNpmTasks('grunt-prettify');
grunt.loadNpmTasks('grunt-text-replace');
grunt.registerTask('default', ['prettify', 'replace']);
};
There was a lot more find/replace stuff that I left out since it's project-specific. This solution pretty much does what I wanted in the original question. I did some manual moving around of files in the name of getting it done, but I believe I'll be using a variation of this moving forward and consider it a work in progress.
On google chrome, I'd like to intercept some attributes of html tags, and do an action if the attributes has a certain value.
For example, let's say I have a list-item which has an attribute called user:
<li class="MyClass" user="BadUser"> ... </li>
What I would like is to make the content of this item invisible, to delete it, whatever.
I'm new to those extension (I began to take a look at them in this very hour)
How can I do this?
You can use a content script for this purpose. Declare the script (myscript.js in the example below) in your manifest file:
{
"name": "Extension name",
...
"content_scripts":
[
{
"matches": ["*://*/*"],
"js": ["jquery.js", "myscript.js"]
}
],
...
}
Then in the myscript.js write required code, something like this (using jQuery, which is also injected as a content script):
$('[user]').each(function()
{
$(this).removeAttr("user");
});
This is for deleting attribute itself. Of course, you can remove entire element calling remove() instead of removeAttr().
In your content script :
To remove from DOM use this
$('[my_tag]').remove();
And to play with each element you can use this:
$.each($('[my_tag]'), function(index, element) {
console.log(index + ': ' + element);
});