En Emacsfeature varje dag

From Carls wiki

Jump to: navigation, search

I början av sommaren 2007 gav jag mig på att lära mig Emacs ordentligt, lite varje dag. Det här är de mail jag skickade ut under den perioden.

Contents

Policy

Hela maj 2007, bara Emacs när jag skriver texter, inklusive till längre mail, om inte speciella omständigheter råder. Definitivt Emacs i jobbsituationer, och nxml i samband med XML och HTML. Varje dag skriver jag något litet om vad nytt jag har lärt mig, så att jag inte stagnerar utan utvecklas hela tiden.

(Maj förlängdes sedan till juni, och blev efter det mer eller mindre konstant. Nu använder jag Emacs mer än vi.)

Daglig rapport

1 maj

Jag har suttit så länge i vim att jag känner mig lite obekväm i Emacs. Måste tänka lite extra när jag ska spara ett utkast av ett mail, så att jag inte skriver ZZP utan C-x C-s C-x C-c P... mutt känns mer anpassat för vim än för Emacs.

Har redan lärt mig (igen) hur man justerar ett stycke: M-q. (Jämför detta med vims gq} — något mindre Huffmankodat, åtminstone jämfört med de andra funktionerna i vim.)

Jag gillade inte kolumnbredden som Emacs justerade till, så jag lade till det här i .emacs:

(setq-default default-fill-column 79)

Åh, och jag saknade Item 3 så mycket i steveys Effective Emacs att jag lade till detta i .emacs också:

(global-set-key "\\C-w" 'backward-kill-word)
(global-set-key "\\C-x\\C-k" 'kill-region)
(global-set-key "\\C-c\\C-k" 'kill-region)

Bara för att jag överger vim så måste jag ju inte överge de riktigt bra kortkommandona (som dessutom är standard lite varstans). Emacs är ju programmerbar av en anledning.

David påminde mig om C-u, en trevlig funktion för att upprepa saker. Hehe, i vim är syntaxen för samma handling tomma strängen, svårt att slå den Huffmankodningen. C-u utan numeriskt argument defaultar till 4, och man kan stapla C-un efter varandra.

2 maj

Jag saknar redan Ctrl+P och Ctrl+N från vim. Måste hitta hur man gör motsvarande i Emacs.

3 maj

Johan skrev:

Jag har hittat C-p för Emacs:

dabbrev-expand (från dynamic-completion-mode).

Standard bindningen är M-/, vilket kanske inte är så där super med
svensk tangentbordslayout.

Ska se om jag kan göra nåt åt det där med M-/. Annars är väl inte engelskt tangenbord så illa heller. Gnome byter till och med automatiskt mellan olika fönster.

Nu har jag lagt in följande bindningar i min .emacs-inställningsfil:

(global-set-key "\\M-p"     'dabbrev-expand)
(global-set-key "\\M-n"     'dabbrev-expand)

Det blev alltså metaknappen, dvs alt på mitt tangentbord, som fick göra jobbet. Förhoppningsvis inte alltför svårt att lära om. Det är lite synd att M-p och M-n i nuläget gör exakt samma, särskilt eftersom dabbrev-expand är ett sånt kommando som man kan ge ett negativt argument så söker det framåt istället... men jag hittade inget sätt att kunna skicka med parametrar till den metod man vill binda till. Förhoppningsvis har jag lärt mig inom någon vecka hur detta är tänkt att göras. TIlls vidare är M-- M-n ett hyfsat kort alternativ.

Jag måste fixa så att man kan redigera wikin inifrån Emacs!

4 maj

Jag är i promiskuöst läge nu vad gäller Emacs, och surfar runt lite och kollar vad andra har gjort och klistrar in det i min inställningsfil.

I dag blev den den här sidan.

Här är dagens tillägg från den. Jag har tagit russinen ur kakan och formaterat dem snyggt med ;;-kommentarer.

(setq inhibit-startup-message t)  ;; will inhibit startup messages.

(setq require-final-newline t)    ;; will make the last line end in a
                                  ;; carriage return.

(require 'paren) (show-paren-mode t) ;; will highlight matching
                                     ;; parentheses next to cursor.

(setq-default indent-tabs-mode nil)  ;; will introduce spaces instead
                                     ;; of tabs by default.

(setq query-replace-highlight t)      ;; will highlight during query.

(setq search-highlight t)             ;; highlight incremental search

(setq default-major-mode 'text-mode)  ;; will make text-mode default.

(global-font-lock-mode t t)           ;; means that we want
                                      ;; fontification in all modes.

(setq font-lock-maximum-decoration t) ;; denotes our interest in
                                      ;; maximum possible
                                      ;; fontification.

(type-break-mode)                     ;; get intermittent messages to
                                      ;; stop typing

(setq enable-recursive-minibuffers t) ;; allow recursive editing in minibuffer
(resize-minibuffer-mode 1)            ;; minibuffer gets resized if it becomes too big
(follow-mode t)                       ;; follow-mode allows easier
editing of long files

(require 'uniquify)
(setq uniquify-buffer-name-style 'reverse)

(set-background-color "dark slate gray")
(set-foreground-color "blanched almond")

(setq kill-whole-line t)     ;; will make "Ctrl-k" kills an entire
                             ;; line if the cursor is at the beginning
                             ;; of line -- very useful.

(setq c-hungry-delete-key t) ;; will delete "hungrily" in C mode! Use
                             ;; it to see what it does -- very useful.

(setq c-auto-newline 1)      ;; will let emacs put in a
                             ;; "carriage-return" for you
                             ;; automatically after left curly braces,
                             ;; right curly braces, and semi-colons in
                             ;; "C mode" -- very useful.

(add-hook 'c-mode-common-hook
        '(lambda ()
           (turn-on-auto-fill)
           (setq fill-column 80)
           (setq comment-column 60)
           (modify-syntax-entry ?_ "w")       ; now '_' is not
                                              ; considered a
                                              ; word-delimiter
           (c-set-style "ellemtel")           ; set indentation style
           (local-set-key [(control tab)]     ; move to next tempo mark
                          'tempo-forward-mark)
           ))

(global-set-key [f12]         'dabbrev-expand)
(define-key esc-map [f12]     'dabbrev-completion)

;; "funky stuff" ;; proceed with caution

(setq my-key-pairs
    '((?! ?1) (?@ ?2) (?# ?3) (?$ ?4) (?% ?5)
      (?^ ?6) (?& ?7) (?* ?8) (?( ?9) (?) ?0)
      (?- ?_) (?\\" ?') (?{ ?[) (?} ?])         ; (?| ?\\\\)
      ))

(defun my-key-swap (key-pairs)
 (if (eq key-pairs nil)
    (message "Keyboard zapped! Shift-F10 to restore!")
    (progn
      (keyboard-translate (caar key-pairs)  (cadar key-pairs))
      (keyboard-translate (cadar key-pairs) (caar key-pairs))
      (my-key-swap (cdr key-pairs))
      )
  ))

(defun my-key-restore (key-pairs)
 (if (eq key-pairs nil)
    (message "Keyboard restored! F10 to Zap!")
    (progn
      (keyboard-translate (caar key-pairs)  (caar key-pairs))
      (keyboard-translate (cadar key-pairs) (cadar key-pairs))
      (my-key-restore (cdr key-pairs))
      )
  ))

(global-set-key [C-delete]    'kill-word)
(global-set-key [C-backspace] 'backward-kill-word)

(split-window-horizontally)   ;; want two windows at startup
(other-window 1)              ;; move to other window
(shell)                       ;; start a shell
(rename-buffer "shell-first") ;; rename it
(other-window 1)              ;; move back to first window

En trevlig grej med M-q är att den sköter kommentarer väldigt automatiskt. Känns bättre än vim, åtminstone vims default.

Ah, och jag har fixat så att M-p är komplettering bakåt och M-n komplettering framåt nu -- det lärde jag mig också på den sidan. Så här ser det ut:

(global-set-key "\\M-p"     'dabbrev-expand)
(global-set-key "\\M-n"     '(lambda () (interactive) (dabbrev-expand -1)))

Lambda alltså. Känns som en hyfsat ren lösning.

Johan skrev även:

Kan vara intressant:

 <http://emacs.traduc.org/fusion/info/autotype/>

Där fanns hippie-expand med också (den där eclipse expansionen som
visst verkar vara en klon av emacs hippie-expand)

5 maj

Idag blir ett kort inlägg från mig, för jag vill hem och äta. :) Jag har lagt in följande i min .emacs-inställningsfil:

(setq make-backup-files         nil) ; Don't want any backup files
(setq auto-save-list-file-name  nil) ; Don't want any .saves files
(setq auto-save-default         nil) ; Don't want any auto saving

Jag vill inte ha en massa backupfiler som strösslas ut i filstrukturen. Jag har svn.

(Att göra: ta reda på hur väl Emacs och svn leker med varandra numera.)

6 maj

Johan skrev:

Det här med att utforska emacs var ju kul.

Att använda skeletons tillsammans med abbrev är kraftfullt. Ett
skeleton är ett slags makro för att sätta in fördefinierad text,
medans man kan använda abbrevs för att automatkomplettera på exakt det
sättet som OO.o gör (fast utan att man ser vad det kommer att
automatkomplettera till).

Exempel för perl-programmering. Jag vill när jag skrivit "foreach" att
det skall utvecklas till hela foreach loopen med hjälp att fylla i
loop-variabel och looplista och sedan hamna i foreachloopens kropp.

; är kommentars-tecknet i elisp.

Skeleton-definition:

(define-skeleton perl-skeleton-foreach ; det här är namnet
   "Insert a foreach loop" ; beskrivning (om jag tolkat det rätt)
   "Loop variable: "  ; den här frågan kommer att skrivas ut i minibuffern
   > "foreach my $" str " (" ("Loop over: " str ", ") -2 ") {" \\n
   _ \\n                      ; När skeletonet är färdigprocessat, sätt markören här (_).
   -4 "}" \\n
)

Ok, de rader jag inte kommenterat innehåller den text som kommer att
sättas in. str ersätts av den texten man skriver som svar på frågan i
minibuffern. Det verkar som att första frågan efter str slutar
processas direkt medans de efterföljande processas tills man skriver
in tomma strängen.

Nu kan man anroppa det här skeletonet med M-x perl-skeleton-foreach.
Men det tar tid, bättre att automatanropa det när man skriver
"foreach". Detta görs så här:

(eval-after-load "perl-mode" ; Vill bara ha makrot när vi proggar perl
   '(define-abbrev-table 'perl-mode-abbrev-table '( ; Lägg till i abbrev i rätt abbrev-tabell
 ("foreach" "" perl-skeleton-foreach) ; skrivning av foreach skall anropa perl-skeleton-foreach
)))

Mallen för abbrevet är följande:
("förkortning" "expansion" hook)

Här vill vi inte ha någon expansion, vi anropar en hook istället.

Det här kallar jag jurre burre.

Tror jag skall definiera massor av makron som expanderar till små
trevliga saker. För mer godis se:

<http://www.perlmonks.org/?node_id=116951>
<http://www.emacswiki.org/cgi-bin/emacs-en/AbbrevMode>
<http://www.emacswiki.org/cgi-bin/emacs-en/SkeletonMode>

Angående svn etc:

Tja, det verkar finnas något som heter vc-svn installerat i Emacs redan... det funkar för att committa i alla fall (jag har provat).

Men den bästa nyheten är att knappkombinationen C-x v v är bunden till funktionen vc-next-action, som beskrivs så här i dokumentationen: "Do the next logical version control operation on the current file."

/me ♥ Emacs

(Det innebär dock inte att jag inte vill veta exakt vad den där funktionen gör i olika sammanhang, bara för att vara på den säkra sidan.)

7 maj

Idag kände jag vad jag saknade i Emacs: en motsvarighet till dt<tecken>, där "<tecken>" är ett skrivtecken, vilket som helst. I vim kan man göra detta, med effekten att allting försvinner mellan markören fram till (men inte inklusive) nästa förekomst på raden av det tecken man skrev in. Mycket praktiskt.

Går det at få? Antar att det är svårt att fixa lika smidigt, men jag är nöjd med förslag som bara kräver någon knapptryckning ytterligare också.

8 maj

Hittade det, och det är ungefär lika smidigt: funktionen zap-to-char är bunden till M-z. Wohoo!

9 maj

Ibland förvandlas idyllen till en dystopi. zap-to-char gör två saker fel:

  1. Den är okänslig för storbokstavighet. (Uppdatering: Ok, det berodde enligt dokumentationen på en variabel som heter case-fold-search. Ställer man om den till nil så löser det sig. Det andra problemet kvarstår dock.)
  1. Den tar bort till och med tecknet man skickar in som parameter,

inte bara till tecknet.

Nu vill jag binda M-z till en ny funktion som gör det jag vill. Hur hittar man källkoden till zap-to-char?

11 maj

Idag gjorde jag det enkelt för mig och anammade det första tipset i Yegges Emacs-tipslista.

Adjöss Caps Lock. Nu har jag tre Ctrl istället.

En till grej: jag har insett att jag -- ursäkta uttrycket -- tycker väldigt illa om type-break. Så jag plockade bort de här raderna ur .emacs igen:

(type-break-mode)                     ;; get intermittent messages to
                                      ;; stop typing

Jonathan tycker att jag är underlig som hoppar tillbaka och börjar använda Emacs just när jag har övertygat honom om vims förträfflighet och han själv har börjat använda det. Men jag tror att livet handlar om en balans mellan vim och Emacs. Och det har varit rätt mycket vim för min del på sistone.

12 maj

Funktionen c-toggle-auto-newlines är bra att känna till om man inte vill att Emacs automatiskt ska sätta ens öppnande klamrar på nästa rad när man skriver in dem. (Jag indenterar enligt BSD, inte enligt K&R.) Vilket läge man är inne i när man skriver sin kod indikeras på statusraden med "Java/lh" om funktionen är avstängd och "Java/lah" om funktionen är på.

picture-mode verkar kul. Textytan blir en stor rityta istället -- det är fortfarande tecken man skriver, men ytan är oändlig nedåt och åt höger. Man kan ställa om skrivriktningen till vilken som helst av fyra rektilinjära riktningar och fyra diagonala.

13 maj

Nu har jag lyckats installera psvn, och det verkar mycket bättre än vc-svn. Jag vet mer när jag har använt det i några dagar.

23 maj

Kolla in SXEmacs — man ska inte hävda att Emacs vanilj gör allt och lite till, innan man har läst beskrivningen av SXEmacs...

1 juni

Jag har upptäckt hur man matar in kinesiska tecken i Emacs! Rena himmelriket. Så nu blir mitt eget inmatningsprogramsprojekt lite mindre akut. (Ska nog göra det till en webbapp istället så att jag kan mata in kinesiska tecken på vilken nätansluten dator som helst istället.) Det finns både möjligheter att mata in tecken baserat på tecknens utseende och på tecknens uttal. (Jag behöver skapa ett snabbkommando för att kunna byta snabbt mellan dessa. Och dessutom för att kunna byta till och från latinsk text.)

Det är sådana här saker som gör Emacs helt oslagbart. Det känns väldigt solitt och genomtestat. Inmatning av esperantobokstäver med hattar (ĉĝĥĵŝ): bara att skriva cirkumflex + bokstav som man skulle ha gissat. Funkar inte i Firefox, så jag fick markera och mittenklistra. :) Hur man skriver ŭ har jag inte listat ut än.

Jag har börjat använda shell mer i Emacs. Hyfsat bra när man inser och vänjer sig vid dess begränsningar. Dessa vägs upp till stor del av att bufferten fungerar som vilken annan textbuffert som helst i Emacs, vilket är trevligt.

Jag har bestämt mig för att förlänga prövotiden av Emacs till att innefatta juni månad också. Jag har varit för distraherad under maj med plugg. Heh, jag har ju inte ens börjat ta en ordentlig titt på Elisp ännu. :)

8 juni

Titta vad jag hittade:

Emacs for Vi Programmers
<http://grok2.tripod.com/>

Snubblade på denna sida i mitt sökande efter en bra metod för att hoppa till en given rad i ett program. Hur kan det inte finnas en snabb knappkombination för att hoppa till en rad i en buffert i default-Emacs? Jag har blivit så van vid det från vi att fingrarna inte vet vad de ska ta sig till. Enligt sidan finns visserligen

M-x goto-line RET 92

men det är 15 knapptryckningar, 12 om man räknar snällt (det går att tabbkomplettera på två ställen för att det ska gå snabbare). I vim behövs fyra:

92gg

Jag vill inte kasta bort mitt liv på att utföra långa repetitiva rörelser på tangentbordet. Jag vill ha en knappbindning för goto-line, så att jag åtminstone kan skriva

C-u 92 <bindning>

Då börjar vi snacka, fem till sju knapptryckningar, redan halverat.

...Det är bara det att jag inte kommer på någon bra knappbindning. C-g används redan till annat, och C-l också. (Det är när man letar efter lediga knappbindningar som man inser hur mycket Emacs innehåller redan.) Nån som har ett förslag?

14 juni

Två saker jag verkligen saknar från vi: Ctrl+Y (den berömda "måla schackrutigt"-knappen, som kopierar tecken från raden ovanför) och J (magisk ersättning av nyraden i slutet av raden (oavsett var på den man står), plus allt whitespace på nästa rad, mot ett enda mellanslag. Blir en sorts bakvänd Enter med indentering).

Jag har förresten planer på att skriva en Elisp-funktion som gör att man kan göra vissa Excel-liknande grejer i Emacs.

17 juni

Jag har kört Emacs en del i textterminalläge de senaste dagarna. Dels lite för att vänja mig vid känslan, dels för att jag arbetar fjärrt på IBGs webbserver, som jag inte vill sega ned genom att tunnla X.

gnome-terminal, min absoluta favoritterminalemulator här i världen, stjäl en del tangentbindningar (framförallt M-n som jag har bundit till "nästa ord i filen som börjar så här", men som får gnome-terminal att öppna menyn "Tabs" -- ah, hittade var man stängde av det) och blockerar andra, framförallt kombinationer av Ctrl och riktningstangenter (vilket inte nödvändigtvis är gnome-terminals fel faktiskt, det kan vara ssh-uppkopplingen som ställer till det).

Jag försöker vänja mig vid att ha Ctrl uppe under Tab, men gamla hundar sitter i mossen. Det är dock mycket bekvämare när man kommer ihåg det.

Kommandot `shell` i Emacs har jag använt mig av flitigt*. Det är faktiskt väldigt trevligt när man binder om vissa knappkombinationer i huvudet. I grunden är det en vanlig Emacs-buffert, det vill säga man kan gå in och ändra var som helst i den, kopiera och klistra som man vill, osv. Men Emacs fetlägger dessutom alla kommandon man skriver, färgkodar kommandoflaggor, prompter och output till stderr, samt vissa vanligt förekommande format som unifierade diffar. Det är säkert konfigurerbart, dessutom. Eftersom pilarna numera navigerar i bufferten får man lära sig att använda M-p och M-n för att bläddra i kommandohistoriken.

Tabkomplettering fångas av Emacs och Bara Funkar. Om man skriver på nästa kommando medan det förra fortfarande kör så låter Emacs raden man skriver på följa med utan att kontaminera outputen som produceras under tiden. Fantastiskt. Lösenord fångas av Emacs och Bara Funkar.

* Kommandot `shell` i Emacs har jag använt mig av flitigt. Måste dock erkänna att impulsen att skriva `vi $fil` sitter kvar, och gör man det får man se lite väl mycket av vilka kontrollsekvenser vi skickar till terminalen. Så jag skrev just

alias vi="echo use emacs to edit "

i min Emacs-terminal.

(`less` funkar, men på ett lite annat sätt, nån form av fattigmansläge. Behovet av `less` i Emacs är dock inte jättestort.)