Display open IDE file in context section above input box rather than in the footer (#4470)

This commit is contained in:
Shreya Keshive
2025-07-18 18:14:46 -04:00
committed by GitHub
parent 4915050ad4
commit 73745ecd03
4 changed files with 121 additions and 66 deletions

View File

@@ -7,7 +7,8 @@
import React from 'react';
import { Text } from 'ink';
import { Colors } from '../colors.js';
import { type MCPServerConfig } from '@google/gemini-cli-core';
import { type ActiveFile, type MCPServerConfig } from '@google/gemini-cli-core';
import path from 'path';
interface ContextSummaryDisplayProps {
geminiMdFileCount: number;
@@ -15,6 +16,7 @@ interface ContextSummaryDisplayProps {
mcpServers?: Record<string, MCPServerConfig>;
blockedMcpServers?: Array<{ name: string; extensionName: string }>;
showToolDescriptions?: boolean;
activeFile?: ActiveFile;
}
export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
@@ -23,6 +25,7 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
mcpServers,
blockedMcpServers,
showToolDescriptions,
activeFile,
}) => {
const mcpServerCount = Object.keys(mcpServers || {}).length;
const blockedMcpServerCount = blockedMcpServers?.length || 0;
@@ -30,18 +33,26 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
if (
geminiMdFileCount === 0 &&
mcpServerCount === 0 &&
blockedMcpServerCount === 0
blockedMcpServerCount === 0 &&
!activeFile?.filePath
) {
return <Text> </Text>; // Render an empty space to reserve height
}
const activeFileText = (() => {
if (!activeFile?.filePath) {
return '';
}
return `Open File (${path.basename(activeFile.filePath)})`;
})();
const geminiMdText = (() => {
if (geminiMdFileCount === 0) {
return '';
}
const allNamesTheSame = new Set(contextFileNames).size < 2;
const name = allNamesTheSame ? contextFileNames[0] : 'context';
return `${geminiMdFileCount} ${name} file${
const name = allNamesTheSame ? contextFileNames[0] : 'Context';
return `${geminiMdFileCount} ${name} File${
geminiMdFileCount > 1 ? 's' : ''
}`;
})();
@@ -54,36 +65,39 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
const parts = [];
if (mcpServerCount > 0) {
parts.push(
`${mcpServerCount} MCP server${mcpServerCount > 1 ? 's' : ''}`,
`${mcpServerCount} MCP Server${mcpServerCount > 1 ? 's' : ''}`,
);
}
if (blockedMcpServerCount > 0) {
let blockedText = `${blockedMcpServerCount} blocked`;
let blockedText = `${blockedMcpServerCount} Blocked`;
if (mcpServerCount === 0) {
blockedText += ` MCP server${blockedMcpServerCount > 1 ? 's' : ''}`;
blockedText += ` MCP Server${blockedMcpServerCount > 1 ? 's' : ''}`;
}
parts.push(blockedText);
}
return parts.join(', ');
})();
let summaryText = 'Using ';
if (geminiMdText) {
summaryText += geminiMdText;
let summaryText = 'Using: ';
const summaryParts = [];
if (activeFileText) {
summaryParts.push(activeFileText);
}
if (geminiMdText && mcpText) {
summaryText += ' and ';
if (geminiMdText) {
summaryParts.push(geminiMdText);
}
if (mcpText) {
summaryText += mcpText;
// Add ctrl+t hint when MCP servers are available
if (mcpServers && Object.keys(mcpServers).length > 0) {
if (showToolDescriptions) {
summaryText += ' (ctrl+t to toggle)';
} else {
summaryText += ' (ctrl+t to view)';
}
summaryParts.push(mcpText);
}
summaryText += summaryParts.join(' | ');
// Add ctrl+t hint when MCP servers are available
if (mcpServers && Object.keys(mcpServers).length > 0) {
if (showToolDescriptions) {
summaryText += ' (ctrl+t to toggle)';
} else {
summaryText += ' (ctrl+t to view)';
}
}

View File

@@ -4,16 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
import React, { useEffect, useState } from 'react';
import React from 'react';
import { Box, Text } from 'ink';
import { Colors } from '../colors.js';
import {
shortenPath,
tildeifyPath,
tokenLimit,
ideContext,
ActiveFile,
} from '@google/gemini-cli-core';
import { shortenPath, tildeifyPath, tokenLimit } from '@google/gemini-cli-core';
import { ConsoleSummaryDisplay } from './ConsoleSummaryDisplay.js';
import process from 'node:process';
import Gradient from 'ink-gradient';
@@ -49,24 +43,6 @@ export const Footer: React.FC<FooterProps> = ({
const limit = tokenLimit(model);
const percentage = promptTokenCount / limit;
const [activeFile, setActiveFile] = useState<ActiveFile | undefined>(
undefined,
);
useEffect(() => {
const updateActiveFile = () => {
const currentActiveFile = ideContext.getActiveFileContext();
setActiveFile(currentActiveFile);
};
updateActiveFile();
const unsubscribe = ideContext.subscribeToActiveFile(setActiveFile);
return () => {
unsubscribe();
};
}, []);
return (
<Box marginTop={1} justifyContent="space-between" width="100%">
<Box>
@@ -83,19 +59,6 @@ export const Footer: React.FC<FooterProps> = ({
{branchName && <Text color={Colors.Gray}> ({branchName}*)</Text>}
</Text>
)}
{activeFile && activeFile.filePath && (
<Text>
<Text color={Colors.Gray}> | </Text>
<Text color={Colors.LightBlue}>
{shortenPath(tildeifyPath(activeFile.filePath), 70)}
</Text>
{activeFile.cursor && (
<Text color={Colors.Gray}>
:{activeFile.cursor.line}:{activeFile.cursor.character}
</Text>
)}
</Text>
)}
{debugMode && (
<Text color={Colors.AccentRed}>
{' ' + (debugMessage || '--debug')}