mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-26 13:04:49 -07:00
feat(ui) Make useAlternateBuffer the default (#12976)
This commit is contained in:
@@ -232,7 +232,7 @@ their corresponding top-level category object in your `settings.json` file.
|
|||||||
- **`ui.useAlternateBuffer`** (boolean):
|
- **`ui.useAlternateBuffer`** (boolean):
|
||||||
- **Description:** Use an alternate screen buffer for the UI, preserving shell
|
- **Description:** Use an alternate screen buffer for the UI, preserving shell
|
||||||
history.
|
history.
|
||||||
- **Default:** `false`
|
- **Default:** `true`
|
||||||
- **Requires restart:** Yes
|
- **Requires restart:** Yes
|
||||||
|
|
||||||
- **`ui.customWittyPhrases`** (array):
|
- **`ui.customWittyPhrases`** (array):
|
||||||
|
|||||||
@@ -84,8 +84,11 @@ describe('extension reloading', () => {
|
|||||||
await run.expectText('- hello');
|
await run.expectText('- hello');
|
||||||
|
|
||||||
// Update the extension, expect the list to update, and mcp servers as well.
|
// Update the extension, expect the list to update, and mcp servers as well.
|
||||||
await run.sendText('/extensions update test-extension');
|
await run.sendKeys('/extensions update test-extension');
|
||||||
await run.type('\r');
|
await run.expectText('/extensions update test-extension');
|
||||||
|
await run.sendKeys('\r');
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
|
await run.sendKeys('\r');
|
||||||
await run.expectText(
|
await run.expectText(
|
||||||
` * test-server (remote): http://localhost:${portB}/mcp`,
|
` * test-server (remote): http://localhost:${portB}/mcp`,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -192,7 +192,12 @@ export class InteractiveRun {
|
|||||||
timeout,
|
timeout,
|
||||||
200,
|
200,
|
||||||
);
|
);
|
||||||
expect(found, `Did not find expected text: "${text}"`).toBe(true);
|
expect(
|
||||||
|
found,
|
||||||
|
`Did not find expected text: "${text}". Output was:\n${stripAnsi(
|
||||||
|
this.output,
|
||||||
|
)}`,
|
||||||
|
).toBe(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This types slowly to make sure command is correct, but only work for short
|
// This types slowly to make sure command is correct, but only work for short
|
||||||
@@ -1004,7 +1009,7 @@ export class TestRig {
|
|||||||
const options: pty.IPtyForkOptions = {
|
const options: pty.IPtyForkOptions = {
|
||||||
name: 'xterm-color',
|
name: 'xterm-color',
|
||||||
cols: 80,
|
cols: 80,
|
||||||
rows: 24,
|
rows: 80,
|
||||||
cwd: this.testDir!,
|
cwd: this.testDir!,
|
||||||
env: Object.fromEntries(
|
env: Object.fromEntries(
|
||||||
Object.entries(env).filter(([, v]) => v !== undefined),
|
Object.entries(env).filter(([, v]) => v !== undefined),
|
||||||
|
|||||||
@@ -497,7 +497,7 @@ const SETTINGS_SCHEMA = {
|
|||||||
label: 'Use Alternate Screen Buffer',
|
label: 'Use Alternate Screen Buffer',
|
||||||
category: 'UI',
|
category: 'UI',
|
||||||
requiresRestart: true,
|
requiresRestart: true,
|
||||||
default: false,
|
default: true,
|
||||||
description:
|
description:
|
||||||
'Use an alternate screen buffer for the UI, preserving shell history.',
|
'Use an alternate screen buffer for the UI, preserving shell history.',
|
||||||
showInDialog: true,
|
showInDialog: true,
|
||||||
|
|||||||
@@ -529,6 +529,7 @@ describe('startInteractiveUI', () => {
|
|||||||
|
|
||||||
// Verify render options
|
// Verify render options
|
||||||
expect(options).toEqual({
|
expect(options).toEqual({
|
||||||
|
alternateBuffer: true,
|
||||||
exitOnCtrlC: false,
|
exitOnCtrlC: false,
|
||||||
isScreenReaderEnabled: false,
|
isScreenReaderEnabled: false,
|
||||||
onRender: expect.any(Function),
|
onRender: expect.any(Function),
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ import { requestConsentNonInteractive } from './config/extensions/consent.js';
|
|||||||
import { disableMouseEvents, enableMouseEvents } from './ui/utils/mouse.js';
|
import { disableMouseEvents, enableMouseEvents } from './ui/utils/mouse.js';
|
||||||
import { ScrollProvider } from './ui/contexts/ScrollProvider.js';
|
import { ScrollProvider } from './ui/contexts/ScrollProvider.js';
|
||||||
import ansiEscapes from 'ansi-escapes';
|
import ansiEscapes from 'ansi-escapes';
|
||||||
|
import { isAlternateBufferEnabled } from './ui/hooks/useAlternateBuffer.js';
|
||||||
|
|
||||||
const SLOW_RENDER_MS = 200;
|
const SLOW_RENDER_MS = 200;
|
||||||
|
|
||||||
@@ -170,7 +171,8 @@ export async function startInteractiveUI(
|
|||||||
process.stdout.write('\x1b[?7l');
|
process.stdout.write('\x1b[?7l');
|
||||||
}
|
}
|
||||||
|
|
||||||
const mouseEventsEnabled = settings.merged.ui?.useAlternateBuffer === true;
|
const useAlternateBuffer = isAlternateBufferEnabled(settings);
|
||||||
|
const mouseEventsEnabled = useAlternateBuffer;
|
||||||
if (mouseEventsEnabled) {
|
if (mouseEventsEnabled) {
|
||||||
enableMouseEvents();
|
enableMouseEvents();
|
||||||
}
|
}
|
||||||
@@ -236,7 +238,7 @@ export async function startInteractiveUI(
|
|||||||
recordSlowRender(config, renderTime);
|
recordSlowRender(config, renderTime);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
alternateBuffer: settings.merged.ui?.useAlternateBuffer,
|
alternateBuffer: useAlternateBuffer,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -437,7 +439,7 @@ export async function main() {
|
|||||||
// input showing up in the output.
|
// input showing up in the output.
|
||||||
process.stdin.setRawMode(true);
|
process.stdin.setRawMode(true);
|
||||||
|
|
||||||
if (settings.merged.ui?.useAlternateBuffer) {
|
if (isAlternateBufferEnabled(settings)) {
|
||||||
process.stdout.write(ansiEscapes.enterAlternativeScreen);
|
process.stdout.write(ansiEscapes.enterAlternativeScreen);
|
||||||
|
|
||||||
// Ink will cleanup so there is no need for us to manually cleanup.
|
// Ink will cleanup so there is no need for us to manually cleanup.
|
||||||
|
|||||||
+12
-12
@@ -16,16 +16,16 @@ Tips for getting started:
|
|||||||
2. Be specific for the best results.
|
2. Be specific for the best results.
|
||||||
3. Create GEMINI.md files to customize your interactions with Gemini.
|
3. Create GEMINI.md files to customize your interactions with Gemini.
|
||||||
4. /help for more information.
|
4. /help for more information.
|
||||||
╭──────────────────────────────────────────────────────────────────────────────╮
|
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ ✓ tool1 Description for tool 1 │
|
│ ✓ tool1 Description for tool 1 │
|
||||||
│ │
|
│ │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||||
╭──────────────────────────────────────────────────────────────────────────────╮
|
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ ✓ tool2 Description for tool 2 │
|
│ ✓ tool2 Description for tool 2 │
|
||||||
│ │
|
│ │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||||
╭──────────────────────────────────────────────────────────────────────────────╮
|
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ o tool3 Description for tool 3 │
|
│ o tool3 Description for tool 3 │
|
||||||
│ │
|
│ │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────╯"
|
╰─────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders complete footer in narrow terminal (baseline narrow) > complete-footer-narrow 1`] = `" ...s/to/make/it/long no sandbox gemini-pro (100%)"`;
|
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders complete footer in narrow terminal (baseline narrow) > complete-footer-narrow 1`] = `" ...s/to/make/it/long no sandbox gemini-pro (100%)"`;
|
||||||
|
|
||||||
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders complete footer with all sections visible (baseline) > complete-footer-wide 1`] = `" ...directories/to/make/it/long no sandbox (see /docs) gemini-pro (100% context left)"`;
|
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders complete footer with all sections visible (baseline) > complete-footer-wide 1`] = `" ...irectories/to/make/it/long no sandbox (see /docs) gemini-pro (100% context left)"`;
|
||||||
|
|
||||||
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders footer with CWD and model info hidden to test alignment (only sandbox visible) > footer-only-sandbox 1`] = `" no sandbox (see /docs)"`;
|
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders footer with CWD and model info hidden to test alignment (only sandbox visible) > footer-only-sandbox 1`] = `" no sandbox (see /docs)"`;
|
||||||
|
|
||||||
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders footer with all optional sections hidden (minimal footer) > footer-minimal 1`] = `""`;
|
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders footer with all optional sections hidden (minimal footer) > footer-minimal 1`] = `""`;
|
||||||
|
|
||||||
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders footer with only model info hidden (partial filtering) > footer-no-model 1`] = `" ...directories/to/make/it/long no sandbox (see /docs)"`;
|
exports[`<Footer /> > footer configuration filtering (golden snapshots) > renders footer with only model info hidden (partial filtering) > footer-no-model 1`] = `" ...irectories/to/make/it/long no sandbox (see /docs)"`;
|
||||||
|
|||||||
@@ -1,57 +1,57 @@
|
|||||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
exports[`InputPrompt > command search (Ctrl+R when not in shell) > expands and collapses long suggestion via Right/Left arrows > command-search-render-collapsed-match 1`] = `
|
exports[`InputPrompt > command search (Ctrl+R when not in shell) > expands and collapses long suggestion via Right/Left arrows > command-search-render-collapsed-match 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ (r:) Type your message or @path/to/file │
|
│ (r:) Type your message or @path/to/file │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll →
|
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll →
|
||||||
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
|
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
|
||||||
..."
|
..."
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > command search (Ctrl+R when not in shell) > expands and collapses long suggestion via Right/Left arrows > command-search-render-expanded-match 1`] = `
|
exports[`InputPrompt > command search (Ctrl+R when not in shell) > expands and collapses long suggestion via Right/Left arrows > command-search-render-expanded-match 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ (r:) Type your message or @path/to/file │
|
│ (r:) Type your message or @path/to/file │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll ←
|
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll ←
|
||||||
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
|
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
|
||||||
llllllllllllllllllllllllllllllllllllllllllllllllll"
|
llllllllllllllllllllllllllllllllllllllllllllllllll"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > command search (Ctrl+R when not in shell) > renders match window and expanded view (snapshots) > command-search-render-collapsed-match 1`] = `
|
exports[`InputPrompt > command search (Ctrl+R when not in shell) > renders match window and expanded view (snapshots) > command-search-render-collapsed-match 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ (r:) commit │
|
│ (r:) commit │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
git commit -m "feat: add search" in src/app"
|
git commit -m "feat: add search" in src/app"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > command search (Ctrl+R when not in shell) > renders match window and expanded view (snapshots) > command-search-render-expanded-match 1`] = `
|
exports[`InputPrompt > command search (Ctrl+R when not in shell) > renders match window and expanded view (snapshots) > command-search-render-expanded-match 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ (r:) commit │
|
│ (r:) commit │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
git commit -m "feat: add search" in src/app"
|
git commit -m "feat: add search" in src/app"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > snapshots > should not show inverted cursor when shell is focused 1`] = `
|
exports[`InputPrompt > snapshots > should not show inverted cursor when shell is focused 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ > Type your message or @path/to/file │
|
│ > Type your message or @path/to/file │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > snapshots > should render correctly in shell mode 1`] = `
|
exports[`InputPrompt > snapshots > should render correctly in shell mode 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ ! Type your message or @path/to/file │
|
│ ! Type your message or @path/to/file │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > snapshots > should render correctly in yolo mode 1`] = `
|
exports[`InputPrompt > snapshots > should render correctly in yolo mode 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ * Type your message or @path/to/file │
|
│ * Type your message or @path/to/file │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InputPrompt > snapshots > should render correctly when accepting edits 1`] = `
|
exports[`InputPrompt > snapshots > should render correctly when accepting edits 1`] = `
|
||||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
"╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ > Type your message or @path/to/file │
|
│ > Type your message or @path/to/file │
|
||||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -5,8 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { useSettings } from '../contexts/SettingsContext.js';
|
import { useSettings } from '../contexts/SettingsContext.js';
|
||||||
|
import type { LoadedSettings } from '../../config/settings.js';
|
||||||
|
|
||||||
|
export const isAlternateBufferEnabled = (settings: LoadedSettings): boolean =>
|
||||||
|
settings.merged.ui?.useAlternateBuffer !== false;
|
||||||
|
|
||||||
export const useAlternateBuffer = (): boolean => {
|
export const useAlternateBuffer = (): boolean => {
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
return settings.merged.ui?.useAlternateBuffer ?? false;
|
return isAlternateBufferEnabled(settings);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2025 Google LLC
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { colorizeCode } from './CodeColorizer.js';
|
||||||
|
import { renderWithProviders } from '../../test-utils/render.js';
|
||||||
|
import { LoadedSettings } from '../../config/settings.js';
|
||||||
|
|
||||||
|
describe('colorizeCode', () => {
|
||||||
|
it('renders empty lines correctly when useAlternateBuffer is true', () => {
|
||||||
|
const code = 'line 1\n\nline 3';
|
||||||
|
const settings = new LoadedSettings(
|
||||||
|
{ path: '', settings: {}, originalSettings: {} },
|
||||||
|
{ path: '', settings: {}, originalSettings: {} },
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
settings: { ui: { useAlternateBuffer: true, showLineNumbers: false } },
|
||||||
|
originalSettings: {
|
||||||
|
ui: { useAlternateBuffer: true, showLineNumbers: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ path: '', settings: {}, originalSettings: {} },
|
||||||
|
true,
|
||||||
|
new Set(),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = colorizeCode({
|
||||||
|
code,
|
||||||
|
language: 'javascript',
|
||||||
|
maxWidth: 80,
|
||||||
|
settings,
|
||||||
|
hideLineNumbers: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { lastFrame } = renderWithProviders(<>{result}</>);
|
||||||
|
// We expect the output to preserve the empty line.
|
||||||
|
// If the bug exists, it might look like "line 1\nline 3"
|
||||||
|
// If fixed, it should look like "line 1\n \nline 3" (if we use space) or just have the newline.
|
||||||
|
|
||||||
|
// We can check if the output matches the code (ignoring color codes if any, but lastFrame returns plain text usually unless configured otherwise)
|
||||||
|
// Actually lastFrame() returns string with ANSI codes stripped by default in some setups, or not.
|
||||||
|
// But ink-testing-library usually returns the visual representation.
|
||||||
|
|
||||||
|
expect(lastFrame()).toMatch(/line 1\s*\n\s*\n\s*line 3/);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
} from '../components/shared/MaxSizedBox.js';
|
} from '../components/shared/MaxSizedBox.js';
|
||||||
import type { LoadedSettings } from '../../config/settings.js';
|
import type { LoadedSettings } from '../../config/settings.js';
|
||||||
import { debugLogger } from '@google/gemini-cli-core';
|
import { debugLogger } from '@google/gemini-cli-core';
|
||||||
|
import { isAlternateBufferEnabled } from '../hooks/useAlternateBuffer.js';
|
||||||
|
|
||||||
// Configure theming and parsing utilities.
|
// Configure theming and parsing utilities.
|
||||||
const lowlight = createLowlight(common);
|
const lowlight = createLowlight(common);
|
||||||
@@ -150,7 +151,7 @@ export function colorizeCode({
|
|||||||
? false
|
? false
|
||||||
: (settings?.merged.ui?.showLineNumbers ?? true);
|
: (settings?.merged.ui?.showLineNumbers ?? true);
|
||||||
|
|
||||||
const useMaxSizedBox = settings?.merged.ui?.useAlternateBuffer !== true;
|
const useMaxSizedBox = !isAlternateBufferEnabled(settings);
|
||||||
try {
|
try {
|
||||||
// Render the HAST tree using the adapted theme
|
// Render the HAST tree using the adapted theme
|
||||||
// Apply the theme's default foreground color to the top-level Text element
|
// Apply the theme's default foreground color to the top-level Text element
|
||||||
@@ -160,10 +161,7 @@ export function colorizeCode({
|
|||||||
let hiddenLinesCount = 0;
|
let hiddenLinesCount = 0;
|
||||||
|
|
||||||
// Optimization to avoid highlighting lines that cannot possibly be displayed.
|
// Optimization to avoid highlighting lines that cannot possibly be displayed.
|
||||||
if (
|
if (availableHeight !== undefined && useMaxSizedBox) {
|
||||||
availableHeight !== undefined &&
|
|
||||||
settings?.merged.ui?.useAlternateBuffer === false
|
|
||||||
) {
|
|
||||||
availableHeight = Math.max(availableHeight, MINIMUM_MAX_HEIGHT);
|
availableHeight = Math.max(availableHeight, MINIMUM_MAX_HEIGHT);
|
||||||
if (lines.length > availableHeight) {
|
if (lines.length > availableHeight) {
|
||||||
const sliceIndex = lines.length - availableHeight;
|
const sliceIndex = lines.length - availableHeight;
|
||||||
@@ -180,7 +178,7 @@ export function colorizeCode({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box key={index}>
|
<Box key={index} minHeight={useMaxSizedBox ? undefined : 1}>
|
||||||
{/* We have to render line numbers differently depending on whether we are using MaxSizeBox or not */}
|
{/* We have to render line numbers differently depending on whether we are using MaxSizeBox or not */}
|
||||||
{showLineNumbers && useMaxSizedBox && (
|
{showLineNumbers && useMaxSizedBox && (
|
||||||
<Text color={activeTheme.colors.Gray}>
|
<Text color={activeTheme.colors.Gray}>
|
||||||
@@ -238,7 +236,7 @@ export function colorizeCode({
|
|||||||
const lines = codeToHighlight.split('\n');
|
const lines = codeToHighlight.split('\n');
|
||||||
const padWidth = String(lines.length).length; // Calculate padding width based on number of lines
|
const padWidth = String(lines.length).length; // Calculate padding width based on number of lines
|
||||||
const fallbackLines = lines.map((line, index) => (
|
const fallbackLines = lines.map((line, index) => (
|
||||||
<Box key={index}>
|
<Box key={index} minHeight={useMaxSizedBox ? undefined : 1}>
|
||||||
{/* We have to render line numbers differently depending on whether we are using MaxSizeBox or not */}
|
{/* We have to render line numbers differently depending on whether we are using MaxSizeBox or not */}
|
||||||
{showLineNumbers && useMaxSizedBox && (
|
{showLineNumbers && useMaxSizedBox && (
|
||||||
<Text color={activeTheme.defaultColor}>
|
<Text color={activeTheme.defaultColor}>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import { lerp } from '../../utils/math.js';
|
import { lerp } from '../../utils/math.js';
|
||||||
import { type LoadedSettings } from '../../config/settings.js';
|
import { type LoadedSettings } from '../../config/settings.js';
|
||||||
|
import { isAlternateBufferEnabled } from '../hooks/useAlternateBuffer.js';
|
||||||
|
|
||||||
const getMainAreaWidthInternal = (terminalWidth: number): number => {
|
const getMainAreaWidthInternal = (terminalWidth: number): number => {
|
||||||
if (terminalWidth <= 80) {
|
if (terminalWidth <= 80) {
|
||||||
@@ -27,7 +28,7 @@ export const calculateMainAreaWidth = (
|
|||||||
settings: LoadedSettings,
|
settings: LoadedSettings,
|
||||||
): number => {
|
): number => {
|
||||||
if (settings.merged.ui?.useFullWidth !== false) {
|
if (settings.merged.ui?.useFullWidth !== false) {
|
||||||
if (settings.merged.ui?.useAlternateBuffer) {
|
if (isAlternateBufferEnabled(settings)) {
|
||||||
return terminalWidth - 1;
|
return terminalWidth - 1;
|
||||||
}
|
}
|
||||||
return terminalWidth;
|
return terminalWidth;
|
||||||
|
|||||||
@@ -278,8 +278,8 @@
|
|||||||
"useAlternateBuffer": {
|
"useAlternateBuffer": {
|
||||||
"title": "Use Alternate Screen Buffer",
|
"title": "Use Alternate Screen Buffer",
|
||||||
"description": "Use an alternate screen buffer for the UI, preserving shell history.",
|
"description": "Use an alternate screen buffer for the UI, preserving shell history.",
|
||||||
"markdownDescription": "Use an alternate screen buffer for the UI, preserving shell history.\n\n- Category: `UI`\n- Requires restart: `yes`\n- Default: `false`",
|
"markdownDescription": "Use an alternate screen buffer for the UI, preserving shell history.\n\n- Category: `UI`\n- Requires restart: `yes`\n- Default: `true`",
|
||||||
"default": false,
|
"default": true,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"customWittyPhrases": {
|
"customWittyPhrases": {
|
||||||
|
|||||||
Reference in New Issue
Block a user