efinger.el/README.md
Andros Fenollosa d1b6664a2a Bump version to 1.0.0 and show efinger-finger output raw
Add an optional RAW argument to efinger--start so efinger-finger
streams the server reply verbatim, without the title header.
2026-08-18 12:50:20 +02:00

9 KiB

Efinger for Emacs

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

Requires Emacs 28.1 or later.

Finger, born at Stanford in 1971, is arguably the first social network: your whole profile lives in a plain-text .plan file that anyone can read with finger you@your-host. John Carmack famously kept his DOOM/Quake development diary this way. Efinger lets you keep a list of accounts and browse their .plan files from a two-pane interface, the same way you follow feeds in Elfeed. For the story behind the protocol, see Finger: la red social de 1971.

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@happynetbox.com"
          ("Backup Box ring" "ring@thebackupbox.net"))))

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@happynetbox.com"
          ("Backup Box ring" "ring@thebackupbox.net"))))

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@happynetbox.com"
        ("Backup Box ring" "ring@thebackupbox.net")))

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/.