FG42/docs/videos.org

896 lines
22 KiB
Org Mode
Raw Permalink Normal View History

2022-12-04 21:59:31 +00:00
#+TITLE: Emacs From Scratch - An Emacs tutorial for beginners
2021-12-21 21:18:32 +00:00
#+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) CANCELLED(c@/!) FAILED(f@/!)
#+TAGS: READER(r) MISC(m)
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty overview
2022-01-09 20:14:50 +00:00
* DONE Episode 1 - Introduction
CLOSED: [2022-01-09 Sun 19:03]
2021-12-21 21:18:32 +00:00
** What is it all about?
- Create an editor, development environment and Window Manager (yeah window manager) and ...
- GNU/Emacs is amazing
- Spread the joy
- Guide for contributors
- A guide for people who wants to learn some Lisp
** The Plan
- Parallel video series to *How to build a compiler with LLVM and MLIR*
- Git branches
- No live coding
- Start from Emacs and Jump to FG42
- Feel free to contribute
** FG42 and a bit of history
- It's my:
+ Editor/IDE
+ Email client
+ Window Manager
+ File Manager
+ Terminal Emulator
+ IRC client (at some point)
+ TODO manager
+ "Office suit" (air qoute)
+ ....
- Started on 2010 in a train
- I'm working on the V3
- Requirements
+ Emacs >= 27.1
- Website: https://fg42.org/
- Repository: https://devheroes.codes/FG42
- Website: https://lxsameer.com
- Email: lxsameer@gnu.org or lxsameer@lxsameer.com
2022-02-14 10:15:37 +00:00
* DONE Episode 2 - Survive on the first day
CLOSED: [2022-02-11 Fri 10:28]
2022-01-09 20:14:50 +00:00
** Why bother?
** Why GNU/Emacs?
*** People might say because of
- Org-mode
- LSP support
- Support for many many languages
- It's lightweight
- Tons of plugins
- ...
*** I'd say
- Coz it's a lisp environment with an editor attached to it
- Lisp is the difference
+ It's super easy to extend/hack emacs
+ In compare to other editors
- You can do pretty much whatever your like in ELisp
- It's like a framework for building an editor
** FAQ
*** What is the difference between Doom, Spacemacs, FG42 and ...?
Different editors based on Emacs
*** Which one should I use?
*** How to install Emacs packages?
** UI Basics & Basic Concepts
- Window
- Frame
- Mode line
- Buffers
- Mini buffer/Echo area
- Point
- Major mode
- Minor mode
** Basic Keybindings
How to read key bindings? Here is an example =C-x M-e 4=, it means press =x= key while
holding =Control= and then press =e= key while pressing down =Alt= and finally press =4=.
- Emacs tutorial =C-h t= (or https://www.gnu.org/software/emacs/tour/)
- Quit emacs =C-x C-c=
- Abort =C-g=
- Get Help =C-h= family
+ =C-h f=
+ =C-h v=
+ =C-h m=
+ =C-h k=
+ =C-h a=
- Run a command (function) =M-x=
- Visit a file =C-x C-f=
- Search in Buffer =C-s=
- Save buffer =C-x C-s=
- Select region =C-SPC=
- Copy =M-w=
- Cut(killing) =C-w=
- Paste(yanking) =C-y=
- Kill buffer =C-x k=
- Switch buffer =C-x b=
- Undo =C-/=
- Eval expression =C-x C-e=
- =describe-mode=
** Lisp basics
- Expressions everywhere
- Code a data structure
- Almost everything in Lisp evaluates to themselves except:
+ lists
+ Symbols
+ ...
- Lisp laws:
1. Everything in Lisp is an expression and evaluation of an expression
means replacing it with its value
2. Almost everything in Lisp evaluates to themselves except:
- Lists
- Symbols
- Quotes
- ...
2022-03-14 16:26:37 +00:00
-
3. List evaluation
* DONE Episode 3 - Lisp Basics
CLOSED: [2022-03-12 Sat 18:38]
2022-02-14 10:15:37 +00:00
** FAQ:
- How to install Emacs?
+ Just make sure to have *Emacs >= 27.1*
- What's the routine to use Emacs ?
+ Don't use Emacs like how you use other Editors.
+ There is no limits(Almost).
- How evaluate forms?
+ *C-x C-e* at the end of any expression and anywhere
+ ielm
+ Batch mode
** So Fare:
*** Lisp rules:
1. Lisp is made of Expressions and they evaluate to a value.
2. All the expression types evaluates to themselves with some exceptions.
3. List evaluation
*** We will continue with Lisp basics for few episodes
** Variables
- How to define variables and constants
- Set the value of a variable
- Global and local scope
- Lexical bindings vs Dynamic bindings
+ =-*- lexical-binding: t; -*-=
** Functions
- How to define functions
- vs macros
- vs special forms
2022-04-13 12:48:29 +01:00
* DONE Episode 4 - Conditionals
CLOSED: [2022-04-09 Sat 11:24]
2022-03-14 16:26:37 +00:00
** What we learned so far
** what is true and what's not
** Let & prog family
** Conditional special forms
- if
- when
- unless
- cond
** Useful forms and functions
- eq
- equal
- and
- not
- or
- ...
** Type Predicts
- numberp
- stringp
- listp
- boundp
- More at https://www.gnu.org/software/emacs/manual/html_node/elisp/Type-Predicates.html
** type-of
2022-05-18 20:19:18 +01:00
* DONE Episode 5 - Lists
CLOSED: [2022-05-18 Wed 12:40]
2022-04-13 12:48:29 +01:00
** What is a list?
- Not a primitive type
- A linked list made out of cons cells
** Cons Cells
- A container for pairs
- CAR
- CDR (could-er)
#+NAME: ep-5-cons
#+BEGIN_SRC graphviz-dot :file /tmp/cons.svg :cmdline -Kdot -Tsvg
digraph {
graph [bgcolor=transparent]
fontcolor="gray80"
node [color=gray80 shape="box", fontcolor="gray80"]
edge [color=gray80]
rankdir = "LR"
subgraph cluster_0 {
label="Cell"
color="gray80"
graph [bgcolor=transparent, fontcolor="gray80"]
node [color=gray80 shape="box", fontcolor="gray80"]
a0[label="car: 'head"]
b0[label="cdr: 'tail"]
}
}
#+END_SRC
#+RESULTS: ep-5-cons
[[file:/tmp/cons.svg]]
#+BEGIN_SRC emacs-lisp
(setq x1 (cons 'head 'tail))
(car x1)
(cdr x1)
'(head . tail)
(cons 2 nil)
(cons 1 x1)
#+END_SRC
#+NAME: ep-5-list
#+BEGIN_SRC graphviz-dot :file /tmp/list.svg :cmdline -Kdot -Tsvg
digraph {
graph [bgcolor=transparent]
fontcolor="gray80"
node [color=gray80 shape="box", fontcolor="gray80"]
edge [color=gray80]
rankdir = "LR"
subgraph cluster_0 {
label="Cell"
color="gray80"
graph [bgcolor=transparent, fontcolor="gray80"]
node [color=gray80 shape="box", fontcolor="gray80"]
a0[label="car: 1"]
b0[label="cdr: "]
}
subgraph cluster_1 {
label="Cell"
color="gray80"
node [color=gray80 shape="box"]
a1[label="car: 2"]
b1[label="cdr: "]
b0 -> a1
}
subgraph cluster_2 {
label="Cell"
color="gray80"
node [color=gray80 shape="box"]
a2[label="car: 3"]
b2[label="cdr: nil"]
b1 -> a2
}
}
#+END_SRC
#+RESULTS: ep-5-list
[[file:/tmp/list.svg]]
#+BEGIN_SRC emacs-lisp
(setq x2 (cons 1 (cons 2 (cons 3 nil))))
(setq x3 (list 1 2 3))
#+END_SRC
** Some useful functions
- add-to-list
#+BEGIN_SRC emacs-lisp
(setq x4 (list 1 2 3 4))
(add-to-list 'x4 3)
(add-to-list 'x4 6)
#+END_SRC
- push & pop
#+BEGIN_SRC emacs-lisp
(setq x5 (list 1 2 3 4))
(push 1 x5)
(pop x5)
#+END_SRC
- member
#+BEGIN_SRC emacs-lisp
(setq x6 (list 'a 'b 1 2))
(member 'z x6)
(member 1 x6)
#+END_SRC
- delete
#+BEGIN_SRC emacs-lisp
(setq x7 (list 1 2 3 4 5))
(delete 3 x7)
x7
#+END_SRC
- remove
#+BEGIN_SRC emacs-lisp
(setq x8 (list 1 2 3 4 5))
(remove 3 x8)
x8
#+END_SRC
- car
- cdr
#+BEGIN_SRC emacs-lisp
(setq x9 (list 1 2 3 4))
(car x9)
(cdr x9)
#+END_SRC
2022-06-18 18:37:14 +01:00
* DONE Episode 6 - Property & Association Lists
CLOSED: [2022-06-13 Mon 10:38]
2022-05-18 20:19:18 +01:00
** I have an idea
- Develop *FG42* on stream
- I'll announce the date and time on:
+ Twitter: @lxsameer
+ Youtube Community (maybe)
** eq vs equal
- ~eq~ checks whether two objects are the same
- ~equal~ checks whether two objects have similar structure and content.
** Property List (plist)
- Is a list of paired elements
- Each of the pairs associates a property name with a property or value
- The order of the property names (keys) is not significant
- Keys must be unique
- Emacs uses plists to store text properties and symbol properties
*** Examples
#+BEGIN_SRC emacs-lisp
(setq x '(:a 1 "b" 2 c 3 :d ("foo" "bar") :j nil))
x
#+END_SRC
*** Functions
- ~plist-get~ or ~lax-plist-get~
#+BEGIN_SRC emacs-lisp
(plist-get x :a)
(plist-get x "b")
(lax-plist-get x "b")
#+END_SRC
- ~plist-put~ or ~lax-plist-put~
#+BEGIN_SRC emacs-lisp
(plist-put x :z 325)
(plist-put x :z 10)
(lax-plist-put x "b" 20)
#+END_SRC
- ~plist-member~
#+BEGIN_SRC emacs-lisp
(plist-get x :j)
(plist-get x :g)
(plist-member x :j)
(plist-member x :g)
#+END_SRC
** An example use case of plist
#+BEGIN_SRC emacs-lisp
(defun foo (&rest args)
(message "ARGS: %s" args)
(plist-get args :name))
(foo :age 20 :name 'bob "blah" '(12 34 4))
#+END_SRC
** Association List (alist)
- It is a list of cons cells called associations
- Mapping some keys to some values
- The ~CAR~ of each cons cell is the key, and the ~CDR~ is the associated value
- The order of associations matters
*** Examples
#+BEGIN_SRC emacs-lisp
(setq y '((:a . 1) ("b" . 2) (c . 3) (:d "foo" "bar")))
y
#+END_SRC
*** Functions
- ~assoc~
#+BEGIN_SRC emacs-lisp
(assoc :a y)
(assoc "b" y)
#+END_SRC
- ~rassoc~
#+BEGIN_SRC emacs-lisp
(rassoc 1 y)
(rassoc 3 y)
#+END_SRC
- ~assq~
#+BEGIN_SRC emacs-lisp
(assq :a y)
(assq "b" y)
#+END_SRC
- ~alist-get~
#+BEGIN_SRC emacs-lisp
(alist-get :a y)
(alist-get :z y "blah")
#+END_SRC
- ~cons~
#+BEGIN_SRC emacs-lisp
(setq y1 (cons '(:z . 31) y))
(assoc :z y1)
#+END_SRC
** References
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Plist-Access.html
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Plists-and-Alists.html
2022-06-18 18:37:14 +01:00
2022-07-12 15:53:46 +01:00
* DONE Episode 7 - Basic Loops
CLOSED: [2022-07-09 Sat 10:31]
2022-06-18 18:37:14 +01:00
** About previous episode
- Duplicate keys in an association list
- ~eval-defun~
** While
- Form:
#+BEGIN_SRC emacs-lisp
(while CONDITION
...body...)
#+END_SRC
- Loops and evaluates ~body~ as long as the ~CONDITION~ evaluates to true.
- It always evaluats to the value of the ~CONDITION~ which will be false aaaaall the time.
- We need to explicitly manage the condition.
- Example:
#+BEGIN_SRC emacs-lisp
(let ((foo 1))
(while (< foo 10)
(message ">> %s" foo)
(setq foo (+ 1 foo))))
(let ((foo '(bar baz)))
(while foo
(message ">> %s" (car foo))
(setq foo (cdr foo))))
#+END_SRC
** dolist
- It's a macro
- Form:
#+BEGIN_SRC emacs-lisp
(dolist (element list [result])
...body...)
#+END_SRC
- Evaluates the ~body~ with ~element~ set to the CAR of ~list~ on each iteration
- At the ends evaluates ~result~ and return the evaluation result (if ~result~ is provided)
- Example:
#+BEGIN_SRC emacs-lisp
(let ((foo '(9 8 7 6 5 4)))
(dolist (x foo (+ 10 1))
(message ">> %s" x)))
(let ((foo '(9 8 7 6 5 4)))
(macroexpand-1
'(dolist (x foo 10)
(message ">> %s" x))))
#+END_SRC
** dotimes
- It's a macro too
- Form:
#+BEGIN_SRC emacs-lisp
(dotimes (var number)
...body...)
#+END_SRC
- It's similar to ~dolist~ but iterates ~number~ of times
- ~var~ in will contains the number of current iteration
- Example:
#+BEGIN_SRC emacs-lisp
(let ((foo 10))
(dotimes (x foo)
(message ">> %s" x)))
(let ((foo 10))
(macroexpand-1
'(dotimes (x foo)
(message ">> %s" x))))
#+END_SRC
2022-08-01 15:01:45 +01:00
* DONE Episode 8 - More Loops
CLOSED: [2022-07-29 Fri 15:11]
2022-06-18 18:37:14 +01:00
** Recursion
2022-07-12 15:53:46 +01:00
- A *Recursive* function, is a function that defines in terms of itself
- Easy to implement
- But should be careful with it to aviod infinit loops
*** Example
#+BEGIN_SRC emacs-lisp
(defun foo (int)
(print int)
(when (> int 0)
(foo (- int 1))))
(foo 10)
#+END_SRC
2022-06-18 18:37:14 +01:00
** Functional style loops
2022-07-12 15:53:46 +01:00
*** Mapping functions Family
- ~mapcar~
#+BEGIN_SRC emacs-lisp
(mapcar #'1+ '(1 2 3 4 5))
(mapcar (lambda (x) (* x x))
'(1 2 3 4))
#+END_SRC
- ~mapc~
#+BEGIN_SRC emacs-lisp
(mapc #'1+ '(1 2 3 4 5))
(mapc #'print '(1 2 3 4 5))
#+END_SRC
- ~map-concat~
#+BEGIN_SRC emacs-lisp
(mapconcat (lambda (x)
(format "[%s]" x))
'(1 2 3 4 5)
" <|> ")
#+END_SRC
*** Seq module
A collection of handy functions that operate on ~sequences~.
- ~seq-reduce~
#+BEGIN_SRC emacs-lisp
(require 'seq)
(seq-reduce
(lambda (acc x)
(+ acc x))
'(1 2 3 4)
0)
#+END_SRC
- ~seq-filter~
#+BEGIN_SRC emacs-lisp
(seq-filter (lambda (x) (< x 10))
'(8 12 22 9))
#+END_SRC
- ~seq-partition~
#+BEGIN_SRC emacs-lisp
(seq-partition '(a b c d e f) 2)
#+END_SRC
- ~seq-min~, ~seq-max~
2022-09-12 15:24:31 +01:00
* DONE Episode 9 - Introduction to Macros
CLOSED: [2022-09-11 Sun 11:08]
2022-08-01 15:01:45 +01:00
** What is a macro?
- A macro is defined much like a function
- It works on compile time
- It returns a new expression as the return value
- The compiler "expands" a macro by replacing the macro call with the return value of the macro
- Different evaluation rule than functions
+ Unlike function calls, the arguments to a macro will be passed to the macro as they are,
without evaluation.
- Macros vs inline functions
** How to define and expand a macro?
- We can define a macro using ~defmacro~ form
#+BEGIN_SRC emacs-lisp
(defmacro inc (val)
(list #'1+ val))
(defmacro mydef (name val)
(list 'setq (intern (concat "my-" (symbol-name name))) val))
(defmacro foo (val)
(1+ val))
#+END_SRC
- We can inspect the expansion process using the ~macroexpand~ function family.
+ ~macroexpand~: Expands the macros until no macro exists in the top level forms
+ ~macroexpand-all~: Expands the macros all the way down to the subforms
+ ~macroexpand-1~: Expands the macro only for one level or cycle
#+BEGIN_SRC emacs-lisp
(macroexpand-1 '(inc 10))
(macroexpand-1 '(mydef blah 20))
(print (macroexpand-1 '(when (> 10 5) (print "something"))))
#+END_SRC
** Feedback or question
- https://lxsameer.com
- [[https://twitter.com/lxsameer][@lxsameer]] on Twitter
2022-11-05 12:46:53 +00:00
* DONE Episode 10 - More on Macros
CLOSED: [2022-11-04 Fri 15:25]
2022-09-12 15:24:31 +01:00
** Quasiquote aka backquote (`)
- Backquote constructs allow us to quote an expression, but selectively evaluate sub-expressions
- Similar to a template engine for lisp expressions
- It can be used on its own but it will shine in macro definitions
- On the simplest form it is identical to ~quote~
- Special markers ~,~ and ~,@~ can be used to mark expressions for evaluation
- ~,~ will replace the return value of the evaluation with the expression
- ~,@~ will replace and splice the return value of the evaluation
*** Examples
#+BEGIN_SRC emacs-lisp
`3
`(1 2 3 4)
`(1 2 3 ,(+ 5 6))
`(1 2 3 ,(list 4 5 6))
`(1 2 3 ,@(list 4 5 6))
`(setq ,(intern (upcase "some_var")) 3)
#+END_SRC
2022-08-01 15:01:45 +01:00
** ~declare~ form
2022-09-12 15:24:31 +01:00
- It's a special macro which can be used to add meta properties to a function or macro
+ ~doc-string~
+ ~indent~
** Real Examples
Let's discuss ~defflag~ and ~when-flag~ macros in [[file:../core/fg42/flags.el]]
2022-12-04 21:59:31 +00:00
* DONE Episode 11 - Common pitfalls of Macros
CLOSED: [2022-12-04 Sun 12:15]
2022-11-05 12:46:53 +00:00
** Compiletime vs runtime
#+BEGIN_SRC emacs-lisp
;; `do-something-with-side-effect' evaluates on compile time
;; in the macro's context
(defmacro wrong (x)
(when x
(do-something-with-side-effect x)))
;; `do-something-with-side-effect' evaluates on run time
;; in the caller's context
(defmacro correct (x)
(when x
`(do-something-with-side-effect ,x)))
#+END_SRC
** Variable Capture
#+BEGIN_SRC emacs-lisp
;; `result' will hide any binding with the same name in the
;; parent scope
(defmacro wrong (f &rest body)
`(let ((result ,f))
(if result
,@body
(message "Failed: %s" result))))
(defvar result 1)
(wrong 200 (message "> %s" result))
;; Instead we need to generate a local binding
(defmacro correct (f &rest body)
(let ((var (gensym)))
`(let ((,var ,f))
(if ,var
,@body
(message "Failed: %s" ,var)))))
(defvar result 1)
(correct 200 (message "%s" result))
#+END_SRC
More on *uninterned* symbols: https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Symbols.html
** Many evaluation
#+BEGIN_SRC emacs-lisp
;; The argument `x' will be evaluated 2 times in this example.
;; what if it contains side effects?
(defmacro wrong (x)
`(if ,x
(do-something-with ,x)
(do-somthing-else ,x)))
;; It's better to use a local binding for it and evaluate it
;; just once
(defmacro correct (x)
(let ((var (gensym)))
`(let ((,var ,x))
(if ,var
(do-something-with ,var)
(do-somthing-else ,var)))))
#+END_SRC
** Evaluating arguments of a macro
Never evaluate the arguments of a macro manually. E.g. with =eval=
#+BEGIN_SRC emacs-lisp
;; `eval' here will be evaluated before the caller context
;; is even populated
(defmacro wrong (x)
(list 'setq (eval x) 'blah))
;; The correct way is to mark `x' for evaluation instead
(defmacro correct (x)
`(setq ,x 'blah))
#+END_SRC
More info: https://www.gnu.org/software/emacs/manual/html_node/elisp/Eval-During-Expansion.html
** What's next?
* DONE Episode 12 - Features & Load Paths
CLOSED: [2023-01-14 Sat 11:44]
2022-12-04 21:59:31 +00:00
** Emacs Lisp files
Write elisp code in files with =.el= suffix.
*** Batch mode
Execute an elisp file via Emacs in a non-interactive (script like) fashion:
#+BEGIN_SRC bash
emacs --batch -l /path/to/the/file
#+END_SRC
*** =load= function
Loads an elisp file into the running Emacs process. For more info ~C-h f load~.
#+BEGIN_SRC emacs-lisp
(load "/path/to/the/file")
(load "PATH1")
#+END_SRC
- It first looks for the =PATH + .elc= combination
- If not successful, looks for the =PATH + .el= combination
- If not successful, looks for platform dependent suffixes
- If not successful, tries to load the =PATH= as it is
** Load Path
*** =load-path=
List of directories to search for files to load.
#+BEGIN_SRC emacs-lisp
(add-to-list 'load-path "/path/to/a/directory")
#+END_SRC
*** =EMACSLOADPATH= environment variable
** Emacs =feature=
Emacs tracks loaded packages and file via =features=. Each elisp file can =provide=, zero or
more =features=.
Features are just symbols.
*** =features= list
A list of all loaded features. For more info, try ~C-h v features~.
*** =featurep=
A predicate function to check whether a feature is loaded or not.
#+BEGIN_SRC emacs-lisp
(featurep 'some-feature)
#+END_SRC
*** =provide=
#+BEGIN_SRC emacs-lisp
(provide 'some-feature)
#+END_SRC
*** =require=
If the given feature as the parameter is not loaded yet, loads it via the =load=
function. For more info, ~C-h f require~.
#+BEGIN_SRC emacs-lisp
(require 'some-feature)
;; Or
(require 'some-feature "/path/to/file")
#+END_SRC
** Installing Emacs packages the hard way
We can clone a library somewhere on the disk and add the path to it to the =load-path= list
and load the library files.
But that would be tedious to do so for all the libraries. That's why we use a package manager
* DONE Episode 13 - Editing Modes, Part 1
CLOSED: [2023-06-10 Sat 15:44]
2023-02-08 15:52:45 +00:00
Emacs provides a concept called ~editing mode~ that allows
us to control different aspect of the editor.
** Major Modes
Major modes are mutually exclusive, so each Buffer has exactly on
major mode and just one major mode can be active at any given
time. So, it is possible to switch between different major modes.
Major modes control the main behaviour of your editor for each buffer.
For example, The active major mode might:
- Provide syntax highlighter
- Control the indentation
- Provide a local =keymap=
- ...
To put it simply, major modes are specialized to handle certain files
and buffers.
*** Naming Convenstion
Usually, the name of a major mode is like =<major-mode-name>-mode= which is
an interactive function that we can call either directly or via =M-x= interface.
For example:
- python-mode
- fundamental-mode
- emacs-lisp-mode
- ...
**** Keymap
*We will take about Keymaps in the future*
Major modes usually have a keymap to hold their local keybindings that has the
the =-map= suffix.
**** Hooks
*We will take about Hooks in the future*
Hooks are lists of functions that can be called on certain occasions. For example,
after a major mode activates.
Usually major modes come with at least one hook called =<major-mode-name>-hook= that
runs after the major mode activates. E.g. =emacs-lisp-mode-hook= or =python-mode-hook=.
*** How Emacs choose a major mode for a buffer?
When we open a file, Emacs goes through some hoops to figure out what major mode
should it choose for that buffer.
To put it simply and avoid a lot of details, Emacs will try to match the buffer name
against the keys in ~auto-mode-alist~ and uses the mode provided by that key as a value.
#+BEGIN_SRC emacs-lisp
(("\\`/tmp/fol/" . text-mode)
("\\.texinfo\\'" . texinfo-mode)
("\\.texi\\'" . texinfo-mode)
("\\.el\\'" . emacs-lisp-mode)
("\\.c\\'" . c-mode)
("\\.h\\'" . c-mode)
…)
#+END_SRC
For more info check out:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Auto-Major-Mode.html
*** How to switch the major mode
Just call the other mode or
- ~major-mode-suspend~: Kills all the buffer local variables and record them
- ~major-mode-restore~: This function restores the major mode recorded by ~major-mode-suspend~
For more info:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Major-Modes.html
** Minor Modes
A minor mode provides optional features that users may enable or disable independently of
the choice of major mode. Minor modes can be enabled individually or in combination.
The main difference with major modes is that minor modes are not mutually exclusive and
are not tied to buffers. They can operate globally or local to buffers.
*** How to enable/disable minor modes?
In order to toggle a minor mode we just have to call its function with no argument
*interactively*. In order to disable a minor mode we can pass a negative integer,
and to enable it we can pass a positive integer.
#+BEGIN_SRC emacs-lisp
;; Enable
(blah-mode 1)
;; Disable
(blah-mode -1)
#+END_SRC
** Useful functions and variables
- ~describe-mode~: Display documentation of current major mode and minor modes and a brief
summary of the state of the current buffer.
- ~local-minor-modes~: This buffer-local variable lists the currently enabled minor modes
in the current buffer, and is a list of symbols.
- ~global-minor-modes~: This variable lists the currently enabled global minor modes,
and is a list of symbols.
- ~minor-mode-list~: The value of this variable is a list of all minor mode commands.
* Episode 14 - Editing Modes, Part 2
** Quick overview:
*** A simple minor mode
*** Interactive functions
*** Hooks
*** Keymaps
** Let's do it
** Resources:
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Library-Headers
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Hooks.html
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Keymaps.html