Merge remote-tracking branch 'refs/remotes/origin/master'
This commit is contained in:
@@ -2,74 +2,106 @@
|
|||||||
#+AUTHOR: Martin Sukaný
|
#+AUTHOR: Martin Sukaný
|
||||||
#+DATE: 2026-02-23
|
#+DATE: 2026-02-23
|
||||||
#+STARTUP: overview
|
#+STARTUP: overview
|
||||||
#+include: ~/org/templates/document.org
|
|
||||||
|
|
||||||
* Emacs macOS Build s macOS Zoom Accessibility
|
* Emacs macOS Build s macOS Zoom Accessibility
|
||||||
|
|
||||||
Návod na buildování GNU Emacs pro macOS s patchem pro =UAZoomChangeFocus=,
|
Návod na sestavení GNU Emacs pro macOS s patchem, který opravuje sledování
|
||||||
který opravuje sledování kurzoru v macOS Zoom "Follow keyboard focus".
|
kurzoru při zapnutém macOS Zoom ("Follow keyboard focus"). Postup vychází
|
||||||
|
z reálné zkušenosti z buildu v únoru 2026.
|
||||||
|
|
||||||
[[./attachments/image-20260223-145400.png]]
|
** Proč je to potřeba
|
||||||
|
|
||||||
** Kontext
|
macOS Zoom funguje jako magnifier přes celou obrazovku nebo v okně. Režim
|
||||||
|
"Follow keyboard focus" by měl automaticky posouvat viewport za textovým
|
||||||
|
kurzorem. Ve vanilla GNU Emacs to ale nefunguje.
|
||||||
|
|
||||||
macOS Zoom "Follow keyboard focus" ve vanilla GNU Emacs nefunguje. Root cause:
|
Příčina: Emacs má vlastní NSView, který neimplementuje NSAccessibility protokol
|
||||||
Emacs nemá implementovanou NSAccessibility pro vlastní NSView a hlavně
|
a hlavně nevolá =UAZoomChangeFocus()= z =HIServices/UniversalAccess.h=. Tuto funkci
|
||||||
nevolá =UAZoomChangeFocus()= z =HIServices/UniversalAccess.h=.
|
volají iTerm2 (=PTYTextView.m=) i Chromium (=render_widget_host_view_mac.mm=) a
|
||||||
|
je to jediný spolehlivý způsob, jak Zoom přinutit sledovat kurzor v custom view.
|
||||||
|
|
||||||
Patch je v repozitáři [[https://git.apps.sukany.cz/martin/emacs-doom][martin/emacs-doom]]
|
Standardní NSAccessibility notifikace samy o sobě nestačí — Zoom je event-driven
|
||||||
v =patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch=.
|
a potřebuje explicitní volání =UAZoomChangeFocus()= s aktuální pozicí kurzoru
|
||||||
|
v souřadnicích AX obrazovky (origin vlevo nahoře, tzn. y-osa je otočená oproti
|
||||||
|
Cocoa, kde origin je vlevo dole).
|
||||||
|
|
||||||
** Prerekvizity
|
Patch je uložený v repozitáři =martin/emacs-doom= na Giteě:
|
||||||
|
=patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch=
|
||||||
|
|
||||||
|
** Krok 1: Prerekvizity
|
||||||
|
|
||||||
|
Nejprve nainstaluj Xcode Command Line Tools (nutné pro kompilaci):
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
# Xcode Command Line Tools
|
|
||||||
xcode-select --install
|
xcode-select --install
|
||||||
|
|
||||||
# Homebrew závislosti
|
|
||||||
brew install autoconf libgmp texinfo pkg-config gnutls libxml2 \
|
|
||||||
jansson tree-sitter librsvg imagemagick
|
|
||||||
|
|
||||||
# Volitelné ale doporučené
|
|
||||||
brew install libgccjit # native compilation
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Stažení zdrojů
|
Pak nainstaluj závislosti přes Homebrew:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
brew install autoconf libgmp texinfo pkg-config gnutls libxml2 jansson tree-sitter librsvg imagemagick
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Pro native compilation (volitelné, výrazně rychlejší Emacs):
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
brew install libgccjit
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Krok 2: Stažení zdrojového kódu Emacs
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
git clone https://github.com/emacs-mirror/emacs.git
|
git clone https://github.com/emacs-mirror/emacs.git
|
||||||
cd emacs
|
cd emacs
|
||||||
|
git checkout emacs-31
|
||||||
# Doporučená stable větev (aktuálně emacs-30)
|
|
||||||
git checkout emacs-30
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Aplikace accessibility patche
|
Větev =emacs-31= je aktuálně doporučená stable větev. Až bude k dispozici =emacs-32=,
|
||||||
|
použij tu.
|
||||||
|
|
||||||
|
** Krok 3: Aplikace accessibility patche
|
||||||
|
|
||||||
|
Stáhni config repozitář s patchem:
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
# Stáhni patch z martin/emacs-doom
|
|
||||||
git clone https://git.apps.sukany.cz/martin/emacs-doom.git /tmp/emacs-doom-config
|
git clone https://git.apps.sukany.cz/martin/emacs-doom.git /tmp/emacs-doom-config
|
||||||
|
#+end_src
|
||||||
|
|
||||||
# Aplikuj patch
|
Aplikuj patch:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
git am /tmp/emacs-doom-config/patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch
|
git am /tmp/emacs-doom-config/patches/0001-ns-implement-AXBoundsForRange-for-macOS-Zoom-cursor-.patch
|
||||||
|
#+end_src
|
||||||
|
|
||||||
# Ověř aplikaci
|
Ověř, že patch byl aplikovaný:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
grep "UAZoomChangeFocus" src/nsterm.m | head -3
|
grep "UAZoomChangeFocus" src/nsterm.m | head -3
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Patch implementuje:
|
Výsledkem by mělo být několik řádků s voláním =UAZoomChangeFocus=. Pokud grep
|
||||||
- =UAZoomChangeFocus()= — přímé volání Zoom API po každém pohybu kurzoru
|
nic nevrátí, patch se neaplikoval správně.
|
||||||
- =NSAccessibilitySelectedTextChangedNotification= — standardní AX notifikace
|
|
||||||
- =NSAccessibilityFocusedUIElementChangedNotification= — notifikace při focusu
|
|
||||||
- =accessibilityBoundsForRange:= — nová NSAccessibilityProtocol API
|
|
||||||
- =AXBoundsForRange= — starší fallback API
|
|
||||||
- =NSAccessibilityTextAreaRole= — správná role pro Emacs view
|
|
||||||
|
|
||||||
** Konfigurace a Build
|
Co patch přidává do =src/nsterm.m=:
|
||||||
|
|
||||||
|
- Volání =UAZoomChangeFocus()= po každém pohybu kurzoru — koordináty jsou
|
||||||
|
přepočítány z Cocoa (origin vlevo dole) do AX prostoru (origin vlevo nahoře)
|
||||||
|
ručním y-flipem: =primaryH - y - height=
|
||||||
|
- =NSAccessibilitySelectedTextChangedNotification= — notifikace po pohybu kurzoru
|
||||||
|
- =NSAccessibilityFocusedUIElementChangedNotification= — notifikace při zaměření okna
|
||||||
|
- =accessibilityBoundsForRange:= — nové API (macOS 10.10+)
|
||||||
|
- Fallback přes starší =AXBoundsForRange= pro starší verze
|
||||||
|
- =NSAccessibilityTextAreaRole= pro EmacsView
|
||||||
|
|
||||||
|
** Krok 4: Konfigurace
|
||||||
|
|
||||||
|
Spusť autogen a pak configure. Základní konfigurace (bez native compilation):
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
./configure \
|
./configure \
|
||||||
--with-ns \
|
--with-ns \
|
||||||
--with-tree-sitter \
|
--with-tree-sitter \
|
||||||
@@ -82,15 +114,9 @@ Patch implementuje:
|
|||||||
--without-x \
|
--without-x \
|
||||||
--without-dbus \
|
--without-dbus \
|
||||||
CFLAGS="-O2 -g3"
|
CFLAGS="-O2 -g3"
|
||||||
|
|
||||||
# Build — -j počet CPU jader
|
|
||||||
make -j$(sysctl -n hw.ncpu)
|
|
||||||
|
|
||||||
# Vytvoří nextstep/Emacs.app
|
|
||||||
make install
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Volitelně: s native compilation (rychlejší Emacs)
|
S native compilation (pokud máš libgccjit):
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
./configure \
|
./configure \
|
||||||
@@ -104,77 +130,154 @@ make install
|
|||||||
CFLAGS="-O2 -g3"
|
CFLAGS="-O2 -g3"
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Instalace
|
** Krok 5: Build
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
# Přesuň Emacs.app do /Applications
|
make -j$(sysctl -n hw.ncpu)
|
||||||
cp -r nextstep/Emacs.app /Applications/Emacs.app
|
|
||||||
|
|
||||||
# Vytvoř wrapper script (NE symlink — Emacs nenajde data přes symlink)
|
|
||||||
sudo tee /usr/local/bin/emacs << 'EOF'
|
|
||||||
#!/bin/sh
|
|
||||||
exec /Applications/Emacs.app/Contents/MacOS/Emacs "$@"
|
|
||||||
EOF
|
|
||||||
sudo chmod +x /usr/local/bin/emacs
|
|
||||||
|
|
||||||
# Ověření
|
|
||||||
emacs --version
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Proč wrapper script, ne symlink
|
Parametr =-j$(sysctl -n hw.ncpu)= použije všechna dostupná jádra. Build trvá
|
||||||
|
přibližně 5–15 minut podle hardwaru.
|
||||||
|
|
||||||
|
Po dokončení build vytvoří =nextstep/Emacs.app=:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
make install
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Krok 6: Instalace
|
||||||
|
|
||||||
|
Přesuň Emacs.app do /Applications:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
cp -r nextstep/Emacs.app /Applications/Emacs.app
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Vytvoř wrapper script. Pozor: použij wrapper script, ne symlink. Symlink nefunguje
|
||||||
|
správně — Emacs počítá cesty k Lisp souborům z =argv[0]=, a přes resolved symlink
|
||||||
|
je najde špatně. Projeví se to chybami jako:
|
||||||
|
|
||||||
Symlink (/usr/local/bin/emacs → .../Emacs.app/Contents/MacOS/Emacs) nefunguje
|
|
||||||
správně. Emacs počítá cesty k Lisp souborům z =argv[0]=, ne přes resolved symlink.
|
|
||||||
Výsledkem jsou chyby:
|
|
||||||
#+begin_example
|
#+begin_example
|
||||||
Warning: arch-dependent data dir 'Contents/MacOS/libexec/': No such file or directory
|
Warning: arch-dependent data dir 'Contents/MacOS/libexec/': No such file or directory
|
||||||
Warning: Lisp directory 'Contents/Resources/lisp': No such file or directory
|
Warning: Lisp directory 'Contents/Resources/lisp': No such file or directory
|
||||||
#+end_example
|
#+end_example
|
||||||
|
|
||||||
Wrapper script předává správnou cestu.
|
Správné řešení — wrapper script:
|
||||||
|
|
||||||
** macOS Accessibility nastavení
|
|
||||||
|
|
||||||
Po každém novém buildu (nový binary) je potřeba znovu udělit permission:
|
|
||||||
|
|
||||||
1. System Settings → Privacy & Security → Accessibility
|
|
||||||
2. Přidat nové =/Applications/Emacs.app=
|
|
||||||
3. Zapnout toggle
|
|
||||||
|
|
||||||
Bez tohoto kroku =UAZoomChangeFocus()= neovlivní Zoom viewport.
|
|
||||||
|
|
||||||
** Doom Emacs sync
|
|
||||||
|
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
# Po instalaci
|
sudo tee /usr/local/bin/emacs > /dev/null << 'EOF'
|
||||||
~/.emacs.d/bin/doom sync
|
#!/bin/sh
|
||||||
|
exec /Applications/Emacs.app/Contents/MacOS/Emacs "$@"
|
||||||
|
EOF
|
||||||
|
sudo chmod +x /usr/local/bin/emacs
|
||||||
|
#+end_src
|
||||||
|
|
||||||
# Pokud doom hledá emacs v jiné cestě
|
Ověření:
|
||||||
which emacs # musí vrátit /usr/local/bin/emacs
|
|
||||||
|
#+begin_src sh
|
||||||
|
which emacs
|
||||||
emacs --version
|
emacs --version
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Ověření Zoom funkcionality
|
Výstup =which emacs= musí být =/usr/local/bin/emacs=.
|
||||||
|
|
||||||
1. System Settings → Accessibility → Zoom → zapnout "Use keyboard shortcut to zoom"
|
** Krok 7: Accessibility permission
|
||||||
2. Zoom mode: Full Screen nebo Split Screen
|
|
||||||
3. Advanced → Zoom follows: =Keyboard focus=
|
|
||||||
4. Otevři Emacs, začni psát
|
|
||||||
5. Zoom viewport by měl sledovat kurzor
|
|
||||||
|
|
||||||
** Časté problémy
|
Po každém novém buildu (nový binární soubor) je potřeba znovu udělit oprávnění.
|
||||||
|
Bez toho =UAZoomChangeFocus()= neovlivní Zoom viewport — volání proběhne, ale
|
||||||
|
macOS ho ignoruje bez Accessibility přístupu.
|
||||||
|
|
||||||
| Problém | Příčina | Řešení |
|
Postup:
|
||||||
|------------------------------------+---------------------------------------+-----------------------------------------------|
|
1. Otevři System Settings → Privacy & Security → Accessibility
|
||||||
| doom sync: "emacs not found" | Wrapper script chybí nebo není v PATH | Viz sekce Instalace |
|
2. Přidej =/Applications/Emacs.app=
|
||||||
| Zoom nesleduje kurzor | Accessibility permission chybí | Přidat Emacs.app znovu do Privacy & Security |
|
3. Zapni toggle vedle Emacs
|
||||||
| Zoom nesleduje kurzor | Patch nebyl aplikován | Ověřit: =grep UAZoomChangeFocus src/nsterm.m= |
|
|
||||||
| Build selže na nsterm.m | Chybí Xcode CLT nebo závislosti | =xcode-select --install= + brew install |
|
Pokud Emacs v seznamu už je (ze starého buildu), odeber ho a přidej znovu —
|
||||||
| "Contents/MacOS/libexec not found" | Symlink místo wrapper scriptu | Nahradit wrapper scriptem |
|
macOS identifikuje aplikace i podle binary hash a starý záznam neplatí.
|
||||||
|
|
||||||
|
** Krok 8: Doom Emacs sync
|
||||||
|
|
||||||
|
Pokud používáš Doom Emacs, spusť sync po instalaci nového Emacsu:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
~/.emacs.d/bin/doom sync
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Pokud doom hlásí, že nenajde Emacs, zkontroluj:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
which emacs
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Musí vrátit =/usr/local/bin/emacs=. Pokud vrátí jinou cestu, je problém
|
||||||
|
s PATH nebo chybí wrapper script.
|
||||||
|
|
||||||
|
** Krok 9: Ověření Zoom funkcionality
|
||||||
|
|
||||||
|
Nastav Zoom v System Settings:
|
||||||
|
1. System Settings → Accessibility → Zoom
|
||||||
|
2. Zapni "Use keyboard shortcut to zoom" nebo "Use scroll gesture with modifier keys to zoom"
|
||||||
|
3. Zoom style: Full Screen nebo Window (obojí funguje)
|
||||||
|
4. Klikni na "Advanced..." → záložka "Zoom Follows the Cursor"
|
||||||
|
5. Nastav "Zoom follows: Keyboard focus"
|
||||||
|
|
||||||
|
Otevři Emacs a začni psát. Zoom viewport by měl automaticky sledovat textový
|
||||||
|
kurzor při každém pohybu (šipky, PageUp/Down, přechod mezi buffery).
|
||||||
|
|
||||||
|
** Řešení problémů
|
||||||
|
|
||||||
|
*Zoom nesleduje kurzor*
|
||||||
|
|
||||||
|
Nejčastější příčiny jsou dvě. Za prvé, chybí Accessibility permission — viz Krok 7.
|
||||||
|
Za druhé, patch nebyl správně aplikovaný. Ověření:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
grep "UAZoomChangeFocus" /Applications/Emacs.app/Contents/MacOS/../../../src/nsterm.m 2>/dev/null || \
|
||||||
|
echo "Zkontroluj zdrojový kód nebo přelož znovu"
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Nebo v build adresáři:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
grep "UAZoomChangeFocus" src/nsterm.m | wc -l
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Pokud výsledek je 0, patch chybí. Aplikuj znovu a přelož.
|
||||||
|
|
||||||
|
*Build selže na nsterm.m*
|
||||||
|
|
||||||
|
Zkontroluj, zda jsou nainstalované Xcode Command Line Tools:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
xcode-select -p
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Pokud cesta neexistuje nebo vrátí chybu, spusť =xcode-select --install= znovu.
|
||||||
|
|
||||||
|
*doom sync hlásí "emacs not found"*
|
||||||
|
|
||||||
|
Zkontroluj wrapper script:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
cat /usr/local/bin/emacs
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Soubor musí existovat a obsahovat =exec /Applications/Emacs.app/Contents/MacOS/Emacs "$@"=.
|
||||||
|
Pokud neexistuje, viz Krok 6.
|
||||||
|
|
||||||
|
*Chyby "libexec not found" nebo "lisp not found" při startu*
|
||||||
|
|
||||||
|
Příčina je symlink místo wrapper scriptu. Zkontroluj:
|
||||||
|
|
||||||
|
#+begin_src sh
|
||||||
|
ls -la /usr/local/bin/emacs
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Pokud výstup ukazuje =->= (symlink), smaž ho a vytvoř wrapper script podle Kroku 6.
|
||||||
|
|
||||||
** Reference
|
** Reference
|
||||||
|
|
||||||
- Patch repo: [[https://git.apps.sukany.cz/martin/emacs-doom][martin/emacs-doom]]
|
- Patch repozitář: [[https://git.apps.sukany.cz/martin/emacs-doom][martin/emacs-doom]]
|
||||||
- Ghostty issue (stejný problém): https://github.com/nicowillis/Ghostty/issues/4053
|
- Podobný problém v Ghostty: https://github.com/nicowillis/Ghostty/issues/4053
|
||||||
- iTerm2 implementace: =PTYTextView.m:refreshAccessibility=
|
- Stejný přístup v iTerm2: =src/PTYTextView.m=, funkce =refreshAccessibility=
|
||||||
- Chromium implementace: =render_widget_host_view_mac.mm:OnSelectionBoundsChanged=
|
- Stejný přístup v Chromium: =render_widget_host_view_mac.mm=, funkce =OnSelectionBoundsChanged=
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Matrix v Emacsu — Ement.el
|
* Matrix v Emacsu — Ement.el
|
||||||
|
|
||||||
Ement.el je nativní Matrix klient pro Emacs. Plná integrace s Doom Emacs
|
Ement.el je nativní Matrix klient pro Emacs. Plná integrace s Doom Emacs
|
||||||
přes prefix =SPC o M=.
|
přes prefix =SPC o M= (uppercase M — =SPC o m= je obsazeno mu4e).
|
||||||
|
|
||||||
** Instalace
|
** Instalace
|
||||||
|
|
||||||
@@ -20,23 +20,36 @@ Po přidání spustit:
|
|||||||
~/.emacs.d/bin/doom sync
|
~/.emacs.d/bin/doom sync
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Připojení (bez E2EE)
|
** Server a účet
|
||||||
|
|
||||||
Spusť =SPC o M c= nebo =M-x ement-connect=:
|
- Homeserver: =https://matrix.apps.sukany.cz=
|
||||||
|
- User ID: =@martin:sukany.cz=
|
||||||
|
- E2EE: *zakázáno na straně serveru* (=encryption: false= v OpenClaw config) — Pantalaimon se nepoužívá a není potřeba
|
||||||
|
|
||||||
|
** Automatické připojení
|
||||||
|
|
||||||
|
Emacs se automaticky připojí při startu (=doom-after-init-hook=) pomocí
|
||||||
|
uložené session. Nepotřebuješ zadávat heslo — token je uložen v souboru:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
~/.doom.d/ement-sessions.el
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Při prvním použití (nebo po výmazu session souboru) spusť =SPC o M c=
|
||||||
|
a zadej:
|
||||||
#+begin_example
|
#+begin_example
|
||||||
Homeserver URL: https://matrix.apps.sukany.cz
|
Homeserver URL: https://matrix.apps.sukany.cz
|
||||||
User ID: @martin:sukany.cz
|
User ID: @martin:sukany.cz
|
||||||
Password: (zadej interaktivně)
|
Password: (interaktivně)
|
||||||
#+end_example
|
#+end_example
|
||||||
|
|
||||||
Po prvním připojení se session uloží do =~/.cache/emacs/ement.el= (token).
|
Po úspěšném připojení se session uloží a příště je připojení automatické.
|
||||||
Příště se připojí automaticky.
|
|
||||||
|
|
||||||
** Klávesové zkratky (SPC o M)
|
** Klávesové zkratky (SPC o M)
|
||||||
|
|
||||||
| Zkratka | Funkce |
|
| Zkratka | Funkce |
|
||||||
|-----------|----------------------------|
|
|-------------|-----------------------------------------------|
|
||||||
|
| =SPC o M o= | Otevřít panel (inteligentní — viz níže) |
|
||||||
| =SPC o M c= | Připojit (ement-connect) |
|
| =SPC o M c= | Připojit (ement-connect) |
|
||||||
| =SPC o M C= | Odpojit |
|
| =SPC o M C= | Odpojit |
|
||||||
| =SPC o M l= | Seznam místností |
|
| =SPC o M l= | Seznam místností |
|
||||||
@@ -45,12 +58,18 @@ Příště se připojí automaticky.
|
|||||||
| =SPC o M j= | Připojit se k místnosti |
|
| =SPC o M j= | Připojit se k místnosti |
|
||||||
| =SPC o M n= | Notifikace (nové zprávy) |
|
| =SPC o M n= | Notifikace (nové zprávy) |
|
||||||
| =SPC o M m= | Zmínky (@martin) |
|
| =SPC o M m= | Zmínky (@martin) |
|
||||||
| =SPC o M s= | Manuální sync |
|
|
||||||
|
*** Inteligentní otevření panelu (SPC o M o)
|
||||||
|
|
||||||
|
=my/ement-open= se chová podle aktuálního stavu:
|
||||||
|
- Již připojeno → okamžitě otevře seznam místností
|
||||||
|
- Session soubor existuje → obnoví bez zadání hesla, po sync otevře místnosti
|
||||||
|
- Žádná session → interaktivní =ement-connect=, pak otevře místnosti
|
||||||
|
|
||||||
*** V místnosti (room buffer)
|
*** V místnosti (room buffer)
|
||||||
|
|
||||||
| Klávesa | Akce |
|
| Klávesa | Akce |
|
||||||
|-----------|---------------------------------|
|
|-------------|---------------------------------|
|
||||||
| =RET= | Napsat zprávu |
|
| =RET= | Napsat zprávu |
|
||||||
| =M-RET= | Compose buffer (pro delší text) |
|
| =M-RET= | Compose buffer (pro delší text) |
|
||||||
| =S-RET= | Odpovědět na zprávu na pointu |
|
| =S-RET= | Odpovědět na zprávu na pointu |
|
||||||
@@ -62,112 +81,45 @@ Příště se připojí automaticky.
|
|||||||
| =r m= | Seznam členů |
|
| =r m= | Seznam členů |
|
||||||
| =M-g M-l= | Přejít na seznam místností |
|
| =M-g M-l= | Přejít na seznam místností |
|
||||||
|
|
||||||
** E2EE — šifrované místnosti přes Pantalaimon
|
** E2EE
|
||||||
|
|
||||||
Ement.el sám o sobě E2EE nepodporuje. Řešení: [[https://github.com/matrix-org/pantalaimon][Pantalaimon]] — lokální proxy
|
E2EE je na serveru *zakázáno* — veškerá komunikace mezi Emacs klientem
|
||||||
démon, který transparentně šifruje/dešifruje zprávy.
|
a homeserverem probíhá nešifrovaně (ale přes HTTPS). Toto je záměrné
|
||||||
|
rozhodnutí: Megolm session errors způsobovaly nečitelné zprávy na iOS zařízeních,
|
||||||
|
spolehlivost je důležitější.
|
||||||
|
|
||||||
*** Instalace Pantalaimon
|
Pantalaimon *se nepoužívá* a není potřeba instalovat.
|
||||||
|
|
||||||
#+begin_src sh
|
** Konfigurace v config.el
|
||||||
# macOS
|
|
||||||
brew install pantalaimon
|
|
||||||
|
|
||||||
# nebo přes pip
|
Relevantní sekce (viz =~/.doom.d/config.el=):
|
||||||
pip3 install pantalaimon
|
- =ement-sessions-file= — nastaven na =~/.doom.d/ement-sessions.el= (před načtením balíčku)
|
||||||
#+end_src
|
- =ement-save-sessions t= — session se uloží při =kill-emacs=
|
||||||
|
- =ement-auto-sync t= — na pozadí se synchronizuje automaticky
|
||||||
|
- =ement-room-show-avatars nil= — avatary jsou vypnuty (výkon)
|
||||||
|
- =ement-notify-mentions-p t= — notifikace při zmínkách
|
||||||
|
|
||||||
*** Konfigurace
|
** Místnosti
|
||||||
|
|
||||||
Vytvoř =~/.config/pantalaimon/pantalaimon.conf=:
|
| Název | Room ID | Použití |
|
||||||
|
|----------------------|-----------------------------------------|-----------------------|
|
||||||
#+begin_src ini
|
| Daneel - AI assistant | =!bVBXrchJJVQRoyHQwU:sukany.cz= | Hlavní DM s Daneel |
|
||||||
[sukany]
|
| Email summaries | =!okPPZiCqKrzZeGkpzv:sukany.cz= | Email notifikace |
|
||||||
Homeserver = https://matrix.apps.sukany.cz
|
| Nakopni se (Daneel) | =!moHRlJaLrwEBYDDzGg:sukany.cz= | Nakopni se kurz |
|
||||||
ListenAddress = localhost
|
| Sprava serveru | =!NmZsNYaigZZensbSIi:sukany.cz= | Infra01 monitoring |
|
||||||
ListenPort = 8009
|
| Weekly review | =!rHpupKCgxNRJoomtij:sukany.cz= | Týdenní přehledy |
|
||||||
SSL = yes
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
*** Spuštění
|
|
||||||
|
|
||||||
#+begin_src sh
|
|
||||||
# Spustit na pozadí
|
|
||||||
pantalaimon --config ~/.config/pantalaimon/pantalaimon.conf &
|
|
||||||
|
|
||||||
# Nebo jako launchd service (macOS) — viz níže
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
*** Připojení ement přes Pantalaimon
|
|
||||||
|
|
||||||
Při =SPC o M c= (ement-connect) zadej jako homeserver proxy URL:
|
|
||||||
#+begin_example
|
|
||||||
Homeserver URL: http://localhost:8009
|
|
||||||
User ID: @martin:sukany.cz
|
|
||||||
Password: (stejné jako normálně)
|
|
||||||
#+end_example
|
|
||||||
|
|
||||||
Pantalaimon transparentně přepošle vše na =matrix.apps.sukany.cz=
|
|
||||||
a zašifruje/dešifruje E2EE místnosti.
|
|
||||||
|
|
||||||
*** Automatický start Pantalaimon (macOS LaunchAgent)
|
|
||||||
|
|
||||||
Vytvoř =~/Library/LaunchAgents/pantalaimon.plist=:
|
|
||||||
|
|
||||||
#+begin_src xml
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
||||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>Label</key>
|
|
||||||
<string>pantalaimon</string>
|
|
||||||
<key>ProgramArguments</key>
|
|
||||||
<array>
|
|
||||||
<string>/usr/local/bin/pantalaimon</string>
|
|
||||||
<string>--config</string>
|
|
||||||
<string>/Users/martin/.config/pantalaimon/pantalaimon.conf</string>
|
|
||||||
</array>
|
|
||||||
<key>RunAtLoad</key>
|
|
||||||
<true/>
|
|
||||||
<key>KeepAlive</key>
|
|
||||||
<true/>
|
|
||||||
<key>StandardOutPath</key>
|
|
||||||
<string>/tmp/pantalaimon.log</string>
|
|
||||||
<key>StandardErrorPath</key>
|
|
||||||
<string>/tmp/pantalaimon.log</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src sh
|
|
||||||
launchctl load ~/Library/LaunchAgents/pantalaimon.plist
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
*** Poznámka k E2EE ověření klíčů
|
|
||||||
|
|
||||||
Při prvním připojení přes Pantalaimon se zobrazí výzva k ověření zařízení
|
|
||||||
(cross-signing). Ověř v Element nebo jiném klientu — bez toho ement
|
|
||||||
nemusí zobrazovat zprávy v E2EE místnostech.
|
|
||||||
|
|
||||||
** Konfigurace uložena v
|
|
||||||
|
|
||||||
- Ement session (token): =~/.cache/emacs/ement.el=
|
|
||||||
- Pantalaimon data (E2EE klíče): =~/.local/share/pantalaimon/=
|
|
||||||
- Pantalaimon konfig: =~/.config/pantalaimon/pantalaimon.conf=
|
|
||||||
|
|
||||||
** Časté problémy
|
** Časté problémy
|
||||||
|
|
||||||
| Problém | Příčina | Řešení |
|
| Problém | Příčina | Řešení |
|
||||||
|---|---|---|
|
|--------------------------------|--------------------------------|-------------------------------------------------|
|
||||||
| "Invalid homeserver" | Špatná URL | Zkontrolovat https://matrix.apps.sukany.cz |
|
| Auto-connect nefunguje | Session soubor chybí nebo poškozený | =SPC o M c= pro nové přihlášení |
|
||||||
| E2EE místnosti prázdné | Pantalaimon neběží | =pantalaimon &= |
|
| "Invalid homeserver" | Špatná URL | Zkontrolovat =https://matrix.apps.sukany.cz= |
|
||||||
| Zprávy se nezobrazují | Cross-signing neproběhlo | Ověřit zařízení v Element |
|
| Zprávy se nezobrazují | Session expirovala | =SPC o M C= → =SPC o M c= |
|
||||||
| Auto-sync nefunguje | Session nebyla uložena | =SPC o M c= znovu |
|
| Pomalý start | Avatary zapnuty | =(setq ement-room-show-avatars nil)= |
|
||||||
| "Unverified device" | Nové zařízení | Ověřit v Element → Settings → Devices |
|
|
||||||
|
|
||||||
** Reference
|
** Reference
|
||||||
|
|
||||||
- [[https://github.com/alphapapa/ement.el][ement.el GitHub]]
|
- [[https://github.com/alphapapa/ement.el][ement.el GitHub]]
|
||||||
- [[https://github.com/matrix-org/pantalaimon][Pantalaimon GitHub]]
|
|
||||||
- Konfigurace: =~/.doom.d/config.el= (sekce MATRIX)
|
- Konfigurace: =~/.doom.d/config.el= (sekce MATRIX)
|
||||||
|
- Session soubor: =~/.doom.d/ement-sessions.el=
|
||||||
|
|||||||
169
notes/emacs-new-features.org
Normal file
169
notes/emacs-new-features.org
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
#+TITLE: Doom Emacs — testovací průvodce novými featurami
|
||||||
|
#+DATE: 2026-02-23
|
||||||
|
#+STARTUP: showall
|
||||||
|
|
||||||
|
* link-hint — rychlá navigace po odkazech
|
||||||
|
Umožňuje otevřít nebo zkopírovat jakýkoli odkaz v bufferu pomocí avy-style přeskakování.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
- Buffer obsahuje alespoň jeden odkaz (org link, URL, file path)
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři libovolný org soubor s odkazy (např. =inbox.org=)
|
||||||
|
2. Stiskni =SPC j k= — měly by se objevit avy hinty na všech odkazech
|
||||||
|
3. Vyber hint → odkaz se otevře v prohlížeči/Emacsu
|
||||||
|
4. Stiskni =SPC j K= → vyber odkaz → URL se zkopíruje do clipboard
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- =SPC j k= zobrazí hinty a odkaz se otevře
|
||||||
|
- =SPC j K= zkopíruje URL (ověř přes =C-y= / paste)
|
||||||
|
|
||||||
|
* Avy keybindings — skoky na znaky a řádky
|
||||||
|
Rozšířené avy bindingy pod =SPC j= pro rychlou navigaci v bufferu.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři libovolný soubor s textem
|
||||||
|
2. =SPC j j= → zadej 2 znaky → avy zobrazí hinty na výskytech
|
||||||
|
3. Vyber hint → kurzor skočí na pozici
|
||||||
|
4. =SPC j l= → avy zobrazí hinty na řádcích → vyber řádek
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- Kurzor se přesune na vybranou pozici
|
||||||
|
|
||||||
|
* olivetti-mode — distraction-free psaní
|
||||||
|
Centruje text na šířku 90 znaků pro pohodlné čtení a psaní.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři org soubor — olivetti se zapne automaticky (hook)
|
||||||
|
2. Ověř, že text je vycentrovaný s okraji po stranách
|
||||||
|
3. Otevři markdown soubor — stejné chování
|
||||||
|
4. V jiném režimu (např. elisp): =SPC t o= pro manuální toggle
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- Org/markdown buffery mají centrovaný text na ~90 znaků
|
||||||
|
- =SPC t o= zapíná/vypíná olivetti v libovolném bufferu
|
||||||
|
|
||||||
|
* org-modern — vizuální vylepšení org-mode
|
||||||
|
Nahrazuje hvězdičky nadpisů symboly (◉○✸✿), vylepšuje tabulky a checkboxy.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři org soubor s nadpisy různých úrovní
|
||||||
|
2. Zkontroluj, že =*= jsou nahrazeny symboly ◉, ○, ✸, ✿
|
||||||
|
3. Vytvoř tabulku — měla by mít vylepšený vizuální styl
|
||||||
|
4. Vytvoř checkbox =[X]= / =[ ]= — měl by být stylizovaný
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- Nadpisy používají Unicode symboly místo hvězdiček
|
||||||
|
- Tabulky a checkboxy vypadají vizuálně lépe
|
||||||
|
|
||||||
|
* org-fragtog — automatický render LaTeX fragmentů
|
||||||
|
Při přesunutí kurzoru na/z LaTeX fragmentu se automaticky zobrazí/skryje náhled.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
- LaTeX nainstalovaný (=latexmk= v PATH)
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři org soubor a vlož LaTeX fragment: =$E = mc^2$=
|
||||||
|
2. Přesuň kurzor pryč z fragmentu → měl by se vyrenderovat jako obrázek
|
||||||
|
3. Přesuň kurzor zpět na fragment → zobrazí se zdrojový kód
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- LaTeX fragmenty se automaticky renderují/skrývají při pohybu kurzoru
|
||||||
|
|
||||||
|
* org-super-agenda — skupiny v agenda view
|
||||||
|
Rozděluje agenda view do pojmenovaných skupin: Dnes, Brzy, Čekám, Kyndryl, ZTJ, Ostatní.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
- Existují org soubory s TODO položkami (různé stavy, tagy, deadlines)
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Přidej několik TODO s různými vlastnostmi:
|
||||||
|
- =TODO= s deadline dnes
|
||||||
|
- =TODO= s deadline za 2 dny
|
||||||
|
- =WAIT= položka
|
||||||
|
- =TODO= s tagem =:kyndryl:=
|
||||||
|
- =TODO= s tagem =:ztj:=
|
||||||
|
2. Otevři agenda: =SPC o A a= (nebo =M-x org-agenda=, volba =a=)
|
||||||
|
3. Zkontroluj, že položky jsou rozděleny do skupin
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- Agenda zobrazuje sekce: Dnes, Brzy, Čekám, Projekt Kyndryl, ZTJ, Ostatní
|
||||||
|
|
||||||
|
* org-noter — PDF anotace
|
||||||
|
Umožňuje vytvářet org poznámky synchronizované s pozicí v PDF dokumentu.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
- Existuje PDF soubor k anotování
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři PDF soubor v Emacsu (=pdf-view-mode=)
|
||||||
|
2. =SPC o n= → spustí org-noter session (vytvoří/otevře org soubor)
|
||||||
|
3. Naviguj na stránku v PDF
|
||||||
|
4. =SPC o N= → vloží poznámku na aktuální pozici
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- Emacs se rozdělí horizontálně (PDF vlevo, org vpravo)
|
||||||
|
- Poznámky jsou provázané s pozicí v PDF
|
||||||
|
|
||||||
|
* GPTel rewrite — vylepšení textu přes AI
|
||||||
|
Odešle vybraný region do GPTel s instrukcí "vylepši" a nahradí odpovědí.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
- Env proměnná =OPENWEBUI_API_KEY= je nastavena
|
||||||
|
- AI backend (ai.apps.sukany.cz) je dostupný
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři soubor s textem
|
||||||
|
2. Označ region (=v= + pohyb v evil normal mode)
|
||||||
|
3. =SPC o g r= → region se odešle do GPTel → odpověď nahradí region
|
||||||
|
4. V org souboru: umísti kurzor na heading, =SPC o g p= → heading + obsah se odešle jako kontext do GPTel chatu
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- =SPC o g r= nahradí vybraný text vylepšenou verzí
|
||||||
|
- =SPC o g p= otevře GPTel chat s obsahem heading jako kontextem
|
||||||
|
|
||||||
|
* git-link — kopírování URL na Gitea
|
||||||
|
Generuje webový odkaz na aktuální soubor/řádek v Gitea repozitáři.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
- Soubor je v git repozitáři s remote na =git.apps.sukany.cz=
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři soubor v git repozitáři (např. v emacs-doom)
|
||||||
|
2. =SPC g y= → zkopíruje URL na aktuální soubor/řádek do clipboard
|
||||||
|
3. =SPC g Y= → zkopíruje URL na aktuální commit
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- URL v clipboard ukazuje na =git.apps.sukany.cz/...= a je funkční v prohlížeči
|
||||||
|
|
||||||
|
* Forge — Gitea integrace v Magitu
|
||||||
|
Přidává podporu pro Gitea issues, PRs a notifikace přímo v Magit.
|
||||||
|
|
||||||
|
** Prerekvizity
|
||||||
|
- =doom sync= proběhl úspěšně
|
||||||
|
- Gitea API token vytvořen a uložen v =~/.authinfo=:
|
||||||
|
: machine git.apps.sukany.cz login daneel^forge password <TOKEN>
|
||||||
|
|
||||||
|
** Jak otestovat
|
||||||
|
1. Otevři Magit v repozitáři hostovaném na Gitea: =SPC g g=
|
||||||
|
2. Stiskni =N= (forge notifications) nebo ='= (forge dispatch)
|
||||||
|
3. =@ l l= — list issues
|
||||||
|
|
||||||
|
** Ověření
|
||||||
|
- Forge se připojí ke Gitea API a zobrazí issues/PRs
|
||||||
|
- Pokud token chybí, Forge zobrazí chybu s instrukcí
|
||||||
Reference in New Issue
Block a user