can I attach functions to the coffee console before it starts? - coffeescript

Let's say I want to have a pp function:
coffee> pp = (obj) -> JSON.stringify(obj)
[Function]
coffee> pp({cat: "fancy"})
'{"cat":"fancy"}'
coffee>
Is there a way that I can have that function be available immediately when the console loads? I'm looking at coffee -r "utils.coffee", but don't see any way to put that required library into an object that's available at the command line. It looks like I might be able to alter repl.js, but that seems like a bad idea.

You can put those functions into the global variable (which is kinda Node's version of window) and then use the -r option.
# utils.coffee
global.pp = (obj) -> JSON.stringify(obj)
And then run, on the same directly utils.coffee of:
coffee -r ./utils
It should start a CoffeeScript REPL and have the pp function available as a global variable:
coffee> pp ohmy: 'neat'
'{"ohmy":"neat"}'
Update: it seems the -r command-line option was removed in CoffeeScript's master. It probably wasn't meant to be used this way :(
Update 2: There's another way to do this! And it doesn't rely on any command-specific parameter:
{ echo "require './utils'"; cat; } | coffee
It will, however, not work 100% like the Coffee REPL. The arrow keys for example don't seem to work.
Edit (jc): Using this method allows you to make an unload for node, which is handy:
# utils.coffee
global.unload = (moduleName) ->
cacheName = require.resolve(moduleName)
delete require.cache[cacheName]
$ coffee -r ~/Dev/utils.coffee
coffee> unload
[Function]
Update 3: Another possibility is to "create your own REPL". Not really reimplementing anything. Based on this hacky solution, you could do something like:
#! /usr/bin/env coffee
# REPL functions.
global.pp = (obj) -> JSON.stringify(obj)
# Start the REPL.
require 'coffee-script/lib/coffee-script/repl'
And then use that script as your new REPL. It will work exactly like the normal Coffee REPL plus the new functions (no problems with arrow keys nor TAB completion :)
BTW, i think you'll need to have CoffeeScript installed without the -g option on npm for that to work.
It is a very hacky solution though. It relies on the internal CoffeeScript implementation file structure and its functionality, and that could change at any moment (in fact, i'm aware that there has been some work done in a new revamped Coffee REPL based on Node's one... i hope that functionality gets exposed to be used programmatically, so these kind of hacks are not hacks any more).

Have a look at #Daniel's (Daniel Taylor's) excellent nesh, an enhanced node shell that also speaks CoffeeScript: http://danielgtaylor.github.io/nesh/
Here's how you would load your pp function into a CoffeeScript REPL:
nesh -c -e 'pp = (obj) -> JSON.stringify(obj)'
Similarly, if you wanted to load a file, say ~/.nesh_profile.coffee (analogous to loading a shell profile), on startup, use:
nesh -c -e ~/.nesh_profile.coffee
Small caveat: The REPL language - JavaScript v. CoffeeScript - and the language of the code you're loading must be the same. Edit: The only exception is that you can always load JavaScript via a file with extension .js, even when starting a CoffeeScript REPL. (By contrast, you can't specify a JS string when starting a CoffeeScript REPL).
To automate loading of your 'nesh profile' into a CoffeeScript REPL you could define an alias in your shell profile; e.g.:
alias neshc='nesh -c -e ~/.nesh_profile.coffee'
Update: Here's how you can use the very same 'nesh profile' with a JavaScript REPL; compilation to JavaScript is performed on the fly using process substitution:
alias neshj='nesh -e <(coffee -bp ~/.nesh_profile.coffee)'
nesh is available as an npm package, so you can easily install it as follows:
sudo npm install nesh -g

Related

Autoconf : How to get program output in a string and check if another string is present in that

I am developing a Qt application in Python. It uses a resource file, which needs to be compiled. I am using autotools to manage compilation and installation of my projects.
Now, in order for the resource file to be usable by the application, it needs to be compiled with a certain version of the compilation program (pyrcc). I can get the version by putting the output of pyrcc -version in a variable in configure.ac. But then, I don't know how to check whether the string pyrcc5 is present in the output. If it is not present, I want to tell the user that his PyRCC programm has the wrong version, and abort configure.
Additionally, I would like to avoid the need of an extra variable for the program output, but instead do it like this (Pseudo code):
if "pyrcc5" not in output of "pyrcc -version":
say "pyrcc has wrong version"
exit 1
How can I do this ?
When writing a configure.ac for Autoconf, always remember that you are basically writing a shell script. Autoconf provides a host of macros that afford you a lot of leverage, but you can usually at least get an idea about basic "How can I do X in Autoconf?" questions by asking instead "How would I do X in a portable shell script?"
In particular, for ...
I would like to avoid the need of an extra variable for the program
output, but instead do it like this (Pseudo code):
if "pyrcc5" not in output of "pyrcc -version":
say "pyrcc has wrong version"
exit 1
... the usual tool for a portable shell script to use for such a task is grep, and, happily, the easiest way to apply it to the task does not require an intermediate variable. For example, this implements exactly your pseudocode (without emitting any extraneous messaging to the console):
if ! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null; then
echo "pyrcc has wrong version"
exit 1
fi
That pipes the output of pyrcc -version into grep, and relies on the fact that grep exits with a success status if and only if it finds any matches.
You could, in fact, put exactly that in your configure.ac, but it would be more idiomatic to
Use the usual Autoconf mechanisms to locate pyrcc and grep, and to use the versions discovered that way;
Use the Autoconf AS_IF macro to write the if construct, instead of writing it literally;
Use standard Autoconf mechanisms for emitting a "checking..." message and reporting on its result; and
Use the standard Autoconf mechanism for outputting a failure message and terminating.
Of course, all of that makes the above considerably more complex, but also more flexible and portable. It might look like this:
AC_ARG_VAR([PYRCC], [The name or full path of pyrcc. Version 5 is required.])
# ...
AC_PROG_GREP
AC_CHECK_PROGS([PYRCC], [pyrcc5 pyrcc], [])
AS_IF([test "x${PYRCC}" = x],
[AC_MSG_ERROR([Required program pyrcc was not found])])
# ...
AC_MSG_CHECKING([whether ${PYRCC} has an appropriate version])
AS_IF([! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null], [
AC_MSG_RESULT([no])
AC_MSG_ERROR([pyrcc version 5 is required, but ${PYRCC} is a different version])
], [
AC_MSG_RESULT([yes])
])
In addition to portability and conventional Autoconf progress messaging, that also gets the builder a way to specify a particular pyrcc executable to configure (by setting variable PYRCC in its environment), documents that in configure's help text, and exports PYRCC as a make variable.
Oh, and I snuck in a check for pyrcc under the name pyrcc5, too, though I don't know whether that's useful in practice.
The final result no longer looks much like the shell script fragment I offered first, I grant. But again, the pure shell script fragment could be used as is, and also, the fully Autoconfiscated version is derived directly from the pure script.

Run Coffeescript Interactive (REPL) with a script

In python, I can run a script and enter interactive mode in the context of that script. This lets me mess with global variables and what not to examine program state.
$ python -i hello.py
Can I do this with Coffeescript? I've tried the following:
$ coffee -i hello.coffee
doesn't load hello.coffee. It's equivalent to coffee -i
$ cat hello.coffee | coffee -i
runs the script line by line in REPL but ends REPL after the EOF.
I've recently started a project to create an advanced interactive shell for Node and associated languages like CoffeeScript. One of the features is loading a file or string in the context of the interpreter at startup which takes into account the loaded language.
http://danielgtaylor.github.com/nesh/
Example:
# Load a string
nesh -c -e 'hello = (name) -> "Hello, #{name}"'
# Load a file
nesh -c -e hello.coffee
Then in the interpreter you can access the hello function. Also a good idea to create an alias in bash:
alias cs='nesh -c'
cat foo.coffee - | coffee -i
tells cat to first output your code and then output stdin, which gives you what you're looking for I think.
I am confronted with this problem as well. The one provide by #int3 doesn't solve this problem, for CoffeeScript is one indentation based language. stdin will pass the code line by line, but the repl is not smart enough to realize this. Since you post this question, I suggest you create one issue (feature request) on CoffeeScript

Integrate Cppcheck with Emacs

Is it possible to integrate Cppcheck with Emacs in a more sophisticated way than simply calling the shell command on the current buffer? I would like Emacs to be able to parse Cppcheck's messages and treat them as messages from a compiler (similar to how compile works), such as using C-x ` to visit the targets of Cppcheck's messages.
Here is some example output Cppcheck:
$ cppcheck --enable=all test.cpp
Checking test.cpp...
[test.cpp:4]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 5
[test.cpp:38]: (style) The scope of the variable 'i' can be reduced
[test.cpp:38]: (style) Variable 'i' is assigned a value that is never used
[test.cpp:23]: (error) Possible null pointer dereference: p
[test.cpp:33]: (error) Possible null pointer dereference: p
Checking usage of global functions..
[test.cpp:36]: (style) The function 'f' is never used
[test.cpp:1]: (style) The function 'f1' is never used
[test.cpp:9]: (style) The function 'f2' is never used
[test.cpp:26]: (style) The function 'f3' is never used
Hmmm... I think this is really simple actually. Just use 'compile', as in M-x compile, and type as the compile command:
cppcheck --template='{file}:{line}:{severity}:{message}' --quiet <filename>
Where the filename is the name of the file on which you wish to run cppcheck. That puts the output of cppcheck into a form that the compilation buffer can parse and gives you the full functionality you get with, for instance, a g++ compile.
The --quiet is probably not necessary but since all I care about are the errors that's what I use.
You can use flymake which ships with Emacs.
The basic idea is to write a flymake command that runs cppcheck and then massages the output into a format the flymake can use. If you then enable flymake in your c++ mode buffers, you'll get on the fly error highlighting.
This is an example of flymake working with my Python buffers using pyflakes.
flymake in general expects output in this form
filename:line_number: class: message
Where filename is the name of the file, number is the line number, class is a string like error or warning indicating the type of message and message is a string indicating the actual error. cppcheck output looks close to this. You should probably write a little wrapper to convert the output of cppcheck to this format and then add a hook to turn on flymake for c++ mode.
With C, adding something like gcc -Wall -o nul -S ${CHK_SOURCES} to your Makefile with under a target check-syntax and running flymake-mode does what's necessary. I think it'll be similar for c++ mode.
For the gory details, you should check out http://flymake.sourceforge.net/
Is it possible to integrate Cppcheck with Emacs in a more sophisticated way
Yes, it is possible. Use flymake. I'm surprised no one has done this yet for cppcheck.
No problem, you can do it yourself. Add cppcheck as a new flavor of flymake tool. To do that, follow an existing example. It's not too complicated to do, but coming in cold, it's hard to know what to do. (I've never seen a guide document that describes how to integrate new tools into flymake). Following an existing working example solves that.
Here's a 7k file that adds PHP CodeSniffer as a flymake tool. http://www.emacswiki.org/emacs/flyphpcs.el
Most of that 7k is comments...
You should be able to modify that to add any arbitrary tool to flymake. The key steps are:
Associate your target file extension (example: .cpp) with a pair of functions (init and cleanup) that do your flymake stuff.
define a function to generate the command line, each time flymake scans your buffer. Ths fn gets the name of the file backing the buffer, and produces a command line. In your case it would run cppcheck with all the appropriate command line parameters. The fn that generates the command line is called by the init fn referenced in #1.
define a regex that matches error messages generated by your tool, and add that regex to the flymake list. This allows flymake to extract error messages from the output of the tool you run. By parsing the output, flymake can get the line numbers and highlight broken lines in your buffer.
based on the answers, flymake sounds good.
you can write a cppcheck parser but it sounds easier to use cppcheck --template option.
cppcheck --template="{file}:{line}:{severity}:{message}" foo.cpp
might match flymake pattern. It is just an idea.
The quickest way is probably to use flymake and add an extra target to your makefile.
This setup is working for me:
check-syntax: cppcheck
g++ -o nul -S ${CHK_SOURCES} $(CFLAGS)
cppcheck:
cppcheck --enable=all --quiet --template={file}:{line}:{severity}:{message} ${CHK_SOURCES}

Getting rid of CoffeeScript's closure wrapper

How can I omit the automatic closure wrappers that hides my variables from the global scope?
(function() {
// my compiled code
}).call(this);
Just playing around with CoffeeScript+SproutCore, and of course, I'd prefer to leave the scope as it is: in this case there is no need to protect anything from overwriting.
I know I can use # or this. at the declaration, but that's not too elegant.
Quick and dirty solution: Use the console flag -b (bare). Warning: Kittens will die if you do that!
Clean solution: Don't do that.
Usage: coffee [options] path/to/script.coffee
-c, --compile compile to JavaScript and save as .js files
-i, --interactive run an interactive CoffeeScript REPL
-o, --output set the directory for compiled JavaScript
-j, --join concatenate the scripts before compiling
-w, --watch watch scripts for changes, and recompile
-p, --print print the compiled JavaScript to stdout
-l, --lint pipe the compiled JavaScript through JSLint
-s, --stdio listen for and compile scripts over stdio
-e, --eval compile a string from the command line
-r, --require require a library before executing your script
-b, --bare compile without the top-level function wrapper
-t, --tokens print the tokens that the lexer produces
-n, --nodes print the parse tree that Jison produces
--nodejs pass options through to the "node" binary
-v, --version display CoffeeScript version
-h, --help display this help message
I used another option which was to attach my global variables to the global object in the scope of my function. I attached mine to the 'window'. This keeps your JavaScript encapsulated and only exposes the variable that you need in the global scope.

Auto-complete command line arguments

In bash, executables such as mplayer and imagemagick's "convert" have a cool auto-complete functionality on their command line arguments. For instance, if I type
mplayer <tab><tab>
in one of my video folders, then mplayer will list all media files located in that folder, and only the media files.
Similarly, if I type
convert -<tab><tab>
then I will see all the possible options of the convert script, which is great.
My question is how to achieve a similar functionality, using bash, ruby or python scripts?
This is an example of BASH's smart completion. A basic description is here, a guide to writing your own extensions is here and another (Debian-based) guide is here. And here's a fuller featured introduction to the complete command (the command that facilitates this behaviour).
The link to writing your own extension in the accepted answer has gone dead. Quoting here from http://web.archive.org/web/20090409201619/http://ifacethoughts.net/2009/04/06/extending-bash-auto-completion/
Bash provides you a way of specifying your keywords, and using them to
auto complete command line arguments for your application. I use vim
as a wiki, task managemer and contacts. The vim helptags system lets
me index the content instead of searching through it, and the speed
shows it. One feature I wanted to add to this was to access these tags
from outside vim.
This can be done in a straight forward way:
$ vim -t tagname
This takes me directly to specific content marked using this tag. However, this will be more productive if I can provide
auto-completion for the tags.
I first defined a Bash function for the vim commandline. I added the
following code to my .bashrc file:
function get {
vim -t $1
} Now I can use get tagname command to get to the content.
Bash programmable completion is done by sourcing the
/etc/bash-completion script. The script lets us add our
auto-completion script /etc/bash-completion.d/ directory and executes
it whenever it is called. So I added a script file called get with the
following code in that directory.
_get()
{
local cur
COMPREPLY=()
#Variable to hold the current word
cur="${COMP_WORDS[COMP_CWORD]}"
#Build a list of our keywords for auto-completion using
#the tags file
local tags=$(for t in `cat /home/anadgouda/wiki/tags | \
awk '{print $1}'`; do echo ${t}; done)
#Generate possible matches and store them in the
#array variable COMPREPLY
COMPREPLY=($(compgen -W "${tags}" $cur))
}
#Assign the auto-completion function _get for our command get.
complete -F _get get Once the /etc/bash-completion is sourced, you will get auto-completion for the tags when you use the get command.
Along with my wiki I use it for all the documentation work and at
times the code too. I also use the tags file created from my code. The
indexing system lets me remember the context instead of the filenames
and directories.
You can tweak this system for any of the tools you use. All you need
to do is get a list of the keywords for your command and give it to
the Bash programmable completion system.
This functionality in bash is provided by bash-completion and similar functionality is included in zsh. If you want to add support for some program not currently supported by one of these tools, you need to write your own extensions for them.
How do I enable bash completion on Ubuntu?
sudo apt-get install bash-completion
source /etc/profile.d/bash_completion.sh
sudo apt i[TAB]