Skip to content

Commit

Permalink
Merge pull request #1 from kv9898/feature/neat-nested-outline
Browse files Browse the repository at this point in the history
Move comment handling to loop
  • Loading branch information
kv9898 authored Oct 17, 2024
2 parents c83b756 + 3dd37ee commit 5d57786
Showing 1 changed file with 61 additions and 60 deletions.
121 changes: 61 additions & 60 deletions crates/ark/src/lsp/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,84 +146,85 @@ fn parse_comment_as_section(comment: &str) -> Option<(usize, String)> {
None
}

fn index_node(
fn index_assignment_with_comments(
node: &Node,
contents: &Rope,
parent: &mut DocumentSymbol,
symbols: &mut Vec<DocumentSymbol>,
section_stack: &mut Vec<(usize, *mut DocumentSymbol)>,
) -> Result<bool> {
// Maintain hierarchy for comment sections
if node.node_type() == NodeType::Comment {
let comment_text = contents.node_slice(&node)?.to_string();

if let Some((level, title)) = parse_comment_as_section(&comment_text) {
let start = convert_point_to_position(contents, node.start_position());
let end = convert_point_to_position(contents, node.end_position());

let symbol = DocumentSymbol {
name: title,
kind: SymbolKind::STRING,
detail: None,
children: Some(Vec::new()),
deprecated: None,
tags: None,
range: Range { start, end },
selection_range: Range { start, end },
};

// Pop until we find a suitable parent for this level
while let Some((current_level, _)) = section_stack.last() {
if *current_level >= level {
section_stack.pop();
} else {
break;
}
}
let comment_text = contents.node_slice(&node)?.to_string();

// Check if the comment starts with one or more '#' followed by any text and ends with 4+ punctuations
if let Some((level, title)) = parse_comment_as_section(&comment_text) {
// Create a symbol based on the parsed comment
let start = convert_point_to_position(contents, node.start_position());
let end = convert_point_to_position(contents, node.end_position());

let symbol = DocumentSymbol {
name: title, // Use the title without the trailing '####' or '----'
kind: SymbolKind::STRING, // Treat it as a string section
detail: None, // No need to display level details
children: Some(Vec::new()), // Prepare for child symbols if any
deprecated: None,
tags: None,
range: Range { start, end },
selection_range: Range { start, end },
};

// Push the new symbol to the current parent
if let Some((_, current_parent_ptr)) = section_stack.last() {
let current_parent = unsafe { &mut **current_parent_ptr };
current_parent.children.as_mut().unwrap().push(symbol);
let new_parent = current_parent
.children
.as_mut()
.unwrap()
.last_mut()
.unwrap();
section_stack.push((level, new_parent as *mut DocumentSymbol));
while let Some((current_level, _)) = section_stack.last() {
if *current_level >= level {
section_stack.pop();
} else {
parent.children.as_mut().unwrap().push(symbol);
let new_parent = parent.children.as_mut().unwrap().last_mut().unwrap();
section_stack.push((level, new_parent as *mut DocumentSymbol));
break;
}

return Ok(true);
}
}

// Handle assignments (like `a <- 1`)
if matches!(
node.node_type(),
NodeType::BinaryOperator(BinaryOperatorType::LeftAssignment) |
NodeType::BinaryOperator(BinaryOperatorType::EqualsAssignment)
) {
// Push the new symbol to the current parent
if let Some((_, current_parent_ptr)) = section_stack.last() {
let current_parent = unsafe { &mut **current_parent_ptr };
return index_assignment(node, contents, current_parent, symbols, section_stack);
current_parent.children.as_mut().unwrap().push(symbol);
let new_parent = current_parent
.children
.as_mut()
.unwrap()
.last_mut()
.unwrap();
section_stack.push((level, new_parent as *mut DocumentSymbol));
} else {
parent.children.as_mut().unwrap().push(symbol);
let new_parent = parent.children.as_mut().unwrap().last_mut().unwrap();
section_stack.push((level, new_parent as *mut DocumentSymbol));
}

return Ok(true);
} else {
// No need to index the comment
return Ok(false);
}
}

// Recurse into children
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
if is_indexable(&child) {
if let Some((_, current_parent_ptr)) = section_stack.last() {
let current_parent = unsafe { &mut **current_parent_ptr };
let result = index_node(&child, contents, current_parent, symbols, section_stack);

fn index_node(
node: &Node,
contents: &Rope,
parent: &mut DocumentSymbol,
symbols: &mut Vec<DocumentSymbol>,
) -> Result<bool> {
if child.node_type() == NodeType::Comment {
let result: Result<bool> =
index_assignment_with_comments(&child, contents, parent, &mut section_stack);
if let Err(error) = result {
error!("{:?}", error);
}
} else {
// todo: deal with the stacks of other types
if let Some((_, current_parent_ptr)) = section_stack.last() {
let current_parent = unsafe { &mut **current_parent_ptr };
let result = index_node(&child, contents, current_parent, symbols);
if let Err(error) = result {
error!("{:?}", error);
}
}
}
}
}
Expand Down

0 comments on commit 5d57786

Please sign in to comment.