diff --git a/elisp.html.markdown b/elisp.html.markdown index 16a0311c..bda5f00f 100644 --- a/elisp.html.markdown +++ b/elisp.html.markdown @@ -1,7 +1,7 @@ --- language: elisp contributors: - - ["Bastien Guerry", "http://bzg.fr"] + - ["Bastien Guerry", "https://bzg.fr"] - ["Saurabh Sandav", "http://github.com/SaurabhSandav"] filename: learn-emacs-lisp.el --- @@ -9,7 +9,7 @@ filename: learn-emacs-lisp.el ```scheme ;; This gives an introduction to Emacs Lisp in 15 minutes (v0.2d) ;; -;; Author: Bastien / @bzg2 / http://bzg.fr +;; Author: Bastien / @bzg2 / https://bzg.fr ;; ;; First make sure you read this text by Peter Norvig: ;; http://norvig.com/21-days.html diff --git a/fr-fr/elisp-fr.html.markdown b/fr-fr/elisp-fr.html.markdown new file mode 100644 index 00000000..2e0a9408 --- /dev/null +++ b/fr-fr/elisp-fr.html.markdown @@ -0,0 +1,372 @@ +--- +language: elisp +contributors: + - ["Bastien Guerry", "https://bzg.fr"] + - ["Saurabh Sandav", "http://github.com/SaurabhSandav"] +translators: + - ["Bastien Guerry", "https://bzg.fr"] +filename: learn-emacs-lisp-fr.el +lang: fr-fr +--- + +```scheme +;; Ceci est une introduction à Emacs Lisp en 15 minutes (v0.2d) +;; +;; Auteur : Bastien / @bzg2 / https://bzg.fr +;; +;; Prenez d'abord le temps de lire ce texte en anglais de Peter Norvig : +;; http://norvig.com/21-days.html +;; +;; Ensuite installez GNU Emacs 24.3 (ou une version ultérieure) : +;; +;; Debian : apt-get install emacs (voir les instructions pour votre distribution) +;; MacOSX : http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg +;; Windows : http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip +;; +;; Vous trouverez plus d'informations sur l'installation : +;; http://www.gnu.org/software/emacs/#Obtaining + +;; Avertissement important : +;; +;; Suivre ce tutoriel ne risque pas d'endommager votre ordinateur, +;; sauf si vous vous énervez au point de le jeter par terre. En tout +;; cas, je décline toute responsabilité en cas de problème. +;; Amusez-vous bien ! + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Lancez Emacs. +;; +;; Tapez la touche "q" pour enlever le message d'accueil. +;; +;; Maintenant regardez la ligne grise au pied de la fenêtre : +;; +;; "*scratch*" est le nom de l'espace d'édition dans lequel vous vous +;; trouvez. Cet espace d'édition est appelé un "buffer". +;; +;; Le buffer scratch est le buffer par défaut quand on ouvre Emacs. +;; Vous n'éditez jamais de fichier directement : vous éditez des +;; buffers que vous pouvez sauvegarder dans des fichiers. +;; +;; "Lisp interaction" désigne le jeu de commandes disponible ici. +;; +;; Emacs a un jeu de commandes par défaut pour chaque buffer, et +;; plusieurs autres jeux de commandes disponibles quand vous activez +;; un mode particulier. Ici nous utilisons `lisp-interaction-mode', +;; qui propose des commandes pour évaluer et naviguer dans du code +;; Elisp. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Le point-virgule commence un commentaire partout sur une ligne. +;; +;; Les programmes Elisp sont composés d'expressions symboliques aussi +;; appelées "sexps" : +(+ 2 2) + +;; Cette expression symbolique se lit "Ajouter 2 à 2". + +;; Les sexps sont placées entre parenthèses, possiblement sur +;; plusieurs niveaux : +(+ 2 (+ 1 1)) + +;; Une expression symbolique contient des atomes ou d'autres +;; expressions symboliques. Dans les exemples ci-dessus, 1 et 2 sont +;; des atomes et (+ 2 (+ 1 1)) et (+ 1 1) des expressions symboliques. + +;; Dans le mode `lisp-interaction-mode' vous pouvez évaluer les sexps. +;; Placez le curseur juste après la parenthèse fermante, tenez la +;; touche "Control" enfoncée et appuyez sur la touche "j" (soit le +;; raccourci "C-j"). + +(+ 3 (+ 1 2)) +;; ^ curseur ici +;; `C-j' => 6 + +;; `C-j' insère le résultat de l'évaluation dans le buffer. + +;; `C-x C-e' affiche le même résultat dans la ligne tout en bas +;; d'Emacs, appelée le "minibuffer". On utilise en général `C-x C-e', +;; pour ne pas encombrer le buffer avec du texte inutile. + +;; `setq' assigne une valeur à une variable : +(setq my-name "Bastien") +;; `C-x C-e' => "Bastien" (affiché dans le minibuffer) + +;; `insert' va insérer "Hello!" là où se trouve le curseur : +(insert "Hello!") +;; `C-x C-e' => "Hello!" + +;; Nous utilisons `insert' avec un seul argument "Hello!", mais +;; nous pouvons passer plus d'arguments - ici nous en passons deux : + +(insert "Hello" " world!") +;; `C-x C-e' => "Hello world!" + +;; Vous pouvez utiliser des variables au lieu de chaînes de caractères : +(insert "Hello, I am " my-name) +;; `C-x C-e' => "Hello, I am Bastien" + +;; Vous pouvez combiner les sexps en fonctions : +(defun hello () (insert "Hello, I am " my-name)) +;; `C-x C-e' => hello + +;; Vous pouvez évaluer les fonctions : +(hello) +;; `C-x C-e' => Hello, I am Bastien + +;; Les parenthèses vides dans la définition de la fonction signifient +;; qu'elle ne prend pas d'argument. Mais toujours utiliser `my-name' +;; est ennuyant, demandons à la fonction d'accepter un argument (ici +;; l'argument est appelé "name") : + +(defun hello (name) (insert "Hello " name)) +;; `C-x C-e' => hello + +;; Maintenant appelons la fonction avec la chaîne de caractères "you" +;; comme valeur de son unique argument : +(hello "you") +;; `C-x C-e' => "Hello you" + +;; Youpi! + +;; Faites une pause. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Maintenant ouvrez un nouveau buffer appelé "*test*" dans une +;; nouvelle fenêtre : + +(switch-to-buffer-other-window "*test*") +;; `C-x C-e' +;; => [l'écran a deux fenêtres et le curseur est dans le buffer *test*] + +;; Placez la souris sur la fenêtre du haut et cliquez-gauche pour +;; retourner dans cette fenêtre. Ou bien utilisez `C-x o' (i.e. tenez +;; control-x appuyé et appuyez sur o) pour aller dans l'autre fenêtre +;; interactivement. + +;; Vous pouvez combiner plusieurs sexps avec `progn' : +(progn + (switch-to-buffer-other-window "*test*") + (hello "you")) +;; `C-x C-e' +;; => [L'écran a deux fenêtres et le curseur est dans le buffer *test*] + +;; Maintenant si ça ne vous dérange pas, je vais arrêter de vous +;; demander de faire `C-x C-e' : faites-le pour chaque sexp qui suit. + +;; Retournez toujours dans le buffer *scratch* avec la souris ou `C-x o'. + +;; Il est souvent utile d'effacer le contenu du buffer : +(progn + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello "there")) + +;; Ou d'aller à l'autre fenêtre : +(progn + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello "you") + (other-window 1)) + +;; Vous pouvez associer une valeur à une variable locale avec `let' : +(let ((local-name "you")) + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello local-name) + (other-window 1)) + +;; Dans ce cas pas besoin d'utiliser `progn' puisque `let' combine +;; aussi plusieurs sexps. + +;; Mettons en forme une chaîne de caractères : +(format "Hello %s!\n" "visitor") + +;; %s désigne l'emplacement de la chaîne, remplacé par "visitor". +;; \n est le caractère de saut de ligne. + +;; Améliorons notre fonction en utilisant "format" : +(defun hello (name) + (insert (format "Hello %s!\n" name))) + +(hello "you") + +;; Créons une autre fonction qui utilise `let' : +(defun greeting (name) + (let ((your-name "Bastien")) + (insert (format "Hello %s!\n\nI am %s." + name ; l'argument de la fonction + your-name ; la variable "let-bindée" "Bastien" + )))) + +;; Et évaluons-la : +(greeting "you") + +;; Certaines fonctions sont interactives : +(read-from-minibuffer "Enter your name: ") + +;; Évaluer cette fonction va renvoyer ce que vous avez saisi dans le +;; minibuffer. + +;; Faisons que notre fonction `greeting' vous demande votre nom : +(defun greeting (from-name) + (let ((your-name (read-from-minibuffer "Enter your name: "))) + (insert (format "Hello!\n\nI am %s and you are %s." + from-name ; l'argument de la fonction + your-name ; la variable "let-bindée", entrée dans le minibuffer + )))) + +(greeting "Bastien") + +;; Complétons la fonction pour qu'elle affiche le résultat dans +;; l'autre fenêtre : +(defun greeting (from-name) + (let ((your-name (read-from-minibuffer "Enter your name: "))) + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (insert (format "Hello %s!\n\nI am %s." your-name from-name)) + (other-window 1))) + +;; Maintenant testons : +(greeting "Bastien") + +;; Faites une pause. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Stockons une liste de noms : +(setq list-of-names '("Sarah" "Chloe" "Mathilde")) + +;; Récupérez le premier élément de la liste avec `car' : +(car list-of-names) + +;; Récupérez tous les élements sauf le premier avec `cdr' : +(cdr list-of-names) + +;; Ajoutez un élément au début avec `push' : +(push "Stephanie" list-of-names) + +;; Note : `car' et `cdr' ne modifient pas la liste, mais `push' oui. +;; C'est une différence importante : certaines fonctions n'ont pas +;; d'effets de bord (comme `car') et d'autres oui (comme `push'). + +;; Évaluons `hello' pour tous les éléments dans `list-of-names' : +(mapcar 'hello list-of-names) + +;; Améliorons `greeting' pour dire hello aux noms de `list-of-names' : +(defun greeting () + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (mapcar 'hello list-of-names) + (other-window 1)) + +(greeting) + +;; Vous vous souvenez de la fonction `hello' définie ci-dessus ? Elle +;; prend seulement un argument, un nom. `mapcar' appelle `hello' en +;; utilisant successivement chaque élément de `list-of-names' comme +;; argument de `hello'. + +;; Maintenant arrangeons un peu ce qui est affiché dans le buffer : + +(defun replace-hello-by-bonjour () + (switch-to-buffer-other-window "*test*") + (goto-char (point-min)) + (while (search-forward "Hello") + (replace-match "Bonjour")) + (other-window 1)) + +;; (goto-char (point-min)) va au début du buffer. +;; (search-forward "Hello") cherche la chaîne "Hello". +;; (while x y) évalue la sexp(s) y tant que x renvoie quelque chose. +;; Si x renvoie `nil' (rien), nous sortons de la boucle. + +(replace-hello-by-bonjour) + +;; Vous devriez voir toutes les occurrences de "Hello" dans le buffer +;; *test* remplacées par "Bonjour". + +;; Vous devriez aussi avoir une erreur : "Search failed: Hello". +;; +;; Pour éviter cette erreur, il faut dire à `search-forward' si la +;; recherche doit s'arrêter à un certain point du buffer, et si elle +;; doit s'arrêter silencieusement si aucune chaîne n'est trouvée. + +;; (search-forward "Hello" nil t) fait ça : + +;; L'argument `nil' indique que la recherche n'est pas limitée à une +;; position. L'argument `t' indique de s'arrêter silencieusement si +;; rien n'est trouvé. + +;; Nous utilisons cette sexp dans la fonction ci-dessous, qui ne +;; renvoie pas d'erreur : + +(defun hello-to-bonjour () + (switch-to-buffer-other-window "*test*") + (erase-buffer) + ;; Dit hello aux noms de `list-of-names' + (mapcar 'hello list-of-names) + (goto-char (point-min)) + ;; Remplace "Hello" par "Bonjour" + (while (search-forward "Hello" nil t) + (replace-match "Bonjour")) + (other-window 1)) + +(hello-to-bonjour) + +;; Mettons les noms en gras : + +(defun boldify-names () + (switch-to-buffer-other-window "*test*") + (goto-char (point-min)) + (while (re-search-forward "Bonjour \\(.+\\)!" nil t) + (add-text-properties (match-beginning 1) + (match-end 1) + (list 'face 'bold))) + (other-window 1)) + +;; Cette fonction introduit `re-search-forward' : au lieu de chercher +;; la chaîne "Bonjour", nous cherchons un "pattern" en utilisant une +;; "expression régulière" (le préfixe "re-" signifie "regular +;; expression"). + +;; L'expression régulière est "Bonjour \\(.+\\)!" et se lit : +;; la chaîne "Bonjour ", et +;; un groupe de | c'est la syntaxe \\( ... \\) +;; n'importe quel caractère | c'est le . +;; une ou plusieurs fois | c'est le + +;; et la chaîne "!". + +;; Prêt ? Testons ! + +(boldify-names) + +;; `add-text-properties' ajoute des propriétés textuelles telle que +;; des "faces" (une "face" définit la fonte, la couleur, la taille et +;; d'autres propriétés du texte.) + +;; Et voilà, c'est fini. Happy hacking! + +;; Si vous voulez en savoir plus sur une variable ou une fonction : +;; +;; C-h v une-variable RET +;; C-h f une-fonction RET +;; +;; Pour lire le manuel Emacs Lisp avec Emacs : +;; +;; C-h i m elisp RET +;; +;; Pour lire en ligne une introduction à Emacs Lisp : +;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html + +;; Merci à ces personnes pour leurs retours et suggetions : +;; - Wes Hardaker +;; - notbob +;; - Kevin Montuori +;; - Arne Babenhauserheide +;; - Alan Schmitt +;; - LinXitoW +;; - Aaron Meurer +```