How to refactor in Sublime Text? (Ruby, Rails, JavaScript) - javascript

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

Related

Converting flex/bison parser for use in the browser

I've made a simple programming language and compiler using Flex and Yacc, and I want to be able to convert my code for use in the browser.
I've already taken a look at projects like Jison, but I don't think that would work for me as I'd then have to maintain two different codebases.
Looking around some more, I'm pretty sure compiling my compiler to WebAssembly and running that in the browser would be the solution. Only problem is that I'm not sure how to go about doing that. Can the Flex library that I pass when linking the lexer and the parser together (-lfl) also be compiled along with my compiler?
I really have no experience with WASM and I'm pretty new to Flex/Yacc too, so there may be some very obvious solution, but I can't seem to find anything.
If you want to take a look at my code: https://github.com/inobulles/aqua-compiler/tree/master/langs/amber
Thanks alot for your time!
There is nothing of much use in -lfl; you shouldn't need it in any real application.
If you don't define yywrap() in your flex file, then add
%option noyywrap
to your flex prologue, so that flex doesn't put a reference to yywrap into the generated code. If you do define yywrap then you already don't need -lfl, but you still might think about %option noyywrap so that you don't need the definition.
I don't know how WASM deals with stdio.h functions; presumably, your intent is to use some other mechanism to feed text into your lexer, but the generated code will still contain references to standard library I/O functions (as does the code generated by Bison).

Extending JavaScript syntax in Monaco Editor with full integration

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!

How to parse a Javascript file and get all the used variables?

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/

ctags, jsctags/doctorjs, Tagbar step by step

I need help on setting up ctags, jsctags, and tagbar so I can have a workable Javascript editing envrionment. I got everything installed but couldn't get an idea how ctags and jsctags work together so I don't know how to configure properly. I have done quite a bit Google around but the information is pretty broken and lacks consistency. I got an error similar to this post, ctags and tagbar configuration are out of sync. I'm on OS X mountain lion and iterm2.
Any help would be greatly appreciated. A step by step instructions would be excellent.
Thx.
First, you have to understand that jsctags and ctags will probably never be in sync. Even if you have only a simple function, both programs may output slightly different informations. Thus it is advised to use one or the other but not both.
Second, AFAIK, TagBar doesn't need to be configured to use jsctags instead of ctags. If you are doing JavaScript it will simply default to jsctags if it's available. TagBar shouldn't complain if you have a working jsctags.
Third, for its own tag-related functionalities (:tag, :tselect, <C-]>, etc.), Vim only relies on the presence of one or more physical tags files. Whether those files are generated by ctags, jsctags or whatevertags is not a concern as long as they are generated correctly.
And now we arrive at the fourth point which is where the pain really is: neither Tagbar nor its older cousin TagList actually use a physical tags file. They tap ctags or jsctags directly without even trying to use or update any existing tags file. Because of that, and the fact that TagBar only deals with the current buffer, your own physical tags file (and thus Vim's tag-related functionalities) and TagBar are almost guaranteed to be out of sync. Even if you use the same indexer.
So… I'd advise you to use either ctags or jsctags and forget anything about syncing TagBar's and Vim's tags-related stuff as both things are completely separate:
Use TagBar to understand/navigate in your current buffer.
Use Vim's tag-related functionalities to move around your project.
Random thoughts…
For Vim to locate your tags file(s) easily, you should put this line in your ~/.vimrc:
set tags=./tags,tags;/
./tags means "look for a tags file in the directory of the current file", tags means "look for a tags file in the working directory", ;/ means "keep looking up and up until you reach /".
The TagBar wiki talks about a bug in jsctags, make sure that you are not concerned by it.
jsctags is better than ctags when you write crazy "modern" JavaScript with lots of callbacks and self-executing functions. If your JavaScript is more traditional, ctags may be enough.

HTML syntax highlighting in javascript strings in vim

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")

Categories