Skip to content

Commit 597bbf7

Browse files
majiayu000claude
andauthored
fix: 🐞 Bug: Model is deleted when renaming, then pressing Ctrl-C (#228)
* fix: prevent model deletion when cancelling rename with Ctrl-C or Esc When a user pressed Ctrl-C during a rename operation, the model would be deleted. This happened because Ctrl-C was treated the same as Enter, causing the (partial) rename to proceed and delete the original model. This fix: - Adds a 'cancelled' flag to textInputModel to track cancellation - Returns the old name when Ctrl-C or Esc is pressed - Handles cancellation in handleRenameModelKey and handleCopyModelKey - Updates the UI hint to show both cancel options Fixes #227 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: majiayu000 <1835304752@qq.com> * fix: return explicit cancel status from promptForNewName - Change promptForNewName to return (string, bool) to explicitly signal cancellation - Fix ambiguity where newName == oldName couldn't distinguish between: - User cancelled (Ctrl-C/Esc) - User intentionally kept the same name (Tab + Enter) - Remove unreachable empty name check (was dead code) - For copy: require different name, show error if same name - For rename: allow same name gracefully with "Name unchanged" message Addresses review feedback from GitHub Copilot on PR #228 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Signed-off-by: majiayu000 <1835304752@qq.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent cb1f2d8 commit 597bbf7

2 files changed

Lines changed: 33 additions & 12 deletions

File tree

app_model.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -685,9 +685,13 @@ func (m *AppModel) handleCopyModelKey() (tea.Model, tea.Cmd) {
685685
}()
686686
logging.DebugLogger.Println("CopyModel key matched")
687687
if item, ok := m.list.SelectedItem().(Model); ok {
688-
newName := promptForNewName(item.Name) // Pass the selected item as the model
689-
if newName == "" {
690-
m.message = "Error: name can't be empty"
688+
newName, cancelled := promptForNewName(item.Name)
689+
if cancelled {
690+
m.message = styles.InfoStyle().Render("Copy cancelled")
691+
} else if newName == "" {
692+
m.message = styles.ErrorStyle().Render("Error: name can't be empty")
693+
} else if newName == item.Name {
694+
m.message = styles.ErrorStyle().Render("Error: new name must be different from the original name")
691695
} else {
692696
copyModel(m, m.client, item.Name, newName)
693697
m.message = fmt.Sprintf("Model %s copied to %s", item.Name, newName)
@@ -790,9 +794,14 @@ func (m *AppModel) handleInspectModelKey() (tea.Model, tea.Cmd) {
790794
func (m *AppModel) handleRenameModelKey() (tea.Model, tea.Cmd) {
791795
logging.DebugLogger.Println("RenameModel key matched")
792796
if item, ok := m.list.SelectedItem().(Model); ok {
793-
newName := promptForNewName(item.Name)
794-
if newName == "" {
797+
newName, cancelled := promptForNewName(item.Name)
798+
if cancelled {
799+
m.message = styles.InfoStyle().Render("Rename cancelled")
800+
} else if newName == "" {
795801
m.message = styles.ErrorStyle().Render("Error: name can't be empty")
802+
} else if newName == item.Name {
803+
// User explicitly confirmed the same name, no action needed
804+
m.message = styles.InfoStyle().Render("Name unchanged")
796805
} else {
797806
err := renameModel(m, item.Name, newName)
798807
if err != nil {

text_input.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ type textInputModel struct {
1515
textInput textinput.Model
1616
oldName string
1717
quitting bool
18+
cancelled bool
1819
}
1920

2021
// promptForNewName displays a text input prompt for renaming a model.
21-
func promptForNewName(oldName string) string {
22+
// Returns the new name and a boolean indicating if the operation was cancelled.
23+
func promptForNewName(oldName string) (string, bool) {
2224
ti := textinput.New()
2325
// print 'renaming oldName' to the console with the oldName in purple
2426
ti.Prompt = oldName + "\n" + "Name for new model: "
@@ -46,23 +48,33 @@ func promptForNewName(oldName string) string {
4648
logging.ErrorLogger.Printf("Error starting text input program: %v\n", err)
4749
}
4850

51+
// If the user cancelled (Ctrl-C or Esc), return empty string and cancelled=true
52+
if m.cancelled {
53+
logging.InfoLogger.Println("Rename cancelled by user")
54+
return "", true
55+
}
56+
4957
newName := m.textInput.Value()
5058

59+
// If user pressed enter without typing anything, return empty string
5160
if newName == "" {
52-
// error handling
53-
logging.ErrorLogger.Println("No new name entered, returning old name")
54-
return oldName
61+
logging.DebugLogger.Println("No new name entered, returning empty string")
62+
return "", false
5563
}
5664

57-
return newName
65+
return newName, false
5866
}
5967

6068
func (m *textInputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
6169
var cmd tea.Cmd
6270
switch msg := msg.(type) {
6371
case tea.KeyMsg:
6472
switch msg.String() {
65-
case "ctrl+c", "enter":
73+
case "ctrl+c", "esc":
74+
m.quitting = true
75+
m.cancelled = true
76+
return m, tea.Quit
77+
case "enter":
6678
m.quitting = true
6779
return m, tea.Quit
6880
}
@@ -83,6 +95,6 @@ func (m textInputModel) View() string {
8395
return fmt.Sprintf(
8496
"\n%s\n\n%s",
8597
m.textInput.View(),
86-
"(ctrl+c to cancel)",
98+
"(esc or ctrl+c to cancel)",
8799
)
88100
}

0 commit comments

Comments
 (0)