2025-11-04 05:17:27 +01:00
|
|
|
import os
|
|
|
|
|
import os.path
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
from pr.editor import RPEditor
|
|
|
|
|
from pr.multiplexer import close_multiplexer, create_multiplexer, get_multiplexer
|
|
|
|
|
|
|
|
|
|
from ..tools.patch import display_content_diff
|
|
|
|
|
from ..ui.edit_feedback import track_edit, tracker
|
|
|
|
|
|
2025-11-04 05:17:27 +01:00
|
|
|
_editors = {}
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
|
2025-11-04 05:17:27 +01:00
|
|
|
def get_editor(filepath):
|
|
|
|
|
if filepath not in _editors:
|
|
|
|
|
_editors[filepath] = RPEditor(filepath)
|
|
|
|
|
return _editors[filepath]
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
|
2025-11-04 05:17:27 +01:00
|
|
|
def close_editor(filepath):
|
|
|
|
|
try:
|
|
|
|
|
path = os.path.expanduser(filepath)
|
|
|
|
|
editor = get_editor(path)
|
|
|
|
|
editor.close()
|
|
|
|
|
|
|
|
|
|
mux_name = f"editor-{path}"
|
|
|
|
|
mux = get_multiplexer(mux_name)
|
|
|
|
|
if mux:
|
|
|
|
|
mux.write_stdout(f"Closed editor for: {path}\n")
|
|
|
|
|
close_multiplexer(mux_name)
|
|
|
|
|
|
|
|
|
|
return {"status": "success", "message": f"Editor closed for {path}"}
|
|
|
|
|
except Exception as e:
|
|
|
|
|
return {"status": "error", "error": str(e)}
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
|
2025-11-04 05:17:27 +01:00
|
|
|
def open_editor(filepath):
|
|
|
|
|
try:
|
|
|
|
|
path = os.path.expanduser(filepath)
|
|
|
|
|
editor = RPEditor(path)
|
|
|
|
|
editor.start()
|
|
|
|
|
|
|
|
|
|
mux_name = f"editor-{path}"
|
|
|
|
|
mux_name, mux = create_multiplexer(mux_name, show_output=True)
|
|
|
|
|
mux.write_stdout(f"Opened editor for: {path}\n")
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
return {
|
|
|
|
|
"status": "success",
|
|
|
|
|
"message": f"Editor opened for {path}",
|
|
|
|
|
"mux_name": mux_name,
|
|
|
|
|
}
|
2025-11-04 05:17:27 +01:00
|
|
|
except Exception as e:
|
|
|
|
|
return {"status": "error", "error": str(e)}
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
|
2025-11-04 05:17:27 +01:00
|
|
|
def editor_insert_text(filepath, text, line=None, col=None, show_diff=True):
|
|
|
|
|
try:
|
|
|
|
|
path = os.path.expanduser(filepath)
|
|
|
|
|
|
|
|
|
|
old_content = ""
|
|
|
|
|
if os.path.exists(path):
|
2025-11-04 08:09:12 +01:00
|
|
|
with open(path) as f:
|
2025-11-04 05:17:27 +01:00
|
|
|
old_content = f.read()
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
position = (line if line is not None else 0) * 1000 + (
|
|
|
|
|
col if col is not None else 0
|
|
|
|
|
)
|
|
|
|
|
operation = track_edit("INSERT", filepath, start_pos=position, content=text)
|
2025-11-04 05:17:27 +01:00
|
|
|
tracker.mark_in_progress(operation)
|
|
|
|
|
|
|
|
|
|
editor = get_editor(path)
|
|
|
|
|
if line is not None and col is not None:
|
|
|
|
|
editor.move_cursor_to(line, col)
|
|
|
|
|
editor.insert_text(text)
|
|
|
|
|
editor.save_file()
|
|
|
|
|
|
|
|
|
|
mux_name = f"editor-{path}"
|
|
|
|
|
mux = get_multiplexer(mux_name)
|
|
|
|
|
if mux:
|
2025-11-04 08:09:12 +01:00
|
|
|
location = (
|
|
|
|
|
f" at line {line}, col {col}"
|
|
|
|
|
if line is not None and col is not None
|
|
|
|
|
else ""
|
|
|
|
|
)
|
2025-11-04 05:17:27 +01:00
|
|
|
preview = text[:50] + "..." if len(text) > 50 else text
|
|
|
|
|
mux.write_stdout(f"Inserted text{location}: {repr(preview)}\n")
|
|
|
|
|
|
|
|
|
|
if show_diff and old_content:
|
2025-11-04 08:09:12 +01:00
|
|
|
with open(path) as f:
|
2025-11-04 05:17:27 +01:00
|
|
|
new_content = f.read()
|
|
|
|
|
diff_result = display_content_diff(old_content, new_content, filepath)
|
|
|
|
|
if diff_result["status"] == "success":
|
|
|
|
|
mux.write_stdout(diff_result["visual_diff"] + "\n")
|
|
|
|
|
|
|
|
|
|
tracker.mark_completed(operation)
|
|
|
|
|
result = {"status": "success", "message": f"Inserted text in {path}"}
|
|
|
|
|
close_editor(filepath)
|
|
|
|
|
return result
|
|
|
|
|
except Exception as e:
|
2025-11-04 08:09:12 +01:00
|
|
|
if "operation" in locals():
|
2025-11-04 05:17:27 +01:00
|
|
|
tracker.mark_failed(operation)
|
|
|
|
|
return {"status": "error", "error": str(e)}
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
|
|
|
|
|
def editor_replace_text(
|
|
|
|
|
filepath, start_line, start_col, end_line, end_col, new_text, show_diff=True
|
|
|
|
|
):
|
2025-11-04 05:17:27 +01:00
|
|
|
try:
|
|
|
|
|
path = os.path.expanduser(filepath)
|
|
|
|
|
|
|
|
|
|
old_content = ""
|
|
|
|
|
if os.path.exists(path):
|
2025-11-04 08:09:12 +01:00
|
|
|
with open(path) as f:
|
2025-11-04 05:17:27 +01:00
|
|
|
old_content = f.read()
|
|
|
|
|
|
|
|
|
|
start_pos = start_line * 1000 + start_col
|
|
|
|
|
end_pos = end_line * 1000 + end_col
|
2025-11-04 08:09:12 +01:00
|
|
|
operation = track_edit(
|
|
|
|
|
"REPLACE",
|
|
|
|
|
filepath,
|
|
|
|
|
start_pos=start_pos,
|
|
|
|
|
end_pos=end_pos,
|
|
|
|
|
content=new_text,
|
|
|
|
|
old_content=old_content,
|
|
|
|
|
)
|
2025-11-04 05:17:27 +01:00
|
|
|
tracker.mark_in_progress(operation)
|
|
|
|
|
|
|
|
|
|
editor = get_editor(path)
|
|
|
|
|
editor.replace_text(start_line, start_col, end_line, end_col, new_text)
|
|
|
|
|
editor.save_file()
|
|
|
|
|
|
|
|
|
|
mux_name = f"editor-{path}"
|
|
|
|
|
mux = get_multiplexer(mux_name)
|
|
|
|
|
if mux:
|
|
|
|
|
preview = new_text[:50] + "..." if len(new_text) > 50 else new_text
|
2025-11-04 08:09:12 +01:00
|
|
|
mux.write_stdout(
|
|
|
|
|
f"Replaced text from ({start_line},{start_col}) to ({end_line},{end_col}): {repr(preview)}\n"
|
|
|
|
|
)
|
2025-11-04 05:17:27 +01:00
|
|
|
|
|
|
|
|
if show_diff and old_content:
|
2025-11-04 08:09:12 +01:00
|
|
|
with open(path) as f:
|
2025-11-04 05:17:27 +01:00
|
|
|
new_content = f.read()
|
|
|
|
|
diff_result = display_content_diff(old_content, new_content, filepath)
|
|
|
|
|
if diff_result["status"] == "success":
|
|
|
|
|
mux.write_stdout(diff_result["visual_diff"] + "\n")
|
|
|
|
|
|
|
|
|
|
tracker.mark_completed(operation)
|
|
|
|
|
result = {"status": "success", "message": f"Replaced text in {path}"}
|
|
|
|
|
close_editor(filepath)
|
|
|
|
|
return result
|
|
|
|
|
except Exception as e:
|
2025-11-04 08:09:12 +01:00
|
|
|
if "operation" in locals():
|
2025-11-04 05:17:27 +01:00
|
|
|
tracker.mark_failed(operation)
|
|
|
|
|
return {"status": "error", "error": str(e)}
|
|
|
|
|
|
2025-11-04 08:09:12 +01:00
|
|
|
|
2025-11-04 05:17:27 +01:00
|
|
|
def editor_search(filepath, pattern, start_line=0):
|
|
|
|
|
try:
|
|
|
|
|
path = os.path.expanduser(filepath)
|
|
|
|
|
editor = RPEditor(path)
|
|
|
|
|
results = editor.search(pattern, start_line)
|
|
|
|
|
|
|
|
|
|
mux_name = f"editor-{path}"
|
|
|
|
|
mux = get_multiplexer(mux_name)
|
|
|
|
|
if mux:
|
2025-11-04 08:09:12 +01:00
|
|
|
mux.write_stdout(
|
|
|
|
|
f"Searched for pattern '{pattern}' from line {start_line}: {len(results)} matches\n"
|
|
|
|
|
)
|
2025-11-04 05:17:27 +01:00
|
|
|
|
|
|
|
|
result = {"status": "success", "results": results}
|
|
|
|
|
close_editor(filepath)
|
|
|
|
|
return result
|
|
|
|
|
except Exception as e:
|
|
|
|
|
return {"status": "error", "error": str(e)}
|