No description
Find a file
Andros Fenollosa 9a80d68374 Docs: drop intro blurb and use real account examples
Remove the top intro paragraph and the Emacs version note from the
README, and update the efinger-accounts examples to the two accounts
actually used, labelling the personal one "Andros".
2026-08-18 13:00:21 +02:00
test Add efinger: a Finger client and .plan feed reader 2026-08-18 11:16:05 +02:00
.gitignore Add efinger: a Finger client and .plan feed reader 2026-08-18 11:16:05 +02:00
efinger.el Docs: drop intro blurb and use real account examples 2026-08-18 13:00:21 +02:00
LICENSE Add efinger: a Finger client and .plan feed reader 2026-08-18 11:16:05 +02:00
Makefile Add efinger: a Finger client and .plan feed reader 2026-08-18 11:16:05 +02:00
README.md Docs: drop intro blurb and use real account examples 2026-08-18 13:00:21 +02:00

Efinger for Emacs

A client for the Finger protocol (RFC 1288) with an Elfeed-inspired reader for Emacs.

How it works

        Emacs                          Finger servers (TCP 79)
 +---------------------+
 |  *efinger*          |   n / p       +----------------------+
 |  ------------------ |------ move -->|  happynetbox.com     |
 | >random@happynetbox |               |  thebackupbox.net    |
 |  Carmack diary      |   RET / l     |  your own fingerd    |
 |  ring@thebackupbox  |<-- enter/back |                      |
 +----------+----------+               +----------+-----------+
            |                                     |
            v  preview                            | async, :nowait
 +---------------------+                          |
 |  *efinger .plan*    |<-------------------------+
 |  the fingered text  |
 +---------------------+
  1. You keep a list of finger accounts in efinger-accounts.
  2. M-x efinger opens the account list next to a content pane.
  3. Moving with n / p fingers the account under point and previews its .plan in the other pane, asynchronously so Emacs never blocks.
  4. RET jumps into the content, l goes back to the list, q closes both panes.

Buffers

Account list + content (M-x efinger)

 Efinger — n/p move · RET open · g refresh · q quit
┌────────────────────────┬───────────────────────────────────────┐
│ random@happynetbox.com │ johnc@idsoftware.com                   │
│ Carmack diary          │ ───────────────────────────────────── │
│ ring@thebackupbox.net  │                                        │
│ me@happynetbox.com     │ -------------------------------------- │
│                        │ John Carmack's .plan for Aug 18, 1997  │
│                        │ -------------------------------------- │
│                        │                                        │
│                        │ I get asked about the DOOM source code │
│                        │ every once in a while, so here is a    │
│                        │ full status update:                    │
│                        │ ...                                    │
└────────────────────────┴───────────────────────────────────────┘

Single account (M-x efinger-finger)

 .plan — l back · n/p next/prev · g refresh · q quit
Emily Carter
Marine biologist. Coffee, kayaks and old maps.

--- 2026-08-14 ---
Back from sampling on the coast. Three jars of plankton to review.

Features

  • Account list: keep your finger accounts in efinger-accounts and browse them in a dedicated buffer, the way Elfeed lists feeds.
  • Live preview: move with n / p and the .plan under point is fingered and shown in the content pane automatically.
  • Two-pane reader: RET enters the content pane to read and scroll, l returns to the list, q closes both.
  • Asynchronous connections: connections use :nowait, so Emacs never freezes even when a host resolves but never answers on port 79 (the common case today).
  • Connection timeout: a stalled connection is abandoned after efinger-connection-timeout seconds with a clear message, instead of hanging.
  • Graceful errors: refused or timed-out connections are reported in the content pane, never as a backtrace.
  • One-off finger: M-x efinger-finger fingers a single user@host in its own buffer, showing the server reply raw, with no title header.
  • Configurable layout: list on the left and content on the right (horizontal), or list on top and content below (vertical).
  • Ports and listing: targets accept an optional :port; omitting the user (host or @host) asks the server to list every user.
  • UTF-8: replies are decoded as UTF-8, so accents and box drawing render correctly.

Keymap

Account list (efinger-list-mode)

Key Description
n Move to next account and preview it
p Move to previous account and preview it
RET Enter the content pane for this account
g Re-finger the account at point
G Rebuild the list from efinger-accounts
q Close both panes

Content pane (efinger-plan-mode)

Key Description
l Back to the account list
n Preview next account (stay in content)
p Preview previous account (stay in content)
g Re-finger the current account
q Close both panes
SPC / DEL Scroll the content up / down

Installation

MELPA

M-x package-install RET efinger RET

use-package with :vc (Emacs 29+)

(use-package efinger
  :vc (:url "https://git.andros.dev/andros/efinger.el"
       :rev :newest)
  :config
  (setq efinger-accounts
        '(("random" "random@happynetbox.com")
          ("Andros" "me@andros.dev"))))

use-package with :load-path

For manual installation or Emacs < 29:

(use-package efinger
  :load-path "/path/to/efinger.el"
  :config
  (setq efinger-accounts
        '(("random" "random@happynetbox.com")
          ("Andros" "me@andros.dev"))))

Manual

Clone the repository and place the file in a directory on your load-path:

git clone https://git.andros.dev/andros/efinger.el.git

Then add to your init file:

(add-to-list 'load-path "/path/to/efinger.el")
(require 'efinger)
(setq efinger-accounts
      '(("random" "random@happynetbox.com")
        ("Andros" "me@andros.dev")))

Usage

  1. Set efinger-accounts in your init file. Each entry is either a "[user@]host[:port]" string or a (LABEL "[user@]host[:port]") list.
  2. Run M-x efinger to open the reader.
  3. Move with n / p to preview each account, RET to read one in full, l to return to the list and q to quit.
  4. Or run M-x efinger-finger to finger a single account on demand.

Public servers you can try today: random@happynetbox.com, benbrown@happynetbox.com and ring@thebackupbox.net.

Customization

Run M-x customize-group RET efinger RET to list all available options.

Key options:

  • efinger-accounts: the accounts shown in the reader.
  • efinger-port (default 79): default finger TCP port.
  • efinger-connection-timeout (default 10): seconds before a stalled connection is abandoned; nil waits indefinitely.
  • efinger-forward-host (default nil): send user@host instead of just user (finger forwarding, for old daemons).
  • efinger-layout (default horizontal): horizontal (list left, content right) or vertical (list top, content bottom).
  • efinger-list-width (default 40): list width in columns (horizontal).
  • efinger-list-height (default 12): list height in lines (vertical).

The Finger protocol

Finger is minimal: the client opens a TCP connection to port 79 of the server, sends a single line (the user name, or an empty line to list everyone) terminated by CRLF, and the server replies with plain text and closes the connection. No encryption, no headers, no sessions. You can speak it by hand:

echo "random" | nc happynetbox.com 79

Contributing

Contributions are welcome! Please see the contribution guidelines for instructions on how to submit issues or pull requests.

License

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.