Skip to content

Commit e224f12

Browse files
committed
cp dines
1 parent a77f5e0 commit e224f12

10 files changed

Lines changed: 53 additions & 30 deletions

File tree

src/commands/blueprint/list.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { getBlueprintUrl } from "../../utils/url.js";
1818
import { colors } from "../../utils/theme.js";
1919
import { getStatusDisplay } from "../../components/StatusBadge.js";
2020
import { DevboxCreatePage } from "../../components/DevboxCreatePage.js";
21-
import { exitAlternateScreenBuffer } from "../../utils/screen.js";
21+
import { useExitOnCtrlC } from "../../hooks/useExitOnCtrlC.js";
2222

2323
const PAGE_SIZE = 10;
2424
const MAX_FETCH = 100;
@@ -310,17 +310,14 @@ const ListBlueprintsUI = ({
310310
};
311311
}, []);
312312

313+
// Handle Ctrl+C to exit
314+
useExitOnCtrlC();
315+
313316
// Handle input for all views - combined into single hook
314317
useInput((input, key) => {
315318
// Don't process input if unmounting
316319
if (!isMounted.current) return;
317320

318-
// Handle Ctrl+C to force exit
319-
if (key.ctrl && input === "c") {
320-
exitAlternateScreenBuffer(); // Exit alternate screen
321-
process.exit(130);
322-
}
323-
324321
// Handle operation input mode
325322
if (executingOperation && !operationResult && !operationError) {
326323
const currentOp = allOperations.find(

src/commands/devbox/list.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { ResourceActionsMenu } from "../../components/ResourceActionsMenu.js";
1818
import { ActionsPopup } from "../../components/ActionsPopup.js";
1919
import { getDevboxUrl } from "../../utils/url.js";
2020
import { useViewportHeight } from "../../hooks/useViewportHeight.js";
21-
import { exitAlternateScreenBuffer } from "../../utils/screen.js";
21+
import { useExitOnCtrlC } from "../../hooks/useExitOnCtrlC.js";
2222
import { colors } from "../../utils/theme.js";
2323

2424
interface ListOptions {
@@ -548,13 +548,10 @@ const ListDevboxesUI = ({
548548

549549
// Removed refresh icon animation to prevent constant re-renders and flashing
550550

551-
useInput((input, key) => {
552-
// Handle Ctrl+C to force exit
553-
if (key.ctrl && input === "c") {
554-
exitAlternateScreenBuffer(); // Exit alternate screen
555-
process.exit(130);
556-
}
551+
// Handle Ctrl+C to exit
552+
useExitOnCtrlC();
557553

554+
useInput((input, key) => {
558555
const pageDevboxes = currentDevboxes.length;
559556

560557
// Skip input handling when in search mode - let TextInput handle it

src/components/DevboxActionsMenu.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Breadcrumb } from "./Breadcrumb.js";
1010
import { colors } from "../utils/theme.js";
1111
import { useViewportHeight } from "../hooks/useViewportHeight.js";
1212
import { useNavigation } from "../store/navigationStore.js";
13+
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
1314
import {
1415
getDevboxLogs,
1516
execCommand,
@@ -224,6 +225,9 @@ export const DevboxActionsMenu = ({
224225
}
225226
}, [executingOperation]);
226227

228+
// Handle Ctrl+C to exit
229+
useExitOnCtrlC();
230+
227231
useInput((input, key) => {
228232
// Handle operation input mode
229233
if (executingOperation && !operationResult && !operationError) {

src/components/DevboxCreatePage.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { SuccessMessage } from "./SuccessMessage.js";
1010
import { Breadcrumb } from "./Breadcrumb.js";
1111
import { MetadataDisplay } from "./MetadataDisplay.js";
1212
import { colors } from "../utils/theme.js";
13+
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
1314

1415
interface DevboxCreatePageProps {
1516
onBack: () => void;
@@ -135,6 +136,9 @@ export const DevboxCreatePage = ({
135136

136137
const currentFieldIndex = fields.findIndex((f) => f.key === currentField);
137138

139+
// Handle Ctrl+C to exit
140+
useExitOnCtrlC();
141+
138142
useInput((input, key) => {
139143
// Handle result screen
140144
if (result) {

src/components/DevboxDetailPage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DevboxActionsMenu } from "./DevboxActionsMenu.js";
99
import { getDevboxUrl } from "../utils/url.js";
1010
import { colors } from "../utils/theme.js";
1111
import { useViewportHeight } from "../hooks/useViewportHeight.js";
12+
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
1213

1314
interface DevboxDetailPageProps {
1415
devbox: any;
@@ -171,6 +172,9 @@ export const DevboxDetailPage = ({
171172
? formatTimeAgo(selectedDevbox.create_time_ms)
172173
: "";
173174

175+
// Handle Ctrl+C to exit
176+
useExitOnCtrlC();
177+
174178
useInput((input, key) => {
175179
// Don't process input if unmounting
176180
if (!isMounted.current) return;
@@ -605,7 +609,7 @@ export const DevboxDetailPage = ({
605609

606610
// Detailed info mode - full screen
607611
if (showDetailedInfo) {
608-
const detailLines = [<></>]; //buildDetailLines()]];
612+
const detailLines = buildDetailLines();
609613
const viewportHeight = detailViewport.viewportHeight;
610614
const maxScroll = Math.max(0, detailLines.length - viewportHeight);
611615
const actualScroll = Math.min(detailScroll, maxScroll);

src/components/MainMenu.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Breadcrumb } from "./Breadcrumb.js";
66
import { VERSION } from "../cli.js";
77
import { colors } from "../utils/theme.js";
88
import { useViewportHeight } from "../hooks/useViewportHeight.js";
9-
import { exitAlternateScreenBuffer } from "../utils/screen.js";
9+
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
1010

1111
interface MenuItem {
1212
key: string;
@@ -51,6 +51,9 @@ export const MainMenu = ({ onSelect }: MainMenuProps) => {
5151
// Use centralized viewport hook for consistent layout
5252
const { terminalHeight } = useViewportHeight({ overhead: 0 });
5353

54+
// Handle Ctrl+C to exit
55+
useExitOnCtrlC();
56+
5457
useInput((input, key) => {
5558
if (key.upArrow && selectedIndex > 0) {
5659
setSelectedIndex(selectedIndex - 1);
@@ -66,9 +69,6 @@ export const MainMenu = ({ onSelect }: MainMenuProps) => {
6669
onSelect("blueprints");
6770
} else if (input === "s" || input === "3") {
6871
onSelect("snapshots");
69-
} else if (key.ctrl && input === "c") {
70-
exitAlternateScreenBuffer();
71-
process.exit(130);
7272
}
7373
});
7474

src/components/ResourceListView.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ErrorMessage } from "./ErrorMessage.js";
88
import { Table, Column } from "./Table.js";
99
import { colors } from "../utils/theme.js";
1010
import { useViewportHeight } from "../hooks/useViewportHeight.js";
11-
import { exitAlternateScreenBuffer } from "../utils/screen.js";
11+
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
1212

1313
// Format time ago in a succinct way
1414
export const formatTimeAgo = (timestamp: number): string => {
@@ -211,17 +211,14 @@ export function ResourceListView<T>({ config }: ResourceListViewProps<T>) {
211211

212212
const selectedResource = currentResources[selectedIndex];
213213

214+
// Handle Ctrl+C to exit
215+
useExitOnCtrlC();
216+
214217
// Input handling
215218
useInput((input, key) => {
216219
// Don't process input if unmounting
217220
if (!isMounted.current) return;
218221

219-
// Handle Ctrl+C to force exit
220-
if (key.ctrl && input === "c") {
221-
exitAlternateScreenBuffer(); // Exit alternate screen
222-
process.exit(130);
223-
}
224-
225222
const pageResourcesCount = currentResources.length;
226223

227224
// Skip input handling when in search mode

src/hooks/useExitOnCtrlC.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Hook to handle Ctrl+C (SIGINT) consistently across all screens
3+
* Exits the program with proper cleanup of alternate screen buffer
4+
*/
5+
import { useInput } from "ink";
6+
import { exitAlternateScreenBuffer } from "../utils/screen.js";
7+
8+
export function useExitOnCtrlC(): void {
9+
useInput((input, key) => {
10+
if (key.ctrl && input === "c") {
11+
exitAlternateScreenBuffer();
12+
process.exit(130); // Standard exit code for SIGINT
13+
}
14+
});
15+
}
16+

src/screens/DevboxListScreen.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { ActionsPopup } from "../components/ActionsPopup.js";
1919
import { getDevboxUrl } from "../utils/url.js";
2020
import { useViewportHeight } from "../hooks/useViewportHeight.js";
2121
import { colors, sanitizeWidth } from "../utils/theme.js";
22+
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
2223

2324
export function DevboxListScreen() {
2425
// Get state from store
@@ -393,12 +394,11 @@ export function DevboxListScreen() {
393394
},
394395
];
395396

397+
// Handle Ctrl+C to exit
398+
useExitOnCtrlC();
399+
396400
// Input handling
397401
useInput((input, key) => {
398-
if (key.ctrl && input === "c") {
399-
process.exit(130);
400-
}
401-
402402
const pageDevboxes = devboxes.length;
403403

404404
// Search mode

src/screens/SSHSessionScreen.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ import {
1313
import { Breadcrumb } from "../components/Breadcrumb.js";
1414
import { colors } from "../utils/theme.js";
1515
import figures from "figures";
16+
import { useExitOnCtrlC } from "../hooks/useExitOnCtrlC.js";
1617

1718
export function SSHSessionScreen() {
1819
const { params, navigate } = useNavigation();
1920

21+
// Handle Ctrl+C to exit (before SSH connects or on error)
22+
useExitOnCtrlC();
23+
2024
// Extract SSH config from params
2125
const keyPath = params.keyPath;
2226
const proxyCommand = params.proxyCommand;

0 commit comments

Comments
 (0)