Plik konfiguracyjny
Jak działa config.json — lokalizacja, włączanie, dwukierunkowa synchronizacja na żywo, schemat i obsługa błędów.
BetterCmdTab może przechowywać każde ustawienie w zwykłym pliku JSON, który synchronizuje się w obie strony z oknem ustawień. Zmień plik, a zmiana zostanie zastosowana na żywo; zmień coś w aplikacji, a plik zostanie zaktualizowany. Plik zaprojektowano tak, aby nadawał się do repozytorium z plikami konfiguracyjnymi.
Lokalizacja
~/.config/bettercmdtab/config.json$XDG_CONFIG_HOME jest uwzględniany, gdy wskazuje ścieżkę bezwzględną. W takim
przypadku plik znajduje się w $XDG_CONFIG_HOME/bettercmdtab/config.json.
Ścieżka może być dowiązaniem symbolicznym — przed zapisem jest rozwiązywana, dzięki czemu zastępowany jest cel dowiązania, a nie samo dowiązanie.
Włączanie
Samo istnienie pliku włącza funkcję. BetterCmdTab nigdy nie tworzy go samodzielnie.
- Brak pliku — cała funkcja pozostaje nieaktywna. Nic nie jest zapisywane ani obserwowane.
- Plik istnieje — zmiany są stosowane na żywo, a ustawienia zmienione w aplikacji zapisywane z powrotem.
- Usunięcie pliku — synchronizacja zostaje zatrzymana.
Aby go utworzyć, użyj Ustawienia → Ogólne → Kopia zapasowa → Plik konfiguracyjny → Utwórz…. Spowoduje to zapisanie bieżących ustawień i uruchomienie synchronizacji. Możesz też utworzyć plik ręcznie, o ile katalog istniał już w chwili uruchomienia aplikacji:
mkdir -p ~/.config/bettercmdtab
echo '{}' > ~/.config/bettercmdtab/config.jsonJeśli podczas uruchamiania nie istniał ani ~/.config, ani
~/.config/bettercmdtab, aplikacja nie ma czego obserwować i plik utworzony później
zostanie wykryty dopiero po ponownym uruchomieniu aplikacji (lub naciśnięciu
Utwórz…). To celowe — obserwowanie $HOME w oczekiwaniu na pojawienie się .config
budziłoby aplikację przy każdym zapisie pliku konfiguracyjnego.
Format
Płaski obiekt JSON z parami klucz: wartość. Klucze to nazwy preferencji
Switcher.* bez prefiksu, dlatego Switcher.layoutMode jest zapisywany jako
layoutMode.
{
"$schema": "schema.json",
"layoutMode": "windowPreview",
"sortOrder": "mruWindows",
"spaceScope": "visibleSpaces",
"panelScalePercent": 110,
"stayOpenOnRelease": true,
"pinnedBundleIDs": ["com.apple.Safari", "com.figma.Desktop"]
}W pełni kwalifikowane klucze ("Switcher.layoutMode") również są akceptowane podczas
odczytu, dzięki czemu stary plik napisany ręcznie nadal działa. Nigdy nie są zapisywane.
Format celowo nie ma wersji. Nieznane klucze są ignorowane, a brakujące zachowują bieżące wartości, dlatego plik można współdzielić między wersjami aplikacji w obu kierunkach.
Obsługa w edytorze
Obok config.json aplikacja zapisuje schema.json i wskazuje go w kluczu $schema
pliku konfiguracyjnego. Jest to JSON Schema (draft 2020-12) generowany przez uruchomioną
wersję aplikacji, więc nigdy nie pozostaje za nią w tyle: opisuje każdy klucz, każda
wartość wyliczeniowa ma listę dozwolonych wartości z takimi samymi etykietami jak w
oknie ustawień, a każdy klucz liczbowy zawiera akceptowany zakres.
Dzięki temu VS Code, środowiska JetBrains, Zed i każdy edytor z serwerem języka JSON oferują uzupełnianie, dokumentację po wskazaniu kursorem oraz sprawdzanie poprawności w tekście.
$schema jest wskaźnikiem, a nie ustawieniem — jest ignorowany podczas importu i nigdy
nie jest przechowywany.
Działanie synchronizacji
Plik → aplikacja. Zapisy są scalane przez 200 ms i odczytywane poza głównym wątkiem, a następnie stosowane na głównym wątku. Obsługiwane są edytory zapisujące atomowo (zapis do pliku tymczasowego, a następnie zmiana nazwy na docelową) — obserwator ponownie dołącza się do nowego pliku.
Aplikacja → plik. Zmiany w oknie ustawień są zapisywane atomowo z opóźnieniem 500 ms. Oczekująca zmiana jest synchronicznie zapisywana podczas zamykania aplikacji, więc ostatnie zmienione ustawienie nie zostanie utracone.
Plik jest normalizowany przy każdym zapisie
Każda zastosowana zmiana zapisuje plik ponownie jako pełną kanoniczną migawkę — wszystkie aktualnie przechowywane ustawienia, czytelne formatowanie i klucze posortowane alfabetycznie. Częściowy plik napisany ręcznie zostanie rozszerzony przy pierwszej zmianie, a własne formatowanie nie zostanie zachowane.
To koszt dwukierunkowej synchronizacji — plik i okno ustawień nigdy nie mogą być sprzeczne. Jeśli chcesz przechowywać minimalny plik w systemie kontroli wersji, zachowaj własną kopię, a synchronizowany plik traktuj jako generowany. (JSON nie obsługuje komentarzy, więc nic innego nie zostanie utracone.)
Dlaczego plik ma mniej kluczy niż dokumentacja
Plik zawiera ustawienia, które zostały faktycznie zapisane, a nie wszystkie 85 udokumentowanych kluczy. Preferencja jest przechowywana po pierwszej zmianie (albo gdy zapisze ją migracja), dlatego nowa instalacja tworzy niemal pusty plik, który rośnie wraz z dostosowywaniem ustawień.
Nie stanowi to problemu: brak klucza oznacza „nadal ma wartość domyślną”, dokładnie tak jak traktuje go import. Dodaj ręcznie dowolny udokumentowany klucz, a zostanie natychmiast zastosowany.
Częściowe zmiany i obsługa błędów
Import jest zawsze częściowy i nigdy nie niszczy danych:
- Pominięte klucze zachowują bieżącą wartość. Zapisanie
{"layoutMode": "list"}zmienia układ i nic więcej. - Nierozpoznane klucze są ignorowane, dzięki czemu konfiguracja z nowszej wersji nadal zostanie zastosowana.
- Nieprawidłowy JSON jest odrzucany w całości. Bieżące ustawienia zostają zachowane, a przyczyna trafia do dziennika; te same błędne bajty nie są ponownie analizowane przy każdym zapisie, a naprawienie pliku powoduje jego zastosowanie.
- Wartości o nieprawidłowej strukturze — na przykład JSON
null— są pomijane osobno dla każdego klucza. Ten klucz zachowuje wartość, a reszta pliku nadal jest stosowana. - Liczby spoza zakresu są ograniczane do akceptowanego zakresu widocznego w dokumentacji, a nie odrzucane.
- Nierozpoznane wartości wyliczeniowe wracają do wartości domyślnej danego klucza.
Czego nie ma w pliku
Niektóre dane są celowo wykluczone i nie są ani eksportowane, ani importowane:
| Wykluczone dane | Powód |
|---|---|
Skróty wyzwalające ⌘Tab / ⌘` | Rejestrator skrótów przechowuje je pod własnymi kluczami poza przestrzenią nazw Switcher.* |
disabledSymbolicHotKeys | Rejestr natywnych skrótów wyłączonych na tym Macu — import kopii z innego Maca mógłby trwale wyłączyć natywny ⌘Tab |
recentlyClosed | Historia sesji, a nie konfiguracja |
customCommitSoundFilename | Plik dźwiękowy znajduje się w katalogu Application Support tego Maca |
accentChoice, customAccentHex | Wycofane w 26.7 — przełącznik zawsze używa koloru akcentu macOS |
Skróty o ograniczonym zakresie są przypadkiem pośrednim: scopedShortcutList zapisuje
identyfikator, zakres i nazwę każdej pozycji, ale sam skrót jest rejestrowany poza tym
plikiem. Synchronizacja pliku z nowym Makiem przenosi skróty; ich kombinacje klawiszy
trzeba tam zarejestrować ponownie.
Alternatywa: eksport i import
Jeśli nie chcesz pliku synchronizowanego na żywo, w sekcji Ustawienia → Ogólne →
Kopia zapasowa znajdziesz też jednorazowe przyciski Eksportuj ustawienia i
Importuj ustawienia. Eksport zapisuje dokładnie ten sam płaski format JSON w
wybranym pliku .json. Import akceptuje ten format, a także starszą otoczkę .cmdtab
tworzoną przez wcześniejsze wersje.