Göm menyn

Emacs

Vad är Emacs?

Emacs är en programvara som vanligtvis används för att skriva och redigera text i olika former. Det går dock att göra betydligt mer saker. Exempel på sådant är att spela tetris och skicka mail. Anledningen till att Emacs kan göra så många saker är att programmet går att utöka med Emacs egna språk Emacs Lisp, en variant av Lisp. Detta gör att Emacs är särskilt väl anpassat för att skriva programkod i och med att texteditorn kan förändras för olika programspråk. I det här dokumentet presenterar vi några inställningar som kan göra Emacs mer användbart för er när i programmerar i det.

Frame, Window och Buffer

I Emacs finns det tre olika delar av det grafiska gränssnittet som är grundläggande för hur man använder Emacs. De är frame, window och buffer. Frame är, förvirrande nog, ett grafiskt fönster som Emacs använder sig av. Window är en grafisk del av en frame i vilken man kan visa olika buffers. En buffer är, till skillnad från de övriga, inte något grafiskt utan ett logiskt utrymme där olika filer kan visas, editeras eller köras (till exempel är de Python-filer som ni skriver i en buffer per fil och tetrisspelet är även det en buffer). Utöver de buffers som har ens textfiler finns det även en minibuffer vilken används för att ge indata till Emacs-kommandon (till exempel M-x som beskrivs nedan) och ge information till användaren.

Det hela kan enkelt bli lite bökigt när man beskriver det med ord, men ta en titt på exemplet nedan så klarnar det förhoppningsvis.

Emacs layout

Kortkommandon

I Emacs finns det väldigt många olika kortkommandon för att utföra olika funktioner. Det gör att man som användare kan utföra saker väldigt fort när man väl har lärt sig de olika kommandona. Tyvärr gör det även att Emacs kan vara ganska långsamt innan man har lärt sig var kortkommandona finns. Men när man har tagit sig förbi den tröskeln går det istället väldigt fort.

Kortkommandona i Emacs bygger på att man använder metaknappen (M) och kontrollknappen (C) i kombination med andra bokstäver på tangentbordet. Vidare kan ett kortkommando bestå av en sekvens av dem. Ett exempel är kortkommandot för att spara den aktuella filen i Emacs: C-x C-s. Vilket betyder håll ner kontrollknappen och tryck på x följt av håll ner kontrollknappen och tryck på s.

Skulle man glömma bort ett kommando i Emacs kan man använda sig av M-x kommandot vilket öppnar en prompt i minibuffern. Där kan man skriva in namnet på kommandot man vill använda. Ett exempel är M-x replace-string, vilket är en search-and-replace funktion.

Nedan är ett par tabeller med några av de vanligare kommandona man kan tänkas vilja använda i Emacs:

Spara och öppna

Kortkommando Beskrivning
C-x C-f Öppna en fil (skapar filen om den inte finns) i det aktuella fönstret
C-x C-s Sparar filen i den aktuella buffern
C-x C-m f Sätter vilken teckenkodning (eng. charset) som ska användas i den aktuella buffern
C-x C-c Avsluta Emacs

Förflyttning av markör

Kortkommando Beskrivning
C-f Flytta markören ett steg åt höger
C-b Flytta markören ett steg till vänster
C-n Flytta markören ett steg ner
C-p Flytta markören ett steg upp
C-a Flytta markören till början av raden
C-e Flytta markören till slutet av raden
M-g M-g Flytta markören till raden som du ger som indata
M-< Flytta markören till början av filen
M-> Flytta markören till slutet av filen

Frame, Window och Buffer

Kortkommando Beskrivning
C-x 3 Dela aktuellt window vertikalt i två
C-x 2 Dela aktuellt window horisontellt i två
C-x o Byt vilket window som är aktivt
C-x 0 Stäng aktuellt window
C-x 1 Stäng alla andra window
C-x b Byt buffer genom att skriva in namnet
C-x -> Byt buffer ett steg till höger i bufferlistan
C-x <- Byt buffer ett steg till vänster i bufferlistan

Copy, cut, paste och edit

Kortkommando Beskrivning
C-blankspace Sätt början av markering (markör ej på början av markering) eller avsluta markering (markör på början av markering)
C-w Klipp markerad text
C-y Klistra in markerad text
M-w Kopiera markerad text
C-k Klipp ut allt på raden från markörens position
C-d Ta bort tecknet som markören står på
C-m Ett annat kommando för radbrytning
C-_ eller C-/ eller C-u Ångra
M-x replace-string Byter ut alla träffar från markörens nuvarande position av den första strängen mot den andra strängen

Konfigurering

Som nämnt innan kan Emacs användas till väldigt mycket och på olika sätt. Det beror på att Emacs kan utökas med egenskriven kod (i Emacs lisp), men då uppstår frågan om hur Emacs vet vilken kod som ska läsas in? För att lösa det här problemet har man i Emacs en reserverad fil som kallas för .emacs och är placerad i hemkatalogen (precis som för bash terminalen, .bashrc, och Macs OS X terminal, .profile). Den här filen är en textfil med Emacs lisp-kod som körs varje gång Emacs startas. Vi kommer inte gå in djupare på hur man skriver Emacs lisp-koden här för närvarande, men det är viktigt att känna till .emacs filen för att göra några mindre modifikationer som gör livet lättare när man kodar i Emacs. Några exempel på modifikationer tas upp nedan (Modes).

Modes

En texteditor kan användas för att skriva i många olika programmeringsspråk, markupspråk eller rena datafiler. Naturligtvis vill man som användare att färgkodningen ska fungera för all språk som man använder editorn för att skriva i. Men eftersom varje språk inte har samma syntax måste editorn konfigureras för de olika språken. I Emacs sköts det här genom så kallade modes. En mode är mer eller mindre en funktionalitet som är aktivt för en eller flera buffers. För att göra det lite mer komplicerat har Emacs två typer av modes, major mode och minor mode.

En major mode är den övergripande moden som beskriver hur själva redigeringen går till i buffern. Det tillåts enbart, och krävs, att varje buffer har en major mode aktiverad. Vanligtvis kommer Emacs automatiskt att välja vilken major mode som ska vara aktiv för en buffer från filändelsen. Ett exempel på en major mode är python-mode vilken sköter inställningar för indentering, färgsättning av koden, med mera.

En minor mode hanterar en väl avgränsad del av redigeringen. För de här modesen finns det ingen begränsning för hur många som får vara aktiva per buffer. Det finns inte ens en begränsning för hur många buffers som en minor mode är aktiv för. Några exempel på minor modes är linum-mode (radnumrering), aspell-/ispell-mode (rättstavning) och whitespace-mode (radlängd, onödiga tecken och tab-visualisering).

För att aktivera en mode (minor eller major) använder man sig av M-x kommandot och skriver in namnet på moden. Om man till exempel vill aktivera linum-mode skriver man "M-x linum-mode" och trycker på enter-knappen. Vill man stänga av en mode kör man samma kommando igen.

Det finns en uppsjö av olika modes som kan användas men de som man vanligtvis använder är redan installerade i Emacs. För att ge en inblick i några modes som man kan tänkas vilja använda när man använder Emacs (i den här kursen och andra sammanhang) kommer vi att gå igenom ett par små men användbara minor modes. Vi kommer även visa lite Emacs lisp kod som man kan lägga in i sin .emacs fil för att moden automatiskt ska startas när Emacs startas eller när en major mode startas.

Radlängd och onödiga tecken

En vanlig sak som man vill hålla koll på när man skriver kod är hur långa raderna är så att man undviker att de blir för långa. För att slippa behöva anpassa storleken på framen man använder kan man istället låta Emacs markera alla tecken som är efter den radlängden som man vill ha. Det är en av sakerna som whitespace-mode sköter åt en.

Whitespace-mode visar (lite beroende på inställningarna) alla tecken som är längre än den angivna radlängden, tab-tecken och så kallade trailing whitespaces (whitespaces som är på slutet av raden utan några icke speciella tecken, likt radbrytning, efter dem).

För att starta whitespace-mode när man startar Emacs kan man lägga till följande kod i sin .emacs fil:

(require 'whitespace)
(setq whitespace-style '(face empty tabs lines-tail trailing))
(setq whitespace-line-column 79)
(global-whitespace-mode t)

För att starta whitespace-mode när python-mode körs kan man lägga till följande kod i sin .emacs fil:

(require 'whitespace)
(add-hook 'python-mode
	(lambda ()
		(setq whitespace-style '(face empty tabs lines-tail trailing))
		(setq whitespace-line-column 79)
		(global-whitespace-mode t)))

Radnumrering

Ytterligare en mindre sak som man kan vilja se när man skriver sin kod är radnumrering av koden. Dels för att man ofta får ut felmeddelanden från interpretatorn (eller kompilatorn) med angivningar till vilken rad som det har gått fel på. För att Emacs ska visa radnumrering kan man använda sig av linum-mode.

För att starta linum-mode när man startar Emacs kan man lägga till följande kod i sin .emacs fil:

(require 'linum)
(global-linum-mode 1)

För att starta linum-mode när python-mode körs kan man lägga till följande kod i sin .emacs fil:

(require 'linum)
(add-hook 'python-mode
	(lambda ()
		(global-linum-mode 1)))

Kända buggar

Tyvärr är Emacs, likt de flesta program, inte utan problem. För att man inte ska behöva bekymra sig över dessa problem listar vi upp de som vi har stött på och några sätt att lösa dem lokalt.

Arithmetic Error när man indenterar kod i Python (Emacs 24)

Det finns ett känt problem i Emacs 24 vilket gör att Pythons indenteringsvariabel sätts till null och därmed får man aritmetiska fel när man försöker indentera filen.

För att slippa det här problemet kan man använda någon av de följande lösningarna:

  • Använd Emacs 23 istället för Emacs 24.
  • När man stöter på problemet kan man skriva in "M-x set-variable RET python-indent-offset RET 4 RET" där RET betyder att du trycker på enter-knappen.
  • Uppdatera din .emacs-fil till att innehålla följande kodbit. Observera att koden inte är testad. Hör gärna av dig om du har använt denna kod och problemet fortfarande uppstår.
(add-hook 'python-indent-guess-indent-offset
	  (lambda ()
	    (if (= python-indent-offset 0)
		(set (make-local-variable 'python-indent-offset) 4))))

Alternativa texteditorer

Många studenter vill byta från Emacs och använda något annat under kursens gång. Det är oftast OK men se kommentarerna under byta till en alternativ editor i vanliga frågor


Sidansvarig: Peter Dalenius
Senast uppdaterad: 2021-12-03