CurseMol 4.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python3 -m py_compile cursemol.py)",
5
+ "Bash(python3 -c \"import cursemol; print\\('Module loaded successfully'\\)\")",
6
+ "Bash(timeout 2 uv run ./cursemol.py \"CCO\" 2>&1 | head -20 || true)",
7
+ "Bash(python -m py_compile cursemol.py)"
8
+ ]
9
+ }
10
+ }
@@ -0,0 +1,11 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+ .python-version
9
+
10
+ # Virtual environments
11
+ .venv
@@ -0,0 +1,3 @@
1
+ [style]
2
+ based_on_style = google
3
+ ALLOW_SPLIT_BEFORE_DICT_VALUE = False
cursemol-4.1.0/.tokens ADDED
@@ -0,0 +1,2 @@
1
+ TEST_PYPI_TOKEN=pypi-AgENdGVzdC5weXBpLm9yZwIkMDIwNTk1YzMtMDQ3NC00NzI1LWJjZGUtNjYwZjU3MjRhZTcwAAIqWzMsIjc5NzJkNTJiLWIwMDgtNDc3YS1hY2IwLTU1NjhlZjY4NDkyZiJdAAAGIAi7P9yqYsM8CF1KN_c5HIAzKSXweQ__wsC5U3KuMjDu
2
+ PYPI_TOKEN=pypi-AgEIcHlwaS5vcmcCJDRjMDk2ODYzLTgxMGMtNDA1OS1iZmZlLWYwY2UwNzU4Y2RkNQACKlszLCJmMzI3MGQyMi05ZDAxLTQyN2QtYmY1OS0wNmI3ODQ4NmQ3ZmIiXQAABiAz2GRvHEwziWkKwgOl50WDB23f5rT6bpidWOjpjMrGKA
@@ -0,0 +1,161 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working
4
+ with code in this repository.
5
+
6
+ ## Project Overview
7
+
8
+ CurseMol is a terminal-based molecular sketcher built with Python curses and
9
+ RDKit. It's a Python package (~1861 lines) that allows interactive drawing
10
+ and editing of chemical structures in the terminal.
11
+
12
+ ## Running the Application
13
+
14
+ ```bash
15
+ # Install the package
16
+ uv sync
17
+
18
+ # Run the installed command
19
+ cursemol
20
+
21
+ # Load a SMILES string on startup
22
+ cursemol "CCO"
23
+
24
+ # See all options
25
+ cursemol --help
26
+ ```
27
+
28
+ The application outputs the final SMILES string to stdout when you quit (q).
29
+
30
+ ## Development Setup
31
+
32
+ ```bash
33
+ # Install dependencies and package in editable mode
34
+ uv sync
35
+
36
+ # Format code with yapf (Google style as configured in .style.yapf)
37
+ yapf -i src/cursemol/__init__.py
38
+ ```
39
+
40
+ ## Architecture
41
+
42
+ ### Project Structure
43
+
44
+ The package is organized as follows:
45
+ - `pyproject.toml`: Package configuration using hatchling build backend
46
+ - `src/cursemol/__init__.py`: Main application code (~1861 lines)
47
+ - Entry point: `cursemol` command (configured in pyproject.toml)
48
+
49
+ ### Core Data Structures
50
+
51
+ - **State**: Main application state containing the RDKit molecule, scale,
52
+ box (bounding coordinates), y_offset, and SMILES display toggle
53
+ - **UndoHistory**: Manages undo/redo stack by saving/restoring serialized
54
+ molecule states
55
+ - **ScreenDimensions**: Holds screen dimensions (rows, cols, max_y, max_x)
56
+ - **Mode**: Enum for UI modes (NORMAL, MOVE, SELECT, BOND)
57
+ - **capture_rdkit_log**: Context manager for capturing RDKit logging output
58
+
59
+ ### Coordinate System
60
+
61
+ The application maps between three coordinate spaces:
62
+ 1. **Molecular coordinates**: Actual 3D coordinates from RDKit (Angstroms)
63
+ 2. **Screen coordinates**: Terminal cursor position (columns/rows)
64
+ 3. **Scaled coordinates**: Adjusted for zoom level and aspect ratio
65
+
66
+ Key constants:
67
+ - `ASPECT_RATIO = 0.4`: Compensates for terminal character width/height ratio
68
+ - `DEFAULT_SCALE = 8.0`: Columns per angstrom
69
+ - `MIN_SCALE/MAX_SCALE`: Zoom limits
70
+
71
+ Functions to convert between coordinate systems:
72
+ - `screen_to_mol_coords()`: cursor position → molecular coordinates
73
+ - `screen_coords_for_atom()`: atom → screen position
74
+ - `recalculate_box_and_offset()`: Centers molecule after modifications
75
+
76
+ ### RDKit Integration
77
+
78
+ The application wraps RDKit's molecular editing capabilities:
79
+ - Uses `RWMol` (read-write molecule) for editing operations
80
+ - `AllChem.Compute2DCoords()` for 2D coordinate generation
81
+ - `Chem.WedgeMolBonds()` to assign wedge/dash stereochemistry from 3D coords
82
+ - Stereochemistry detection via `DetectBondStereochemistry()`,
83
+ `AssignChiralTypesFromBondDirs()`, and `AssignStereochemistry()`
84
+ - `Chem.MolToSmiles()` / `Chem.MolFromSmiles()` for serialization
85
+ - `compute_coords_with_fixed_atoms()`: Custom coordinate generation that
86
+ preserves existing atom positions when appending fragments
87
+
88
+ ### Bond Representation
89
+
90
+ Bonds are rendered as ASCII characters between atoms:
91
+ - Single bonds: dots (·) or middle dots (·)
92
+ - Double bonds: equals signs (=)
93
+ - Triple bonds: hash marks (#)
94
+ - Wedge bonds: solid bullets (●) pointing from narrow to wide end
95
+ - Dash bonds: hollow bullets (○) pointing from narrow to wide end
96
+
97
+ The `reverse_bond()` function handles stereochemistry direction changes.
98
+
99
+ ### State Management
100
+
101
+ All operations that modify the molecule use save/restore pattern:
102
+ 1. Save current state to undo history
103
+ 2. Perform operation
104
+ 3. Recalculate box and offset to keep molecule centered
105
+
106
+ Key editing operations:
107
+ - `insert_or_modify_atom()`: Add/change atoms at cursor
108
+ - `modify_bond()`: Add/change bonds between atoms
109
+ - `delete_at_cursor()`: Remove atoms or bonds
110
+ - `append_smiles_fragment()`: Attach SMILES fragments to atoms or bonds
111
+ - `connect_sidechain_to_bond()`: Special logic for ring formation when
112
+ appending to bonds
113
+
114
+ ### Screen Rendering
115
+
116
+ The rendering pipeline:
117
+ 1. `fill_screen_buffer()`: Creates arrays of characters and colors
118
+ 2. Renders atoms (with element symbols, charges)
119
+ 3. Renders bonds using Bresenham line algorithm in `draw_line()`
120
+ 4. `render_screen_buffer()`: Writes buffer to screen with colors
121
+ 5. Adds status line and optional SMILES display
122
+
123
+ ### Application Flow
124
+
125
+ - `main()`: Entry point that parses arguments and initializes the application
126
+ - `setup_tty()`: Ensures proper TTY handling for curses
127
+ - `init_curses()`: Configures curses environment (colors, cursor visibility)
128
+ - `main_loop()`: Main event loop handling keyboard input and screen updates
129
+ - `redraw_screen()`: Coordinates rendering of molecule, UI elements, and messages
130
+
131
+ ## Key Implementation Details
132
+
133
+ ### Cursor Navigation
134
+ - The cursor can be on empty space, atoms, or bonds
135
+ - `find_atom_at_cursor()`: Locates atom within tolerance
136
+ - `find_nearest_atom()`: Finds closest atom for snapping or bond creation
137
+ - `find_bond_atoms()`: Identifies which bond the cursor is over by checking
138
+ proximity to line segments
139
+
140
+ ### Molecule Cleanup
141
+ - Ctrl-L triggers `cleanup_coordinates()` which regenerates all 2D
142
+ coordinates using `Compute2DCoords()`
143
+ - This is useful after manual edits that distort the structure
144
+
145
+ ### Area Delete (X key)
146
+ - Implements rectangle selection in screen coordinates
147
+ - `delete_atoms_in_rect()` converts screen rect to molecular coordinates
148
+ and deletes atoms within the rectangle
149
+
150
+ ### SMILES Fragment Appending
151
+ When appending to a bond (not an atom), the fragment forms a ring by
152
+ connecting its first and last atoms to the two bond atoms. This allows
153
+ easy ring fusion operations.
154
+
155
+ ### UI Helpers
156
+ - `prompt_user_input()`: Generic prompt for text input
157
+ - `enter_smiles()`: Specialized prompt for SMILES strings
158
+ - `enter_element()`: Specialized prompt for element symbols
159
+ - `show_help()`: Displays help screen with keybindings
160
+ - `draw_instructions()`: Shows mode-specific status line
161
+ - `draw_error_message()`: Displays error messages to user
cursemol-4.1.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, Schrodinger, LLC - All Rights Reserved
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.4
2
+ Name: CurseMol
3
+ Version: 4.1.0
4
+ Summary: Molecular sketcher for the terminally committed
5
+ Project-URL: source, https://github.com/i-tub/cursemol
6
+ Author-email: Ivan Tubert-Brohman <ivan.tubert@gmail.com>
7
+ License-File: LICENSE
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console :: Curses
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: BSD License
12
+ Classifier: Natural Language :: English
13
+ Classifier: Operating System :: POSIX
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: rdkit
18
+ Description-Content-Type: text/markdown
19
+
20
+ ## CurseMol - Molecular sketcher for the terminally committed
21
+
22
+ Have you ever been working on a terminal with programs that use SMILES for
23
+ input or output, and switching to your GUI sketcher is too annoying? (Not
24
+ to mention reading or writing the SMILES by hand.)
25
+
26
+ Enter CurseMol, the curses-based molecular editor, with keybindings inspired
27
+ by vi! The molecules are depicted using ASCII art (actually, not exactly; a few
28
+ non-ASCII Unicode characters are used, as well.)
29
+
30
+ You can read in a SMILES string or start from a blank canvas, and when you
31
+ exit, the final SMILES is printed to stdout, which can be useful for piping
32
+ directly into other programs.
33
+
34
+ ![Screen recording of sketching naproxen](https://raw.githubusercontent.com/i-tub/cursemol/master/demo.gif)
35
+
36
+ ```
37
+ Controls:
38
+ h, j, k, l - Move cursor left/down/up/right (arrow keys supported too)
39
+ H, J, K, L - Move cursor faster (10 cells horizontal, 4 cells vertical)
40
+ Space - Snap cursor to nearest atom
41
+ m - Enter move mode (hjkl moves molecule, Esc to exit)
42
+ s - Enter a SMILES string to replace the current molecule
43
+ S - Toggle SMILES display
44
+ i - Insert/modify atom at cursor position
45
+ a - Append atoms from SMILES to atom or bond under cursor
46
+ (appending to a bond forms a ring by connecting the bond
47
+ atoms to the first and last atoms from the SMILES)
48
+ c, n, o - Insert/modify carbon/nitrogen/oxygen atom
49
+ x - Delete atom or bond
50
+ D - Delete fragment (all atoms connected to cursor atom)
51
+ X - Area delete (select rectangle)
52
+ +, - - Increase/decrease formal charge on atom
53
+ <, > - Zoom out/in
54
+ b - Add bond mode (add atom and move it, Enter to accept)
55
+ 1, 2, 3 - Add bond or change bond (order 1/2/3) between nearest atoms
56
+ w, d - Add/change to wedge or dash bond (press again to reverse)
57
+ @ - Clear canvas (reset to blank slate)
58
+ u, r - Undo/redo
59
+ Ctrl-L - Clean up (regenerate coordinates)
60
+ ? - Show this help
61
+ q - Quit and print SMILES to stdout
62
+ ```
63
+
64
+ ### Requirements
65
+
66
+ - Python (tested with 3.11)
67
+ - RDKit (tested with 2025.09.6)
@@ -0,0 +1,48 @@
1
+ ## CurseMol - Molecular sketcher for the terminally committed
2
+
3
+ Have you ever been working on a terminal with programs that use SMILES for
4
+ input or output, and switching to your GUI sketcher is too annoying? (Not
5
+ to mention reading or writing the SMILES by hand.)
6
+
7
+ Enter CurseMol, the curses-based molecular editor, with keybindings inspired
8
+ by vi! The molecules are depicted using ASCII art (actually, not exactly; a few
9
+ non-ASCII Unicode characters are used, as well.)
10
+
11
+ You can read in a SMILES string or start from a blank canvas, and when you
12
+ exit, the final SMILES is printed to stdout, which can be useful for piping
13
+ directly into other programs.
14
+
15
+ ![Screen recording of sketching naproxen](https://raw.githubusercontent.com/i-tub/cursemol/master/demo.gif)
16
+
17
+ ```
18
+ Controls:
19
+ h, j, k, l - Move cursor left/down/up/right (arrow keys supported too)
20
+ H, J, K, L - Move cursor faster (10 cells horizontal, 4 cells vertical)
21
+ Space - Snap cursor to nearest atom
22
+ m - Enter move mode (hjkl moves molecule, Esc to exit)
23
+ s - Enter a SMILES string to replace the current molecule
24
+ S - Toggle SMILES display
25
+ i - Insert/modify atom at cursor position
26
+ a - Append atoms from SMILES to atom or bond under cursor
27
+ (appending to a bond forms a ring by connecting the bond
28
+ atoms to the first and last atoms from the SMILES)
29
+ c, n, o - Insert/modify carbon/nitrogen/oxygen atom
30
+ x - Delete atom or bond
31
+ D - Delete fragment (all atoms connected to cursor atom)
32
+ X - Area delete (select rectangle)
33
+ +, - - Increase/decrease formal charge on atom
34
+ <, > - Zoom out/in
35
+ b - Add bond mode (add atom and move it, Enter to accept)
36
+ 1, 2, 3 - Add bond or change bond (order 1/2/3) between nearest atoms
37
+ w, d - Add/change to wedge or dash bond (press again to reverse)
38
+ @ - Clear canvas (reset to blank slate)
39
+ u, r - Undo/redo
40
+ Ctrl-L - Clean up (regenerate coordinates)
41
+ ? - Show this help
42
+ q - Quit and print SMILES to stdout
43
+ ```
44
+
45
+ ### Requirements
46
+
47
+ - Python (tested with 3.11)
48
+ - RDKit (tested with 2025.09.6)
File without changes
Binary file
cursemol-4.1.0/l ADDED
@@ -0,0 +1,145 @@
1
+ commit 8c157c90bbef1a927b1544c9be4686d112bf08cd
2
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
3
+ Date: Fri Mar 27 20:07:19 2026 -0400
4
+
5
+ Support drawing from blank slate
6
+
7
+ commit ef291c59c032394fe570d8cec86af2e329ad0058
8
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
9
+ Date: Fri Mar 27 20:03:43 2026 -0400
10
+
11
+ +/- commands
12
+
13
+ commit 8253c4ee6e9a26631e2e8fe19e9884e7c7bb36ad
14
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
15
+ Date: Fri Mar 27 20:01:25 2026 -0400
16
+
17
+ Add charges
18
+
19
+ commit 6a3f76d8a4f132017e9d322019c5240ab09f8c92
20
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
21
+ Date: Fri Mar 27 19:54:28 2026 -0400
22
+
23
+ CNO commands; strong kekulization
24
+
25
+ commit db6151ca7c5fc8b2622918fca7c6d6911a7b7187
26
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
27
+ Date: Fri Mar 27 19:48:35 2026 -0400
28
+
29
+ Delete bond with x
30
+
31
+ commit 565b9bc5524de27822c763923087bd6806ded257
32
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
33
+ Date: Fri Mar 27 19:15:09 2026 -0400
34
+
35
+ Cleanup command
36
+
37
+ commit 8af0dfc2ac1c8ce5df4b20f804a1d0487896c339
38
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
39
+ Date: Fri Mar 27 19:12:38 2026 -0400
40
+
41
+ Delete atom
42
+
43
+ commit bc088b06dc88c1b6f42f96ad9abe0c0f3f6a9760
44
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
45
+ Date: Fri Mar 27 19:09:41 2026 -0400
46
+
47
+ Add yapf
48
+
49
+ commit bc27afc4f2bc6f31f33350070704137fdb1c1aa5
50
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
51
+ Date: Fri Mar 27 19:06:15 2026 -0400
52
+
53
+ Print SMILES on exit
54
+
55
+ commit 08e07f6d61fe018bea1e9a618e2224a774116da2
56
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
57
+ Date: Fri Mar 27 19:00:31 2026 -0400
58
+
59
+ Silence logger
60
+
61
+ commit 951d354a6cfa38f13a4878b27cbbf83519ea174a
62
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
63
+ Date: Fri Mar 27 18:55:55 2026 -0400
64
+
65
+ Catch some exceptions
66
+
67
+ commit 324178f21f049fed2a62ce1dd0e66298e7013c94
68
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
69
+ Date: Fri Mar 27 18:51:33 2026 -0400
70
+
71
+ Add bonds
72
+
73
+ commit f69ff9ef1bb267df0953e1c65f101e178569d0a1
74
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
75
+ Date: Fri Mar 27 18:43:02 2026 -0400
76
+
77
+ Show SMILES
78
+
79
+ commit c109e38c566fcadd3825949e7f6f102448f3b78c
80
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
81
+ Date: Fri Mar 27 18:38:34 2026 -0400
82
+
83
+ Center
84
+
85
+ commit 4e2110934b74bfbd780f8b21485bda57e5868da4
86
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
87
+ Date: Fri Mar 27 18:35:34 2026 -0400
88
+
89
+ Add atom
90
+
91
+ commit c505e4a30122ecd5705152111273970c952ecef3
92
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
93
+ Date: Fri Mar 27 18:03:30 2026 -0400
94
+
95
+ Refactor
96
+
97
+ commit 768df063496719360c0673489cae3044241c85c7
98
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
99
+ Date: Fri Mar 27 18:01:27 2026 -0400
100
+
101
+ Add argparse; remove x
102
+
103
+ commit 5e17acafcc8e535be75c82171791fea5ad01e784
104
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
105
+ Date: Fri Mar 27 17:56:53 2026 -0400
106
+
107
+ Do partial redraw
108
+
109
+ commit f4b9a9b30794bb6b05bb359f17c729663fc093f4
110
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
111
+ Date: Fri Mar 27 17:51:39 2026 -0400
112
+
113
+ Make sketch persistent
114
+
115
+ commit cf26daa2b09d1c0e930534c5fa8fefebbdc560e7
116
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
117
+ Date: Fri Mar 27 17:47:54 2026 -0400
118
+
119
+ First try at sketching
120
+
121
+ commit a9a70f7e3f7ae2fadd941e8a9bf4c48a002b9451
122
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
123
+ Date: Fri Mar 27 17:45:50 2026 -0400
124
+
125
+ Add draw_mol() stub
126
+
127
+ commit 6942be59e0535d42bb3e09321070f4ab6e986f82
128
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
129
+ Date: Fri Mar 27 17:37:15 2026 -0400
130
+
131
+ Refactor
132
+
133
+ commit 846d78de47e9f62d1df97d33b53a1f965b8d6c33
134
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
135
+ Date: Fri Mar 27 17:35:27 2026 -0400
136
+
137
+ Prompt for SMILES
138
+
139
+ commit b1308fa44a021abbfbe0b4becea98348009bb4c1
140
+ Author: Ivan Tubert-Brohman <Ivan.Tubert-Brohman@schrodinger.com>
141
+ Date: Fri Mar 27 17:30:58 2026 -0400
142
+
143
+ Curses hello world
144
+
145
+ Just move around and place Xes.
cursemol-4.1.0/notes ADDED
@@ -0,0 +1,44 @@
1
+ Ideas:
2
+
3
+ How to depict stereo wedges and dashes?
4
+
5
+ Maybe we could change the first bond character, or maybe the first half of the
6
+ bond, to a ^ or v instead of a dot, to signal if the bond goes up or down
7
+ relative to the beginning atom.
8
+
9
+ We could also use bold, reverse, or color. But in any case a tricky part is
10
+ that the bond is directional; we can't simply tag the entire bond.
11
+
12
+ What other characters might we use?
13
+
14
+ From pure ASCII:
15
+
16
+ : second half of dotted bond?
17
+ | second half of solid wedge?
18
+ ,
19
+ >
20
+ <
21
+ "
22
+ '
23
+ `
24
+ * (better for dummy atoms)
25
+ ~ (better for wiggly bonds)
26
+
27
+ Cvvv...C
28
+ C^^^...C
29
+
30
+ From Unicode maybe arrows?
31
+
32
+
33
+
34
+
35
+ or bullets? Let's go with that (solid bullet / empty bullet / middle dot)
36
+
37
+ TODO:
38
+
39
+ - Add a "fit to screen" command?
40
+ - Improvements to bond selection: make the angle tolerance a function of
41
+ distance.
42
+ - There's a stereochemistry bug! Cleanup can cause epimerization! We need to
43
+ assign stereo before doing cleanup.
44
+ - Capture Ctrl-C?
@@ -0,0 +1,36 @@
1
+ [project]
2
+ name = "CurseMol"
3
+ dynamic = ["version"]
4
+ description = "Molecular sketcher for the terminally committed"
5
+ authors = [
6
+ { name = "Ivan Tubert-Brohman", email = "ivan.tubert@gmail.com" }
7
+ ]
8
+ readme = "README.md"
9
+ requires-python = ">= 3.11"
10
+ dependencies = [
11
+ "rdkit",
12
+ ]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Science/Research",
16
+ "Topic :: Scientific/Engineering :: Chemistry",
17
+ "Intended Audience :: Science/Research",
18
+ "License :: OSI Approved :: BSD License",
19
+ "Programming Language :: Python :: 3",
20
+ "Operating System :: POSIX",
21
+ "Environment :: Console :: Curses",
22
+ "Natural Language :: English",
23
+ ]
24
+
25
+ [project.urls]
26
+ source = "https://github.com/i-tub/cursemol"
27
+
28
+ [project.scripts]
29
+ cursemol = "cursemol:main"
30
+
31
+ [build-system]
32
+ requires = ["hatchling"]
33
+ build-backend = "hatchling.build"
34
+
35
+ [tool.hatch.version]
36
+ path = "src/cursemol/__init__.py"