Textmate Javascript Validate Syntax Command - javascript

I spend a lot of time in TextMate 2 writing PHP and a lesser amount writing Javascript.
I've always found the Validate Syntax command in Textmate very useful as a final quick sanity check before saving. I was wondering today if there were a way to do something similar for Javascript and I think I've found a solution in acorn:
https://github.com/ternjs/acorn
Running something along these lines:
acorn --silent <file-here>; echo $?
Returns either a 0 if it's valid or a 1 if it's not. If not it also returns an error with the line where the syntax error occurs:
Unexpected token (50:1)
1
Seems like it's almost perfect for use in a simple Validate Syntax command.
But that's where I ran into a brick wall of ignorance. I'm not sure how to get from there to an actual command in TextMate and looking at the PHP example and a few others left me no further along partly because I've got almost no Ruby experience and it appears to that's how commands are usually written in TextMate.
Anyone with more experience writing TextMate commands care to take a pass at it?
Based on Graham's suggestion and additional help here's a working command:
#!/usr/bin/env bash
#Write scope of JS to a temp file
echo "$(</dev/stdin)" > ${TMPDIR}acorn-validation.js;
#Capture output of acorn syntax check (Note that acorn sends the output to STDERR thus the 2>&1)
ACORN_OUTPUT=$( (acorn --silent ${TMPDIR}acorn-validation.js) 2>&1 );
echo 'Running syntax check with acorn...';
if [[ "" == $ACORN_OUTPUT ]]; then
echo 'No syntax errors detected';
fi
if [[ "" != $ACORN_OUTPUT ]]; then
#Find the line/column value
LINE=$(echo $ACORN_OUTPUT | grep -oE '([0-9]+:[0-9]+)';);
echo '';
echo 'Syntax error on '${LINE};
echo ${ACORN_OUTPUT/($LINE)/};
#Send cursor to the place where the error occured
LINE=(${LINE//:/ });
open "txmt://open/?url=file://${TM_FILEPATH}&line=${LINE[0]}&column=${LINE[1]}";
fi
Make sure Input is set to Scope and Output is set to Show in Tool Tip.

Install Acorn globally:
npm install -g acorn
Find out where acorn been installed:
which acorn
Mine said (because I use nvm):
~/.nvm/versions/node/v6.2.2/bin/acorn
Add that bin folder to your TextMate Path, use a colon to delineate:
So my PATH is:
$PATH:/opt/local/bin:/usr/local/bin:/usr/texbin:/usr/local/bin:$HOME/.nvm/versions/node/v6.2.2/bin:$HOME/.rvm/rubies/ruby-2.3.3/bin
Now open the bundle editor:
Create a bundle, or open an existing, and press cmd+n to create a new file, select "command" from the dropdown.
Paste this into the command, cmd+s to save.
Update: This command has been brought from proof of concept to functional by (OP) Jamie Poitra, so check the question for his script.
#!/usr/bin/env bash
acorn ${TM_FILE}
All set.

Related

/bin/sh: node: command not found - in VScode, running Javascript

Im trying to run this simple code in VSCode for learning Javascript but I keep getting this error:
[Running] node "/var/folders/xr/30nkhmxs7159fblbjtfj2jhw0000gn/T/tempCodeRunnerFile.javascript"
/bin/sh: node: command not found
[Done] exited with code=127 in 0.014 seconds
I've looked online and have tried changing the CodeRunner Executable Map as I saw in another post but it doesn't seem to be helping.
Thanks!
let admin, name; // can declare two variables at once
name = "John";
admin = name;
alert( admin ); // "John"
First of all, check the output of which node in the default terminal application. If the output is empty, this means that the path where the node binary resides is not in your $PATH.
Try to find the location of the node executable. After this, check what's the shell you're using by running echo $SHELL. If it returns something like /bin/bash, create a file(may already exist) named ".bash_profile" or ".bashrc" and there, add the following: export PATH=$PATH:<location of node>, replacing <location of node> with the actual location of the node binary.
in this page: How to run javascript code in Visual studio code? /bin/sh: 1: node: not found
dmcquiggin had resolve this problem:
Locate the path to your Node executable, by typing the following command in a terminal:
which node
The result will be similar to the following (I use nvm to manage my Node versions, yours might look a little different)
/home/my_username/.nvm/versions/node/v10.15.1/bin/node
Make a note of / copy this path.
Open VS Code. Either press Ctrl+, (on Linux), or from the File menu, select Preferences > Settings.
In the search box at the top of this window, type:
Executor Map
Click the 'Edit in settings.json' link displayed under the first result.
Add the following to the end of the settings file, replacing the path with the one from step 1.
"code-runner.executorMap": {
"javascript": "/home/my_username/.nvm/versions/node/v10.15.1/bin/node"
}
this also works on my mac, cheers

Output semantic code blocks with Prism

I'm inputting markdown data and outputting HTML files with Pandoc. Using the --no-highlight flag, I can get the syntax to output without the built-in basic syntax highlighting, and use Prism.js to highlight the code instead, which is much more robust.
However, Prism requires that the code or pre have language-* in the class name. Using php as an example, Pandoc outputs <pre class="php">. I've managed to hack it to work by using:
```language-php
As the start of each code block. However, when I want to export the same code as an EPUB, it won't recognize the language to be able to use the built in syntax highlighting.
Here are the commands I use for EPUB and HTML output:
# epub output
pandoc assets/metadata.yaml chapters/*.md -o build/book.epub
# html output
pandoc assets/metadata.yaml chapters/*.md -s --toc --no-highlight --css ../assets/style.css -A assets/template/footer.html -o build/book.html
My issue:
I want to be able to write
```php
As the start of my code blocks, instead of
```language-php
So both Prism.js and the built-in syntax highlighter will work, with my EPUB and HTML generation.
If I could get Pandoc to interpret "```php" as class="language-php", this would solve the issue.
Here is a link on the Pandoc GitHub for someone else with the same issue I'm trying to solve.
I'm for using sed as well, but as a pre-processor. You could write a script like the one below, and name it pre-process:
#!/bin/bash -e
derived_dir=derived
rm -fr ${derived_dir} && mkdir -p ${derived_dir}
for file in $*
do
cat ${file} | sed 's/```php/```language-php/g' > ${derived_dir}/$(basename ${file})
done
echo "${derived_dir}/*"
Then you could use ```php in your source, and produce html via:
pandoc assets/metadata.yaml $(pre-process chapters/*.md) -s --toc --no-highlight --css ../assets/style.css -A assets/template/footer.html -o build/book.html
Hope this helps.

How to set up a conditional npm script based on the output of another?

This is an issue I have run into before when trying to set something up with npm scripts, yet I have not been able to solve it. Not even sure this is possible, preferably I would like the solution to work in both Mac and Windows environments.
I'm trying to split up some of the logic of my npm scripts into several short scripts that can call each other. This in combination with variables would make the scripts better maintainable and readable for other developers.
I can not figure out however how to use the result of one npm script in another. I'm hardly a bash expert so that why I'm looking for some help here (:
In this example I'm trying to set up a script which allows the developer to easily launch a docker (virtual) environment.
in the package.json:
...
"config": {
"docker": {
"container": "docker-test"
}
},
"scripts": {
"container_run": "docker run -d -p 80:80 $npm_package_config_docker_container"
"container_running": "docker inspect -f {{.State.Running}} $npm_package_config_docker_container || echo 'false'",
"container_stop": "docker stop $npm_package_config_docker_container && docker rm $npm_package_config_docker_container",
"start": "???"
}
So here I have a variable containing the name of a docker container to be run: $npm_package_config_docker_container.
When I do npm run container_running, this will return true, if the container is running or throw an error if the container is not there in which case it will echo 'false'. So far so good.
Now I would like the start script to check if the container if running, if so stop the container and start a new run and of it is not running just start a new run.
So something like this:
"start": "if [ container_running == "true" ]; then container_stop && container_run; else container_run; fi"
So the question is how to achieve this? And as a bonus question, can this be done in a way that is compatible in both Mac and Windows environments?
Any help would be much appreciated!!
After some more digging I found a solution to his although I'm sure this could be improved.
You can use command substitution to run $(npm run container_running), this will return all the output from running that command (in a subshell).
Then you can test the output to check if the last word was 'true'.
"start": "if [[ $(npm run container_running) == *true ]]; then npm run container_stop && npm run container_run; else npm run container_run; fi"
Have not tested this on Windows yet.
If anyone has a better idea / solution please let me know!
Honestly, for anything more complex than a single command with options, I create a bin folder and add a custom script file for it, then have one of the non scripts call that instead. E.g.:
"container_run": "./bin/container-run"
The thing is, you don't have to be a bash expert then because you can create that file with a #! /usr/env node at the top and then write the rest in JavaScript.

Python and the Spidermonkey Javascript engine on Linux

I have successfully installed Spidermonkey JS engine on my Linux machine ( Ubuntu ).
Basically my goal is to make it execute Ajax (js) scripts and return the result back to my Python script. I'm basically trying to build a good O.O. web scraper. But it's pretty hard for me to get all of this working.
I'm now at the point where when I type JS in my terminal I can start executing Javascript.
I've been Googling and found this little snipet on Stackoverflow :
import urllib2
import spidermonkey
js = spidermonkey.Runtime()
js_ctx = js.new_context()
script = urllib2.urlopen('http://etherhack.co.uk/hashing/whirlpool/js/whirlpool.js').read()
js_ctx.eval_script(script)
js_ctx.eval_script('var s="abc"')
js_ctx.eval_script('print(HexWhirpool(s))')
but it failed to run with the error that module Spidermonkey can not be found.
I'm a bit lost now. Anyone able to help?
I also tried easy_install python-spidermonkey with no luck, for libnspr-dev package is absent.
So, I've built package from source. Instructions from project page (Debian Stretch):
Building
Check out the Python-Spidermonkey module from the SVN repository ( I downloaded it as source archive, direct link )
Unpack, and cd to ./python-spidermonkey/trunk
CPPFLAGS="-Wno-format-security" python setup.py build (these flags for Debian)
Error jsemit.h:508:32: error: expected ‘(’ before ‘)’ token uintN decltype); means that decltype cannot be used as variable (maybe it's a macro or something else), fix it this way:
sed -e 's/decltype/dectyp/' -i.ORIG ./js/src/jsemit.h
sed -e 's/decltype/dectyp/' -i.ORIG ./js/src/jsemit.cpp
Error jsemit.cpp:6490:1: error: narrowing conversion of ‘-1’ from ‘int’ to ‘uint8 {aka unsigned char}’ inside { } [-Wnarrowing] means illegal variable conversion, recompile it manually:
cd js/src
g++ -o Linux_All_DBG.OBJ/jsemit.o -c -Wall -Wno-narrowing -Wno-format -MMD -g3 -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R -DHAVE_VA_COPY -DVA_COPY=va_copy -DPIC -fPIC -DDEBUG -DDEBUG_user -DEDITLINE -ILinux_All_DBG.OBJ jsemit.cpp
Error spidermonkey.c:1:2: error: #error Do not use this file, it is the result of a failed Pyrex compilation. - some trouble with pyrex. There is a patch. Do it this way:
wget -O - https://storage.googleapis.com/google-code-attachments/python-spidermonkey/issue-14/comment-4/cinit.patch | patch -p1 ./spidermonkey.pyx
Installation
su, and python setup.py install as root.
Running
By default, setup script installs libjs.so to /usr/local/lib/, so I did ln -s /usr/local/lib/libjs.so /usr/lib/libjs.so (but you'd better use solution from Seagal82)
Without this step, python keeps complaining about import ImportError: libjs.so: cannot open shared object file: No such file or directory
I also had an error ImportError: cannot import name Runtime after from spidermonkey import Runtime. The reason possibly was in old easy_install data in ~/.local/lib/python2.7/site-packages/spidermonkey/. After removing it, all runs smooth
Recently i got a task need to do something like Web scraping,
and for the javascript part, currently want to try using python-spidermonkey to resolve it and see if this might work for me ...
and i seem to meet situation might alike, after i think i finished install python-spidermonkey, i execute the script above, i got this error:
Traceback (most recent call last):
File "spidermonkeytest.py", line 2, in <module>
import spidermonkey
ImportError: libjs.so: cannot open shared object file: No such file or directory
then after some searching by google...i found the solution probably in the end of here:
http://hi.baidu.com/peizhongyou/item/ec1575c3f0e00e31e80f2e48
i setup these things:
$sudo vi /etc/ld.so.conf.d/libjs.so.conf
fill in this line:
/usr/local/lib/
save & exit, execute ldconfig:
$sudo ldconfig
then i can run the script provided above by #Synbitz Prowduczions
don't know if this is the answer you need, or this still helps?
You need to try libnspr4. If that doesn't work, you can always download it from Mozilla and build the code yourself.
It is not difficult to type ./config && make && make install to build the library yourself after untarring the source. If you build yourself, files will likely be in
/usr/local/{include,lib}
Also just try Googling for "YOUR_OS_NAME install nspr4".
I believe someone wrote a C/C++ header file translator for Python ctypes. Although I can't say much else because I don't use Python.
SpiderMonkey also has its own implementation of ctypes modeled after Python. So technically if you know javascript you could forego using Python altogether since you want to do some ajax with it. You will need to brush up on the NSPR or C runtime sockets to meet the requirements for your projects using only Spidermonkey.
OR a web search for Python +AJAX might turn up exactly what you need.

doctorjs(aka jsctags) not work with vim+tagbar

I am using windows 7 64bit...
I've installed nodejs 0.6.11 by MSI installer, the installation path is "C:\Program Files (x86)\nodejs", it was automatically added to my %PATH% by the installer, I installed doctorjs by steps below:
I copied doctorjs files under "C:\Program Files (x86)\nodejs\doctorjs"
I created jsctags.cmd filled with content copied from https://gist.github.com/1438882
I added following lines in my _vimrc:
let g:tagbar_type_javascript = {
\ 'ctagsbin' : 'C:\Program Files (x86)\nodejs\jsctags.cmd'
\ }
The problem is, when I run jsctags.cmd "{My js folder}", it generates tags file with only content below:
!_TAG_FILE_FORMAT 2 /extended format/
!_TAG_FILE_SORTED 0 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Patrick Walton /pwalton#mozilla.com/
!_TAG_PROGRAM_NAME jsctags //
!_TAG_PROGRAM_URL http://github.com/pcwalton/jsctags /GitHub repository/
!_TAG_PROGRAM_VERSION 0.1 //
And when I run :tagbaropen in vim, it shows nothing for current js file..
Please kindly guide me where I did wrong, thank you!
Since you're getting some output, it looks like you have the gist implemented correctly. But maybe your expectation of how to use it at a command line is different than the way it really works?
FYI: jsctags.cmd "{my js folder}" returns an empty tags file on my machine too. I don't think the command interface is very mature yet... so it looks like creating a tagfile of a whole folder is not possible - yet...
Try jsctags.cmd "{file}". This should create a populated tag file.
Also note that tagbar calls jsctags like this: jsctags -f - {file}. This streams the output to stdout. So if you're debugging, try this form of the command.
As another debugging tip, modify your batchfile to output debugging info. ie:
Add lines like this:
echo "%~dp0"\"node.exe" "D:\opt\node\doctorjs\bin\jsctags.js" %* > d:\debug.txt
Looking in d:\debug.txt will let you see what the command looks like as it is called from tagbar.
BTW: The gist you're using was mine... I am wondering if I didn't test this batch file well enough with folders that have spaces in them. Do some tests in both folders with and without spaces to see if there is a difference. If you get more insight into where it works/doesn't, let me know and I can investigate further.
Your issue might be related to the commit of narcissus you've cloned for doctorjs. Go into the narcissus folder in the doctorjs folder and run
git checkout 4ae5aff8b3
This should switch the head to the proper version of the file.

Categories

Resources