Some years ago I got really addicted to armagetron advanced. A Snake-like game where you drive Tron Light cycles.
It's dead simple, but the simplicity itself is what makes it so awesome. In fact, The only kind of games that trapped me in the last 10 years where playable with 4 buttons max. (sdmkun, elastomania, *cave, and most ABA games).
So I installed armagetronad again and went to the internetz to play some styball. It's a bummer that there are no styball servers anymore. But thanks to that I fetched the source to see if I could find the styball mode, and.... besides finding it, I also found a branch which embeded lua into armagetronad. Yeah, modding arma in lua will be great.
I hope I don't get addicted again.
And, as a gift, here you have an explanation of rubber, a great concept to deal with latency in armagetron. I think it's one of the things that make aa so amazing.
Ah, and here's a cheatlist for armagetronad. nice to have, eh? :)
Btw, it's funny that I loved that game before watching the movie, and before knowing that this movie was somehow related to smalltalk. Hey, even in the 'Tron legacy' movie, there's emacs appearing in some occasion :)
domingo, 24 de febrero de 2013
lunes, 28 de enero de 2013
a simple pattern to shorten the feedback cycle
Lately I had to do some work on nginx configuration and
lua-scripting (here is the detailed info on augmenting an API through nginx and lua). To do so, the development cycle is the following:
The 'trick' is to use buffer local variables to run the appropiate commands in each buffer. So you should set a variable called run-command, to the string that will be executed when saving.
Hint: here's the pattern for the prop-line in case you want emacs to set the variable automatically when you open the file.
For more fancyness, there's also add-file-local-variable-prop-line which can help you.
And the tiny code to hook the command to after-save hook.
- edit nginx conf file or lua file called from the nginx conf file.
- restart or reload nginx.
- check in nginx log file for errors
- Try the feature via curl or browser
The 'trick' is to use buffer local variables to run the appropiate commands in each buffer. So you should set a variable called run-command, to the string that will be executed when saving.
Hint: here's the pattern for the prop-line in case you want emacs to set the variable automatically when you open the file.
# -*- run-command: "/opt/openresty/nginx/sbin/nginx -c /home/rgrau/workspace/nginx-translator/config_nginx.conf -p /tmp/nginx/ -s reload"; -*
For more fancyness, there's also add-file-local-variable-prop-line which can help you.
And the tiny code to hook the command to after-save hook.
(defun rgc/run-command () (interactive) (when (boundp 'run-command) (shell-command run-command))) (add-to-list 'after-save-hook 'rgc/run-command)To speed up the 3rd step, you can play with tailing the log file in a shell-mode buffer, or use auto-reverse-tail-mode. But let's leave it for another post :) Btw, Next weekend I'll be the next FOSDEM. If anyone wants to meet and hack some elisp or discuss vim vs emacs with a beer, ping me (raimonster at gmail dot com)
miércoles, 9 de enero de 2013
Parsing elisp code with elisp
Today, in Reddit there was this guy presenting a utility library for elisp.
In the comments, there was a discussion about generating documentation
from an elisp file. The approach there is fine: parsing the file via
regexen and asking for the documentation to the elisp system itself.
Here's another version I wrote that walks through the code looking for
defuns and defmacros. The code parses a buffer, and picks the
docstring from the code itself, so it catches it even if the methods
haven't been evaluated. It's not a real advantage as you won't
probably try to document a code you aren't evaluating, but just for
the sake of the exmple, I think it's a good learning exercice.
So here's the code:
M-: (fetch-defuns (current-buffer)) will return a minimal org-file skeleton with the function names and their docs.
The cool way to ask for the documentation of a function, however, is just (documentation 'name-of-fun). try it. It's great.
Happy emacs hacking!
In the comments, there was a discussion about generating documentation
from an elisp file. The approach there is fine: parsing the file via
regexen and asking for the documentation to the elisp system itself.
Here's another version I wrote that walks through the code looking for
defuns and defmacros. The code parses a buffer, and picks the
docstring from the code itself, so it catches it even if the methods
haven't been evaluated. It's not a real advantage as you won't
probably try to document a code you aren't evaluating, but just for
the sake of the exmple, I think it's a good learning exercice.
So here's the code:
(defun fetch-defuns (buffer) (interactive) (save-excursion (goto-char (point-min)) (let (sexp (defuns nil) (defmacros nil)) (condition-case nil (while t (setq sexp (read buffer)) (when (listp sexp) (case (car sexp) (defun (push (cons (cadr sexp) (doc-if-any sexp)) defuns)) (defmacro (push (cons (cadr sexp) (doc-if-any sexp)) defmacros))))) (error nil)) (generate-docs defuns)))) (defun doc-if-any (sexp) "search for the doc" (when (stringp (cadddr sexp)) (cadddr sexp))) (defun generate-docs (defuns) "generate a simple org with the docs" (mapconcat (lambda (x) (format "* %s %s" (car x) (or (cdr x) "-undocumented-"))) defuns "\n\n"))
M-: (fetch-defuns (current-buffer)) will return a minimal org-file skeleton with the function names and their docs.
The cool way to ask for the documentation of a function, however, is just (documentation 'name-of-fun). try it. It's great.
Happy emacs hacking!
sábado, 29 de diciembre de 2012
using ido-completing-read to get input from users
Lately, ido is my shortcut to many commands that I used to execute in shell. It's great to have a flexible matching with autocompletion, inside your development environment. The function to call from your elisp code is ido-completing-read which has the following signature:
(ido-completing-read PROMPT CHOICES &optional PREDICATE REQUIRE-MATCH
INITIAL-INPUT HIST DEF INHERIT-INPUT-METHOD)
Let's see an example of using ido to collect a parameter from the
user. I have my favourite streaming radios stored in pls or asx
files, and this little function allows me to type M-x radio RET to
listen any of those.(defun radio () (interactive) (let ((filename (ido-completing-read "which radio?: " (directory-files "/home/rgrau/bin/radios/" nil "\\.pls$\\|\\.asx$")))) (async-shell-command (concat "mplayer -playlist /home/rgrau/bin/radios/" filename) "*mplayer*" ) (message "choosen: %s" filename)))
Now you can easily port many commands you used to run on terminal to be executed inside your favourite editor.
EDIT: A copypasta fail made this post appear like without body in planet emacsen. sorry :(
jueves, 29 de noviembre de 2012
a neat ruby idiom
[rgrau] guys, I just learned a new idiom [rgrau] (@foo ||= []) << bar [michal] :) [rgrau] It's not crystal clear, but I like it [rgrau] my perl background damaged my brain beyond repair [jakub] rgrau: idiom or idiot? [rgrau] you pick [jakub] ok, done [rgrau] I know which one you picked [jakub] u r smart [rgrau] u idiom [rgrau] that log goes to my blog inside ruby section
sábado, 24 de noviembre de 2012
'symbols, :symbols and ':symbols
The other day, hacking a kind of project manager for emacs (YES. Another one) which I will explain in a future post, I bumped in a couple of wtfs, that turned out to be my own mental fuckup, not an elisp wtf.
Let's dissect plist-get with different kinds of atoms as keys, and try to explain why they work or they don't. Little schemer style.
Why? The whole plist is is quoted, being a literal list, so if there's no need to re-quote it again.
Why? We built the list with the list constructor, so we have to quote the symbol directory. because we want a simbol.
Why? :directory is a different symbol from 'directory, and the whole thing is quoted.
Why? the plist is not a literal, but again. :directory and 'directory are different things
You see?
And this is again correct. Makes sense, no?
Then, the relation between :foo and 'foo is none, but (eq :foo ':foo) is t.
Let's dissect plist-get with different kinds of atoms as keys, and try to explain why they work or they don't. Little schemer style.
(plist-get '('directory ":fdsa" 'irc "channel") 'directory) ; nil
Why? The whole plist is is quoted, being a literal list, so if there's no need to re-quote it again.
(plist-get (list 'directory ":fdsa" 'irc "channel") 'directory) ; ":fdsa"
Why? We built the list with the list constructor, so we have to quote the symbol directory. because we want a simbol.
(plist-get '(:directory ":fdsa" 'irc "channel") 'directory) ; nil
Why? :directory is a different symbol from 'directory, and the whole thing is quoted.
(plist-get (list :directory ":fdsa" 'irc "channel") 'directory) ; nil
Why? the plist is not a literal, but again. :directory and 'directory are different things
(plist-get (list :directory ":fdsa" 'irc "channel") :directory) ; ":fdsa"
You see?
(plist-get '(:directory ":fdsa" 'irc "channel") :directory) ; ":fdsa"
And this is again correct. Makes sense, no?
Then, the relation between :foo and 'foo is none, but (eq :foo ':foo) is t.
jueves, 22 de noviembre de 2012
emacs taking to much memory?
[p1] my emacs takes up more memory than firefox, hm
[rgrau] open more firefox tabs
[p3] install more extensions
I love #emacs help style :)
Suscribirse a:
Entradas (Atom)