Blog

Last edit

Summary: bez kalendarza

Deleted:

< month:+0


For the English part of the blog, see Content AND Presentation.

2019-11-11 Diffing buffer fragments

While working on a certain project, I needed to check the differences between two text fragments. We all know and love diff, but it operates on files, and what I had was two fragments of two files (or sometimes even of one file) which I wanted to compare.

There are a few solutions to this problem, but they seemed too complicated for me. I know Ediff is powerful, but it always seemed to complex for me to learn. There is the little-known compare-windows command, which is nice, but less sophisticated then a usual diff, and has a major drawback of not displaying any “report” showing the differences – it is well-suited to interactive use, but sometimes I’d like to have something more “tangible” to look at after doing the comparison.

Well, the main problem of diffing two regions is the user interface. The commands ediff-regions-linewise and ediff-regions-wordwise do a good job of being quite intuitive, but only up to the moment when Ediff is launched;-).

A few days ago it struck me that I could reuse a very basic and well-known UI for that: the kill ring. How about a command which would diff the last two kills? Then, using it would be as simple as marking the first region, pressing M-w, marking the second one, pressing M-w again, and invoking the command.

And the coolest thing about it was that it only took me a few minutes to code this command! It is extremely simplistic, and uses temporary files in a not-so-elegant way, but it does its job well enough for me. I’ve been using it for some time now and I really like it.

(defun diff-last-two-kills ()
  "Write the last two kills to temporary files and diff them."
  (interactive)
  (let ((old "/tmp/old-kill") (new "/tmp/new-kill"))
    (with-temp-file new
      (insert (current-kill 0 t)))
    (with-temp-file old
      (insert (current-kill 1 t)))
    (diff old new "-u" t)))

As usual, Emacs’ shows one of its main strengths: extensibility. I have no idea if you could do this in Vim (probably yes) or in Sublime Text or VSCode or what-have-you, but I suspect that even if it was possible, it might take more time to write.

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2019-11-04 Starting Emacs with custom configuration directory

The usual thing people are told to do when debugging/isolating Emacs problems is to say emacs -Q, that is, start Emacs without reading in any configuration. Sometimes, however, this may not be a good idea. When there is some problem with packages, however, we may actually want to load some things, like a minimal set of packages if we suspect they do not work together. Of course, what we don’t want is changing our configuration.

Strangely enough, Emacs has a lot of options to suppress loading some parts of its default config (-q and -Q are the most well-known), but I couldn’t find any option to allow for a different location of its config files. That is not really a problem, however, since the place it looks for the configs is well-defined in relation to the user’s home directory. This means that it is enough to say e.g. HOME=/tmp emacs (assuming Bash at least, which is what everyone is using anyway, right? ;-) ), and we can install whatever package(s) we want, customize variables etc. – everything will go to /tmp/.emacs, /tmp/.emacs.d etc. What’s even better, we do not lose all of this configuration after restarting Emacs in the same way (of course, on systems where /tmp is cleared on reboot, this is not as persistent as it could be, but we can use anything instead of /tmp).

This may be quite useful not only for debugging problems with packages (right now I have some troubles with js2-mode, for instance, and the above technique seems to confirm that it is my config and not js2-mode which is to blame…), but also for demoing stuff. I hope to give some talk with slides shown from within Emacs in some time, and I do not necessarily want to use my normal config for that – if only because the modeline shows the minor modes I have turned on, and it might introduce a lot of noise for the audience.

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2019-10-28 PostgreSQL, jsonb each and cross joins

A few days ago I stumbled on a PostgreSQL query I didn’t really understand. I asked a question on Stack Overflow and learned something I would have known if only I had read the manual…

Assume that we have a table with a jsonb column like this:

# create temporary table test_table(
  name text,
  data jsonb
);
# insert into test_table values ('name1', '{"a": 1, "b": 2}'), ('name2', '{"c": 3, "d": 4, "e": 5}');
# table test_table;
 name  |           data
-------+--------------------------
 name1 | {"a": 1, "b": 2}
 name2 | {"c": 3, "d": 4, "e": 5}
(2 rows)

The query in question lookes like this:

select * from test_table cross join jsonb_each(test_table.data);

Can you guess its result? If not, read on.

The jsonb_each by itself converts a jsonb value to a set of rows with columns key and value:

# select jsonb_each('{"a": 1, "b": 2}'::jsonb);
 jsonb_each 
------------                                                                                                                                                                                  
 (a,1)                                                                                                                                                                                        
 (b,2)                                                                                                                                                                                        
(2 rows)                                                                                                                                                                                      

Let us make a few notes here. First of all, the column names are not visible above because of the way composite types are printed in PostgreSQL. (You can say e.g. select key, value from jsonb_each('{"a": 1, "b": 2}'::jsonb); – or even select * from... – to see them.) Note also that key is of type text, but value is of type jsonb – there is also jsonb_each_text returning both columns of type text. Finally explicit casting to jsonb is not necessary – I added it only for clarity.

Now the way joins work is that both sides of the join are calculated independently, and so we cannot e.g. refer to a row from the left-hand side of a join in the expression on the right-hand side. (An exception to this – or rather, a way to break this rule – is the lateral join.) What I missed, however, is another exception: for functions the lateral key word is optional; the function’s arguments can contain references to columns provided by preceding FROM items in any case. (The details can be found here – look for LATERAL.)

This means that what happens here is that the jsonb_each is computed independently for each row of the test_table and only then cross joined with it. In other words, we obtain this:

# select * from test_table cross join jsonb_each(test_table.data);
 name  |           data           | key | value 
-------+--------------------------+-----+-------
 name1 | {"a": 1, "b": 2}         | a   | 1
 name1 | {"a": 1, "b": 2}         | b   | 2
 name2 | {"c": 3, "d": 4, "e": 5} | c   | 3
 name2 | {"c": 3, "d": 4, "e": 5} | d   | 4
 name2 | {"c": 3, "d": 4, "e": 5} | e   | 5
(5 rows)

This is really handy, but not exactly what I expected. As usual, PostgreSQL turns out to be really, really clever.

CategoryEnglish, CategoryBlog, CategoryPostgreSQL

Comments on this page

More...