MCPcopy Create free account
hub / github.com/GongShichen/LuminaCode / Execute

Method Execute

tools/builtin.go:227–284  ·  view source on GitHub ↗
(_ context.Context, execCtx ExecutionContext, input any)

Source from the content-addressed store, hash-verified

225}
226
227func (t *EditFileTool) Execute(_ context.Context, execCtx ExecutionContext, input any) (string, error) {
228 in := deref[EditFileInput](input)
229 path := resolveToolPath(execCtx, in.FilePath)
230 data, err := os.ReadFile(path)
231 if err != nil {
232 return formatEditError(editReadFailed, fmt.Sprintf("Error reading file: %s", err)), nil
233 }
234 fileContent := decodeToolBytes(data)
235 lineEndings := detectLineEndings(fileContent)
236 if lineEndings == "\r\n" {
237 fileContent = strings.ReplaceAll(fileContent, "\r\n", "\n")
238 }
239 cleanedNew := stripTrailingWhitespace(in.NewString, path)
240 if cascading := checkCascadingEdit(execCtx, path, in.OldString); cascading != "" {
241 return cascading, nil
242 }
243 actualOld := findActualString(fileContent, in.OldString)
244 if actualOld == "" && in.OldString != "" {
245 return formatEditError(editStringNotFound, fmt.Sprintf("String to replace not found in file.\n Searched for: %s\n Hint: the file may have changed since you last read it.\n%s", truncateForMsg(in.OldString, 120), matchFailureSnippet(fileContent, in.OldString))), nil
246 }
247 if in.OldString == "" {
248 actualOld = ""
249 }
250 count := countOccurrences(fileContent, in.OldString)
251 if !in.ReplaceAll && count > 1 {
252 return formatEditError(editMultipleMatches, fmt.Sprintf("Found %d matches of the string to replace, but replace_all is false.\n To replace all occurrences, set replace_all=true.\n To replace only one, include more surrounding context to make the match unique.", count)), nil
253 }
254 actualNew := cleanedNew
255 if actualOld != in.OldString {
256 actualNew = preserveQuoteStyle(in.OldString, actualOld, cleanedNew)
257 }
258 if actualNew == "" && !strings.HasSuffix(in.OldString, "\n") && strings.Contains(fileContent, actualOld+"\n") {
259 actualOld += "\n"
260 }
261 newContent := strings.ReplaceAll(fileContent, actualOld, actualNew)
262 if !in.ReplaceAll && actualOld != "" {
263 newContent = strings.Replace(fileContent, actualOld, actualNew, 1)
264 }
265 recordAppliedEdit(execCtx, path, in.OldString, actualNew)
266 writeContent := newContent
267 if lineEndings == "\r\n" {
268 writeContent = strings.ReplaceAll(writeContent, "\n", "\r\n")
269 }
270 if err := os.WriteFile(path, []byte(writeContent), 0o644); err != nil {
271 return formatEditError(editWriteFailed, fmt.Sprintf("Error writing file: %s", err)), nil
272 }
273 updateReadState(execCtx, path, writeContent, detectLineEndings(writeContent), false)
274 replaced := count
275 if !in.ReplaceAll {
276 replaced = 1
277 }
278 diff := generateUnifiedDiff(path, fileContent, writeContent, 3)
279 result := fmt.Sprintf("Edit applied successfully: %d occurrence(s) replaced in %s", replaced, in.FilePath)
280 if diff != "" {
281 result += "\n---DIFF---\n" + diff
282 }
283 return result, nil
284}

Callers

nothing calls this directly

Calls 14

resolveToolPathFunction · 0.85
formatEditErrorFunction · 0.85
decodeToolBytesFunction · 0.85
detectLineEndingsFunction · 0.85
stripTrailingWhitespaceFunction · 0.85
checkCascadingEditFunction · 0.85
findActualStringFunction · 0.85
truncateForMsgFunction · 0.85
matchFailureSnippetFunction · 0.85
countOccurrencesFunction · 0.85
preserveQuoteStyleFunction · 0.85
recordAppliedEditFunction · 0.85

Tested by

no test coverage detected