Skip to content

Commit ecf6293

Browse files
committed
feat(context): add read_section with section targeting
1 parent f7a4d3b commit ecf6293

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

src/context.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,41 @@ fn get_mention_snippet(params: &ContextParams, file_id: i64, name: &str) -> Stri
408408
String::new()
409409
}
410410

411+
// ---------------------------------------------------------------------------
412+
// Section reading
413+
// ---------------------------------------------------------------------------
414+
415+
#[derive(Debug, Serialize)]
416+
pub struct SectionResult {
417+
pub path: String,
418+
pub heading: String,
419+
pub content: String,
420+
pub line_start: usize,
421+
pub line_end: usize,
422+
}
423+
424+
pub fn read_section(
425+
store: &Store,
426+
vault_root: &Path,
427+
file: &str,
428+
heading: &str,
429+
) -> Result<SectionResult> {
430+
let record = store
431+
.resolve_file(file)?
432+
.ok_or_else(|| anyhow::anyhow!("Not found: {file}"))?;
433+
let path = vault_root.join(&record.path);
434+
let content = std::fs::read_to_string(&path)?;
435+
let section = crate::markdown::find_section(&content, heading)
436+
.ok_or_else(|| anyhow::anyhow!("Section not found: {heading}"))?;
437+
Ok(SectionResult {
438+
path: record.path,
439+
heading: section.heading.text,
440+
content: section.content,
441+
line_start: section.body_start,
442+
line_end: section.body_end,
443+
})
444+
}
445+
411446
/// Build a project context bundle: note, child notes, tasks, team, recent mentions.
412447
pub fn context_project(params: &ContextParams, name: &str) -> Result<ProjectContext> {
413448
let (note, project_id, project_folder) = if let Some(pf) = resolve_file(params, name)? {
@@ -1112,4 +1147,20 @@ mod tests {
11121147
assert!(s.is_char_boundary(snap));
11131148
assert!(snap <= 6);
11141149
}
1150+
1151+
#[test]
1152+
fn test_read_section() {
1153+
let tmp = TempDir::new().unwrap();
1154+
let root = tmp.path().to_path_buf();
1155+
let store = Store::open_memory().unwrap();
1156+
let content = "# Person\n\n## Role\n\nEngineer\n\n## Interactions\n\nMet on 2026-03-26\n";
1157+
std::fs::write(root.join("person.md"), content).unwrap();
1158+
store
1159+
.insert_file("person.md", "hash", 100, &[], "per123", None)
1160+
.unwrap();
1161+
1162+
let result = read_section(&store, &root, "person.md", "Interactions").unwrap();
1163+
assert!(result.content.contains("Met on 2026-03-26"));
1164+
assert!(!result.content.contains("Engineer"));
1165+
}
11151166
}

0 commit comments

Comments
 (0)