дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
Project & files - Project view modes (Project Files / Open Files / All Changed Files / Scratches); External Libraries for Python, JDK (src.zip), Node, Cargo, Go, Maven/Gradle jars; read-only jar/zip browsing - ⌘N New popup with type search and more file kinds; New Project, Rename Project, Reload All from Disk, Export/Import Settings, Power Save Mode - File type associations, extra content roots and exclude patterns (indexed and watched without reopening the project) Editor & navigation - Find bar: search scope (comments/strings), Preserve Case, Exclude, multiline, history; Find in Files: Module scope, custom pattern scopes, multiline - Search Everywhere filters, Assign Shortcut, settings results; named bookmark lists, file/folder bookmarks; Structure filters and Show Inherited; Recent Locations timestamps and breadcrumbs; Code Vision author - Completion options, editor tab placement/layout, inline completion (LSP 3.18) - Spell checking (Typo inspection, ide-spell) and Inspections settings with custom profiles; Code Style schemes, formatter markers, Do not format Run, VCS, services, database - Typed run configurations (Shell, Program, npm, Gradle, Maven, Docker, Compound), Modify options, Before launch, env dialog, Current File, Emulate terminal (PTY) - Git log graph/view options, Go to Hash/Branch/Tag, date filter keeps the graph; Pull/Merge/Rebase dialogs, Manage Remotes, Worktrees - Generic Services host (Docker connections/registries, run sessions); TODO scope/changes tabs with changelists; Coverage report import - Data sources: wire-compatible vendors, URL import, SSL certs, Options, Schemas and Advanced tabs, color and comment Workbench - Run Anything, Customize Main Toolbar, named tool window layouts, menu completeness, Code Cleanup, macros, "Don't Show Again", editor banners - Chinese translations for the new UI Claude-Session: https://claude.ai/code/session_01SaPPsVPuk6ZTNsoUCNCbMv
90 рядки
3.2 KiB
TypeScript
90 рядки
3.2 KiB
TypeScript
/**
|
|
* IDEA's "Assign Shortcut" from Search Everywhere (⌥↵ on an action): the
|
|
* Keymap page's keystroke dialog for one action, saved straight to the
|
|
* active keymap (overrides of a bundled keymap, or the user keymap itself).
|
|
*/
|
|
import { useMemo } from "react";
|
|
import { create } from "zustand";
|
|
import { useActions } from "@/platform/actions";
|
|
import { call, commands, isTauri } from "@/platform/ipc";
|
|
import type { Keymap } from "@/platform/keymap";
|
|
import { PRESETS } from "@/platform/keymap";
|
|
import { useProject } from "@/platform/project";
|
|
import { validateSettings } from "../model/schema";
|
|
import {
|
|
activeDraft,
|
|
addBinding,
|
|
removeConflicts,
|
|
withCustomOverrides,
|
|
type Conflict,
|
|
type KeymapDraft,
|
|
} from "./model";
|
|
import { RecordShortcutDialog } from "./RecordShortcutDialog";
|
|
|
|
export const useAssignShortcut = create<{ actionId: string | null }>(() => ({ actionId: null }));
|
|
|
|
export function showAssignShortcut(actionId: string) {
|
|
useAssignShortcut.setState({ actionId });
|
|
}
|
|
|
|
interface KeymapSettings {
|
|
keymap: string;
|
|
keymapOverrides: Keymap;
|
|
customKeymaps: ReturnType<typeof validateSettings>["customKeymaps"];
|
|
}
|
|
|
|
export function draftOf(s: KeymapSettings): KeymapDraft {
|
|
return activeDraft(s.keymap, s.keymapOverrides, s.customKeymaps);
|
|
}
|
|
|
|
/** The settings key and value that add `binding` to `actionId` in the active keymap. */
|
|
export function assignedSetting(
|
|
s: KeymapSettings,
|
|
actionId: string,
|
|
binding: string,
|
|
conflicts: readonly Conflict[],
|
|
removeOthers: boolean,
|
|
): { key: "keymapOverrides" | "customKeymaps"; value: unknown } {
|
|
const draft = draftOf(s);
|
|
const base = removeOthers ? { ...draft, overrides: removeConflicts(draft, conflicts) } : draft;
|
|
const overrides = addBinding(base, actionId, binding);
|
|
const custom = !PRESETS[s.keymap] && !!s.customKeymaps[s.keymap];
|
|
return custom
|
|
? { key: "customKeymaps", value: withCustomOverrides(s.customKeymaps, s.keymap, overrides) }
|
|
: { key: "keymapOverrides", value: overrides };
|
|
}
|
|
|
|
async function save(key: string, value: unknown) {
|
|
if (!isTauri()) {
|
|
const settings = useProject.getState().settings;
|
|
useProject.setState({ settings: { ...(settings ?? {}), [key]: value } as typeof settings });
|
|
return;
|
|
}
|
|
const settings = await call(commands.settingsSet("global", key, JSON.stringify(value)));
|
|
useProject.setState({ settings });
|
|
}
|
|
|
|
export function AssignShortcutOverlay() {
|
|
const actionId = useAssignShortcut((s) => s.actionId);
|
|
const actionMap = useActions((s) => s.actions);
|
|
const raw = useProject((s) => s.settings);
|
|
const settings = useMemo(() => validateSettings(raw), [raw]);
|
|
const actions = useMemo(() => [...actionMap.values()], [actionMap]);
|
|
const action = actionId ? actionMap.get(actionId) : undefined;
|
|
if (!action) return null;
|
|
const close = () => useAssignShortcut.setState({ actionId: null });
|
|
return (
|
|
<RecordShortcutDialog
|
|
action={action}
|
|
actions={actions}
|
|
draft={draftOf(settings)}
|
|
onCancel={close}
|
|
onSubmit={(binding, conflicts, remove) => {
|
|
const { key, value } = assignedSetting(settings, action.id, binding, conflicts, remove);
|
|
close();
|
|
void save(key, value).catch((e) => console.error("cannot save the shortcut", e));
|
|
}}
|
|
/>
|
|
);
|
|
}
|