Showing revision 7

Blog

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

2026-03-09 Create ranges of numbers in vanilla JS

Sometimes you need to create an array with the sequence of numbers, say from 0 to 9. Popular libraries like Lodash or Ramda have a function for that (in both cases, it’s called range), but how to do that concisely in vanilla JS? In case you’re wondering, both Lodash and Ramda use a while loop for this task; can we do better? (In this case “better” does not necessarily mean “faster”, but “shorter”, and – let’s be honest — “in a more clever/hackish/crazy way”.) It turns out that the answer is yes. The idea is to use Array.from with an array-like object possessing only the length property. Array.from has an optional parameter – a mapping function, which is called for every element of the “source array”. Of course, in the case of the {length: ...} object there are no elements, so the argument to the mapping function is effectively undefined. However, this function also receives a second argument, which is the index of the element in the “source array” (much like in the regular Array.prototype.map). This means that we can do this:

Array.from({length: 8}, (_, i) => i)

Interestingly, unlike the regular map, the mapping function in Array.from does not receive the whole “source array” as the third argument. Go figure.

Of course, it’s still possible to use this trick to generate sequences not starting at 0 and with step different than 1 – but the code becomes longer. Here is a snippet generating the sequence of all two-digit odd numbers:

Array.from({length: 45}, (_, i) => 11 + i * 2)

Is this all Array.from can do? Of course not. Another use-case is deduplication (via a set):

Array.from(new Set([1, 1, 2, 3, 5, 8])) // => [ 1, 2, 3, 5, 8 ]

Yet another is splitting strings into individual characters. A popular way to achieve that is to say string.split(''), but this won’t work with certain Unicode characters:

'I🧡JS🤣'.split('') // => [ 'I', '\ud83e', '\udde1', 'J', 'S', '\ud83e', '\udd23' ]
Array.from('I🧡JS🤣') // => [ 'I', '🧡', 'J', 'S', '🤣' ]

In this case, Array.from is not indispensable – a similar effect can be achieved with the spread operator:

[...'I🧡JS🤣'] // => [ 'I', '🧡', 'J', 'S', '🤣' ]

but you could argue that Array.from is slightly more idiomatic since it makes the intent of “converting into an array” more explicit.

That’s it for today – see you next week!

CategoryEnglish, CategoryBlog, CategoryJavaScript

Comments on this page

2026-03-02 Lispy and Iedit

A bit over a decade ago (!) I wrote about Iedit. It’s a very cool package, a bit similar to multiple cursors, very convenient for changing variable names (especially that it has a great feature where the change is restricted to the current function).

I am also a Lispy user. Lispy requires Iedit (and has a binding for it different from the default one – M-i – while Iedit’s default I’m used to is C-;). The problem is, when I added Lispy to my Emacs, it disabled the default C-; (and only installed M-i in Elisp buffers).

Now, I admit that M-i may be a better (or at least not worse) keybinding for Iedit than C-;. It’s default binding is tab-to-tab-stop, which is one of those useless commands Emacs has had probably for decades. Personally, I’m accustomed to C-;, so I wanted Lispy not to interfere with Iedit setting that keybinding.

It turns out that all I had to do was to make sure that Iedit is loaded before Lispy. I think the reason is that Lispy says

(setq iedit-toggle-key-default nil)

and Iedit says

(defcustom iedit-toggle-key-default (kbd "C-;")
  ; ...
  )

and defcustom only sets the value when not already set. So, if you want both Iedit in non-ELisp buffers and Lispy, just use your favorite package manager to make sure that Lispy is loaded after Iedit and you’re done! And if you want M-i to be the Iedit entry point instead of C-; in all buffers, just make sure that

(keymap-global-unset "M-i")
(setq iedit-toggle-key-default (kbd "M-i"))

is evaluated before loading Iedit. (The unsetting is needed because Iedit won’t let you use a keybinding which is already taken by another command.)

That’s it for today, and if you don’t use Iedit (or Lispy), definitely check those packages out – they are both really great!

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2026-02-21 Org links’ targets

When I write blog posts containing several links (usually to Emacs documentation, sometimes to my other posts and sometimes to other websites), one of the things I do is to check if all the links are correct. Usually I just middle-click on every one of them in the browser and see if they lead to the right place. I thought, however, that it would be useful to be able to see where an Org link points to without actually going there.

The most natural thing that occurred to me was to show the link target in the echo area when the point is on the link. I asked how to do it and learned that I’m far from the only one wanting such a feature. It turned out that this is almost supported out of the box.

First of all, Org mode puts the link target in the help-echo text property. This means that hovering the mouse over a link shows a tooltip with the link target. Also, I learned that C-h . (display-local-help) shows that property in the echo area when the point is on the link.

I started to search for methods of doing this without coding it myself, and I was not disappointed. It turns out that Emacs can display “local help” automatically when it is available at point.

One way to do this is to enable the option help-at-pt-display-when-idle. It works very much like Eldoc and in fact it can conflict with it. If you use Eldoc (and as far as I know, (global) Eldoc mode is turned on by default in every buffer that supports it), there is another setting you can use – eldoc-help-at-pt. It’s less configurable than help-at-pt-display-when-idle (see its docstring to know how to fine-tune its behavior), but I don’t need the fine-tuning, so I enabled it in my config. (As is often the case with things I write about here, as of the time of writing this, eldoc-help-at-pt is only available for the brave people who compile Emacs from master.)

One more thing I’d like to be able to do would be to see the target of a link the point is not on. I think I’ve mentioned on my blog that I use Avy. It’s an excellent package from Oleh Krehel, famous for Swiper, Hydra, Lispy and several other Emacs packages. Avy lets the user perform actions at places other than point without moving to them, in a very fast and convenient way. (There is a great article about using and configuring Avy by Karthinks, too – I learned a lot from it!) It turns out, however, that making Avy select Org links is trickier than I thought.

Finding links in Org mode is easy – you just search for the org-link-any-re regex. However, (avy-jump org-link-any-re) doesn’t work because avy-jump only selects visible text, and Org mode only shows the links’ descriptions by default. (This can be changed by calling org-toggle-link-display, but I really don’t like the result, since it makes text with links very hard to read.)

Now what I did was a bit of poking in Avy sources, and for a moment I thought I was able to come up with a solution. I was not particularly happy with it because I don’t fully understand what is going on there;-). It seems that Avy uses the avy--visible-p function (the two dashes mean that it’s an internal function, theoretically subject to change anytime) to determine whether a character is visible or not. This function looks like this:

(defun avy--visible-p (s)
  (let ((invisible (get-char-property s 'invisible)))
    (or (null invisible)
        (eq t buffer-invisibility-spec)
        (null (assoc invisible buffer-invisibility-spec)))))

so if buffer-invisibility-spec is set to t, it will always treat everything as visible (and frankly, I have no idea why it would do that):

(defun avy-goto-org-link ()
  (interactive)
  (let ((buffer-invisibility-spec t))
    (avy-jump org-link-any-re)))

This, however, has an obvious drawback – now legitimately invisible links (for example, ones under folded headlines) are selected as Avy candidates. A natural solution would be to modify buffer-invisibility-spec so that only the link should become visible:

(defun avy-goto-org-link ()
  (interactive)
  (let ((buffer-invisibility-spec
         (remove '(org-link) buffer-invisibility-spec)))
    (avy-jump org-link-any-re)))

This seems to work, but has the same issue as using the org-toggle-link-display function – it makes the whole links (target plus description) visible for the duration of candidate selection.

I decided that the only way I can see is changing buffer-invisibility-spec only during the evaluation of avy--regex-candidates. The standard way of achieving things like that is advice. It is probably not optimal here since I want it to only be active temporarily, and I tried using cl-letf, but failed (and decided that debugging such a convoluted construct is not worth the time). So, advice it is.

(defun avy--regex-candidates-links-visible-advice (orig-fun &rest args)
    "Call `avy--regex-candidates' but with Org links visible."
    (let ((buffer-invisibility-spec
         (if (listp buffer-invisibility-spec)
               (remove '(org-link)
                     buffer-invisibility-spec)
             buffer-invisibility-spec)))
      (apply orig-fun args)))

(defun avy-goto-org-link ()
  (interactive)
  (advice-add 'avy--regex-candidates
              :around
              #'avy--regex-candidates-org-links-visible-advice)
  (avy-jump org-link-any-re)
  (advice-remove 'avy--regex-candidates
                 #'avy--regex-candidates-org-links-visible-advice))

And now it works really well! The last missing thing is a good keybinding for this. Since I bound avy-goto-char to M-j, I decided that M-J (that is, meta-shift-j) is a good enough keychord.

(define-key global-map (kbd "M-J") 'avy-goto-org-link)

Let’s now come back to the idea of displaying a links’ target using Avy.

(defun avy-action-display-local-help (pt)
  "Call `display-local-help' at PT."
  (save-excursion
    (goto-char pt)
    (display-local-help)))

(add-to-list 'avy-dispatch-alist
             '(?. . avy-action-display-local-help)
             t)

And now I can press M-J . and then the character Avy associates with a particular link visible on screen to see its target in the echo area, without moving the point.

A bonus I get here is that display-local-help is useful outside Org mode, too. For example, I use ESLint to find issues in my JavaScript code, and it uses the help-echo property to show ESLint messages when the mouse hovers over the problematic place. And now I can use my newly defined Avy action for that, too! Assuming that the first character in that place is an “h”, I can press M-j h . and the suitable character to see the ESLint message without moving the point nor touching my mouse. Neat!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode

Comments on this page

More...