Blog

Difference between revision 6 and current revision

Summary: bez kalendarza

No diff available.

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

2024-03-18 Follow mode

It is a fairly common opinion that a function should not be larger than your screen. The reality, though, is often different. And even if your functions are shorter, you may want to see more than one at a time. The problem is that our screen are usually not that high. (My laptop gives me 66 lines of text with normal font settings.) You can have an external monitor rotated vertically (I have that at work to see as much of the logs of the application I’m working on as possible), but Emacs gives us another solution – the Follow mode. If you split your window into two (or more) side-by-side windows (for example, using C-x 3) and say M-x follow-mode, the other window will start displaying the “next portion” of the current buffer – that is, its top line will be the line just below the bottom line of the current window. Whenever you scroll either window, the other window follows, so both windows always show two adjacent parts of the current buffer. What’s more, when you go to the bottom line of the current window and press C-n to get to the next line, Emacs automatically switches to the other window without scrolling. This means that the two windows combined will act as one big “virtual window”.

There is also the follow-delete-other-windows-and-split command, which does exactly whet it says on the tin.

It turns out that Follow mode is even better than that! It seems to automatically detect all windows showing the buffer with Follow mode enabled, so if you activate it first and split the window after that, it also works. And it is not restricted to two windows! Try hitting C-x 3 twice (to get three windows) and using Follow mode then – you’ll have three windows following each other. (By the way, if you start with a single window and press C-x 3 twice, you’ll end up with two windows occupying 25% of your Emacs frame’s width and one having 50%. You can remedy that with M-x balance windows. It is smart enough to work reasonably even if you have some windows split vertically and some horizontally. There is also M-x balance-windows-area, which resizes all windows so that their area is the same – try e.g. C-x 1 C-x 2 C-x 3 M-x balance-windows-area to see how it works!).

The last thing I’d like to mention in my paean about Follow mode is that when you want to view the file instead of editing it, it may be a good idea to also turn on Scroll lock mode, where keys used to move the point vertically (like the up and down arrows) scroll the buffer instead.

And that’s it for today – see you next time!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2024-03-11 More psql tricks

As I mentioned many times, I am a PostgreSQL fan. I wrote several times about psql, the default PostgreSQL terminal client. A few days ago I gave a short talk in my company about the virtues of psql, and in preparation for that I looked at its manual (again). As is often the case, I discovered a few hidden gems I didn’t know about.

psql has quite a few “backslash commands” or “metacommands”. Many of them operate on the “current query buffer”, which means what you have typed so far but haven’t yet sent to the server for execution. For example, if you type this:

select *
from my_table-!-

where -!- means the cursor, and then type \g followed by Enter, the metacommand \g will treat the select * from table as its input. However, if the current query buffer is empty, \g will use the previous query.

Since \g basically just sends its input to the server, you can use it instead of the semicolon to end your query. It is more capable than that, though. For example, you can follow it by a filename, and then it will output the result of your query to that file. Alternatively, you can use a pipe symbol followed by a shell command to pass the result to the given command. And if that were not enough, you can follow \g by a list of options and their values in parenthesis. This way, the query will be run with those options set to the given values, as if you invoked \pset before, but the options will only be valid for this single query. For instance, you can generate a file with a LaTeX table, without the annoying vertical lines, and see its first few lines with this invocation:

\g (format=latex border=0) |tee /tmp/table.tex | head -n2

Now, if you remember my troubles with \copy and multiline SQL statements, here is a much simpler way to generate a CSV file from the result of a (possibly multiline) select statement:

select * from my_table
\g (format=csv) my-table.csv

And you can also invoke \g after you successfully ran the select and saw that its results are exactly what you want.

Another trick I learned (or relearned) is the \! metacommand. It allows you to run any shell command without leaving psql. For example, if you want to check the current directory, you can say \! pwd. You can also type \! without any argument, which then runs an interactive shell; when you exit the shell, you get back to your psql prompt.

There is also the \set command, which – surprise! – sets (psql) variables. These variables are a very useful concept. For example, assume that you have some uuid you use all the time, say 9e7c2a24-42bb-4c1c-9479-933ec8d30fd1. Instead of copying and pasting it time and time again, you can say \set uuid_var '9e7c2a24-42bb-4c1c-9479-933ec8d30fd1' and then use it like this:

select * from some_table where some_uuid_column = :'uuid_var';

to get the data about the row with the given uuid. (You can also have a column or table name in some variable and then say things like :"column_var".)

But it gets better! Oftentimes the value(s) you need can be read from some table. For example, let’s assume that you have a user table with columns like user_id, user_full_name or user_email. If you need to query some other tables using (for example) one user’s id and email, you can put them into variables using the \gset metacommand.

select user_id, user_email as email from "user" where user_full_name = 'John Doe'
\gset

and you’ll set the variables user_id and email to the uuid and email of John Doe. (In order for this to work, the query must return exactly one row.) And if you do this a lot, you might want to know that the \gset metacommand takes one optional “prefix” parameter, so \gset p_ will prepend p_ to the names of the variables it creates.

The last thing I’d like to mention is one of the most complicated psql metacommands, \crosstabview. Assume that you have a query that displays e.g. some counts, broken down by two variables. Let’s take an example from Wikipedia:

select 'male' as sex, 'right' as handedness, 43 as count
union
select 'male' as sex, 'left' as handedness, 9 as count
union
select 'female' as sex, 'right' as handedness, 44 as count
union
select 'female' as sex, 'left' as handedness, 4 as count

If you just evaluate it using \g (or a semicolon), you get this table:

  sex   | handedness | count
--------+------------+-------
 male   | left       |     9
 female | left       |     4
 male   | right      |    43
 female | right      |    44
(4 rows)

But if you use \crosstabview instead of \g, you get the following contingency table:

  sex   | left | right
--------+------+-------
 male   |    9 |    43
 female |    4 |    44
(2 rows)

How cool is that‽ Head on to the manual to learn the details (the argumentless invocation of \crosstabview works if the query result has exactly three columns – if it has more, you need to tell psql which column to use as the vertical and horizontal headers and the output).

That’s it for today. Happy querying!

CategoryEnglish, CategoryBlog, CategoryPostgreSQL

Comments on this page

2024-03-02 Some tips about Emacs keyboard macros

Some time ago I had to create some rather repetitive code. These days I often use multiple cursors for such things, but for some reasons this time I decided to go the traditional route and use the built-in keyboard macros. Here’s the catch, though. When you want to use keyboard macros and insert an (incremented) number for every occurrence, you can type f3 (kmacro-start-macro-or-insert-counter) while recording the macro. What I needed, though, was to insert that number twice for every execution of the macro. Typing f3 twice is no good, since every press of it increments the counter. Without giving it much thought, I tried to press C-u f3 during recording of the macro, hoping that it would do what I needed – and lo and behold, it did! As usual, Emacs commands turn out to be well thought-out and intuitive to use (once you get used to the general Emacs philosophy, that is).

After this small success, I decided to go to the manual to learn what other tricks are possible with keyboard macros. I certainly read it – I did read most of the manual, after all, but that was more than two decades ago. Emacs does not stand still, and a lot of functionality has been added since then – and it keeps being added all the time. (For example, when I first learned keyboard macros, you had to use C-x ( and C-x ) to record a macro, C-x e to execute it and C-x C-k C-i to insert the counter. These are not bad bindings, but f3 and f4 are so much simpler!)

And indeed, skimming through the relevant chapter of the manual (and pressing C-x C-k C-h – it turns out that not all macro-related commands are even documented in the manual!) revealed a few gems. One of them (I knew about) is that when you replay the macro, you can give f4 a numeric argument to tell Emacs how many times it should repeat the execution of the macro. That is useful enough, but here’s a bonus: if the argument you give is zero, it runs the macro repeatedly until it encounters an error. This is especially useful if your macro makes some change and moves to the next place to be changed – Emacs movement commands usually signal an error when you try to move past the buffer end, so this is an easy way of telling Emacs to do something “in the rest of the (visible portion of the) buffer”. (Note that giving f3 a negative argument is probably not a good idea – it will repeat the macro indefinitely without any stop condition. As of writing this, it is not documented, I’m not sure if it’s even intended and I found about it the hard way;-).)

One of the coolest thing about Emacs keyboard macros, however, is that you can have more than one of them. Much like kills, they are stored on a “ring”, and when you record a new one, the older ones are pushed down the ring instead of simply forgotten. You can then rotate the ring using C-x C-k C-p and C-x C-k C-n, effectively switching to older or newer macros as the “last macro”. If you just sometimes need the second-to-last entry on the ring and never the earlier ones, you can also use C-x C-k C-t to swap the two entries on the top of the macro ring. Of course, remembering what is in the macro ring and in what order requires some superhuman abilities, but the commands which change the top entry on the macro ring show you that top entry, so it’s not really completely blind. And while there seems to be no command to view the entire macro ring, you can say M-x kmacro-view-macro to see the definition of the macro at the head of the ring and kmacro-view-ring-2nd to see the next one. You can also use the plain old C-h v kmacro-ring to see whole ring – but without the head, which is stored in last-kbd-macro. (Interestingly, C-h v last-kbd-macro is less helpful since it is displayed in a more “internal” format. I have no idea why this works this way, but as part of the experiments while writing this blog post I recorded a macro consisting of two keystrokes, M-c M-f. When it went down the ring, it was displayed – as part of the kmacro-ring variable – this way: #f(kmacro "M-c M-f"); however, when it was at the head, C-h v last-kbd-macro showed this: [134217827 134217830]. Go figure.) And here is another nugget of gold: you can use the command kmacro-view-macro-repeat, bound to C-x C-k C-v, to see the last macro, and if you repeat it more times (and you can press just C-v to do that), Emacs shows you the subsequent macros on the ring – so, to see the third one, you can just press C-x C-k C-v C-v C-v. (Needless to say, it does not change the top entry of the ring.)

What I miss (a bit) is a way to replace the head of the macro ring instead of just appending to it. It’s not a big deal, since it is easy to remove the last macro, using C-x C-k C-d, so that if you make a mistake while recording, you can use that not to pollute the macro ring with incorrect entries. Also, if you expect to need a macro in the future, you can save it in a few ways – give it a name (C-x C-k n, the name will be usable as an M-x command) or a keybinding (C-x C-k b, either as a binding of C-x C-k followed by a digit or a capital letter or any binding – read the manual for the details). You can also save a macro to a register using C-x C-k x – and then, “jumping” to that register will replay that macro. (If you don’t know about Emacs registers, they are a pretty obscure but very useful feature I like a lot.) And if you named your macro, you can open your init file (M-x find-init-file) and say M-x insert-kbd-macro so that Emacs generates Elisp code to define your macro and give it the name you have chosen in every subsequent Emacs session. This way you can extend Emacs without any knowledge of Emacs Lisp! (Of course, if you want to extend Emacs, using Elisp is probably the best thing you can do – as usual, if you want to learn it, I recommend the Introduction to programming in Emacs Lisp by the late Robert J. Chassell and also my book, Hacking your way around in Emacs, which is sort of a “sequel” to it, meaning it covers more advanced material).

Anyway, another cool thing is that if you record a long macro and then find out you’ve made some simple mistake in it, you don’t have to record it again from scratch. You can simply edit the (last) macro, using C-x C-k C-e. Try it out, it’s insanely good! And if you press C-h m while editing a macro, you’ll see a detailed description of the Edit Macro mode.

The last thing I’d like to mention is that you can record a macro which is (sort-of) interactive. I wanted to write more about it, but it turned out that I already did;-). (It is kind of ironic that I ended that post like this: “it may be good to remember that something like this exists. Hopefully I won’t forget about it anymore!”, and indeed I forgot that I wrote that!) And by the way, if you think keyboard macros would be even better with loops and conditionals, you are definitely not alone – and in Emacs Calc they actually have them!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

More...