3.6 KB100 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {Json} from 'shared/typeUtils';
9
10import {Checkbox} from 'isl-components/Checkbox';
11import {Dropdown} from 'isl-components/Dropdown';
12import {Column} from 'isl-components/Flex';
13import {Tooltip} from 'isl-components/Tooltip';
14import {shouldWarnAboutDiagnosticsAtom} from 'isl/src/Diagnostics';
15import {Setting} from 'isl/src/Setting';
16import {T, t} from 'isl/src/i18n';
17import {writeAtom} from 'isl/src/jotaiUtils';
18import {atom, useAtom, useAtomValue} from 'jotai';
19import serverAPI from '../../isl/src/ClientToServerAPI';
20import {ComparisonPanelMode, comparisonPanelMode, setComparisonPanelMode} from './state';
21
22export default function VSCodeSettings() {
23 const panelMode = useAtomValue(comparisonPanelMode);
24 const [openBesides, setOpenBesides] = useAtom(openBesidesSetting);
25 const [checkDiagnostics, setCheckDiagnostics] = useAtom(shouldWarnAboutDiagnosticsAtom);
26 return (
27 <Setting title={<T>VS Code Settings</T>}>
28 <Column alignStart>
29 <Tooltip
30 title={t(
31 'Whether to always open a separate panel to view comparisons, or to open the comparison inside an existing ISL window.',
32 )}>
33 <div className="dropdown-container setting-inline-dropdown">
34 <label>
35 <T>Comparison Panel Mode</T>
36 </label>
37 <Dropdown
38 options={Object.values(ComparisonPanelMode).map(name => ({name, value: name}))}
39 value={panelMode}
40 onChange={event =>
41 setComparisonPanelMode(event.currentTarget.value as ComparisonPanelMode)
42 }
43 />
44 </div>
45 </Tooltip>
46 <Tooltip
47 title={t(
48 'If true, files, diffs, and comparisons will open beside the existing ISL panel instead of in the same View Column. Useful to keep ISL open and visible when clicking on files.',
49 )}>
50 <Checkbox checked={openBesides} onChange={checked => setOpenBesides(checked)}>
51 <T>Open Besides</T>
52 </Checkbox>
53 </Tooltip>
54 <Tooltip
55 title={t(
56 'If true, check VS Code language diagnostics for the files that would be committed / amended. This is best-effort, and only works on files that are already open in VS Code.',
57 )}>
58 <Checkbox checked={checkDiagnostics} onChange={checked => setCheckDiagnostics(checked)}>
59 <T>Check diagnostics before committing / amending</T>
60 </Checkbox>
61 </Tooltip>
62 </Column>
63 </Setting>
64 );
65}
66
67const openBesidesSetting = vscodeConfigBackedAtom<boolean>('sapling.isl.openBeside', false);
68
69function vscodeConfigBackedAtom<T extends Json>(
70 configName: string,
71 defaultValue: T,
72 scope: 'global' | 'workspace' = 'global',
73) {
74 const primitiveAtom = atom<T>(defaultValue);
75
76 serverAPI.postMessage({
77 type: 'platform/subscribeToVSCodeConfig',
78 config: configName,
79 });
80 serverAPI.onMessageOfType('platform/vscodeConfigChanged', config => {
81 if (config.config === configName) {
82 writeAtom(primitiveAtom, config.value as T);
83 }
84 });
85
86 return atom<T, [T | ((prev: T) => T)], void>(
87 get => get(primitiveAtom),
88 (get, set, update) => {
89 const newValue = typeof update === 'function' ? update(get(primitiveAtom)) : update;
90 set(primitiveAtom, newValue);
91 serverAPI.postMessage({
92 type: 'platform/setVSCodeConfig',
93 config: configName,
94 value: newValue,
95 scope,
96 });
97 },
98 );
99}
100