(ctx context.Context, argv []string, cwd string, timeout time.Duration, originalCommand string)
| 1533 | denom := max(len(aTokens), len(bSet)) |
| 1534 | if denom == 0 { |
| 1535 | return 0 |
| 1536 | } |
| 1537 | return float64(intersect) / float64(denom) |
| 1538 | } |
| 1539 | |
| 1540 | func preserveQuoteStyle(originalSearch, actualFromFile, newString string) string { |
| 1541 | quoteMap := map[rune]rune{} |
| 1542 | orig := []rune(originalSearch) |
| 1543 | actual := []rune(actualFromFile) |
| 1544 | for i := 0; i < len(orig) && i < len(actual); i++ { |
| 1545 | if orig[i] != actual[i] && (orig[i] == '"' || orig[i] == '\'') { |
| 1546 | if actual[i] == '“' || actual[i] == '”' || actual[i] == '‘' || actual[i] == '’' { |
| 1547 | quoteMap[orig[i]] = actual[i] |
| 1548 | } |
| 1549 | } |
| 1550 | } |
| 1551 | if len(quoteMap) == 0 { |
| 1552 | return newString |
| 1553 | } |
| 1554 | return strings.Map(func(r rune) rune { |
| 1555 | if repl, ok := quoteMap[r]; ok { |
| 1556 | return repl |
| 1557 | } |
| 1558 | return r |
| 1559 | }, newString) |
| 1560 | } |
| 1561 | |
| 1562 | func checkCascadingEdit(execCtx ExecutionContext, filePath, oldString string) string { |
| 1563 | raw, ok := execCtx["_applied_edits"].(map[string][]map[string]string) |
| 1564 | if !ok { |
| 1565 | return "" |
| 1566 | } |
| 1567 | oldTrimmed := strings.TrimRight(oldString, "\n") |
| 1568 | if oldTrimmed == "" { |
| 1569 | return "" |
| 1570 | } |
| 1571 | for _, prev := range raw[filePath] { |
| 1572 | if strings.Contains(prev["new_string"], oldTrimmed) { |
| 1573 | return formatEditError(editCascadingEdit, "Cascading edit detected: old_string is a substring of a new_string from a previous edit on this file. Re-read the file and adjust the edit to target the original content.") |
| 1574 | } |
| 1575 | } |
| 1576 | return "" |
no test coverage detected