Skip to main content
Glama

semantic-edit-mcp

by jbr
searcher.rs6.28 kB
pub(crate) fn find_positions( source_text: &str, snippet: &str, ) -> Result<Vec<(usize, usize)>, String> { let mut results = vec![]; let (initial_anchor, remaining_snippet) = match snippet.find(char::is_whitespace) { Some(pos) => snippet.split_at(pos), None => (snippet, ""), }; for (start_pos, _) in source_text.match_indices(initial_anchor) { let mut current_pos = start_pos + initial_anchor.len(); if remaining_snippet.is_empty() { results.push((start_pos, current_pos)); continue; } let mut snippet_chars = remaining_snippet.chars(); let mut source_chars = source_text[current_pos..].chars(); let mut snippet_char = snippet_chars.next(); let mut source_char = source_chars.next(); loop { match (snippet_char, source_char) { (Some(s), Some(src)) => { if s == src { snippet_char = snippet_chars.next(); source_char = source_chars.next(); current_pos += src.len_utf8(); } else if s.is_whitespace() { snippet_char = snippet_chars.next(); } else if src.is_whitespace() { source_char = source_chars.next(); current_pos += src.len_utf8(); } else { break; // Mismatch } } (None, _) => { // Snippet exhausted - complete match! results.push((start_pos, current_pos)); break; } (Some(_), None) => break, // Source exhausted, snippet remaining } } } if !results.is_empty() { Ok(results) } else { Err(format!("Anchor \"{snippet}\" not found in source")) } } #[cfg(test)] mod tests { use super::*; fn position_strs<'a>(source: &'a str, snippet: &str) -> Vec<&'a str> { find_positions(source, snippet) .unwrap_or_default() .into_iter() .map(|(start, end)| &source[start..end]) .collect() } #[test] fn test_exact_match_single_line() { let source = "hello world\nfoo bar\nbaz"; let snippet = "foo bar"; let result = position_strs(source, snippet); assert_eq!(result, ["foo bar"]); } #[test] fn test_exact_match_multiline() { let source = "line1\nline2\nline3\nline4"; let snippet = "line2\nline3"; let result = position_strs(source, snippet); assert_eq!(result, ["line2\nline3"]); } #[test] fn test_whitespace_differences() { let source = " hello world \n\t\tfoo\tbar\t\n baz "; let snippet = "hello world\nfoo bar"; let result = position_strs(source, snippet); assert_eq!(result, ["hello world \n\t\tfoo\tbar"]); } #[test] fn test_multiple_matches() { let source = "foo\nbar\nbaz\nfoo\nbar\nqux"; let snippet = "foo\nbar"; let result = position_strs(source, snippet); assert_eq!(result, ["foo\nbar", "foo\nbar"]); } #[test] fn test_overlapping_first_lines() { let source = "abc1abc 1abc\nghi\nabc\njkl"; let snippet = "abc 1 abc"; let result = position_strs(source, snippet); assert_eq!(result, ["abc1abc", "abc 1abc"]); } #[test] fn test_first_line_appears_multiple_times_but_only_one_full_match() { let source = "start\nmiddle\nstart\nend\nother"; let snippet = "start\nend"; let result = position_strs(source, snippet); assert_eq!(result, ["start\nend"]); } #[test] fn test_no_matches_first_line_not_found() { let source = "hello\nworld\nfoo"; let snippet = "missing\nline"; let result = position_strs(source, snippet); assert!(result.is_empty()); } #[test] fn test_no_matches_partial_match() { let source = "hello\nworld\nfoo"; let snippet = "hello\nmissing"; let result = position_strs(source, snippet); assert!(result.is_empty()); } #[test] fn test_single_line_snippet() { let source = "one\ntwo\nthree 3\nfour"; let snippet = "three 3"; let result = position_strs(source, snippet); assert_eq!(result, ["three 3"]); } #[test] fn test_entire_source_matches() { let source = "line1\nline2\nline3"; let snippet = "line1\nline2\nline3"; let result = position_strs(source, snippet); assert_eq!(result, [source]); } #[test] fn test_whitespace_only_differences() { let source = "func(a, b )\n{\n return a + b;\n}"; let snippet = "func(a, b)\n{\nreturn a + b;\n}"; let result = position_strs(source, snippet); assert_eq!(result, [source]); } #[test] fn test_mixed_whitespace_types() { let source = "hello\tworld\r\n foo bar "; let snippet = "hello world\nfoo bar"; let result = position_strs(source, snippet); assert_eq!(result, ["hello\tworld\r\n foo bar"]); } #[test] fn test_trailing_whitespace_in_source() { let source = "line1 \nline2\t\t\nline3"; let snippet = "line1\nline2"; let result = position_strs(source, snippet); assert_eq!(result, ["line1 \nline2"]); } #[test] fn test_snippet_longer_than_remaining_source() { let source = "short\nfile"; let snippet = "short\nfile\nextra\nlines"; let result = position_strs(source, snippet); assert!(result.is_empty()); } #[test] fn test_unicode_characters() { let source = "héllo\nwörld\n测试"; let snippet = "héllo\nwörld"; let result = position_strs(source, snippet); assert_eq!(result, ["héllo\nwörld"]); } #[test] fn test_first_line_at_end_of_source() { let source = "beginning\nmiddle\nend"; let snippet = "end\nextra"; let result = position_strs(source, snippet); assert!(result.is_empty()); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jbr/semantic-edit-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server