Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/utils/claude-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as path from 'path';
import { z } from 'zod';

import type { ClaudeSettings } from '../types/ClaudeSettings';
import type { RenderContext } from '../types/RenderContext';
import {
SettingsSchema,
type InstallationMetadata,
Expand Down Expand Up @@ -518,6 +519,22 @@ function getLayeredSettingsCandidatePathsByPriority(cwd: string): string[] {
return Array.from(new Set(candidates));
}

/**
* Picks the directory whose `.claude` layer `getVoiceConfig` and `getSandboxConfig` read.
*
* The project directory is tried first because that is where the project settings
* layers live; the session cwd can sit anywhere beneath it.
*/
export function resolveClaudeConfigCwd(context: RenderContext): string | undefined {
const candidates = [
context.data?.workspace?.project_dir,
context.data?.cwd,
context.data?.workspace?.current_dir
];

return candidates.find(candidate => typeof candidate === 'string' && candidate.trim().length > 0);
}

interface VoiceLayerResult {
fileExisted: boolean;
enabled: boolean | undefined;
Expand Down
76 changes: 17 additions & 59 deletions src/widgets/CompactionCounter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import { formatTokens } from '../utils/format-tokens';

import {
isMetadataFlagEnabled,
toggleMetadataFlag
isNerdFontEnabled,
setNerdFontFormat,
toggleMetadataFlag,
toggleNerdFont,
type NerdFontFormats
} from './shared/metadata';
import {
getSlotSymbol,
Expand All @@ -34,7 +38,6 @@ const CYCLE_FORMAT_ACTION = 'cycle-format';
const TOGGLE_HIDE_ZERO_ACTION = 'toggle-hide-zero';
const TOGGLE_NERD_FONT_ACTION = 'toggle-nerd-font';
const HIDE_ZERO_METADATA_KEY = 'hideZero';
const NERD_FONT_METADATA_KEY = 'nerdFont';
const TOGGLE_TRIGGERS_ACTION = 'toggle-triggers';
const SHOW_TRIGGERS_METADATA_KEY = 'showTriggers';
const TOGGLE_RECLAIMED_ACTION = 'toggle-reclaimed';
Expand All @@ -60,42 +63,15 @@ function getFormat(item: WidgetItem): CompactionCounterFormat {
return (FORMATS as readonly string[]).includes(format ?? '') ? (format as CompactionCounterFormat) : DEFAULT_FORMAT;
}

function removeNerdFont(item: WidgetItem): WidgetItem {
const { [NERD_FONT_METADATA_KEY]: removedNerdFont, ...restMetadata } = item.metadata ?? {};
void removedNerdFont;

return {
...item,
metadata: Object.keys(restMetadata).length > 0 ? restMetadata : undefined
};
}

function setFormat(item: WidgetItem, format: CompactionCounterFormat): WidgetItem {
if (format === DEFAULT_FORMAT) {
const { format: removedFormat, ...restMetadata } = item.metadata ?? {};
void removedFormat;

return {
...item,
metadata: Object.keys(restMetadata).length > 0 ? restMetadata : undefined
};
}

const { [NERD_FONT_METADATA_KEY]: removedNerdFont, ...restMetadata } = item.metadata ?? {};
void removedNerdFont;

return {
...item,
metadata: {
...restMetadata,
format
}
};
// Only the icon format draws a glyph; the other two are text.
function canUseNerdFont(item: WidgetItem): boolean {
return getFormat(item) === DEFAULT_FORMAT;
}

function isNerdFontEnabled(item: WidgetItem): boolean {
return item.metadata?.[NERD_FONT_METADATA_KEY] === 'true' && getFormat(item) === DEFAULT_FORMAT;
}
const NERD_FONT_FORMATS: NerdFontFormats<CompactionCounterFormat> = {
defaultFormat: DEFAULT_FORMAT,
canUseNerdFont
};

function isHideZeroEnabled(item: WidgetItem): boolean {
return item.metadata?.[HIDE_ZERO_METADATA_KEY] === 'true';
Expand Down Expand Up @@ -179,24 +155,6 @@ function formatStats(data: CompactionData, item: WidgetItem, icon: string): stri
return out;
}

function toggleNerdFont(item: WidgetItem): WidgetItem {
if (getFormat(item) !== DEFAULT_FORMAT) {
return removeNerdFont(item);
}

if (!isNerdFontEnabled(item)) {
return {
...item,
metadata: {
...(item.metadata ?? {}),
[NERD_FONT_METADATA_KEY]: 'true'
}
};
}

return removeNerdFont(item);
}

function formatCount(count: number, format: CompactionCounterFormat, icon: string): string {
switch (format) {
case 'icon-space-number': return `${icon} ${count}`;
Expand Down Expand Up @@ -230,7 +188,7 @@ export class CompactionCounterWidget implements Widget {
modifiers.push(`${metric} value`);
} else {
modifiers.push(getFormat(item));
if (isNerdFontEnabled(item)) {
if (isNerdFontEnabled(item, NERD_FONT_FORMATS)) {
modifiers.push('nerd font');
}
if (isMetadataFlagEnabled(item, SHOW_TRIGGERS_METADATA_KEY)) {
Expand Down Expand Up @@ -262,15 +220,15 @@ export class CompactionCounterWidget implements Widget {
const currentFormat = getFormat(item);
const nextFormat = FORMATS[(FORMATS.indexOf(currentFormat) + 1) % FORMATS.length] ?? DEFAULT_FORMAT;

return setFormat(item, nextFormat);
return setNerdFontFormat(item, nextFormat, NERD_FONT_FORMATS);
}

if (action === TOGGLE_HIDE_ZERO_ACTION) {
return toggleHideZero(item);
}

if (action === TOGGLE_NERD_FONT_ACTION) {
return toggleNerdFont(item);
return toggleNerdFont(item, NERD_FONT_FORMATS);
}

if (action === TOGGLE_TRIGGERS_ACTION) {
Expand Down Expand Up @@ -301,7 +259,7 @@ export class CompactionCounterWidget implements Widget {
return null;
}

const icon = isNerdFontEnabled(item) ? COMPACTION_NERD_FONT_ICON : COMPACTION_ICON;
const icon = isNerdFontEnabled(item, NERD_FONT_FORMATS) ? COMPACTION_NERD_FONT_ICON : COMPACTION_ICON;
return formatStats(data, item, icon);
}

Expand All @@ -318,7 +276,7 @@ export class CompactionCounterWidget implements Widget {
}

keybinds.push({ key: 'f', label: '(f)ormat', action: CYCLE_FORMAT_ACTION });
if (item === undefined || getFormat(item) === DEFAULT_FORMAT) {
if (item === undefined || canUseNerdFont(item)) {
keybinds.push({ key: 'n', label: '(n)erd font', action: TOGGLE_NERD_FONT_ACTION });
}
keybinds.push({ key: 's', label: '(s)plit by trigger', action: TOGGLE_TRIGGERS_ACTION });
Expand Down
75 changes: 15 additions & 60 deletions src/widgets/RemoteControlStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import type {
} from '../types/Widget';
import { getRemoteControlStatus } from '../utils/claude-settings';

import {
isNerdFontEnabled,
setNerdFontFormat,
toggleNerdFont,
type NerdFontFormats
} from './shared/metadata';

const SATELLITE_EMOJI = '📡';
const SATELLITE_NERD_FONT = '';
const SATELLITE_SLASH_NERD_FONT = '';
Expand All @@ -24,7 +31,6 @@ type RemoteFormat = typeof FORMATS[number];
const DEFAULT_FORMAT: RemoteFormat = 'icon';
const CYCLE_FORMAT_ACTION = 'cycle-format';
const TOGGLE_NERD_FONT_ACTION = 'toggle-nerd-font';
const NERD_FONT_METADATA_KEY = 'nerdFont';

function getFormat(item: WidgetItem): RemoteFormat {
const f = item.metadata?.format;
Expand All @@ -36,61 +42,10 @@ function canUseNerdFont(item: WidgetItem): boolean {
return format === 'icon' || (format === 'icon-text' && !item.rawValue);
}

function removeNerdFont(item: WidgetItem): WidgetItem {
const { [NERD_FONT_METADATA_KEY]: removedNerdFont, ...restMetadata } = item.metadata ?? {};
void removedNerdFont;

return {
...item,
metadata: Object.keys(restMetadata).length > 0 ? restMetadata : undefined
};
}

function setFormat(item: WidgetItem, format: RemoteFormat): WidgetItem {
let updatedItem: WidgetItem;

if (format === DEFAULT_FORMAT) {
const { format: removedFormat, ...restMetadata } = item.metadata ?? {};
void removedFormat;

updatedItem = {
...item,
metadata: Object.keys(restMetadata).length > 0 ? restMetadata : undefined
};
} else {
updatedItem = {
...item,
metadata: {
...(item.metadata ?? {}),
format
}
};
}

return canUseNerdFont(updatedItem) ? updatedItem : removeNerdFont(updatedItem);
}

function isNerdFontEnabled(item: WidgetItem): boolean {
return canUseNerdFont(item) && item.metadata?.[NERD_FONT_METADATA_KEY] === 'true';
}

function toggleNerdFont(item: WidgetItem): WidgetItem {
if (!canUseNerdFont(item)) {
return removeNerdFont(item);
}

if (!isNerdFontEnabled(item)) {
return {
...item,
metadata: {
...(item.metadata ?? {}),
[NERD_FONT_METADATA_KEY]: 'true'
}
};
}

return removeNerdFont(item);
}
const NERD_FONT_FORMATS: NerdFontFormats<RemoteFormat> = {
defaultFormat: DEFAULT_FORMAT,
canUseNerdFont
};

function formatStatus(enabled: boolean, format: RemoteFormat, nerdFont: boolean, rawValue: boolean): string {
const stateText = enabled ? 'on' : 'off';
Expand Down Expand Up @@ -123,7 +78,7 @@ export class RemoteControlStatusWidget implements Widget {

getEditorDisplay(item: WidgetItem): WidgetEditorDisplay {
const modifiers: string[] = [getFormat(item)];
if (isNerdFontEnabled(item)) {
if (isNerdFontEnabled(item, NERD_FONT_FORMATS)) {
modifiers.push('nerd font');
}

Expand All @@ -138,19 +93,19 @@ export class RemoteControlStatusWidget implements Widget {
const currentFormat = getFormat(item);
const nextFormat = FORMATS[(FORMATS.indexOf(currentFormat) + 1) % FORMATS.length] ?? DEFAULT_FORMAT;

return setFormat(item, nextFormat);
return setNerdFontFormat(item, nextFormat, NERD_FONT_FORMATS);
}

if (action === TOGGLE_NERD_FONT_ACTION) {
return toggleNerdFont(item);
return toggleNerdFont(item, NERD_FONT_FORMATS);
}

return null;
}

render(item: WidgetItem, context: RenderContext, _settings: Settings): string | null {
const format = getFormat(item);
const nerdFont = isNerdFontEnabled(item);
const nerdFont = isNerdFontEnabled(item, NERD_FONT_FORMATS);

if (context.isPreview) {
return formatStatus(true, format, nerdFont, item.rawValue ?? false);
Expand Down
Loading