domingo, 23 de noviembre de 2014

Temporarily ignore people in IRC

I'm using irc more and more for my communication with others.  And spending more time in IRC means that it makes more sense to optimize it.  And also, erc is a good playground for us, elisp hackers :)

So when someone is bitching or saying nonsensic BS on some IRC channel (or slack, or hipchat, or anything that supports bitlbee), you can ignore him/her, but often you forget to unignore, and after a few hours they tell you something important and you just miss it.  Not good.

So here's a timed ignore command for erc


(defun erc-cmd-TMPIG (&rest users)
  (let ((b (current-buffer)))
    (dolist (user users)
      (erc-process-input-line (format "/ignore %s" user)))
    (run-at-time (* 60 10) nil
                 (lambda ()
                   (dolist (user users)
                     (with-current-buffer b
                         (erc-process-input-line (format "/unignore %s" user))))))))


Yes, some of you reading this will be the victims of this... :)

EDIT: This code needs to be in a file with lexical scope active. otherwise, use lexical-let instead of let

jueves, 13 de noviembre de 2014

Checking what's new with git

Short post today, but kinda useful IMHO.

From time to time I have to show my bosses what our team has done in the last period. We use 2 weeks as our sprint lenght (although we're not following scrum strictly).

Anyway, I was looking for a way to summarize the activities of the team, and instead of trying to remember, or having to write annotations for the next report, I just crafted this nifty little git log command which allows me to know which branches have been merged to master in the last 2 weeks.

So now, 5 minutes before the meeting I just run it and see what I have to debrief to my bosses (or other teams in the company).

git log --since=2.weeks.ago --merges --branches=master --first-parent --graph --pretty=oneline | sed -e 's/.* from/*/'  

Try it in your repos, and see how it works for you. For me it pretty much nails it.

viernes, 31 de octubre de 2014

Poetry with factor.

I'm at the moment at the polyconf in Poznan. The average level of
the conference was very nice and High quality deliveries.

One of the activities of the conference was a programming poetry challenge.

Given that lately I've been doing some factor, and the huge
flexibility of it, I decided that this would be a competitive
advantage. And it certainly is.  Basically because it uses no syntax
at all, you can just type a text, and make this text do nothing.

And the trick is to rewrite no-word to a nop.  In the end I didn't
make it into the poetry contest (the price was a jetbrains license anyway).

Here's the code. Lovely.

jueves, 16 de octubre de 2014

Metaprogramming Zsh - Poor man's autojump (or J (or Z))


There's autojump, there's also J, there's also Z.... Each one of them with its own fans.
I've been trying some of them on and off, but mostly ditched them because I don't need the complexity and I don't get used to type 'z' when I mean 'cd'.


An easy and smart alternative is to autogenerate aliases on boot. It's easy, you can understand all the logic behind it, and your shell will provide the autocompletion. Pretty darn simple.
function aliasgen() {
    for i in ~/workspace/*(/) ; do
        DIR=$(basename $i) ;
        eval "alias $DIR='cd $i'";
    done
}

aliasgen


For your usual projects, this should be more than enough. "But, but sometimes I want it more dynamic aliases, like, for random directories", I hear you say. Ok, then there's this nifty functions that also creates aliases on the fly.


function a() { alias $1=cd\ $PWD; }


When you're in a directory you wanna keep for later, type "a foo", and an alias "foo" that will go to the current directory will be generated.
Even if you wanted to persist them you could create a symbolic link from the "~/workspace" directory in the previous snippet with the choosen name.
These 2 little tricks just show how using old tools and some wit can get you going a long distance.
I hope you enjoyed this. Cya next time!


EDIT: Post deprecated in favour of CDPATH .  At least I learnt a new thing . Thanks Toni!

jueves, 25 de septiembre de 2014

Back to the trenches with... speadsheets?

I'm back to reality after my craziest holidays ever. Great new people, and fun with old friends...

And I'm back with some research on spreadsheets.  My new role as team leader involves some team organization and managing skills.  Due to my inability to organize myself, I'm trying to solve this once for all, and it's also a good oportunity to take another look at org-mode.

I've been dabbling with org-agenda and appointments. The git repo has already some '.org' files :).

So today I was watching a few talks from the StrangeLoop 2014, and I stumbled upon this 'Spreadsheets for developers' talk.  The talk has its points. I don't agree with everything that is said there but it does confirm the overally idea I already had of spreadsheets.  Everyone uses them to solve their own problems. It's the emacs of non-developers.

So I remembered org-spreadsheet, and hacked a bit with it.  It's really impressive, and, although a bit cumbersome in the beginning, I think it has lots of potential. And if spreadsheets are code, org-spreadsheet is more code than excel


There are many many different shortcuts but you only need a few to get started.

shortcut what it does
c-} toggles column/row legend
c-' global formula editor
c-` cell editor (formulas)
c-c c-c (on #tblfm) updates table recalculating
s-RET inserts previous number +1


I really encourage you to read the manual and also the tutorial, where you'll find out how to write formulas with Calc or elisp.


Also a nice trick is the org-table-to-lisp function, that will parse the table the cursor is on and give you a list of lists with the data.

martes, 1 de julio de 2014

More JIT and luajit links

Here's another of these list of links post: About JIT and Luajit.

This is hardcore stuff. I've read all the articles but honestly, I barely get what I'd have to do to write something with this on my own. Anyway...

The luapower site is full of nice tricks for lua libraries. Highly recommended (at least skim it). Specially the design of glue and lua&luajit tricks.

edit: Also, a brainfuck compiler using dynasm
Cya!

miércoles, 21 de mayo de 2014

multiple value return in lua

Lua functions can return multiple values, and the language will natively assign them to the variables on the other side of the equal sign.

local a, b = (function() return 1,2 end)()
print(a,b) => 1     2
That's fine, but when things get a bit more tricky is when the values are not returned in tail call position.
local a, b = (function()
               local res = (function() return 1 , 2 end)()
               return res
             end)()
print(a, b) =>  1    nil
The catch is that lua assigns the 'rest' of the values only to the last element of tables, or argument lists. If we want to wrap a function into another while not being in tail position, we have to use a little trick. This trick is unpack.
local a, b = (function()
               local res = {(function() return 1 , 2 end)()}
               return unpack(res)
             end)()
print(a, b) =>  1    2

jueves, 8 de mayo de 2014

Presenting Eva

I've hacked a tiny little lisp interpreter in lua, and I called Eva, for obvious reasons.

It's not pretty, it's not complete at all. Hell, it doesn't even have strings, you can't call native lua functions, and there are no conses (although you could get them using functions for that).

The whole point of it was to have some fun implementing a tiny lisp-like thingie, and to make it in lua, which is a language that I like quite a lot (although some of its table missfeatures make me cry sometimes)

Without further ado, Eva .

miércoles, 7 de mayo de 2014

erc makes you faster at jokes!

Hi, today's post is a simple sinppet I wrote to ease the pain of looking for recurrent references on the internet.

At work we use IRC heavily (it's our main channel for comunication). As you know,every platform or channel of comunication has its own processes and joke (slightly related (but interesting nonetheless): The medium is the Massage ) . So IRC is mostly about sending links to gifs and to funny images, and funny images with captions in them.

It's so simple that it doesn't even need explanation. You just have to know that all defuns named "erc-cmd-SOMETHING" will be automatically callable from erc as a /something.



(defun erc-cmd-MEME (wat)
  "Fetch links from the alist of knowledge"
  (let ((h '(("trap" "http://4.bp.blogspot.com/-ae1ZRrrjs8c/Th0rz7ZvogI/AAAAAAAAANU/QM2WW-LNZXY/s1600/original.jpg"))))
    (erc-send-message (cadr (assoc wat h)))))

Combined with erc-image.el, it makes a really nice IRC experience :)


viernes, 28 de marzo de 2014

git reset. again

This is shamelessly copied from the web archive.

Assume you start from a "everything is committed and golden" state. Let's pretend you came to this starting point via a git checkout: and then you edit a bunch of stuff, compile/test, and then git add and git commit:
$ git checkout mywork
...edit edit edit...
$ git add ...
$ git commit
If at this point you do a git reset, here's how the type of reset ("soft", "hard", or the default, which is "mixed") affects things:
$ git checkout mywork
            # --hard resets to this point
...edit edit edit...
            # --mixed (default) resets to this point
$ git add ...
            # --soft resets to this point
$ git commit
Also note, as gitster says, that git commit --amend makes the git reset --soft mostly redundant.

jueves, 27 de marzo de 2014

sed vs unix

 UNIX         |  SED
 -------------+----------------------------------------------------------------
 cat          |  sed ':'
 cat -s       |  sed '1s/^$//p;/./,/^$/!d'
 tac          |  sed '1!G;h;$!d'
 grep         |  sed '/patt/!d'
 grep -v      |  sed '/patt/d'
 head         |  sed '10q'
 head -1      |  sed 'q'
 tail         |  sed -e ':a' -e '$q;N;11,$D;ba'
 tail -1      |  sed '$!d'
 tail -f      |  sed -u '/./!d'
 cut -c 10    |  sed 's/\(.\)\{10\}.*/\1/'
 cut -d: -f4  |  sed 's/\(\([^:]*\):\)\{4\}.*/\2/'
 tr A-Z a-z   |  sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'
 tr a-z A-Z   |  sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'
 tr -s ' '    |  sed 's/ \+/ /g'
 tr -d '\012' |  sed 'H;$!d;g;s/\n//g'
 wc -l        |  sed -n '$='
 uniq         |  sed 'N;/^\(.*\)\n\1$/!P;D'
 rev          |  sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
 basename     |  sed 's,.*/,,'
 dirname      |  sed 's,[^/]*$,,'
 xargs        |  sed -e ':a' -e '$!N;s/\n/ /;ta'
 paste -sd:   |  sed -e ':a' -e '$!N;s/\n/:/;ta'
 cat -n       |  sed '=' | sed '$!N;s/\n/ /'
 grep -n      |  sed -n '/patt/{=;p;}' | sed '$!N;s/\n/:/'
 cp orig new  |  sed 'w new' orig
 hostname -s  |  hostname | sed 's/\..*//'

shamelessly copypasted from here

sábado, 22 de marzo de 2014

More Lua iterators


After the permutations post, I thought that we needed something like a 'take' function, that would allow us to use infinite streams safely.

local function take(n, it , param, state)
  local count = 0
  return function()
    count = count+1
    if count <= n then
      return it()
    end
    return nil
  end
end


local function take_while(fun, it , param, state)
  return function()
    if fun() then
      return it()
    end
    return nil
  end
end
 
Simple but nice.

miércoles, 19 de marzo de 2014

Permutations in Lua. An iterator example

Here's some code I just wrote when messing with an algorithm to generate permutations. The code is just perfect to be used in the form of an iterator, and although I was reading the example in Perl (I read it in Higher Order Perl, an amazing book no matter what's your programming language of choice), I thought Lua would be a good candidate for that.

Along the way, I wrote a few utility functions you can see in there. Mostly tests on function composition and mapping over iterators.

Here's the code. If you need to generate permutations, I found this algorithm (which I don't know the name, but let's call it 'odometer counting') very easy to implement and understand. At least easier than Randal's way of doing it.



local inspect = require'inspect'

function map(f, t)
  local r = {}
  if type(t) == 'table' then
    for _, x in ipairs(t) do
      r[#r+1] = f(x)
    end
  else
    for x in t do
      r[#r+1] = f(x)
    end
  end
  return r
end

function count()
  local c = 0
  return function()
    c = c + 1
    return c
  end
end

-- for x in count() do
--   print(x)
--   if x > 10 then break end
-- end

function permutations(...)
  local function inc(t, pos)
    if t[pos][3] == t[pos][2] then
      if pos == 1 then return nil end
      t[pos][3] = 1
      return inc(t, pos-1)
    else
      t[pos][3] = t[pos][3] + 1
      return true
    end

  end

  local sets = {...}
  local state = map(function(x)
                      return {x, #x , 1}
                    end , sets)
  state[#state][3] = 0

  local curr = #state

  return function()
    while true do
      if inc(state, curr) then
        return map(function(s)
                     return s[1][s[3]] end,
                   state)
      else
        return nil
      end
    end
  end
end

function compose(f,g)
  return function (...)
    return f(g(unpack(arg)))
  end
end

pinspect = compose(print, inspect)

map(pinspect, permutations({1,2,3}, {5,6,7}))

local c = 0
for i in permutations({1,2,3,5,6} , {3,4,5,6,7,6}) do
  c = c+1
  if c == 10 then break end
  pinspect(i)
end

miércoles, 5 de marzo de 2014

smart-browser

Since I discovered conkeror, I'm not using w3m that much, because conkeror works great :)

The issue is that doing any kind of web dev in conkeror is suboptimal. Its support for firebug is quite basic. One option is opening different browsers depending on the url. That makes sense, and I used this technique when I was using w3m.

But I wanted to explore a different approach. My problem is the following. Usually I want to open a url in conkeror, but if chromium is already opened, it's probably that I'm using some of the devtools, and I want to keep using it during this 'session'.

What I don't want is to have 2 browsers opened.Unless I open them manually, then, follow the preferences. Although being complex to explain, it just feels right when I use it.

So I hacked some elisp to give priorities to browsers, and use a default one when there's nothing opened.

The idea is quite simple: Just look for the browsers in order of preferences, and open the first one that is already opened. The last one is a hack, to open conkeror by default.

It's an ugly hack, but hopefully you'll learn some elisp API you didn't know :)

Sounds for programmers

Between usual music and abstract music (which I can't get to listen for any long time), I lately discovered some webs that provide generated sounds for as long as you want. Just the fact that they don't have ads is already a big +1 ;)

Pick your favourite :)

jueves, 13 de febrero de 2014

Guix tutorial, using, creating, contributing

GNU Guix is what they call a 'functional package manager'. Think as if git and apt-get had a child. It allows you to do transactional rollbacks or have multiple versions of the same app coexisting. Probably if you're here you already know what's GNU Guix, so I won't bother explaining it again. Visit the official page if you need more info.

To contribute to Guix, you'll have to have a few dependencies installed, and after that, follow a few steps which I'll try to explain in here, as the documentation that's now on the guix site is quite scarce (for newbies at least).

There are a few more steps than in most applications, so I'll put them here. 

- Install guix. Download the git version from git clone git://git.savannah.gnu.org/guix.git. Then, ./bootstrap && ./configure && make # make install is optional
- Create users. Follow these instructions to create some build users.
- Create the package store. mkdir /nix/store
- Create ~/.guix-profile. This should be created by guix-deamon itself.
- Put ~/.guix-profile in $PATH.

 

 Basic commands 

 

To run any guix command, you should have the guix server running. When you run guix commands, the client will connect to the daemon, and will run the command itself.

We'll try to install and run a test demo that guix users use as a minimal test. It's a helloworld app.

- Run server.  ./pre-inst-env guix-daemon --build-users-group=guix-builder
- Search package.  ./pre-inst-env scripts/guix package -s hello
- Install package. ./pre-inst-env scripts/guix package -i hello
- Run hello. The hello app should be in your $PATH.
- Remove package. ./pre-inst-env scripts/guix package -r hello

If you installed Guix system-wide (make install), ./pre-inst-env is not needed.

Guix Recipes


If you're trying to write a recipe for guix, here are the steps to follow, and good practices.

First, let's see what's in the 'hello' recipe, and try to understand it. then, we'll add a few things to make it build something more interesting. The file is in gnu/packages/base.scm, so when we open it we see something like this:

We can see a few interesting lines there. Even if you have no scheme knowledge, you can find out what's going on there.  The name and version of the package in some places, the url (mirror:// means "download from any gnu mirror", but could be just a normal URL), description of the package.

The hash code in the sexp (sha256 (base32   "19qy37gkasc4csb1d3bdiz9snn8mir2p3aj0jgzmfv0r2hi7mfzc")) is a checksum of the downloaded file. You can get that number using

./pre-inst-env scripts/guix download URL or
./pre-inst-env scripts/guix hash FILE.

 

 Example Recipe


As an example, we'll build a relatively simple package, luajit.

In guix, recipes are organized in files, but not necessarily one recipe per file.  When I wrote the luajit recipe, lua.scm already existed, so it made sense to put it in the same file.  If we add a new file, we should add the file in the file gnu-system.am .

Although having different presets for different build systems, many packages need some special tweaking.

here we added PREFIX variable in make phase, and we removed configure phase and test.

Guix installations happen in phases, usng alist-delete we can remove one of them.

We can try the build by using ./pre-inst-env scripts/guix build luajit.  If everything is ok, we can submit the patch.

 

 Sending the patch


If the recipe built correctly, and you can install the package, that's the time for sending the recipe.

Make a commit with the recipe. The commit message should start with 'gnu:', and follow the GNU commit guidelines.

$ git format-patch -1 HEAD #will make a patch for the latest commit.

Send the patch to the mail list.

 

Addendum: Comunity


The community is also important in Free software projects. And this one is really nice. It's small but very helpful. If you have questions, don't hesitate asking in #guix on freenode or in the guix mail list.  Here's an example of a recent conversation I had with Ludovic (the main author of the project)
Neat, no? :)

sábado, 25 de enero de 2014

ANN: erc-youtube.el

 This time is erc-image and erc-tweet's little brother: erc-youtube.

Sometimes, when someone posts a youtube link in an IRC channel, you feel like clicking, but from time to time it's some link you really wouldn't like to have clicked. And it's too late.

Erc-youtube will inline the video's title in the erc buffer so you can decide then if you want to click or not.


Supersimple plugin, but it may be useful for some of you.  Shortly it'll be in melpa.

miércoles, 15 de enero de 2014

ANN: Helm-dash, the documentation browser for emacs

This post is the official announcement of a minor mode Toni and myself have developed which allows you to browse documentation for many languages using helm machinery to drive the find-as-you-type. It's called helm-dash

Intro


Helm is gaining lots of traction lately in the emacs environment (there are over 50 helm-* packages is the melpa now). It's a find-as-yo-type helper which provides an easy way to act on the selections. 

Dash is a mac osX app which lets you browse what they call docsets. Docsets contain an sqlite db and some html with the documentation of a given topic.

helm-dash


The basic usage is pretty simple:
  • helm-dash-install-package will give you the available docsets in the official repo (we'll choose Redis for testing).
  • Add the docset to either the global variable helm-dash-common-docsets. 
     (setq helm-dash-common-docsets '("Redis")) 
  • execute the interactive command helm-dash
  • Type some letters that match a redis command you want to look for (push, for example)
  • Press RET when you are on the command you want. Your favourite browser should open pointing to the documentation.

buffer-local docsets


For further configuration, we allow per-buffer sets of docsets. Let's say you want the GoLang docset available, but just in go-mode buffers. Install Go docset, and evaluate the following elisp:

(defun go-doc ()
  (interactive)
  (setq-local helm-dash-docsets '("Go")))

(add-hook 'go-mode-hook 'go-doc)

Then, when you open a go buffer, helm-dash will search both Redis and Go.

Here's a demo of the basic usage. (Mind that the video is not setting the variables accordingly because they were already set)

Try it, patch it, or talk about it, we'd love to hear your comments and improve it. 

The package has been developed and tested under linux.It should work on Mac OSX but it hasn't been tested there.If you find any issue on Mac, please, Pull Request :)

sábado, 11 de enero de 2014

Evil: The exact amount of vim in emacs (but no more than that)

I love emacs, but I also love modal editing.  Evil was (and vimpulse before that), was a great finding.

What I want is to have a normal mode where most commands feel like vim, and an insert mode where most commands feel like emacs, so c-p would do previous-line in insert mode instead of autocomplete word. Here are some of my tricks (many of them gathered from other people's configs)

99% emacs insert mode

Although using lots of insert mode commands when I was using vim daily, now I hardly find the necessity for them.

(setcdr evil-insert-state-map nil)
(define-key evil-insert-state-map [escape] 'evil-normal-state)

And that's it. with this, you're mostly done. In insert mode, every key but escape will behave as in plain emacs.

Undo-tree? nah (99% of vim in normal mode)

I still prefer emacs' undo-redo schema than the undo-tree. In the docs (also in the code), evil states that undo-tree will be used if available, and regular undo-redo will be used in case it's not there. That sounds fine, but if you get evil from elpa, undo-tree will be downloaded and installed without asking.Uninstalling undo-tree afterwards is not an enough because when loading, evil will complain it has some unmet dependency.

To make evil forget about it I edited the evil-pkg.el in my ~/.emacs.d/elpa/evil-xxxxxxx/ dir deleting undo-tree as a requirementand leaving it like this:

(define-package "evil" "20140109.605" "Extensible Vi layer for Emacs." '((goto-chg "1.6")))

c-r tries to redo

Just remap the desired key in the chosen mode to your prefered function.

(define-key evil-normal-state-map (kbd "C-r") 'isearch-backward) 
With these few tricks you can hack further to fine tune your keybindings and submodes inside evil. If you dig deeper into its code, you'll see it's quite well organized and quite clear.

martes, 7 de enero de 2014

Emacs keybindings everywhere

If you're using conkeror or keysnail you know how nice it is to have the usual keybindings in your browser.

Just in case you aren't using them, or if you're using them but want to have c-a, c-e,etc... in many linux desktop apps, here's a little trick.

Open (or create) the file "~/.gtkrc-2.0" and put the following line

gtk-key-theme-name = "Emacs"
Save, and open plain firefox. Then in any text field, try c-a, c-e, c-k . Neat, right?

You're welcome :)