Skip to content

New sketcher prototype#290

Open
i-tub wants to merge 2 commits intomainfrom
pr/new_sketcher
Open

New sketcher prototype#290
i-tub wants to merge 2 commits intomainfrom
pr/new_sketcher

Conversation

@i-tub
Copy link
Copy Markdown
Contributor

@i-tub i-tub commented Apr 1, 2026

Description

Modern molecular sketchers have become bloated, relying on complex GUI
frameworks, GPUs, and the like. The time has come to reconsider our whole
approach and write a new sketcher from scratch.

Rather than risking a dependency on newfangled technologies such as Qt (1995)
or WebAssembly (2017), let's go back to the basics and build on top of the
curses library, which has been a standard part of Unix since the early 1980s.

In keeping with the Unix philosophy, the new sketcher can run as part of a
pipeline, taking an input SMILES from stdin and printing an output SMILES to
stdout. This allows it to integrate seamlessly with existing tools:

$ grep lig-42 ligands.smi | sketcher.py - > lig-42-analog.smi

The new sketcher, being 100% keyboard-driven (with keybindings inspired by vi)
is more ergonomic and enables greater productivity. Because the molecules are
depicted in ASCII art, they can be copied, pasted, transmitted or stored as
plain text--the most versatile of file formats.

The video below shows a quick overview of the new sketcher in action:

sketcher_demo

Controls:
  h, j, k, l       - Move cursor left, down, up, right
  H, J, K, L       - Move cursor faster (10 cells horizontal, 4 cells vertical)
  Space            - Snap cursor to nearest atom
  m                - Enter move mode (hjkl moves molecule, Esc to exit)
  s                - Enter a SMILES string to replace the current molecule
  S                - Toggle SMILES display
  i                - Insert/modify atom at cursor position
  a                - Append atoms from SMILES to atom or bond under cursor
                     (appending to a bond forms a ring by connecting the bond
                     atoms to the first and last atoms from the SMILES)
  c, n, o          - Insert/modify carbon/nitrogen/oxygen atom
  x                - Delete atom or bond
  D                - Delete fragment (all atoms connected to cursor atom)
  X                - Area delete (select rectangle, Enter to delete, Esc to cancel)
  +, -             - Increase/decrease formal charge on atom
  <, >             - Zoom out/in
  b                - Add bond mode (add atom and move it, Enter to accept, Esc to cancel)
  1, 2, 3          - Add bond or change bond (order 1/2/3) between nearest atoms
  w, d             - Add/change to wedge or dash bond (press again to reverse)
  @                - Clear canvas (reset to blank slate)
  u, r             - Undo/redo
  Ctrl-L           - Clean up (regenerate coordinates)
  ?                - Show this help
  q                - Quit and print SMILES to stdout

Requirements

  • Python (tested with 3.11)
  • RDKit (tested with 2025.09.6)

Testing done

Manual testing on Linux. Note: the new Sketcher does not work with the version
of Python that comes with the Schrödinger core suite, becase it's missing the
curses module for some reason! But it is easy enough to run using uv:

uv run sketcher.py

Unit tests left as an exercise to the reader.

This commit introduces the 2026 version of the Schrödinger sketcher,
which for reasons of efficiency, ergonomics, and versatility is based on
the curses library instead of Qt. It is a single-file Python script,
with RDKit as its only dependency other than Python.
@i-tub i-tub requested a review from cdvonbargen as a code owner April 1, 2026 09:29
@KevKeating
Copy link
Copy Markdown
Collaborator

The next step is to get Live Design integration working via Pyodide

@ujamshed
Copy link
Copy Markdown
Contributor

ujamshed commented Apr 1, 2026

Can we support arrow key movement? Currently this is unusable for my non-vi trained fingers

@i-tub
Copy link
Copy Markdown
Contributor Author

i-tub commented Apr 1, 2026

Can we support arrow key movement? Currently this is unusable for my non-vi trained fingers

Done! I didn't add shift+arrow, however, because while the curses library supports shift+left and shift+right, it does not support shift+up or shift+down! There are some lower-level ways of getting those key combinations, but I didn't want to go down that road just yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants