Następna strona Poprzednia strona Spis treści

5. Delete i Backzspace

Nakłonienie Delete i Backspace do prawidłowej pracy jest wcale trywialne, zwłaszcza w środowisku mieszanym, gdzie komunikujesz się z konsolą, z X, bash, emacsem, logujesz się zdalnie itd. Może będziesz musiał wyedytować kilkanaście plików konfiguracyjnych żeby powiedzieć wszystkim konkretnym programom czego dokładnie chcesz. Z jednej strony problemem jest jakie klawisze wypisują jakie kody (i jak te kody przetrawia kermit czy emacs), a z drugiej strony jakie funkcje są przypisane jakim klawiszom.

Ludzie często skarżą się "mój klawisz wstecznej spacji nie działa", jak gdyby ten klawisz miał wbudowaną funkcję "skasuj poprzedni znak". Niestety wszystko co ten, albo każdy inny, klawisz robi to wypisanie kodu, i można tylko mieć nadzieję że sterownik tty jądra i wszystkie aplikacje można tak skonfigurować że klawisz wstecznej spacji rzeczywiście działa jako klawisz kasujący poprzedni znak.

Większość unixowych programów otrzymują swoje dane wejściowe tty przez sterownik tty jądra w trybie "niesurowym", i zwykłe polecenie stty ustala znak kasujący. Jednak programy takie jak bash, emacs czy X przetwarzają dane wejściowe własnymi metodami, i muszą być każde z osobna przekonane do właściwego działania.

5.1 Jak powiedzieć Unixowi jakiego znaku chcesz używać żeby skasować ostatnio napisany znak?

% stty erase ^?

Jeśli znak jest kasowany, ale w dziwny sposób, coś jest nie w porządku z twoimi ustawieniami tty. Jeśli ustawione jest echoprt, kasowane znaki ujęte są między \ oraz /. Jeśli echoe nie jest ustawione, znak kasowania jest wypisywany (co jest rozsądne w przypadku gdy jest to znak drukujący, jak #). Większość ludzi woli stty echoe -echoprt. Napisanie stty sane zrobi to i więcej. Napisanie stty -a pokazuje bieżące ustawienia. Jak to się stało że domyślnie nie były poprawne? Będą, jeżeli użyjesz poprawnego getty.

Zauważ że wiele programów (jak bash, emacs itd.) mają swoje własne przypisania klawiszy (zdefiniowane w ~/.inputrc, ~/.emacs itd.) i nie wpływa na nie ustawienie znaku kasowania.

Standardowy unixowy sterownik tty nie rozpoznaje kursora, ani klawiszy (takich jak klawiszy strzałek) przesuwających bieżącą pozycję, i stąd nie ma też komendy takiej jak "skasuj bieżący znak". Ale na przykład możesz nauczyć bash na konsoli rozpoznawania Delete wstawiając

set editing-mode emacs
"\e[3~":delete-char

do ~/.inputrc

"Kiedyś getty dobrze oddawało DEL i BS, ale teraz się popsuło"

Dawniej, sterownik konsoli zwykle wypisywał BS-spacja-BS (\010\040\010) gdy otrzymał znak DEL (\177). Dzisiaj, znaki DEL są ignorowane (tak jak powinny, ponieważ sterownik emuluje vt100). Zdobądź lepsze getty, tj. takie które nie wypisuje DEL.

"Login zachowuje się inaczej przy pierwszej i drugiej próbielogowania"

Przy pierwszej próbie, komunikujesz się z getty. Przy drugiej próbie, komunikujesz się z login, innym programem.

5.2 Jak powiedziec Linuxowi jaki kod wysyłać po naciśnięciu klawisza

Na konsoli lub, ściślej, gdy nie jesteś w trybie (pół)surowym, użyj

% loadkeys mykeys.map

A pod X użyj

% xmodmap mykeys.xmap

[gdzie mykeys.(x)map to oczywiście konkretny plik definicji klawiatury - przyp. tłum.]

Zauważ że (od XFree86-2.1) X czyta linuxowe ustawienia układów klawiatury przy initializacji Xowego keymap. Chociaż oba systemy nie są w 100% kompatybilne, oznacza to że w wielu przypadkach używanie xmodmap> stało się zbędne. Załóżmy, na przykład, że chcesz żeby twój klawisz Backspace dawał wsteczną spację (^H, ósemkowe 010), a szary klawisz Delete DEL (ósemkowe 012), dodaj poniższe do etc/rc.local (albo tam gdzie trzymasz swoje pliki inicjalizacyjne).

/usr/bin/loadkeys << EOF
keycode 14 = BackSpace
keycode 111 = Delete
EOF

Zauważ że zmieni to funkcję tych klawiszy tylko gdy nie używa się modyfikatorów. Domyślnie jądro Linuxa pozwala Ctrl-Backspace wypisywać wsteczną spację - czasami przydaje się to jako zapasowe wyjście, gdy stwierdzisz że możesz wypisywać tylko znaki DEL.

Lewy klawisz Alt jest czasem zwany klawiszem Meta, a domyślnie kombinacje AltL-X są przypisane do symbolu Meta-X. Ale jakim ciągiem znaków jest Meta-X? Ustalane jest to (via tty) przez znacznik Meta, ustawiony komendą setmetamode. Dwiema możliwościami są: Esc X albo X iloczyn logiczny 0200.

Dlaczego klawisz Backspace nie wysyła domyślnie wstecznejspacji?

(i) Ponieważ vt100 miał klawisz Delete nad klawiszem Enter.

(ii) Bo Linus tak postanowił.

5.3 Jak nakazać X zamianę Delete i Backspace

% xmodmap -e "keysym BackSpace = Delete" -e "keysym Delete = BackSpace"

Albo, jeśli chcesz tylko żeby klawisz Backspace dawał wsteczną spację:

% xmodmap -e "keycode 22 = BackSpace"

Albo, jeśli chesz tylko żeby klawisz Delete dawał Delete:

% xmodmap -e "keycode 107 = Delete"

(ale zwykle takie jest już domyślne przypisanie).

5.4 Jak powiedzieć emacsowi co robić gdy otrzyma Delete lub wsteczną spację

Wsadź do swojego pliku .emacs linie jak niżej:

  (global-set-key "\?" 'delete-backward-char)
  (global-set-key "\C-h" 'help-command)

Oczywiście możesz w ten sam sposób przypisać inne polecenia innym klawiszom. Zauważ że niektóre tryby główne i poboczne redefiniują przypisania klawiszy. Na przykład w trybie szukania przyrostowego [incremental mode] można znaleźć kod:

(define-key map "\177" 'isearch-delete-char)
(define-key map "\C-h" 'isearch-mode-help)

Oznacza to że używanie dwóch powyższych komend globalnych może nie być dobrym pomysłem. Za dużo jest miejsc z wbudowanym założeniem ^H = pomoc i Del = delete. Nie oznacza to że musisz ustawić klawisze tak żeby Backspace dawało Del. Ale jeśli tak nie jest, najłatwiej jest zmienić ich układ na najniższym możliwym poziomie emacsa.

5.5 Jak nakazać emacsowi zamienienie Delete i Backspace

Wsadź do swojego pliku .emacs linie jak niżej:

  (setq keyboard-translate-table (make-string 128 0))
  (let ((i 0))
  (while (< i 128)
      (aset keyboard-translate-table i i)
      (setq i (1+ i))))
  (aset keyboard-translate-table ?\b ?\^?)
  (aset keyboard-translate-table ?\^? ?\b)

Ostatnie wersje emacsa mają funkcję keyboard-translate, więc można uprościć powyższe do

(keyboard-translate ?\C-h ?\C-?)
(keyboard-translate ?\C-? ?\C-h)

Zauważ że pod X emacs może rozróżniać Ctrl-h i klawisz Backspace (niezależnie od tego jakie kody oba wypisują na konsoli), a domyślnie emacs będzie widział klawisz wstecznej spacji jako DEL (wykonujący polecenia kasowania, przypisane temu znakowi, a nie polecenia pomocy, przypisane do ^H). Można rożróżniać Backspace i Delete, np. poprzez

  (global-unset-key [backspace] )
  (global-set-key [backspace] 'delete-backward-char)
  (global-unset-key [delete] )
  (global-set-key [delete] 'delete-char)

5.6 Jak nakazać kermitowi zamienienie Delete i Backspace

Wsadź do swojego pliku .kermrc linie jak niżej:

  set key \127 \8
  set key \8 \127

5.7 Jak poinformować xterm o twoich ulubionych trybach tty

Xterm dziedziczy zwykle tryby tty po programie który go wywołał. W xdm, domyślne klawisze kasowania i usuwania to # i @, jak w starej dobrej wersji 6 Unixa. Jeśli nie podoba ci się to, możesz wsadzić coś podobnego do

  XTerm*ttymodes: erase ^? kill ^U intr ^C quit ^\ eof ^D susp ^Z start ^Q stop ^S eol ^@

do /usr/lib/X11/app-defaults/XTerm albo do $HOME/.Xresources, zakładając że masz linię

  xrdb $HOME/.Xresources

w swoim $HOME/.xinitrc.

5.8 Jak poinformować xmosaic że klawisz Backspace wypisuje Del

Wsadzenie

  *XmText.translations: #override\n\
         <Key>osfDelete: delete-previous-character()
  *XmTextField.translations: #override\n\
          <Key>osfDelete: delete-previous-character()

do twojego $HOME/.Xresources pomoże.

W Netscape FAQ można jednak przeczytać:

        Dlaczego mój klawisz Backspace nie działa w polach tekstowych?
        Domyślnie, Linux i XFree86 dostarczane są ze źle skonfigurowanymi
        klawiszami Backspace i Delete. Wszystkie programy oparte na Motif
        (w tym oczywiście Netscape Navigator) będą w ten sam sposób źle
        działać.

        Specyfikacja Motif mówi że Backspace ma kasować poprzedni znak a
        Delete ma kasować znak następny. Linux i XFree86 są dostarczane
        z takim ustawieniem że oba klawisze - Backspace i Delete - wypisują
        Delete.

        Możesz to naprawić używając któregoś z programów xmodmap, xkeycaps
        bądź loadkeys i sprawić że odpowiedni klawisz wypisuje klawsym
        wsteczna spacja, a nie Delete.

        Możesz to również naprawić używając pliku .motifbind; patrz
        strona man VirtualBindings(3).

        Uwaga: nie używaj zasobów *XmText.translations lub *XmTextField.
        translations próbując naprawić ten problem. Jeśli tak zrobisz,
        rozwalisz pozostałe przypisania klawiszy w polach tekstowych NN.

5.9 Lepsze rozwiązanie dla programów używających Motifa, jak netscape

Ted Kandell (ted@tcg.net) sugeruje co następuje:

Dodaj poniższe gdzieś w swoim .profile:

  stty erase ^H

Jeśli używasz basha, dodaj poniższe linie do swojego .inputrc:

       "\C-?": delete-char
       "\C-h": backward-delete-char

Dodaj następujące linie do swojego pliku .xinitrc:

       xmodmap <<-EOF
       keycode 22  =  BackSpace osfBackSpace
       keycode 107 =  Delete
       EOF

       # wystartuj tu swojego managera okien, np.
       #(fvwm) 2>&1 | tee /dev/tty /dev/console

       stty sane
       stty erase ^H
       loadmap <<-EOF
       keycode 14  = BackSpace
       keycode 111 = Delete
       EOF

Będzie to definitywnie działać dla klawiatury PC 101 lub 102-klawiszowej, z każdym rozkładem Linuxa/XFree86.

Ważną częścią uczenia aplikacji motifowych takich jak Netscape poprawnej pracy jest dodanie osfBackSpace do keycode 22, oprócz BackSpace.

Zauważ nie po obu stronach znaku = nie mogą się znajdować spacje.

5.10 Co z termcap i terminfo?

Gdy ktoś ma problemy z wsteczną spacją, ma on tendencję do patrzenia w swój kawałek termcap (lub terminfo) opisujący terminal; i rzeczywiście, istnieje tam zdolność kb (lub kbs) opisująca kod wypisywany przez klawisz Backspace. Niemniej niewiele programów jej używa, więc - chyba że masz problemy z jednym konkretnym programem - prawdopodobnie błąd leży gdzie indziej. Oczywiście poprawienie swojego kawałka termcap (terminfo) nie jest złym pomysłem tak czy owak. Patrz niżej pod "Zmienna TERM".


Następna strona Poprzednia strona Spis treści