How to disable "special commands" in node.js REPL? - javascript

Problem Node REPL has some "special commands" like .break and .save. I never use these, but I do very frequently try and paste into the REPL code that's formatted like so:
words.append('ul')
.classed('my-class', true)
.selectAll('li.new-class')
.data((tuple, tupleIdx) => obj[tupleIdx])
.enter()
.append('li')
.classed('new-class', true)
.text(d => '' + foo(d));
(This is d3.js code but similar things happen when using Promises, a chain of .then(...)s starting on each line.)
Of course node complains about "invalid REPL keyword" when it sees .classed or .then on its own line and proceeds to print a sequence of error messages several screens long.
Tenuous pseudo-workaround I've worked around this with a regexp in Vim that moves any whitespace between closing parens and dots to after the dot (:%s/)\n\(\s*\)\./).\r\1/ for completeness) but this is tedious and often I want to copy-paste from a browser and not switch to Vim to reformat some code.
Question Is there any way to disable node REPL "features" which, while well-intentioned, conflict with standard JavaScript practices, such as lines starting with dots?
Or is this too complicated for a terminal application, and if so, is there a way I can communicate with the node REPL via a browser's JS console (not node-monkey which only handles console.log)
PS. This question is mainly about lines starting with . but another such conflict is _ (worked around thankfully by n_).

You can make your own custom REPL. That option should give you maximal control over how your repl behaves.
Since the main problem here is pasting multi-line code into the default repl, as a workaround, try using the .editor special command.
Enter editor mode (Ctrl+D to finish, Ctrl+C to cancel).
It's also mentioned in the answer to this question about writing multiple lines in the node repl
If you're also interested in saving keystrokes, when entering the editor, autocomplete seems to kick in after typing ".ed" so you can shave off three keystrokes in that sense.

You can simply delete the command from the instance:
const replServer = repl.start(/* ... */)
delete replServer.commands.load;
You can even define the whole commands object, take a look at the reference implementation:
https://github.com/nodejs/node/blob/main/lib/repl.js

Here's something tentative: using node-copy-paste, I wrote a tiny module that allows me to paste() the contents of clipboard and evals it after fixing lines starting with ..
This goes in paste.js:
var cp = require('copy-paste'); // npm install node-copy-paste
module.exports = function() {
return eval(cp.paste().replace(/\n\s*\./g, "."));
};
Then in node REPL, paste = require('./paste'); paste() will make it go. Very brittle but it might solve the problem often enough to be valuable.

Related

Javascript autocomplete current line and add {} curly braces?

In VS Code, is there a way I can use keyboard combination like "ctrl+enter" to finish the current line and add { automatically at end of the line? instead of that i have to go to the end of the line my self and type { for it.
For example, when I typed if, VS code gives me if () blocks automatically, and I started typing condition in the braces.
if (condition)
// while the cursor is after 'n' but before ')'
When I'm at the end of the "condition", I have to use arrow key to move to the end and add {}. Do you program Javascript in this way or you have better tools/keyboard shortcut to use?
While I'm programming in Python, most IDE like VScode or Pycharm provides quick completion keyboard shortcut like "ctrl+shift+enter" to finish the line by adding ":" at end of the sentence, which applies to both defining functions, if, for, conditions. But unfortunately I haven't found such a way in Javascript world yet.
Search for snippets on the VS extension section ,I think you can find it there for any programming language .

Find out where this function has been called?

I want to be able to quickly go through all invocations of a function inside a file or outside. Currently i use search in all files method. But is there a way to see where this method was used.
Optional: Also i'd want to go back in other direction as well. Say there is a method call like this:
makeBread();
Now i want to see what the function do. so somehow jump to its declaration.
Find invocation
Trying to use text search to find invocations may easily betray you. Consider this:
function myFunction() {
console.log("Hello :)");
}
document.getElementById("page-title").addEventListener("click", myFunction);
I think you understand where this is going - if you want to get a list of invocations, best bet is to use console.trace at runtime:
function myFunction() {
console.trace();
console.log("Hello :)");
}
Find what the function does
The function can be overriden at runtime. Dynamic languages cannot be analysed like static ones (C++, Java). You wanna know what the function does? Print it in the console at runtime:
console.log(makeBread.toString());
Find declaration
Again, console.trace will tell you the line for every function it came through. You can also get the stack trace as array - but beware that this slows execution a lot, so don't do it in production.
Conclusion
As I said, you cannot inspect dynamic languages where anything can be anything using any IDE reliably. Most IDEs give good hints though, just conbine them with runtime debuging. Consider debuging running application more fun than looking ad the dead code.
More reading
If you want to make some reguler expressions, this is gonna be handy: http://www.bryanbraun.com/2014/11/27/every-possible-way-to-define-a-javascript-function
The console object: https://developer.mozilla.org/en-US/docs/Web/API/Console
Using stack trace: https://stackoverflow.com/a/635852/607407
Not natively, but with plugins, yes
A popular plugin that has this functionality is SublimeCodeIntel:
SublimeCodeIntel will also allow you to jump around symbol definitions even across files with just a click ..and back.
For Mac OS X:
Jump to definition = Control+Click
Jump to definition = Control+Command+Alt+Up
Go back = Control+Command+Alt+Left
Manual Code Intelligence = Control+Shift+space
For Linux:
Jump to definition = Super+Click
Jump to definition = Control+Super+Alt+Up
Go back = Control+Super+Alt+Left
Manual Code Intelligence = Control+Shift+space
For Windows:
Jump to definition = Alt+Click
Jump to definition = Control+Windows+Alt+Up
Go back = Control+Windows+Alt+Left
Manual Code Intelligence = Control+Shift+space

Simple way to check/validate javascript syntax

I have some big set of different javascript-snippets (several thousands), and some of them have some stupid errors in syntax (like unmatching braces/quotes, HTML inside javascript, typos in variable names).
I need a simple way to check JS syntax. I've tried JSLint but it send too many warnings about style, way of variable definitions, etc. (even if i turn off all flags). I don't need to find out style problems, or improve javascript quality, i just need to find obvious syntax errors. Of course i can simply check it in browser/browser console, but i need to do it automatically as the number of that snippets is big.
Add:
JSLint/JSHint reports a lot of problems in the lines that are not 'beauty' but working (i.e. have some potential problems), and can't see the real problems, where the normal compiler will simply report syntax error and stop execution. For example, try to JSLint that code, which has syntax errors on line 4 (unmatched quotes), line 6 (comma required), and line 9 (unexpected <script>).
document.write('something');
a = 0;
if (window.location == 'http://google.com') a = 1;
document.write("aaa='andh"+a+"eded"');
a = {
something: ['a']
something2: ['a']
};
<script>
a = 1;
You could try JSHint, which is less verbose.
Just in case anyone is still looking you could try Esprima,
It only checks syntax, nothing else.
I've found that SpiderMonkey has ability to compile script without executing it, and if compilation failed - it prints error.
So i just created small wrapper for SpiderMonkey
sub checkjs {
my $js = shift;
my ( $js_fh, $js_tmpfile ) = File::Temp::tempfile( 'XXXXXXXXXXXX', EXLOCK => 0, UNLINK => 1, TMPDIR => 1 );
$| = 1;
print $js_fh $js;
close $js_fh;
return qx(js -C -f $js_tmpfile 2>&1);
}
And javascriptlint.com also deals very good in my case. (Thanks to #rajeshkakawat).
Lots of options if you have an exhaustive list of the JSLint errors you do want to capture.
JSLint's code is actually quite good and fairly easy to understand (I'm assuming you already know JavaScript fairly well from your question). You could hack it to only check what you want and to continue no matter how many errors it finds.
You could also write something quickly in Node.js to use JSLint as-is to check every file/snippet quickly and output only those errors you care about.
Just use node --check filename
Semantic Designs' (my company) JavaScript formatter read JS files and formats them. You don't want the formatting part.
To read the files it will format, it uses a full JavaScript parser, which does a complete syntax check (even inside regular expressions). If you run it and simply ignore the formatted result, you get a syntax checker.
You can give it big list of files and it will format all of them. You could use this to batch-check your large set. (If there are any syntax errors, it returns a nonzero error status to a shell).

Javascript refactoring in Vim

I don't need anything super fancy, but some scope aware refactoring would be nice.
Refactoring something in function scope is one of the most common scenarios for me:
var funyfun = function(arg1, arg2) {
arg1 = ...arg2;
arg2....();
}
Is there a vim plugin that would allow me to refactor arg1, for ex, in the scope of that function or do I have to invent my own "select block, find, replace" shortcut.
For extra kudos, something that would "refactor on the fly" as I type, so I can see where changes are being made. Netbeans does an excellent job of this.
This is not limited to a certain block, but this how I would do it with plain Vim:
Move cursor on top of arg1 and type *N
Type ciw and insert replacement.
Now you can use n and N to navigate the occurrences and by pressing . Vim will redo the replacement on the current match
Here's a shortcut for it:
" Simple word refactoring shortcut. Hit <Leader>r<new word> on a word to
" refactor it. Navigate to more matches with `n` and `N` and redo refactoring
" by hitting the dot key.
map <Leader>r *Nciw
Sound a bit like you only want renaming instead of refactoring. Full refactoring is tricky for Javascript, though some IDEs provide approximations. Since the question is about Vim specifically, and hacks aren't excluded, I'll just jump on the scope-aware aspect:
I've got a modified DoctorJS to generate scope-aware tags, with a Vim plugin for scope-aware navigation based on those tags (see blog post/screencast).
The hacky part comes in how navigation is implemented for Vim: I generate a search pattern that includes the scope of the variable and excludes all nested scopes for the same name. So, you could use that search pattern (function scoped_tags#FindTagInScope) to implement renaming (only if all uses are in the same file, and it doesn't exclude comments and the like..). Or you could use the scoped navigation to jump through variable occurrences manually and use '.' to rename them..
A few JavaScript-aware commands for Vim are provided by tern_for_vim, such as :TernRename for scope-aware renaming of variables, :TernDef for jumping to the definition of the thing under the cursor, and so on. You will need to have nodejs and npm installed, make sure to read the installation instructions in the repo.
As a partial solution you can use Eclim with JSDT, which allows you to use power of Eclipse refactoring/debugging/auto-completion/plugins with Vim.
In my experience, it may be a bit slow on older machines, but it's worth giving it a try.
In addition to doing actual scope-aware refactoring and the like, consider :%s/varName/newNav/gc. Per :help :s_c, the c flag passed to :s enters a quick confirmation mode for find/replace operations that prompts you (y/n) on whether each match should be replaced or not.
you can do:
:.,/^}/ s/\<arg1\>/new_name/g
the .,/^}/ is a range that many Ex commands accept: from cursor line to next line starting with a closing brace.
Benoit and Epeli has some good points, however, I find it a bit tedious to write .,/^}/ before my substitute statement, and since it only modifies code from the cursor position to the next line starting with a }, it depends on having the cursor position at the beginning of the function or block (and it will not work for an entire function with an if statement).
So instead I use visual mode in combination with textobjects. For instance, typing vi{ will select all the code inside the closest matching pair of {}, va{ will include the {} characters, and if you do this with visual line (vi{V), you'll get the entire function declaration as well. Then you can just do a :s/\<arg1\>/new_name/g to rename arg1 to new_name, including function parameters.

Emacs + js2-mode: disable indenting completely?

I'm using js2-mode for working with javascript in emacs and for the most part it's very useful. However, the indenting methods are terribly frustrating when working with jQuery, closures, and JSON... for instance, code that I wish to be indented like this:
var foo = jQuery('#mycontainer ul li').each(function(el){
var bar = el.html();
});
Turns out as:
var foo = jQuery('#mycontainer ul li').each(function(el){
var bar = el.html();
});
Is there a way I can just switch off all the indenting "helpers" and just have emacs insert N spaces when I hit the tab key? I know manual-indentation is a step backwards, but having readable code is, IMHO, more useful than a tool that doesn't work as expected.
Not a direct answer to your question, but here is a fork of js2-mode that has improved indenting.
One of the improvements is that your example code is indented the way you ask here.
I guess I will make this a full answer instead of a comment; espresso-mode is included with Emacs, and is designed to be a Javascript mode for Emacs (instead of a Javascript mode that happens to run inside of Emacs). It works like regular programming modes, and also happens to indent things the way you like.
Check out this solution, maps indentation function in js2-mode to partially use indentation from esresso-mode (now known as js-mode included in emacs 23.2 and newer):
http://mihai.bazon.net/projects/editing-javascript-with-emacs-js2-mode
Works exactly as I expect indentation in emacs to work and you still get the parsing awesomeness from js2-mode.
Have you tried new versions of js2-mode? It looks like there's a fix out: http://code.google.com/p/js2-mode/issues/detail?id=94
js2-mode supports "bounce" indenting; you can press tab multiple times to choose different likely indenting levels, so you might be able to get the effect you want that way:
(setq js2-bounce-indent-p t)
You can simply bind TAB to insert itself:
(add-hook 'js2-mode-hook 'my-js2-mode-hook)
(defun my-js2-mode-hook ()
(define-key js2-mode-map [tab] 'self-insert-command))
(But the better solution would, of course, be to find out why the mode thinks it needs so much indentation for anonymous functions, and fix it.)
One other alternative is js3-mode. It indents like this by default, but there seems to be some options that might enable you to tweak it for your liking.
var foo = jQuery('#mycontainer ul li').each(function(el){
var bar = el.html();
});

Categories

Resources