@@ -40,6 +40,7 @@ define(function (require, exports, module) {
4040 const Strings = require ( "strings" ) ;
4141 const StringUtils = require ( "utils/StringUtils" ) ;
4242
43+ const Menus = require ( "command/Menus" ) ;
4344 const Commands = require ( "command/Commands" ) ;
4445 const NotificationUI = require ( "widgets/NotificationUI" ) ;
4546 const TerminalInstance = require ( "./TerminalInstance" ) ;
@@ -52,6 +53,10 @@ define(function (require, exports, module) {
5253 // Constants
5354 const CMD_VIEW_TERMINAL = Commands . VIEW_TERMINAL ;
5455 const CMD_NEW_TERMINAL = "terminal.new" ;
56+ const CMD_TERMINAL_COPY = "terminal.copy" ;
57+ const CMD_TERMINAL_PASTE = "terminal.paste" ;
58+ const CMD_TERMINAL_CLEAR = "terminal.clear" ;
59+ const TERMINAL_CONTEXT_MENU_ID = "terminal-context-menu" ;
5560 const PANEL_ID = "terminal-panel" ;
5661 const PANEL_MIN_SIZE = 100 ;
5762
@@ -125,6 +130,12 @@ define(function (require, exports, module) {
125130 $shellDropdown = $panel . find ( ".terminal-shell-dropdown" ) ;
126131 $flyoutList = $panel . find ( ".terminal-flyout-list" ) ;
127132
133+ // Right-click context menu for terminal content area
134+ $contentArea . on ( "contextmenu" , function ( e ) {
135+ e . preventDefault ( ) ;
136+ terminalContextMenu . open ( e ) ;
137+ } ) ;
138+
128139 // "+" button creates a new terminal with the default shell
129140 $panel . find ( ".terminal-flyout-new-btn" ) . on ( "click" , function ( e ) {
130141 e . stopPropagation ( ) ;
@@ -616,6 +627,49 @@ define(function (require, exports, module) {
616627 CommandManager . register ( "New Terminal" , CMD_NEW_TERMINAL , _createNewTerminal ) ;
617628 CommandManager . register ( Strings . CMD_VIEW_TERMINAL , CMD_VIEW_TERMINAL , _showTerminal ) ;
618629
630+ // Terminal context menu commands
631+ CommandManager . register ( Strings . CMD_COPY , CMD_TERMINAL_COPY , function ( ) {
632+ const active = _getActiveTerminal ( ) ;
633+ if ( active && active . terminal . hasSelection ( ) ) {
634+ navigator . clipboard . writeText ( active . terminal . getSelection ( ) ) ;
635+ active . focus ( ) ;
636+ }
637+ } ) ;
638+ CommandManager . register ( Strings . CMD_PASTE , CMD_TERMINAL_PASTE , function ( ) {
639+ const active = _getActiveTerminal ( ) ;
640+ if ( active && active . isAlive ) {
641+ active . focus ( ) ;
642+ navigator . clipboard . readText ( ) . then ( function ( text ) {
643+ if ( text ) {
644+ nodeConnector . execPeer ( "writeTerminal" , { id : active . id , data : text } ) ;
645+ }
646+ } ) ;
647+ }
648+ } ) ;
649+ CommandManager . register ( Strings . TERMINAL_CLEAR , CMD_TERMINAL_CLEAR , function ( ) {
650+ _clearActiveTerminal ( ) ;
651+ const active = _getActiveTerminal ( ) ;
652+ if ( active ) {
653+ active . focus ( ) ;
654+ }
655+ } ) ;
656+
657+ // Register terminal context menu
658+ const terminalContextMenu = Menus . registerContextMenu ( TERMINAL_CONTEXT_MENU_ID ) ;
659+ terminalContextMenu . addMenuItem ( CMD_TERMINAL_COPY ) ;
660+ terminalContextMenu . addMenuItem ( CMD_TERMINAL_PASTE ) ;
661+ terminalContextMenu . addMenuDivider ( ) ;
662+ terminalContextMenu . addMenuItem ( CMD_TERMINAL_CLEAR ) ;
663+
664+ // Enable/disable Copy based on terminal selection
665+ terminalContextMenu . on ( Menus . EVENT_BEFORE_CONTEXT_MENU_OPEN , function ( ) {
666+ const active = _getActiveTerminal ( ) ;
667+ const hasSelection = active && active . terminal . hasSelection ( ) ;
668+ CommandManager . get ( CMD_TERMINAL_COPY ) . setEnabled ( hasSelection ) ;
669+ CommandManager . get ( CMD_TERMINAL_PASTE ) . setEnabled ( active && active . isAlive ) ;
670+ CommandManager . get ( CMD_TERMINAL_CLEAR ) . setEnabled ( ! ! active ) ;
671+ } ) ;
672+
619673 // Initialize on app ready
620674 AppInit . appReady ( function ( ) {
621675 if ( Phoenix . isSpecRunnerWindow ) {
0 commit comments