I don't know if this is possible/sensible, but I was curious to know if I can have my strings in javascript files have html highlighting. I discovered that strings in php could have SQL syntax highlighting, so I believe it is possible.
But, I don't know vim-scripting, so any help on this appreciated.
I am using the Better Javascript syntax.
PS: If there could be an option to turn it on and off while editing a js file, that would be wonderful
Thanks
Yes, it's possible if you don't mind some syntax file hacking. First you need to include the HTML syntax file from within the Javascript syntax file -- see :help syn-include for info on that; second you need to declare that HTML syntax can be found inside of certain elements (i.e. strings). Third, if you want to have the option of enabling and disabling it, you can make those commands dependent on a global variable, and write some mappings that set or unset the variable and then reload the syntax file.
For examples on how inclusion works, take a look at syntax/html.vim (which includes the Javascript and CSS syntax files), syntax/perl.vim (which includes the POD syntax file), or php.vim (which includes SQL syntax highlighting in strings, conditional on a global ariable).
Edit: did some work on actually making this happen in my copy.
In the head of syntax/javascript.vim, just below syn case ignore, add
syn include #javaScriptHTML syntax/html.vim
unlet b:current_syntax
syn spell default " HTML enables spell-checking globally, turn it off
Then add #javaScriptHTML to the contained= lists for javaScriptStringD and javaScriptStringS.
Finally you have to edit syntax/html.vim to prevent it from trying to include syntax/javascript.vim if it was loaded from javascript: find the line that reads
if main_syntax != 'java' || exists("java_javascript")
and change it to
if main_syntax != 'javascript' && ( main_syntax != 'java' || exists("java_javascript")
Related
I'm trying to extend Monaco Editor to allow users to write in a hybrid of JavaScript and another language, using delimiters to separate them within the same file, similarly to how Markdown allows writing multiple languages using fenced code blocks.
The difference is that I want to keep all the other IDE features that Monaco has built in for JavaScript, such as linting (done via diagnostics), smart auto-completion, jump-to-definition, auto-formatting helpers, and every other IDE feature that comes with Monaco's built-in JavaScript mode. I'd like these features to still work within the JavaScript portion of the code that Monaco is editing, and be disabled for the sub-language portion.
My first attempt was to call setMonarchTokensProvider, passing in a modified version of TypeScript's tokenizer rules. Specifically, I was able to add the beginning-fence delimiter to the root rule and create a new rule for the sub-language in the same way the documentation for Monarch (Monaco's syntax highligher) describes, using #nextEmbedded. (For testing purposes, I've been hard-coding CSS as the embedded language.)
When I call setMonarchTokensProvider like this for the language "javascript", it completely ignores this syntax highlighting tokenizer, and colors the code-fences of CSS as invalid JavaScript, indicating that you cannot override the built-in JavaScript mode this way.
When I call setMonarchTokensProvider with a new language (e.g. "mylang") and set the editor to use that language, it provides correct syntax highlighting (!) for this CSS-in-JS hybrid language. But all other advanced features that were found in the JavaScript mode are no longer present. The editor didn't have any smart auto-completion for methods defined on classes in the same file, or any in-editor error-reporting for invalid syntax, or any of its trademark JavaScript IDE features.
So my next attempt was to modify the pre-bundled Monaco code's TypeScript definition to include my custom syntax highlighting rules. This correctly highlighted my CSS-in-JS code completely (!), when setting the language to "typescript", and left all the other features intact (!) including diagnostics reporting (live-validation and underlining of errors), auto-completion, all of it! (I didn't try it with "javascript" but it's safe to assume it probably works or is trivial to get it working, since JavaScript is actually implemented as a variant configuration of the TypeScript mode in Monaco.)
Unfortunately, it also considered the entire CSS portion of it, including the fence around it, to be invalid JavaScript code.
I know that this is theoretically doable, because within HTML mode, you can embed CSS or JS with full support for proper validation and auto-completion and every other IDE feature; basically, every sub-language in an HTML file works like it's in its own file: HTML features in the root of the file, CSS features within style tags, JS features within script tags.
But digging into the TypeScript plugin's implementation inside Monaco, it's not clear where to begin editing this, either as a user of Monaco the library, or by forking it and patching it up where necessary. I started at trying to modify the DiagnostcsAdapter [sic] and tracing where it's actually implemented, but I got stuck two function-calls deep, where it seems to push a promise of syntax validation that returns a value that's used later, but the implementation of getSyntacticDiagnostics just shells the work out to some other implementation that I can't find anywhere else in the repo, nor in the monaco-languages repo or the vscode repo.
I make the similar thing. My solution is to place non-JS code inside a block comment:
regularJsCode()
/*
[your-syntax-identifying-start-token]
place any syntax you want here
[your-syntax-identifying-end-token]
*/
regularJsCode()
Then you can process it with your tools, parsers, IDE extension etc. And the coolest part you can make VSCode to syntax-highlight it like you want so it won't seem like some hack.
This approach is preferrable because your JS file still remains a 100% valid JS file.
If you still don't want to put your syntax into comments, then you should create your own file extension like .jsx/.tsx. In practical, VSCode terms this means you need to create VSCode extension with language server and stuff. This is not so easy, but the documentation is good. You could assemble your own JS highlighting code inside your VSCode extension using language server: https://github.com/sourcegraph/javascript-typescript-langserver
According to the creator of Monaco:
Architecturally, you can do the following:
use monaco-editor-core directly
define a new language to the editor
fork monaco-typescript and change it to work with your newly defined langauge id. Then, modify the TS language host code to not pass the original models to TypeScript, but first run a preprocess which strips your custom language out of the text, and then only passes on valid TypeScript to the TS compiler. One idea is to replace each character that you remove with a space. This will leave all the position/offset computation work without any effort on your side.
Good luck!
I am gathering a lot of Javascript code from untrusted people and have to integrate it in my project. As is is untrusted, I would like to check if it doesn't do something nasty.
My main concern is the variables the code uses.
To check it is OK, I would like to parse all the code and verify the name of the variables. For instance, that all the variables are included in window.sandboxedVariables.
Is it possible to parse a Javascript code (in any language but preferably Javascript or bash) and get the list of all the variables ? Is it possible to do the same with the imported libraries ?
Is it possible to do with Uglify ? I read a bit the API documentation and found nothing specific.
Thank you very much !
Assuming you're talking about global variables, you can do the following:
clone the window object
load/run the untrusted script
compare the window object to the cloned one
move all newfound items into window.sandboxedVariables
However, this won't work if the untrusted script overrides one of the existing properties (variables) of window.
eslint is a JavaScript source code linting tool that lets you write custom plugins. You should be able to write a plugin that meets your needs. Plus, the plugins can be written in JavaScript.
http://eslint.org/docs/developer-guide
It is impossible to write an algorithm that verifies untrusted JavaScript code. You can parse it, you can run it in a sandbox and analyze its actions. But you can never be sure you've identified everything it might do or every variable it might use once you run it in your real environment.
If you don't trust it then either only run it in a secure sandbox or don't use it.
You could use Mozilla Rhino. It is a JavaScript engine written in Java.
Here you can find an example similar to what you are trying to do:
http://ramkulkarni.com/blog/parsing-javascript-code-using-mozilla-rhino/
I used Netbeans before. How do I do some refactoring (changing variable names, make method out of code, etc) in Sublime Text 2 on a Mac? What I'm doing right now is "select next instance of a word", but that's only because I'm using only one file
I wrote this plugin for JavaScript refactoring
https://github.com/s-a/sublime-text-refactor
I guess there are a lot more out there supporting RoR.
What works for me is the "Find all" option (Ctrl+F and Alt+Enter).
This way you can edit the text and all the matches will be edited at same time.
What happened here was that I just did refactoring via grepping and find/replace. I'm on Vim now and substitute/grepping is still my method when I need to refactor. I guess this is one of the features that an IDE provides that a text editor doesn't.
Alongside ctrl+click you can use ctrl+D also. Works for me.
What I do is select multiple variables with ctrl+click and the once you type, all selected strings are changes. The only difference is that you need to select them manually. But then again -- once you select the first one, all matching variables are highlighted
The sublime-text-refactor plugin works as long as you need to refactor variables. If you need to refactor plain strings it doesn't work. For example if you need to replace 'components' in file paths 'file/*/components' by 'sections' the plugin will not help you because it expects to rename variables (console indicates when I try to refactor: unable to locate components variable).
My answer is not related to sublime text but I was led to this thread when I found the adapted solution so it might help people in the same case. Sublime text is not necesarily the solution for refactoring.
In NodeJs, what I did to ensure refactor across files was to create a gulp task that replaces the value and rewrites the file:
var gulpReplace = require('gulp-replace');
gulp.task('refactor', function(){
gulp.src(['app/**/*.js'], { base: './' })
.pipe(gulpReplace(/components/g, 'sections'))
.pipe(gulp.dest('./'));
});
$gulp refactor
What this does is that, in all js files under the app directory, I replace the string 'components' by the string 'sections'. In my case I needed plain string replacement, it was not variable renaming so the need was very straightforward and this method is very efficient for that. Adapt this method to your case and back up your code before you refactor, as it is the equivalent to find/replace via grep, there is no prior check, be sure of what you're doing.
I advise to delete the gulp task once you are done with your refactoring as it can be very dangerous ! CAUTION
I stumbled upon https://codereview.stackexchange.com/questions/10610/refactoring-javascript-into-pure-functions-to-make-code-more-readable-and-mainta and I don't understand the answer since the user uses an # symbol in a way I've never seen before. What does it do when attached to the if keyword? Can you attach it to other keywords?
It's not a JavaScript thing. It's a symbol used by whatever templating system that answer was referring to. Note that the <script> element has type text/html, which will prevent browsers from paying any attention to its contents.
Some other JavaScript code will find that script and fetch its innerHTML in order to merge the template with some data to create ... well whatever that template makes.
#: syntax in Razor
Said by #StriplingWarrior at Using Razor within JavaScript
It is razor code, not javascript, if you are interested in razor check:
http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx
I have a big javascript file common.js
with all my functions and stuff...and i would like to write a separate file Js
to store only the definitions for all the alert/courtesy messages etc
spread along the file...i don't want to seek and change one by one...
i have created something like this in php, where I have my file, en.php / fr.php /de.php for each language i need...
i was wondering:
1. if i can do the same in Js
2. if there is any way to use the php instead...so woudl be even better to have just one and only file to edit
thanks
Sure -- all you need to do is to create a definitions file for each language that just creates an object with the needed name: value pairs. Your existing JS can then insert defsObject["name"] wherever needed. Your PHP would then determine which of the JS definition files to load by changing the src value of the script tag.
If you are unfamiliar with the object notation, there's loads of examples available on Stack Overflow (tagged JSON).
I don't believe there's a satisfying way using js to include the definitions.