FG42/docs/videos.org

492 lines
11 KiB
Org Mode

#+TITLE: How to build an editor with Emacs Lisp
#+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
* DONE Episode 1 - Introduction
CLOSED: [2022-01-09 Sun 19:03]
** 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
* DONE Episode 2 - Survive on the first day
CLOSED: [2022-02-11 Fri 10:28]
** 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
- ...
-
3. List evaluation
* DONE Episode 3 - Lisp Basics
CLOSED: [2022-03-12 Sat 18:38]
** 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
* DONE Episode 4 - Conditionals
CLOSED: [2022-04-09 Sat 11:24]
** 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
* DONE Episode 5 - Lists
CLOSED: [2022-05-18 Wed 12:40]
** 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
* DONE Episode 6 - Property & Association Lists
CLOSED: [2022-06-13 Mon 10:38]
** 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
* Episode 7 - Basic Loops
** 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
* Episode 8 - More Loops
** Recursion
** Functional style loops