lunes, 28 de diciembre de 2015

Linting guix packages

Guix is getting more mature every day (It's probably going to beta soonish).  One of the commands it got 'recently' is guix lint.

Once you write a package definition you want to know if it complies with guix standards. Let's try guix lint.

  1. Write package definition.
  2. Put the definition into a guix checkout (not your running guix).
  3. run 'guix environment guix'.
  4. cd to the checkout directory.
  5. ./bootstrap && ./configure --localstatedir=/var --prefix= && make
  6. ./pre-inst-env guix lint my-package
  7.  If you get an 'ERROR: missing interface for module (gnutls)', means that you need to install gnutls. 'guix package -i gnutls'
  8. After that, you can finally run 'guix lint my-package', and it'll tell you if you have any obvious failures or warnings in your definition.

miércoles, 23 de diciembre de 2015

dash docset for nginx lua

Here's a quick hack I wrote to fetch the reference doc for nginx lua module and convert it to a dash docset. Which I view using our beloved helm-dash.

Quick, and kinda easy.  It's totally hackish in the way that I'm parsing HTML with regexps. Not even recursive regexps.....

But the thing is that this html is generated by markdown, and as it's fetching for a very concrete type of lines, they are all formatted the same way.

Another option (less hackish but for this concrete case, equally fragile) is using xmlstarlet. The code is also in the import.sh file (for reference).

So here's the kidd/HttpLuaModule.docset repo.

jueves, 3 de diciembre de 2015

Improving Lua support in etags

It seems it's Lua time again!

So for my new project I'm starting in openresty+lua, I needed some kind of support for tags. Lua is a very simple language syntaxwise (it's whole grammar fits in a screen of code).

Etags support is quite poor, in fact, if you read the emacs-devel message when it got added, you'll see how basic is it.

+ * Lua tag functions
+ *  look for function, local function.
+ */
+
+static void
+Lua_functions (inf)
+     FILE *inf;
+{
+  register char *bp;
+
+  LOOP_ON_INPUT_LINES (inf, lb, bp)
+    {
+      if (bp[0] != 'f' && bp[0] != 'l')
+       continue;
+
+      LOOKING_AT (bp, "local");
+
+      if (LOOKING_AT (bp, "function"))
+       get_tag (bp, NULL);
     }
 }

The regex version of this would be:   /^(local)?\s+function\s+(\w)/ .

So I wanted to add support for lines not in the beginning, and also to add support for things like

local foo = function (p1, p2) .... end


So it turned out to not be very difficult to augment etags to do that.

tags:
 etags --language=lua --regex='/.*\([^. \t]\)*[ \t]*=[ \t]*function/\1/' \
 --regex='/.*\(local\|\)[ \t][ \t]*function[ \t]\([^ \t(]*\)[ \t]*(/\2/'  **/*lua

Just adding this to the Makefile allows me to catch the other forms of lua functions. Again, regex to the rescue! :)

viernes, 27 de noviembre de 2015

Managing dockers (and some emacs help)

Docker containers are a great way to isolate an application. You don't need to pollute your host machine with all the dependencies, and makes it easy to deploy it everywhere.

I'm using docker on my local box for some apps I can't (or don't want) to install, one of them being openresty (until there's a guix package (or I manage to create it), I'll keep it that way).  But using docker for local development is a bit more complex than just running an app there.

First, a few tips for using docker for local development:

Using docker without sudo


By default, docker asks for superuser permissions in order to comunicate to docker server. You have to create a user group called docker and add your user to that group. After that, you can run docker commands as your regular user.

Building docker images and running them


In the beginning,I was creating lots of images, because every time you change any code in your app, the image has to be rebuilt. To build an image, being in your app directory (where your Dockerfile is and your code is), you normally do 'docker build .'  Then, after building, the last line of the output contains the hash for that image in a line like: 'Successfully built 01b4cd5d3e'.  you normally want to run it afterwards, so you'll 'docker run -t -i 01b4cd5d3e bash', to get in a console inside it.  I just wrote a couple of shell functions to ease the loop of build and run.

function dbuild {
    export DBUILD=$(docker build . | grep "Successfully built" | col -b | awk '{print $3}')
    echo -n $DBUILD
}

function dattach ()  {
  docker run -t -i $DBUILD bash
}

With this I can save the copypasting of the image id.

There's yet a better trick to not have to rebuild the image every time, which is to mount a directory of the host machine inside the container.  For this to happen, we have to add the '-v' flat to docker run. Now, in the docker file, we'll create a directory for our code to be in, and just mount it the current directory in that place. In my case, the directory is '/opt/apisonator'.
 
function dattach ()  {
  docker run -v $(pwd):/opt/apisonator/:rw -t -i $DBUILD bash
}

With this, we have a pretty slick way to run our code and tests inside docker, with full access to the docker, but also being in synch with the outside.

Sooo.... what about emacs?


In case you have many images and containers, you'll probably want to do bulk actions on them (running them, deleting, etc.). Emacs has 2 modes for interacting with docker: docker.el and docker-tramp.el .

The first one (docker.el) uses tabulated-list to show all docker images and containers in your machine, and allows you to run, pause,kill, push or pull images and containers.

Docker-tramp.el allows you to use tramp to access the files inside the container from your host emacs. That's pretty pretty neat:  c-x c-f //docker:012f23e2fb/var/logs/.... .

Again, emacs saves the day.




viernes, 20 de noviembre de 2015

Mu4e and gmail (multiple accounts)

Using Emacs for reading mails is super neat and all, but honestly, gmail does an amazing job managing mails.  To make things even 'worse', I wrote some small js to ease the process of managing multiple gmail accounts in conkeror.

I tried to replace gmail with gnus multiple times, but it never worked out very well. Mu4e seems the most sensible choice, but I always had issues configuring it for my gmail accounts ("Your IMAP server wants to alert you to the following: Please log in via your web browser:
http://support.google.com/mail/accounts/bing/answer.py?answer=78754 (Failure)" being the last one), but I finally got to solve them.

If you get the "Please log in via your web browser" there are 2 ways of solving it.
  1. As explained here, allow less secure apps, by going to your accouts settings. This may not work in your company account (if they disabled this option)
  2. Add an application password token. By going to your security settings. and adding a new 'application password'. You can use that token in your .offlineimaprc  file.

Once the basic configuration was working, and read pretty much all the docs and blogs on the field, I quickly got annoyed by the 'dashboard' view mu4e offers.  It provides exactly 0 useful info.  So I got rolled up my sleeves and wrote this tiny little function to do my usual actions in mu4e:

I want to know about new mails in both my personal and corporate accounts.

(defun mnew ()
  (interactive)
  (mu4e-headers-search-bookmark "flag:unread AND NOT flag:trashed AND maildir:/raimon@3scale.net/INBOX OR 
                                 flag:unread AND NOT flag:trashed AND maildir:/raimonster@gmail.com/INBOX"))


Not very nice, I know, but for now, it already provides me something I wanted and wasn't quite possible in gmail. also, I don't have to visit the mu4e 'dashboard'.

Ah!, to periodically fetch new mails, for now I'm going with elisp's timer `run-at-time'.

(run-at-time nil (* 60 5) 'mu4e-update-mail-and-index t)

miércoles, 11 de noviembre de 2015

TIL: comint-send-string

I just learned a really powerful elisp function called `comint-send-string' . It's so easy to understand that probably a simple example will be enough.

  (comint-send-string "*shell*" "xclock\n")

Right, it sends a string to a comint buffer named "*shell*". you can use it to easily interact with any inferior process you have in your emacs. that means clojure repls, ruby repls (robe), etc....

miércoles, 21 de octubre de 2015

Command line bookmarks

I saw a Gary Bernhardt's talk where he explains a few console tricks. Most of the tricks themselves I already knew, but the biggest outcome of seeing the talk is the motivation for scripting everything and using small functions to use bash/zsh the fastest possible way.

I'm a big fan of zsh, and I have a fairly big .zshrc (101 aliases, for example).

At work, we use a quite strict and orthogonal way to tag all project issues, so that one can find out easily which issues are waiting for merge, which are halted, or which are being worked on.  As we use github, the usual way is log into github (or waffle) and search .

But when it starts getting repetitive, I usually think how to do it faster. one option was bookmarks in conkeror, but it didn't quite work.

Now, I'm using this in my .zshrc :

BROWSER=/home/rgrau/bin/conkeror
PROJECT=projectname

function ghnext {$BROWSER "https://github.com/3scale/$PROJECT/issues?q=is%3Aopen+label%3AT-core+label%3AB-Next"}
function ghmerge {$BROWSER "https://github.com/3scale/$PROJECT/labels/needs%3A%20merge"}
function ghmy-issues {$BROWSER "https://github.com/3scale/$PROJECT/issues?utf8=%E2%9C%93&q=is:open+assignee:kidd"}
function gh3scale {$BROWSER "https://github.com/3scale/$PROJECT"}
function ghissues {$BROWSER "https://github.com/3scale/$PROJECT/issues"}
function ghcurr {$BROWSER "https://github.com/3scale/$PROJECT/issues?q=is%3Aopen+label%3AB-current+label%3AT-core"}
And here is gary's talk:

viernes, 19 de junio de 2015

Clasp. Implementation and its applications. Just wow

A talk that just left me shitting bricks. And makes me want to return to the drug discovery world via Common Lisp.

If you have any work for me, mail me at raimonster+nospam@gmail.com .

Wow Wow Wow.




And here's another neat story about lisp hackers: Crash Bandicoot in Lisp

domingo, 24 de mayo de 2015

Farewell Mr.Nash. Games and complexity. p vs np

Today, 24 of may 2015,  John Nash passed away in a traffic accident. His wife also passed away in the same accident....

Apart from his work on Game Theory (which I studied a bit back in university), he also had great implications in cryptography and problem complexity.

Here are a couple of good videos about P vs NP. The first one pretty approachable to everyone. Second one is a class from MIT 6.006 by Eric Demaine.





Here's a great talk by Eric Demain I just stumbled upon. This guy is really impressive, follow him everywhere. A true inspiring guy. He's teaching 'Introduction to Algorithms' and 'Advanced Algorithms and Data Structures'




miércoles, 13 de mayo de 2015

[ANN] - Helm-dash 1.2.1 released

It's been a long time since any announcement on helm-dash. Now that we hit 100stars, we are happy to release a new version which supports third party docsets.

Kapeli keeps a list of user contributed docsets which aren't officially supported but in a contrib repo.

As the way to fetch the docsets changes completely from the official ones, I created a kind of adapter that fetches the docsets info and offers a curated version through a very simple API. The app that manages this is called dashes-to-dashes .  Every 20something minutes it updates the list of user contributed docsets, and makes it available for any helm-dash user who runs `m-x helm-dash-install-user-docset'.  The official ones are still available on 'm-x helm-dash-install-docset'.

There are some improvements in the support for windows, and a few bugfixes here and there.

Also, there's a branch waiting to land that will improve the userdoc trimming. When searching "rails | controller" it'll narrow the search just to 'ruby on rails' docset.

Stay tunned, and thanks for the support!

lunes, 4 de mayo de 2015

feh image viewer

My need for viewing images is really low. Just a few screenshots and funny pics, but I need some app to view them.

I usually use emacs for this task, but there's this little suckless app, feh , which is doing its job quite well. I use it to set the background image on my laptop

exec feh --bg-scale ~/dotfiles/wallpapers/sun.png

and I just configured it to accept vim-ish keybindings.

martes, 14 de abril de 2015

Cache is the new GC

Now all rubyists are pros in all Garbage Collection techniques.

And we all have to know the difference between mark&sweep, reference counting, generational, and whatnot (I also see more references to this in the lua mail list lately).

And we're already optimizing for not creating so many objects. And we pray Rust and Nim for being so powerful and fast and allow us to manage memory manually. and we decide that checking for existence of an element in a short Array is probably faster than checking in a small Set.  Even more if we know the distribution of the expected values.... Well... now, the next step is Cache.

Interesting points here http://dev.mensfeld.pl/2015/04/ruby-global-method-cache-invalidation-impact-on-a-single-and-multithreaded-applications/ .

And after that, Locality of variables, and compiler tricks to optimize code. Here's a nice StackOverflow thread.

Inside this thread the thing that brings you back to reality is that compilers are allowed to do pretty amazing things . Things that are so complex, that if you have to have that in mind... well.... good luck.  I guess for real time systems it makes sense, or very low level programming, but there are really complex techniques which seem really hard to anticipate .

What's the point of all that? No idea. it's just funny that sometimes we try to push low level languages to higher levels, and then, we program ruby as if we were forging asm.  Funny :) . In the end, all benchmarks are made to lie in one or other regard, so I guess the most important thing, is having Amdahl's law in mind (or an adaptation of it): All the optimizations you'll do, will apply only to the percentage of code where the optimization is feasible.  The original speaks about intrinsically serial code that cannot be parallelized.   My idea is that optimizing for cache hits in ruby when you have a webapp which does http calls here and there to external systems is not really the way.
 

miércoles, 8 de abril de 2015

Regexp puzzles!

I've been trapped into this http://regexcrossword.com/ for  the whole afternoon...  Pretty cool pastime.

I guess I'd enjoy a bit more complicated one with more usage of recursion, backreferences, and maybe lookaheads...  But it's fine.  A nice exercise to get your brain spinning for a while.

I'm now back to my haskell lectures.   Oh yeah, I'm trying to learn Haskell.

Again

martes, 24 de marzo de 2015

download youtube videos with conkeror

As internet is scarce in my new $HOME, now, when I have some, I tend to download lots of things in my $COWORKING-PLACE and schedule them for watching/reading later.

So I tried to automate the process a little bit. Obviously, using conkeror.

  • install youtube-dl  .
  • put this in your .conkerorrc file.
  • M-x youtube-dl RET
Done.

sábado, 21 de marzo de 2015

more about XEROX

You know I love to read about XEROX stories, right?

Here's an article titled How parc saved xerox.

Enjoy it, and the links of it.   Entertaining and nice

jueves, 19 de marzo de 2015

Wifislax and booting

This is not a particularly general tip or post, but Toni and I have been stuck with it for a few hours (day and 1/2, on and off).

Wifislax is this great auditing linux distro you can install and run from your usb.

But you have to know that even when burning it with either unetbootin or dd, the usb drive is not bootable.  Don't know why, but it's not.

You have to mount the drive, and  run a file called /boot/bootinst.sh .

Tada!.

Stupid, yes. But it took us hours to find out. It took more time to burn the iso than to do the actual 'auditing' job.

miércoles, 18 de marzo de 2015

Corgfiguring

Org is a beast, you probably already know it, whether you use it or not.

I've been using it on and off for a few years (at least 5), but never settling with it. Now it seems it's changing. But I digress.

Something that in the beginning was disturbing me was the many many ways you had to configure its behaviour. there were these #+FOO BAR , and these :PROPERTIES:,  but you never knew which one to use, and in fact, I didn't even try to remember them.

But there's an absolutely coherent logic behind it. I'll try to explain.

If you use org as a way to manage your life, you can store different info in different files. One for calendar related things (that come from google calendar, or some rss feed), captures, captures from your browser, or from different areas of your life (work, home, fun).  Some of them could live in the same file, but you can decide to use different files (One of my biggest questions to date is what should be a file, a heading, or a tag).

So it makes sense to be able to have global configurations for everything.  For example org-startup-folded . this variable defines in which folding state will be your org files opened.

BUT!  There might be a file, which you want different settings.

     #+STARTUP: overview
     #+STARTUP: content
     #+STARTUP: showall
     #+STARTUP: showeverything

Put one of those in the beginning of your file, and this option will override the global variable.

AND! You may want one of the trees/subtrees in that file to be ruled by a different rule.  Then is when you put a property in that given subtree.  In this case, the property is called "VISIBILITY", and the allowed values are folded, children, content, and all.

So after all, it makes sense that things can be configured at so many levels.

Usually, there's a global var and a file setting for most of the options. The subtree level one is not so common, but you get the idea already.