@@ -13,6 +13,12 @@ import type {
1313} from "../../../lib/config/types.js" ;
1414import type { ValidationError } from "./types.js" ;
1515import { editInEditor , detectEditor } from "./editor.js" ;
16+ import {
17+ processShortcuts ,
18+ formatLabelWithShortcut ,
19+ getShortcutForValue ,
20+ } from "../../../lib/shortcuts/index.js" ;
21+ import { selectWithShortcuts } from "../../../lib/shortcuts/select-with-shortcuts.js" ;
1622
1723/**
1824 * Create compact color-coded label
@@ -84,21 +90,45 @@ export async function promptType(
8490 } ;
8591 }
8692
93+ // Process shortcuts for this prompt
94+ const shortcutMapping = processShortcuts (
95+ config . advanced . shortcuts ,
96+ "type" ,
97+ config . types . map ( ( t ) => ( {
98+ value : t . id ,
99+ label : `${ t . id . padEnd ( 8 ) } ${ t . description } ` ,
100+ } ) ) ,
101+ ) ;
102+
103+ const displayHints = config . advanced . shortcuts ?. display_hints ?? true ;
104+
87105 // Find initial type index if provided
88106 const initialIndex = initialType
89107 ? config . types . findIndex ( ( t ) => t . id === initialType )
90108 : undefined ;
91109
92- const selected = await select ( {
93- message : `${ label ( "type" , "magenta" ) } ${ textColors . pureWhite ( "Select commit type:" ) } ` ,
94- options : config . types . map ( ( type ) => ( {
110+ // Build options with shortcuts
111+ const options = config . types . map ( ( type ) => {
112+ const shortcut = getShortcutForValue ( type . id , shortcutMapping ) ;
113+ const baseLabel = `${ type . id . padEnd ( 8 ) } ${ type . description } ` ;
114+ const label = formatLabelWithShortcut ( baseLabel , shortcut , displayHints ) ;
115+
116+ return {
95117 value : type . id ,
96- label : ` ${ type . id . padEnd ( 8 ) } ${ type . description } ` ,
118+ label,
97119 hint : type . description ,
98- } ) ) ,
99- initialValue : initialIndex !== undefined && initialIndex >= 0 ? config . types [ initialIndex ] . id : undefined ,
120+ } ;
100121 } ) ;
101122
123+ const selected = await selectWithShortcuts (
124+ {
125+ message : `${ label ( "type" , "magenta" ) } ${ textColors . pureWhite ( "Select commit type:" ) } ` ,
126+ options,
127+ initialValue : initialIndex !== undefined && initialIndex >= 0 ? config . types [ initialIndex ] . id : undefined ,
128+ } ,
129+ shortcutMapping ,
130+ ) ;
131+
102132 handleCancel ( selected ) ;
103133 const typeId = selected as string ;
104134 const typeConfig = config . types . find ( ( t ) => t . id === typeId ) ! ;
@@ -436,24 +466,39 @@ export async function promptBody(
436466 if ( ! isRequired ) {
437467 // Optional body - offer choice if editor available and preference allows
438468 if ( editorAvailable && preference === "auto" ) {
439- const inputMethod = await select ( {
440- message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite ( "Enter commit body (optional):" ) } ` ,
441- options : [
442- {
443- value : "inline" ,
444- label : "Type inline (single/multi-line)" ,
445- } ,
446- {
447- value : "editor" ,
448- label : "Open in editor" ,
449- } ,
450- {
451- value : "skip" ,
452- label : "Skip (no body)" ,
453- } ,
454- ] ,
469+ const bodyOptions = [
470+ { value : "inline" , label : "Type inline (single/multi-line)" } ,
471+ { value : "editor" , label : "Open in editor" } ,
472+ { value : "skip" , label : "Skip (no body)" } ,
473+ ] ;
474+
475+ const shortcutMapping = processShortcuts (
476+ config . advanced . shortcuts ,
477+ "body" ,
478+ bodyOptions ,
479+ ) ;
480+ const displayHints = config . advanced . shortcuts ?. display_hints ?? true ;
481+
482+ const options = bodyOptions . map ( ( option ) => {
483+ const shortcut = shortcutMapping
484+ ? getShortcutForValue ( option . value , shortcutMapping )
485+ : undefined ;
486+ const label = formatLabelWithShortcut ( option . label , shortcut , displayHints ) ;
487+
488+ return {
489+ value : option . value ,
490+ label,
491+ } ;
455492 } ) ;
456493
494+ const inputMethod = await selectWithShortcuts (
495+ {
496+ message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite ( "Enter commit body (optional):" ) } ` ,
497+ options,
498+ } ,
499+ shortcutMapping ,
500+ ) ;
501+
457502 handleCancel ( inputMethod ) ;
458503
459504 if ( inputMethod === "skip" ) {
@@ -501,22 +546,40 @@ export async function promptBody(
501546
502547 // For required body, offer editor option if available and preference allows
503548 if ( editorAvailable && ( preference === "auto" || preference === "inline" ) ) {
504- const inputMethod = await select ( {
505- message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite (
506- `Enter commit body (required${ bodyConfig . min_length > 0 ? `, min ${ bodyConfig . min_length } chars` : "" } ):` ,
507- ) } `,
508- options : [
509- {
510- value : "inline" ,
511- label : "Type inline" ,
512- } ,
513- {
514- value : "editor" ,
515- label : "Open in editor" ,
516- } ,
517- ] ,
549+ const bodyOptions = [
550+ { value : "inline" , label : "Type inline" } ,
551+ { value : "editor" , label : "Open in editor" } ,
552+ ] ;
553+
554+ const shortcutMapping = processShortcuts (
555+ config . advanced . shortcuts ,
556+ "body" ,
557+ bodyOptions ,
558+ ) ;
559+ const displayHints = config . advanced . shortcuts ?. display_hints ?? true ;
560+
561+ const options = bodyOptions . map ( ( option ) => {
562+ const shortcut = shortcutMapping
563+ ? getShortcutForValue ( option . value , shortcutMapping )
564+ : undefined ;
565+ const label = formatLabelWithShortcut ( option . label , shortcut , displayHints ) ;
566+
567+ return {
568+ value : option . value ,
569+ label,
570+ } ;
518571 } ) ;
519572
573+ const inputMethod = await selectWithShortcuts (
574+ {
575+ message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite (
576+ `Enter commit body (required${ bodyConfig . min_length > 0 ? `, min ${ bodyConfig . min_length } chars` : "" } ):` ,
577+ ) } `,
578+ options,
579+ } ,
580+ shortcutMapping ,
581+ ) ;
582+
520583 handleCancel ( inputMethod ) ;
521584
522585 if ( inputMethod === "editor" ) {
@@ -601,24 +664,39 @@ async function promptBodyRequiredWithEditor(
601664 const edited = await promptBodyWithEditor ( config , body ) ;
602665 if ( edited === null || edited === undefined ) {
603666 // Editor cancelled, ask what to do
604- const choice = await select ( {
605- message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite ( "Editor cancelled. What would you like to do?" ) } ` ,
606- options : [
607- {
608- value : "retry" ,
609- label : "Try editor again" ,
610- } ,
611- {
612- value : "inline" ,
613- label : "Switch to inline input" ,
614- } ,
615- {
616- value : "cancel" ,
617- label : "Cancel commit" ,
618- } ,
619- ] ,
667+ const bodyRetryOptions = [
668+ { value : "retry" , label : "Try editor again" } ,
669+ { value : "inline" , label : "Switch to inline input" } ,
670+ { value : "cancel" , label : "Cancel commit" } ,
671+ ] ;
672+
673+ const shortcutMapping = processShortcuts (
674+ config . advanced . shortcuts ,
675+ "body" ,
676+ bodyRetryOptions ,
677+ ) ;
678+ const displayHints = config . advanced . shortcuts ?. display_hints ?? true ;
679+
680+ const options = bodyRetryOptions . map ( ( option ) => {
681+ const shortcut = shortcutMapping
682+ ? getShortcutForValue ( option . value , shortcutMapping )
683+ : undefined ;
684+ const label = formatLabelWithShortcut ( option . label , shortcut , displayHints ) ;
685+
686+ return {
687+ value : option . value ,
688+ label,
689+ } ;
620690 } ) ;
621691
692+ const choice = await selectWithShortcuts (
693+ {
694+ message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite ( "Editor cancelled. What would you like to do?" ) } ` ,
695+ options,
696+ } ,
697+ shortcutMapping ,
698+ ) ;
699+
622700 handleCancel ( choice ) ;
623701
624702 if ( choice === "cancel" ) {
@@ -694,24 +772,39 @@ async function promptBodyWithEditor(
694772 console . log ( ) ;
695773
696774 // Ask if user wants to re-edit or go back to inline
697- const choice = await select ( {
698- message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite ( "Validation failed. What would you like to do?" ) } ` ,
699- options : [
700- {
701- value : "re-edit" ,
702- label : "Edit again" ,
703- } ,
704- {
705- value : "inline" ,
706- label : "Type inline instead" ,
707- } ,
708- {
709- value : "cancel" ,
710- label : "Cancel commit" ,
711- } ,
712- ] ,
775+ const bodyValidationOptions = [
776+ { value : "re-edit" , label : "Edit again" } ,
777+ { value : "inline" , label : "Type inline instead" } ,
778+ { value : "cancel" , label : "Cancel commit" } ,
779+ ] ;
780+
781+ const shortcutMapping = processShortcuts (
782+ config . advanced . shortcuts ,
783+ "body" ,
784+ bodyValidationOptions ,
785+ ) ;
786+ const displayHints = config . advanced . shortcuts ?. display_hints ?? true ;
787+
788+ const options = bodyValidationOptions . map ( ( option ) => {
789+ const shortcut = shortcutMapping
790+ ? getShortcutForValue ( option . value , shortcutMapping )
791+ : undefined ;
792+ const label = formatLabelWithShortcut ( option . label , shortcut , displayHints ) ;
793+
794+ return {
795+ value : option . value ,
796+ label,
797+ } ;
713798 } ) ;
714799
800+ const choice = await selectWithShortcuts (
801+ {
802+ message : `${ label ( "body" , "yellow" ) } ${ textColors . pureWhite ( "Validation failed. What would you like to do?" ) } ` ,
803+ options,
804+ } ,
805+ shortcutMapping ,
806+ ) ;
807+
715808 handleCancel ( choice ) ;
716809
717810 if ( choice === "cancel" ) {
@@ -951,6 +1044,7 @@ export async function displayStagedFiles(status: {
9511044export async function displayPreview (
9521045 formattedMessage : string ,
9531046 body : string | undefined ,
1047+ config ?: LabcommitrConfig ,
9541048) : Promise < "commit" | "edit-type" | "edit-scope" | "edit-subject" | "edit-body" | "cancel" > {
9551049 // Start connector line using @clack /prompts
9561050 log . info (
@@ -976,36 +1070,47 @@ export async function displayPreview(
9761070 renderWithConnector ( "─────────────────────────────────────────────" ) ,
9771071 ) ;
9781072
979- const action = await select ( {
980- message : `${ success ( "✓" ) } ${ textColors . pureWhite ( "Ready to commit?" ) } ` ,
981- options : [
982- {
983- value : "commit" ,
984- label : "Create commit" ,
985- } ,
986- {
987- value : "edit-type" ,
988- label : "Edit type" ,
989- } ,
990- {
991- value : "edit-scope" ,
992- label : "Edit scope" ,
993- } ,
994- {
995- value : "edit-subject" ,
996- label : "Edit subject" ,
997- } ,
998- {
999- value : "edit-body" ,
1000- label : "Edit body" ,
1001- } ,
1002- {
1003- value : "cancel" ,
1004- label : "Cancel" ,
1005- } ,
1006- ] ,
1073+ // Process shortcuts for preview prompt
1074+ const previewOptions = [
1075+ { value : "commit" , label : "Create commit" } ,
1076+ { value : "edit-type" , label : "Edit type" } ,
1077+ { value : "edit-scope" , label : "Edit scope" } ,
1078+ { value : "edit-subject" , label : "Edit subject" } ,
1079+ { value : "edit-body" , label : "Edit body" } ,
1080+ { value : "cancel" , label : "Cancel" } ,
1081+ ] ;
1082+
1083+ const shortcutMapping = config
1084+ ? processShortcuts (
1085+ config . advanced . shortcuts ,
1086+ "preview" ,
1087+ previewOptions ,
1088+ )
1089+ : null ;
1090+
1091+ const displayHints = config ?. advanced . shortcuts ?. display_hints ?? true ;
1092+
1093+ // Build options with shortcuts
1094+ const options = previewOptions . map ( ( option ) => {
1095+ const shortcut = shortcutMapping
1096+ ? getShortcutForValue ( option . value , shortcutMapping )
1097+ : undefined ;
1098+ const label = formatLabelWithShortcut ( option . label , shortcut , displayHints ) ;
1099+
1100+ return {
1101+ value : option . value ,
1102+ label,
1103+ } ;
10071104 } ) ;
10081105
1106+ const action = await selectWithShortcuts (
1107+ {
1108+ message : `${ success ( "✓" ) } ${ textColors . pureWhite ( "Ready to commit?" ) } ` ,
1109+ options,
1110+ } ,
1111+ shortcutMapping ,
1112+ ) ;
1113+
10091114 handleCancel ( action ) ;
10101115 return action as "commit" | "edit-type" | "edit-scope" | "edit-subject" | "edit-body" | "cancel" ;
10111116}
0 commit comments