domingo, 29 de diciembre de 2013

Hide mouse cursor while typing

Long time ago I already blogged about an emacs way to move the mouse cursor when you are typing close to it.


Yesterday I discovered that there's a much more simple way to unclutter your screen making the cursor invisible.

(setq make-pointer-invisible t)
Voilà, that's it.

jueves, 19 de diciembre de 2013

lua and luajit

In the lua workshop, lots of nice topics were raised, but something that striked me was when everyone agreed that writting lua for luajit or for the official lua VM was totally different, and ppl had different mindsets when writting for one or the other.  I know there's a big difference on how to write bindings to C (luajit being more fond of ffi and stock lua prefering the Lua C Api.


If you wanna know a bit more on how luajit works and where it gets its blazing speed, here you have some links to explore it, and to get a grasp of differences between lua implementations.

Agentzh talking about why he (and cloudflare) are targeting mostly luajit:

Nice introduction to luajit. In fact it's mostly lua, but maybe the second part will be more targeted to luajit

Mike Pall has written a few times about how luajit tracer works.

And here it's a functional library which, not being directly linked to luajit, it makes a really nice usage of iterators to build code structures lazily and make the traces jittable by luajit. nice code read.

If you're on the stock lua vm, here you have a paper with a good overview of how lua 5.0 was implemented.

Also, there are a lot of libraries and apps that are targeting just the luajit implementation. It creates some nasty splits on the community, but you know... these things happen.

martes, 10 de diciembre de 2013

Reading lua source

As I'm digging deeper into lua, I'm from time to time looking at the lua C source code itself, to see how something is implemented.

It's nice to see a highly commented code with some quite clear parts which goes right to the point. Quite tough though and dense at many other parts.  The whole lua 5.2.2 has a bit more than 14K lines. Not bad for the language, compiler, vm, repl, C Api, and libs.

Anyway, here's a couple of links I found useful in case you want to have a deep look at the lua source:

lunes, 2 de diciembre de 2013

Lua Workshop 2013

I was lucky enough to be in the Lua Workshop 2013. Held in Toulouse.

I had lots of fun there, both in the conference and outside it. For me, one of the most important topics raised were the speciation of the Lua world.  Stock Lua, LuaJIT, openresty, luvit ... Many different environments for which lots of packages do not work in different environments (lua-redis and lua-resty-redis, for example). 

This 'problem' extends to other parts of the language and comunity, like packaging. You cannot use luarocks for Luvit, or, the openresty packages are not in LuaRocks. The community is aware of that, and trying to find some compromises to create a healthy ecosystem.  I loved when LuaDist, LuaRocks and the debian packager of lua started an 'impro' discussion on issues they had, pros and cons.

Other talks were also amazing, like Roberto's one: 'Lua, past present and future'. Great way to expose the Lua history and philosophy and reasoning behind some of the features that Lua came to have nowadays. (Spoiler for the future: They are working on Macros!!!)

People modifying the vm to adapt it to their needs were also really wicked cool things we saw there.

Thanks to 3scale for sponsoring my trip, and to the Lua community for being so awesome :).

martes, 12 de noviembre de 2013

Renaming 'used' directories in Zsh and Bash

I can't understand why, oh why, neither bash nor zsh can apply the same policy to mv that they apply to umount, so that when trying to umount a volume that is in use, it tells you so.

When the directory you're in is renamed (moved),the shell keeps showing the old path you were in without notifying you in any way that this directory you see in the prompt is not that anymore.

 Probably it's an inode thing: When you change the name to a file/dir, you probably just have to change the inode's name. And I'm fine with it. Anyway it'd be a waste of resources to try to communicate to other open terminals/shells that there's been a change in a remote directory in the system.

That, and probably for thousand reasons I don't even know its existence.

So the question would be. Why couldn't we make bash/zsh check for the existence of the cwd when displaying PS1 if in the PS1 itself there's the metachart to show the directory path (%~ in zsh)?

Sorry if it sounds a bit rude, I just had an amazing debugging session for 2 hours because I was debugging the wrong thing. My bad, I know, but.....


So here's the way to reproduce
[ /tmp ] %mkdir test
[ /tmp ] %cd test 
[ /tmp/test ] %ls
[ /tmp/test ] %mkdir foo
[ /tmp/test ] %echo OHAI >foo/bar
[ /tmp/test ] %cd foo 
[ /tmp/test/foo ] %ls
bar
                                     In another terminal
                                     [ ~ ] %cd /tmp/test 
                                     [ /tmp/test ] %ls
                                     foo
                                     [ /tmp/test ] %mv foo bar
                                     [ /tmp/test ] %ls bar 
                                     bar
[ /tmp/test/foo ] % ls
bar
[ /tmp/test/foo ] %pwd
/tmp/test/bar


Is there a reason for that?


PS: My real case was something even more tricky as I changed 'reponame' to 'reponame2', and then recreated 'reponame', so I had different shells pointing to 'the same' path, without being actually the same.

domingo, 10 de noviembre de 2013

Jekyll with basic auth in heroku

Dabbling with different systems to write a static site, I was wondering if there would be a way to build a jekyll like site with access control (basic auth is fine) at zero cost.

rack-jekyll is needed to turn jekyll to a rack-like app.  Once we're in rack universe, we can easily add basic auth to it.

Unfortunately, I can't show the repo itself (remember, I needed auth....), but most interesting stuff is just  in the following links. The job left to be done is the glue-ing part.

But If I could do it myself, it can't be any hard.

martes, 29 de octubre de 2013

Keyboard galleries

I recently got a Kinesis Advantage which I'm not yet fully confortable with but I'm getting there. I'll probably explain the pros and cons I found in it in a future post.

 Lately, more and more programmers I know started caring about their keyboards. Some prefer the mechanical IBM M, or newer thinkpad keyboards (with trackpad). In ratpoison's wiki there's a gallery of lots of strange keyboards that ratpoison users have. But today I saw a keyboad gallery that made me really shit bricks.

If you're also a keyboard fan, check it out!

sábado, 26 de octubre de 2013

Memoize in lua

I love how simple and codeless it looks.
 function memoize(func)
   return setmetatable({}, {
     __index = function(self, k) local v = func(k); self[k] = v; return v end,
     __call = function(self, k) return self[k] end
   })
 end
 

lunes, 21 de octubre de 2013

jueves, 17 de octubre de 2013

Yet Another Find File In Project in Emacs

Every other day in reddit /r/emacs there's someone asking for this find-in-project feature that has sublime/textmate/vim(ctrl-p) users so addicted.  Is there anything similar for emacs?

The answer is (as usual), yes, more than one, probably more than needed.

People are suggesting projectile, prelude, helm or fiplr.  The point is that if the only feature you want is to search on a git repo, and you don't want any of the other sugar that projectile/prelude provide (you already know stock emacs), you can write your own in 5 minutes. So I did. Long time ago, when there weren't so many search packages, and I just wanted a fraction of available plugins offered.

It was also a nice exercise when I was learning elisp.

Here it is:


Sorry again to planet emacs readers. The gist isn't showing properly there.... :/

miércoles, 16 de octubre de 2013

TIL: 2013-10-16

  • C-x 8 is the prefix to insert 'strange' characters in emacs.
Not really easy to use as most of the chars take 2 keypresses more, but anyway, I don't have to enter ç or ñ that often.

The credits for this tip go to Toni.

viernes, 4 de octubre de 2013

TIL: 2013-10-4

In which branches is a given commit? (useful after using git pickaxe)

git branch -a --contains [treeish]

martes, 1 de octubre de 2013

Absolute vs relative times in applications

[m] ok
[m] and do you thing relative time is more useful then absolute one?
[m] or vice versa?
[m] the other one will be on tooltip
[rgrau] day/time for me is the most valuable   
[rgrau] batch processes are at 4:00
[k] I think relative time is more useful if it refreshes automatically
[rgrau] not 8 hours ago
[k] like, each 10 seconds
[m] it refreshes automatically
[k] then yes
[rgrau] but you loose track
[rgrau] because you have to synch every time  
[m] for me relative is for quick check
[m] absolute for serious things
[rgrau] at any scale, I know where am I
[rgrau] (tm)
[m] :D
[m] pfff
[m] because it is not 'ago'
[rgrau] absolute time is the way
[rgrau] if it's shorter 
[rgrau] (tm)
[rgrau] in the app logs, if you have to compare , there's absolute date
[rgrau] and absolute dates do not rely in the global state of the world
[rgrau] it's immutable
[rgrau] so better
[rgrau] (and I mean it (tm))
What's your take?

viernes, 27 de septiembre de 2013

Switching gmail accounts in Conkeror

Here I come with another hack for conkeror.

I've been using gnus on and off during the last year, but I keep comming to gmail web interface quite often.

The page mode for gmail is quite nice but there's one thing you can't do using the keyboard (AFAIK). That is changing accounts.

So I wrote a couple of functions to switch along N different gmail accounts you might be logged in.  In the end, I simplified the functions to a single one that just swaps between the zeroeth account and the first one. here we go.

miércoles, 18 de septiembre de 2013

Pretend you never pushed that file in git

Years ago, when I was starting to use git, I commited (and pushed) a file I didn't want. It was a huge TAGS file, which made the repo unusable.

 At that time I found a way to remove it, but today I stumbled upon a github page which explains it way better.

Enjoy

martes, 17 de septiembre de 2013

url-retrieve can't find localhost

Today I found a surprising bug in emacs url package. In fact, I'm not sure where the bug is.

The bug appears when trying to url-retrieve an url on localhost, like:
 
 
(url-retrieve "http://localhost:7070/api/services" 
  (lambda (s) (switch-to-buffer (current-buffer))))

The funny thing is that changing localhost to 127.0.0.1 works. Even adding a line "127.0.0.1 foobar" in my /etc/hosts also fixed it.

No clue why is that,but anyway,  it seems to be fixed in some development branch so I'm going to recompile my 24.3.50.1 to the latest one and see what happens.

jueves, 8 de agosto de 2013

conkeror go to buffer

In conkeror, you're trying continuously to think emacs, so many commands and shortcuts just make sense when you're browsing.

A nice way to move through buffers is obviously c-x b, but from time to time I was typing M-g M-g as if it was a 'goto-line' in emacs, but meaning goto-buffer. 

So let's go and use js to have this goto-buffer 

viernes, 2 de agosto de 2013

TIL: 2013-08-02

  • lua's require can't return multiple values. An easy way to overcome it is using unpack.
    local _ , resource     = unpack(require 'controller_helpers')

lunes, 29 de julio de 2013

TIL: 2013-07-29


  • There are many different ways to completely remove a file from a git repo
  • A CLOS user can change the method combination algorithm for a given function.

martes, 23 de julio de 2013

TIL: 2013-07-23

Today I Learnt:

  • Push a local git branch to a remote with different name:
  • git push origin local_branch:remote_branch 
  • Nginx lua path refering to the nginx -p flag
  •   lua_package_path ";;$prefix/?.lua;";

New section: TIL

With my friend and coworker Mikz, the other day something came out:

"We could do a 'Today I Learnt' daily/weekly meeting, where everyone would tell the others in one sentence something that he/she (unfortunately 100% chances of he) learnt that day/week. That would be a nice starting point for ideas/brainstorms/discussions or just sharing knowledge.

I liked the idea so much that I'll start a section here, where I'll put this kind of stupid things you learn that you normally wouldn't share because "it's just in the docs", or "it's simple, you just have to use it once and that's it" .

We'll see how it turns out.

miércoles, 10 de julio de 2013

Iterating through closures

At 3scale we're developing a product using lua.

It's kind of fun to work in a new project and even more to work with a small and malleable language (and even *more* working with a top-notch lua guy).

Part of the fun working with lua is that the language is so minimal that you have to build your own helpers for some functions that you'd have in other languages, but lua makes it really easy and straighforward.

Here's an example that just appeared when I was writing some tests (using busted, of course)


                
                local f = function()
                  local c = false
                  return function()
                    c = not c
                    return c
                  end
                end
                local l = f()

It's a plain simple closure, I know, but maybe it'll be ilustrative to some ppl not used to this approach.

It's just an iterator that returns true/false as you keep calling it.

You know, closures are the poor-man's objects, and objects are the poor-man's closures.

miércoles, 3 de julio de 2013

Farewell Mr Engelbart

So another of the great guys in CS passed away today.

The visionary man that conceived and brought to life many many things that we give for granted today.

Mouse and other input devices (I recall the one-hand keyboard), the first interactive systems, remote connections,.... all that during the fifties and sixties. A truly impressive amount of leaps from what existed at that time.

I haven't read anywhere explicitly about the relation between Engelbart and Smalltalk, but I'm more than sure that Douglas heavily influenced Kay, and probably the reverse is also true.  Probably one of the 5 most innovative guys in our field. Ever.

For those who don't know about Mr. Engelbart, you have to check "The mother of all demos". Look for the videos yourself. And try to imagine that in the sixties.

Here's a spanish link that talks about innovation, where Kay and Engelbart are mentioned lots of times. a good read also.

And another link about Aaron Schwartz, which links also to Douglas Engelbart. The image in that post and the post itself hit me hard when I saw them the first time. also, recommended read.



jueves, 27 de junio de 2013

github + emacs + conkeror = m-x github-clone-repo

Well, after a month of no activity in this blog (too many real life
issues to attend like european lisp symposium, european CL meeting or Barcelona Music HackDay and Sonar2013 itself), Whatever, I'm back to blogging.

Conkeror

Lately I started to use conkeror as my main browser. That means using
it for most of the tasks, and trying to configure it properly for all
my needs.

It feels really nice when the same shortcuts you'd use in emacs work
in your browser, and in fact, it has a very emacsy approach also on
the code. The browser is written in javascript, and it also has
page-modes, interactive functions, minibuffer, etc...

Awareness

When you use an extensible software you start becomming aware of your
movements.  I had that feeling and wrote org-protocol-github-lines to
add links in github pages that pointed to emacs.

Another feature of org-protocol-github-lines is that you have a new
button on top of github urls where you can clone a repo to your machine.


So what?

Since I have m-x in my browser, I try to write commands for repetitive
tasks (the same I'd do with emacs). So I wrote this little snippet
that you can put in your .conkerorrc and m-x github-clone-repo to get the repo on your box
. provided you have emacs-server running and
org-protocol-github-lines.el evaluated .

If you want to give it a try, you just have to get conkeror, org-protocol-github-lines, and this snippet. And configure them Probably I'll add the snippet to the repo. Pull Requests are also very welcome.

lunes, 27 de mayo de 2013

yet another git reset cheatsheet

After some time since my last git post, here I come again with a link to an explanation of wtf git reset is doing.

It's mostly the same as I pointed in a post 2 years ago, but just explained in a different way, shorter, and probably easier to print in a small paper and stick it in your table.

Enjoy :)

PS: There's a poll running on reddit about git clients. No matter what you're using, vote for magit :)

cool org-mode 8 features

This weekend I stopped playing with lua and finally got some time to upgrade org to the newest version.

Org 8 had lots of improvements and new features compared to 7.9.x.  There were a couple of those that I wanted to try as soon as possible:

  • New Exporters: org-mode now uses org-element to parse org files. That's a big big improvement because that allows users to write new exporters relying on a somewhat more abstract and high level parser api than what we had before.

  • orgstruct and orgstruct++ got orgstruct-heading-prefix-regexp option to set allowed prefixes and be able to fold parts of non-org files as if they where

On the exporters side, I tried org-reveal, and it works great so far. an exporter to make presentations using reveal.js   Probably I'll try it for real next week when when I'll be doing some talk at my workplace.

(require 'ox-reveal)
(setq org-reveal-root "reveal.js")

Meanwhile in orgstruct... being able to define prefixes for orgstruct-mode allows us to have foldable text files. For example, use the following line to make it work in elisp files.

(setq orgstruct-heading-prefix-regexp "^;; ")

miércoles, 22 de mayo de 2013

Lua vs javascript

I love lua.  Well, I luvit so far.

I haven't programmed many many things in lua, but the simplicity of it reminds me of smalltalk (in a veery different meaning of simplicity), or scheme.

The fact that it relies in very few known concepts as lexical scope, tables, and.... and that's it.

More that a language, is a language builder toolset.  It lets you do metaprogramming without really feeling that you're doing metaprogramming.  It makes it so simple you'd say it's "the normal thing".
  • loops? ok, you have 'for', and iterators. made from closures, or whatever, but that's it.
  • TCO? yes, but just if it's explicit.
  • splat arrays by default? as in Perl?... yes, just in the last position, perfect for apply-like calls. or you have unpack.
  • Varargs functions? yup.
With that and a bit of syntax sugar here and there, you have a really powerful language with near to no friction.  Provided you know a few other languages, you can always say: "ah, it behaves like js in the everything is hash, but it has proper scoping, and TCO ...."

I don't know much js, but I think lua is like a well done js.  Here's some funny Hacker News opinion



That and the community. #lua is full of people with background in many other languages, wise and helpful. and quite hacker style. I like it :)


Ah! and there's also metalua, which sounds like great fun. something like tcl's block syntax or lisp quasiquoting to mold lua to your needs.


sábado, 11 de mayo de 2013

Ryan Holiday TNW keynote: manipulating media

I'm having a hard time deciding whether to publish this entry or not, and which words to use to promote this video of Ryan Holiday where he talks about manipulating the media.

The media, and  how easy it is to generate buzz on the media and get traction. That guy might be some kind of marketing ninja.

So in TNW he did a talk about some experiences he had and how he sees the fragility of the truthiness in the media, and how they change mindful investigations for easy PR that will lead to easy clicks

If you watch the talk you'll understand the mixed feelings I had when writing about it. Hopefully the content is mostly correct and he's not playing on us.

Here is  the article, and the video:


domingo, 14 de abril de 2013

Embedding Lua, embedding Guile

Lately I've spent a quite few hours hacking on Lua. I love its simplicity, and the way it exposes lots of inner aspects of the programming language, that are usually hidden from the user in other programming languages.

One of the cool aspects of lua is the easiness of embedding it into your C app. But let's make it more fun. Embed Guile also inthere.

Lua

The process to embed Lua in a C app is quite easy, and simple (for really simple things), but I guess it gets more cumbersome when the complexity of the embedding system increases. Being a stack based vm makes it non-trivial to write some embedding functions (recursive functions, for example).

Guile.

The way to embed guile into an app is also, really easy. And Powerful. And you're not bound to interact with it using a stack based machine, but you just register your functions, and use the generic SCM type for all inputs and outputs. I find it easier than Lua

The Code

Here's a minimal example that does some trivial calculations and the flux of the code passes from C to guile, guile calls another C function, and after this, we call lua which also calls a function we have defined in C. In the end it's doing something like (n! + 1).

jueves, 11 de abril de 2013

Running a shell command on current file

Before being an emacs evangelist, I was a vim evangelist for a few years (next month sublime text), and one feature that I missed in emacs was having a way to reference the current file when executing a command.

In vim, it's pretty common to run commands like

:!gcc %

It's pretty simple and the syntax is really easy to remember, ":" for command mode, "!" to run something, and in the command "%" will be replaced by your filename.

I haven't found anything similar to "%" for emacs, so let's write some elisp to fix it.


(defun shell-execute ()
  (interactive)
  (let ((file-buffer (or (buffer-file-name) ""))
        (command (read-shell-command "Shell command: " nil nil nil)))
    (shell-command (replace-regexp-in-string "%" file-buffer command))))

(global-set-key (kbd "M-!") 'shell-execute)

domingo, 7 de abril de 2013

Guile's deprecation warnings

I've been hacking a bit of Guile (for embedding purposes), and somehow I got to use some deprecated functions: scm_int2num and scm_num2int. The amazing thing is that along with the result of the program, you get the following warning message:
Some deprecated features have been used.  Set the environment
variable GUILE_WARN_DEPRECATED to "detailed" and rerun the
program to get more information.  Set it to "no" to suppress
this message.
Nice, no? Let's set the variable and rerun.
`scm_int2num' is deprecated. Use scm_from_int instead.
`scm_num2int' is deprecated. Use scm_to_int instead.
These kind of things make usin guile a pleasure. Now back to embedding.

viernes, 22 de marzo de 2013

Keyboardless programming

Emacs + Dragon + Duct Tape.
My impression after seeing this amazing talk from PyCon 2013 by Tavis Rudd was a big "WOW"!
Actually, when you see it, you'll shit bricks.
Can your editor do this?
Sublime, really(?). (pun intended)



miércoles, 20 de marzo de 2013

occur: Poor man's taglist

From time to time I see some vim screencast and think: "oh, taglist, that was nice...", and yeah, in emacsland we have lots of alternatives, like full blown ecb, or imenu, or idomenu, I guess there might even exist something with speedbar...

But none of them really cuts it for me, I'd need the ecb one without all other ecb features. Or something like that

So here's the plain dead simple elisp I'm using lately. Just occur-mode and a keybinding to update the search. For ruby, it can't find all the dinamic shit in there, but you get a nice overview of what's in your file, and if it's properly indented (which should be) you also get the notion of what's public, private, etc...

Surprisingly, I'm using it more and more, and I can have different regexes for different filetypes. (even tune it to look for 'get\\|post' if I'm editing sinatra things.)

Dead simple, but it kind of works.
(defun rgc-show-ruby-tags ()
  (interactive)
  (occur "^\\s-*\\\(class \\\|module \\\|def \\\|[^:]include \\\|private\\b\\\|protected\\b\\\)"))

(define-key ruby-mode-map (kbd "C-c t") 'rgc-show-ruby-tags)

domingo, 17 de marzo de 2013

Ratpoison and trays

Ratpoison doesn't come with any system tray by default (unlike stumpwm, which has mode-line).

Why you need a f*cking systray? you ask...  Well, in my laptop I need nm-applet to connect to my wifi.

Lately, I found that using stalonetray and nm-applet is the best combination. No need for gnome, or fancy configurations.


That's all it takes to have it working and not bothering you. It's amazing how easy it is, and how long I postponed this migration falling back to gnome.
  unmanage stalonetray
  exec Downloads/stalonetray-0.8.1/src/stalonetray
  exec nm-applet

I just discovered this other systray app. I never tried it, but I think it's worth a try.

viernes, 1 de marzo de 2013

Melpa, erc-tweet and erc-image

This week Sacha published  a post on her blog related to emacs (welcome back to emacs blogsphere!) and Just before a couple of very nice tricks, she says:
"A kid in a candy store – that’s me with M-x list-packages".

Well, I feel exactly the same.  It feels like when I browsed cpan looking for recent updates in packages. Daily.

Yesterday, a couple of packages I developed came to life in melpa.



erc-image

Shows image linked from erc buffers either inlined in the same erc buffer or in a dedicated buffer (and resizes it to a decent size).

erc-tweet

Shows tweets linked from erc buffers either inlined in the same erc buffer.


Both are quite simple packages, but if you find any issues (which I'm sure there are, because they are my first packages that will reach more than 10 machines), please file a bug either in https://github.com/kidd/erc-image.el  or https://github.com/kidd/erc-tweet.el . Or catch me in #emacs as rgrau or rgc.

W00t!


As a funny related addendum, here's a new package that appeared today in melpa:




So, after some months of doing things like '$ vim ~/.emacs' and overcome that, I'll now be able to 'emacsclient ~/.vimrc' .

Great.


domingo, 24 de febrero de 2013

Armagetron advanced, a few years after

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

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:
  1. edit nginx conf file or lua file called from the nginx conf file.
  2. restart or reload nginx.
  3. check in nginx log file for errors
  4. Try the feature via curl or browser
I 'nulled' the 2nd step via a very simple pattern that I've been using lately. It's dead simple, but involves a few elisp-ities you may or may not know. Anyway, check it out.
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:

 (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!