Skip to content

Commit 09322e9

Browse files
committed
use_claude_code()
1 parent c41e5d9 commit 09322e9

File tree

6 files changed

+505
-101
lines changed

6 files changed

+505
-101
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
^.cache$
2020
^AGENTS\.md$
2121
^compile_commands\.json$
22+
^\.claude$

.claude/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
settings.local.json

.claude/CLAUDE.md

Lines changed: 66 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,82 @@
1-
# CLAUDE.md
1+
## R package development
22

3-
This file provides guidance to Claude Code when working with code in this repository.
3+
### Key commands
44

5-
## About This Project
5+
```
6+
# To run code
7+
Rscript -e "devtools::load_all(); code"
68
7-
lobstr is a package for R developers that prints data structures and objects in a tree-like fashion. It provides specialized `base::str()`-like functions that help visualize objects during development:
9+
# To run all tests
10+
Rscript -e "devtools::test()"
811
9-
- `ast()`: draws the abstract syntax tree of R expressions
10-
- `ref()`: shows hows objects can be shared across data structures by digging into the underlying references
11-
- `obj_size()`: computes the size of an object taking these shared references into account
12-
- `cst()` shows how frames on the call stack are connected
12+
# To run all tests for files starting with {name}
13+
Rscript -e "devtools::test(filter = '^{name}')"
1314
15+
# To run all tests for R/{name}.R
16+
Rscript -e "devtools::test_active_file('R/{name}.R')"
1417
15-
## Key development commands
18+
# To run a single test "blah" for R/{name}.R
19+
Rscript -e "devtools::test_active_file('R/{name}.R', desc = 'blah')"
20+
21+
# To redocument the package
22+
Rscript -e "devtools::document()"
23+
24+
# To check pkgdown documentation
25+
Rscript -e "pkgdown::check_pkgdown()"
26+
27+
# To check the package with R CMD check
28+
Rscript -e "devtools::check()"
29+
30+
# To format code
31+
air format .
32+
```
33+
34+
### Coding
1635

17-
General advice:
18-
* When running R from the console, always run it with `--quiet`
1936
* Always run `air format .` after generating code
37+
* Use the base pipe operator (`|>`) not the magrittr pipe (`%>%`)
38+
* Don't use `_$x` or `_$[["x"]]` since this package must work on R 4.1.
39+
* Use `\() ...` for single-line anonymous functions. For all other cases, use `function() {...}`
2040

2141
### Testing
2242

23-
- Use `devtools::test()` to run all tests
24-
- Use `devtools::test_file("tests/testthat/test-filename.R")` to run tests in a specific file
25-
- DO NOT USE `devtools::test_active_file()`
26-
- All testing functions automatically load code; you don't needs to.
27-
43+
- Tests for `R/{name}.R` go in `tests/testthat/test-{name}.R`.
2844
- All new code should have an accompanying test.
29-
- Tests for `R/{name}.R` go in `tests/testthat/test-{name}.R`.
3045
- If there are existing tests, place new tests next to similar existing tests.
46+
- Strive to keep your tests minimal with few comments.
3147

3248
### Documentation
3349

34-
- Run `devtools::document()` after changing any roxygen2 docs.
35-
- Every user facing function should be exported and have roxygen2 documentation.
36-
- Whenever you add a new documentation file, make sure to also add the topic name to `_pkgdown.yml`.
37-
- Run `pkgdown::check_pkgdown()` to check that all topics are included in the reference index.
38-
- Use sentence case for all headings
39-
40-
## Core Architecture
41-
42-
### Main Components
43-
44-
1. **Abstract Syntax Trees** (`R/ast.R`):
45-
- `ast()` - Visualizes R expression structure as a tree
46-
- Recursively processes calls, symbols, and literals
47-
- Uses rlang for quosure handling and expression manipulation
48-
- Output formatting handled by tree display utilities
49-
50-
2. **Reference Tracking** (`R/ref.R`, `src/address.cpp`):
51-
- `ref()` - Shows memory addresses and shared references
52-
- `obj_addr()`, `obj_addrs()` - Get memory locations of objects
53-
- Tracks how objects are shared across data structures
54-
- Handles lists, environments, and optionally character vectors (global string pool)
55-
- Uses depth-first search with seen tracking to avoid infinite loops
56-
57-
3. **Object Size Calculation** (`R/size.R`, `src/size.cpp`):
58-
- `obj_size()` - Computes memory size accounting for shared references
59-
- `obj_sizes()` - Shows individual contributions of multiple objects
60-
- Handles ALTREP objects correctly (R 3.5+)
61-
- Smart environment handling: stops at global, base, empty, and namespace environments
62-
- C++ implementation traverses object tree with deduplication
63-
64-
4. **Call Stack Trees** (`R/cst.R`):
65-
- `cst()` - Displays call stack relationships
66-
- Wrapper around `rlang::trace_back()` with simplified output
67-
- Shows how frames are connected through parent relationships
68-
69-
5. **Low-Level Inspection** (`R/sxp.R`, `src/inspect.cpp`):
70-
- `sxp()` - Deep inspection of C-level SEXP structures
71-
- Recursive descent into R's internal data structures
72-
- Optional expansion of: character pool, ALTREP, environments, calls, bytecode
73-
- Returns structured list with metadata (type, length, address, named status, etc.)
74-
75-
6. **Memory Utilities** (`R/mem.R`):
76-
- `mem_used()` - Current R memory usage via `gc()`
77-
- Platform-aware node size calculation (32-bit vs 64-bit)
78-
79-
7. **Generic Tree Printing** (`R/tree.R`):
80-
- `tree()` - General-purpose tree printer for nested lists
81-
- Highly customizable (depth, length limits, value/class printers)
82-
- Handles environments with cycle detection
83-
- Attribute display support
84-
85-
### Key Design Patterns
86-
87-
- **Tree Visualization**: Consistent tree-based output across all functions using shared utilities (`R/tree.R`, `R/utils.R`)
88-
- **C++ Integration**: Performance-critical operations (memory addresses, size calculation, SEXP inspection) implemented in C++ via cpp11
89-
- **Reference Tracking**: Inspection functions use `seen` sets to handle cycles and shared references
90-
- **Lazy Evaluation**: `ast()` and `obj_addr()` use rlang quasiquotation to quote the AST or avoid taking unnecessary references
91-
- **Testing Stability**: Address normalization in tests (sequential IDs instead of actual pointers)
92-
93-
### File Organization
94-
95-
- `R/` - R source code organized by main user-facing functions
96-
- `ast.R`, `ref.R`, `size.R`, `cst.R`, `sxp.R` - Main visualization functions
97-
- `mem.R` - Memory utilities
98-
- `address.R` - Address helper functions
99-
- `tree.R` - Generic tree printing infrastructure
100-
- `utils.R` - Shared utilities (string, display, box characters)
101-
- `src/` - C++ source code using cpp11
102-
- `address.cpp` - Memory address extraction
103-
- `size.cpp` - Object size calculation with tree traversal
104-
- `inspect.cpp` - Deep SEXP inspection
105-
- `utils.h` - Shared C++ utilities
106-
- `tests/testthat/` - Comprehensive test suite
107-
108-
### C++ Implementation Details
109-
110-
All C++ code uses the cpp11 interface for R integration:
111-
- Uses `std::set<SEXP>` for tracking seen objects during traversal
112-
- Implements custom vector size calculation matching R's memory allocation strategy
113-
- Handles ALTREP objects (R 3.5+) with conditional compilation
114-
- Recursive tree traversal with depth limits to prevent stack overflow
115-
- Namespace and special environment detection to avoid infinite recursion
116-
117-
This codebase prioritizes accurate visualization of R's internal structures while maintaining performance through C++ implementation of core algorithms.
50+
- Every user-facing function should be exported and have roxygen2 documentation.
51+
- Wrap roxygen comments at 80 characters.
52+
- Internal functions should not have roxygen documentation.
53+
- Whenever you add a new (non-internal) documentation topic, also add the topic to `_pkgdown.yml`.
54+
- Always re-document the package after changing a roxygen2 comment.
55+
- Use `pkgdown::check_pkgdown()` to check that all topics are included in the reference index.
56+
57+
### `NEWS.md`
58+
59+
- Every user-facing change should be given a bullet in `NEWS.md`. Do not add bullets for small documentation changes or internal refactorings.
60+
- Each bullet should briefly describe the change to the end user and mention the related issue in parentheses.
61+
- A bullet can consist of multiple sentences but should not contain any new lines (i.e. DO NOT line wrap).
62+
- If the change is related to a function, put the name of the function early in the bullet.
63+
- Order bullets alphabetically by function name. Put all bullets that don't mention function names at the beginning.
64+
65+
### GitHub
66+
67+
- If you use `gh` to retrieve information about an issue, always use `--comments` to read all the comments.
68+
69+
### Writing
70+
71+
- Use sentence case for headings.
72+
- Use US English.
73+
74+
### Proofreading
75+
76+
If the user asks you to proofread a file, act as an expert proofreader and editor with a deep understanding of clear, engaging, and well-structured writing.
77+
78+
Work paragraph by paragraph, always starting by making a TODO list that includes individual items for each top-level heading.
79+
80+
Fix spelling, grammar, and other minor problems without asking the user. Label any unclear, confusing, or ambiguous sentences with a FIXME comment.
81+
82+
Only report what you have changed.

.claude/settings.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"permissions": {
3+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
4+
"defaultMode": "acceptEdits",
5+
"allow": [
6+
"Bash(air:*)",
7+
"Bash(cat:*)",
8+
"Bash(find:*)",
9+
"Bash(gh issue list:*)",
10+
"Bash(gh issue view:*)",
11+
"Bash(gh pr diff:*)",
12+
"Bash(gh pr view:*)",
13+
"Bash(git checkout:*)",
14+
"Bash(git grep:*)",
15+
"Bash(grep:*)",
16+
"Bash(ls:*)",
17+
"Bash(R:*)",
18+
"Bash(rm:*)",
19+
"Bash(Rscript:*)",
20+
"Bash(sed:*)",
21+
"Skill(*)",
22+
"WebFetch(domain:cran.r-project.org)",
23+
"WebFetch(domain:github.com)",
24+
"WebFetch(domain:raw.githubusercontent.com)"
25+
],
26+
"deny": [
27+
"Read(.Renviron)",
28+
"Read(.env)"
29+
]
30+
}
31+
}

0 commit comments

Comments
 (0)