419 lines
13 KiB
Org Mode
419 lines
13 KiB
Org Mode
#+TITLE: EMACS - the Extensible Machine Aggregating Creative S-Expressions.
|
|
#+AUTHOR: simponic
|
|
#+STARTUP: inlineimages fold
|
|
|
|
[[./img/xkcd.png]]
|
|
|
|
* what is emacs?
|
|
|
|
well... whatever it is, it's better than valve's Steam!
|
|
|
|
* what?
|
|
* yes, emacs is a gaming platform
|
|
** some tetris?
|
|
|
|
comes with emacs.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(tetris)
|
|
#+END_SRC
|
|
|
|
** or bubbles?
|
|
|
|
comes with emacs.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(bubbles)
|
|
#+END_SRC
|
|
|
|
** or the game of life?
|
|
|
|
believe it or not, comes with emacs.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(life)
|
|
#+END_SRC
|
|
|
|
* why have a web browser when you can have emacs?
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(eww "https://print.linux.usu.edu")
|
|
#+END_SRC
|
|
|
|
* or an init system when you can have emacs?
|
|
|
|
[[https://github.com/a-schaefers/systemE]]
|
|
|
|
* or a window manager when you can have emacs?
|
|
|
|
[[https://github.com/ch11ng/exwm]]
|
|
|
|
* or a therapist when you can have emacs?
|
|
|
|
emacs can help you solve all your life's issues. literally.
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(doctor)
|
|
#+END_SRC
|
|
|
|
* or a trongleposting server... in anything but emacs?
|
|
|
|
that's right. a RESTful API, websocket server, and static file HTTP server. in ELisp. in Emacs.
|
|
|
|
does this not blow your mind??
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(use-package web-server
|
|
:ensure t
|
|
:straight '(web-server
|
|
:type git
|
|
:host github
|
|
:repo "eschulte/emacs-web-server"))
|
|
|
|
(defvar *trongle-chats* (make-ring 100)) ;; "db"
|
|
(defvar *static* "/home/lizzy/git/usufslc/emacs/trongleposting-client/build/") ;; npm run build
|
|
(defvar *chatlog* "/home/lizzy/git/usufslc/emacs/log/emacs-presie.txt")
|
|
|
|
(defvar *index* (concat *static* "index.html"))
|
|
(defvar *port* 9000)
|
|
(defvar *safe-chars* "^[ A-Za-z0-9._~()'!*:@,;+?-]+$")
|
|
(defvar *clients* '())
|
|
|
|
(defun current-iso-time ()
|
|
(format-time-string "%FT%T%:z"))
|
|
|
|
(defun safe-string-p (s &optional regex)
|
|
(unless regex (setq regex *safe-chars*))
|
|
(if (null s)
|
|
nil
|
|
(not (null (string-match regex s)))))
|
|
|
|
(defun validate-chat (chat)
|
|
(seq-every-p
|
|
'safe-string-p
|
|
(mapcar (lambda (field)
|
|
(cdr (assoc field chat)))
|
|
'(author message))))
|
|
|
|
(defun deflate-chat (chat)
|
|
(let ((parsed-j (json-parse-string chat)))
|
|
`((author . ,(gethash "author" parsed-j))
|
|
(message . ,(gethash "message" parsed-j)))))
|
|
|
|
(defun inflate-chat (chat)
|
|
(json-serialize chat))
|
|
|
|
(defun inflate-chat-list (chats)
|
|
(json-serialize
|
|
(vconcat [] chats)))
|
|
|
|
(defun remove-client (process event)
|
|
(setq *clients* (seq-filter
|
|
(lambda (proc)
|
|
(not (equal process proc)))
|
|
,*clients*)))
|
|
|
|
(defun handle-ws (proc input)
|
|
(setq *clients* (cons proc *clients*))
|
|
(set-process-sentinel proc 'remove-client)
|
|
(process-send-string proc (ws-web-socket-frame "pong")))
|
|
|
|
(defun new-post (request)
|
|
(with-slots (process headers) request
|
|
(let* ((body (ws-body request))
|
|
(chat (deflate-chat body)))
|
|
(if (validate-chat chat)
|
|
(let* ((chat (cons `(date . ,(current-iso-time)) chat))
|
|
(chat-json (inflate-chat chat)))
|
|
;; store and log
|
|
(ring-insert *trongle-chats* chat)
|
|
(append-to-file (concat chat-json "\n") nil *chatlog*)
|
|
|
|
;; propogate to open clients
|
|
(mapcar (lambda (client)
|
|
(process-send-string
|
|
client
|
|
(ws-web-socket-frame (inflate-chat chat))))
|
|
,*clients*)
|
|
|
|
(ws-response-header process 200 '("Content-Type" . "application/json"))
|
|
(process-send-string process (json-serialize '((success . t)))))
|
|
(ws-response-header process 400 '("Content-Type" . "application/json"))
|
|
(process-send-string process (json-serialize
|
|
'((error . "invalid chat")
|
|
(success . :false))))))))
|
|
|
|
(defun list-posts (request)
|
|
(with-slots (process headers) request
|
|
(ws-response-header process 200 '("Content-Type" . "application/json"))
|
|
(process-send-string process
|
|
(inflate-chat-list
|
|
(reverse (ring-elements *trongle-chats*))))))
|
|
|
|
(defun retrieve-static-file (request)
|
|
(with-slots (process headers) request
|
|
(let* ((path (replace-regexp-in-string "^/" "" (cdr (assoc :GET headers)))))
|
|
(if (equal path "")
|
|
(ws-send-file process *index*)
|
|
(if (ws-in-directory-p *static* path)
|
|
(if (file-directory-p path)
|
|
(ws-send-404 process)
|
|
(ws-send-file process
|
|
(expand-file-name path *static*)))
|
|
(ws-send-404 process))))))
|
|
(ws-start
|
|
`(((:POST . "/posts") . new-post)
|
|
((:GET . "/posts") . list-posts)
|
|
((:GET . ".*") .
|
|
(lambda (request)
|
|
(if (ws-web-socket-connect request 'handle-ws)
|
|
:keep-alive
|
|
(retrieve-static-file request)))))
|
|
,*port*)
|
|
#+END_SRC
|
|
|
|
* EEE-macs
|
|
|
|
i've come up with "Three E's" that kind of cover emacs' design tenets and goals:
|
|
|
|
** 1. be Extensible
|
|
|
|
this is the first and foremost goal of emacs, and one that should certainly be demonstrated by
|
|
the above demos.
|
|
|
|
the only limit is your creativity. and with a fully bytecode JIT compilable LISP, that
|
|
creativity is (don't quote me) _Easy to Express_.
|
|
|
|
** 2. be Evolving
|
|
|
|
like many other softwares, emacs is a living and breathing creature that is continuously
|
|
growing.
|
|
|
|
the emacs community aims to make emacs the provider of an experience at the bleeding edge
|
|
of writing software. major releases often bring about huge features that "evolve" emacs:
|
|
|
|
1. native lsp support (~tree-sitter~, ~eglot~ in 29 - 2023)
|
|
2. elisp JIT compiler to emacs bytecode (28.1 - 2022)
|
|
3. pixel precise scrolling (long awaited)
|
|
|
|
(there's a joke here about emacs still being single threaded somewhere...)
|
|
|
|
** 3. be Easy as possible
|
|
|
|
while emacs may not adhere to the unix philosophy, it is easy to grok by anyone that
|
|
has used a text editor before.
|
|
|
|
even with no experience, today _you_ could simply drop into ~emacs test.c~ and begin
|
|
writing text. there's no weird "action modes" that require a barrier of entry to write
|
|
code - besides knowing the key combination to save and quit, and how to press arrow keys.
|
|
there's no necessary ~emacstutor~.
|
|
|
|
people even create specific "distributions" of emacs like linux itself to provide a simple
|
|
interface for beginners to even further lower the **mean delta time to become dangerous**.
|
|
|
|
at the same time, emacs is more rich in features than any other software due to its
|
|
extensibility. the further you go, the easier it gets. emacs is self documenting in itself
|
|
(i.e. ~describe-*~) and has great online docs too.
|
|
|
|
* so what does the FSF say?
|
|
|
|
#+BEGIN_QUOTE
|
|
"
|
|
Emacs is "an extensible, customizable, free/libre text editor — and more.
|
|
At its core is an interpreter for Emacs Lisp, a dialect of the Lisp programming
|
|
language with extensions to support text editing.
|
|
"
|
|
- https://www.gnu.org/software/emacs
|
|
#+END_QUOTE
|
|
_hopefully_ this is starting to make sense...
|
|
|
|
* final answer
|
|
so to answer the question, "what is emacs?"...
|
|
|
|
0. it's a text editor
|
|
1. it's a window manager
|
|
2. it's a rich email client
|
|
3. it's a native IDE for ELISP, with optional support for all other languages
|
|
4. it's a web browser
|
|
5. it's a gaming console
|
|
6. it's an interpreter
|
|
7. it's a document editor (more on this later)
|
|
8. it's the love of my life (... what)
|
|
9. ~<insert your thing here>~
|
|
|
|
...maybe it's best to ask, "what is it not?".
|
|
|
|
and the answer to that, dear reader, is that emacs is not a good text editor :)
|
|
* ORG mode
|
|
you may've noticed i have these little guys here in my presentation:
|
|
|
|
#+BEGIN_SRC emacs-lisp :results output
|
|
(princ "I run in a source block!")
|
|
#+END_SRC
|
|
|
|
these are source blocks! blocks of code that can be run interactively in an "org" file; like a jupyter
|
|
notebook.
|
|
|
|
org is by far my most used environment in emacs, outside of editing code. but what's an "org" file?
|
|
|
|
well, like the question "what is emacs?" itself, it's another very complicated answer.
|
|
|
|
"org" is a...
|
|
0. presentation software (what you see here)
|
|
1. calendar
|
|
2. latex editor
|
|
3. markdown editor
|
|
4. html editor
|
|
5. obsidian alternative
|
|
6. open office editor
|
|
7. programming notebook
|
|
8. ...
|
|
|
|
* "your life, in plain text"
|
|
|
|
every single org file is simply plain text. that's the **elegancy**. thus, any way there is to
|
|
structure code, can also be applied to org files.
|
|
|
|
as such, it's common for emacs users to define their ~init.el~ (the bootstrap config script run when
|
|
emacs starts) in an org mode document, whose source-blocks are "compiled" into an ~init.el~ file.
|
|
then one can add notes to one's code, organizing it into separate "trees" of concerns.
|
|
|
|
and certainly org is "your life" - ~org-roam~ is a whole second **extensible** [[https://systemcrafters.net/build-a-second-brain-in-emacs/getting-started-with-org-roam/][brain]].
|
|
|
|
* students, this is for you
|
|
|
|
emacs is godly for math and cs students. between this "interactive notebook" and latex editor,
|
|
you can write stuff without the overhead of ~LaTeX~.
|
|
|
|
introducing a function f:
|
|
S = { students at USU }
|
|
M = { members of FSLC }
|
|
B = { cool, uncool }
|
|
f : S \rightarrow B \ni f(x) = {
|
|
cool (x \in M),
|
|
uncool
|
|
}
|
|
definition of a proper subset:
|
|
A \subset B \Leftrightarrow \forall x (x \in A \Rightarrow x \in B) \wedge A \neq B
|
|
|
|
right now, it doesn't look pretty, but watch this:
|
|
|
|
#+BEGIN_SRC emacs-lisp :results silent
|
|
(org-toggle-pretty-entities)
|
|
#+END_SRC
|
|
|
|
with the built-in emacs pdf viewer it's also easy to completely export a document to latex and view
|
|
its compilation. perfect for assignments!
|
|
|
|
* buffers, windows, frames, oh my
|
|
|
|
to get you in the world of emacs, i should at least introduce the very basics.
|
|
+ frames are the "top level instance" of emacs. they're the actual "window" controlled by
|
|
your window manager or terminal emulator in the instance of a tui; you can drag it around
|
|
and such.
|
|
|
|
+ buffers are interfaces between your emacs client and a file (or process). it's what controls
|
|
the individual text on the screen.
|
|
|
|
+ windows simply hold buffers; think of a "glass window" into a buffer.
|
|
i.e. i can create a new window split in my frame
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(split-window-below)
|
|
#+END_SRC
|
|
|
|
i now have two windows, "viewing" the buffer representing the org file of this presentation.
|
|
|
|
* modes
|
|
|
|
#+BEGIN_QUOTE
|
|
"
|
|
A mode is a set of definitions that customize Emacs behavior in useful ways.
|
|
|
|
There are two varieties of modes: minor modes, which provide features that users can turn on
|
|
and off while editing; and major modes, which are used for editing or interacting with a particular
|
|
kind of text.
|
|
" - https://www.gnu.org/software/emacs/manual/html_node/elisp/Modes.html
|
|
#+END_QUOTE
|
|
|
|
by example, "ORG MODE", a major mode, tells emacs how to format the buffer to a window and draw
|
|
all the neat little symbols and indentation.
|
|
|
|
by contrast ~format-all-mode~ is a minor mode that might look at the major mode (maybe LISP mode, or
|
|
C mode) and determines a formatter to auto-format a buffer's file on save.
|
|
|
|
* key bindings
|
|
|
|
there's a reason it's called "emacs pinky"
|
|
|
|
[[./img/emacs_user_fingers.png]]
|
|
|
|
anyways, you should absolutely know:
|
|
+ "C-x C-s" (ctrl-x ctrl-s) to save a file
|
|
+ "C-x C-c" (ctrl-x ctrl-c) to quit an emacs frame
|
|
+ "C-g" (ctrl-g) to cancel something (in most cases) if you fuck up
|
|
+ "C-x u" (ctrl-x u) to undo
|
|
+ "M-x butterfly" (meta / alt - x) "butterfly"
|
|
|
|
* getting started
|
|
you don't really every need to get good in ELISP to use emacs, despite what you may've been lead to
|
|
believe in this presentation.
|
|
|
|
all you need is the help screen. when you open emacs without a file specified, this is what
|
|
you're greeted with.
|
|
|
|
* so is emacs better than vim?
|
|
|
|
** let's see what trongle has to say
|
|
#+BEGIN_SRC
|
|
____________________________________________________
|
|
/ \
|
|
| i'm gonna start using emacs to write my rust |
|
|
----------------------------------------------------
|
|
\\ :::.
|
|
\\ .::::::
|
|
\\ :::::::::
|
|
\\ .:::::::;od8888bo.
|
|
::::::::OP?'::`*YO?
|
|
.:::::::::::::::::.
|
|
,od8888bo;::::::d88b::
|
|
*":d88b:"*::::::Y88D:::
|
|
.:::Y88D::::::::::YP:::::.
|
|
::::::YP::::::::::::::::::::
|
|
::::::::::::::::::::::::::::::. .oo.
|
|
.:::::::::::::::::::::oOOb:::::::. ,oOOOD
|
|
::::::::::::d8b:::::::::*OOO::::::;oOOOOP"
|
|
::::::::::::::`*Y88888P:::OOOb:::;dOOOP"
|
|
.::::::::::::::::::::::::::;OOOD:/dOOOOo::
|
|
.::::::::::::::::::::::::::;OOOOOOOOOOOOO*::
|
|
.:::::::::::::::::::::::::::oOOOOOOOOOOOOOOD::.
|
|
`:::::::::::::::::::::::::::OOOOOOOOOOOOOOOB::'
|
|
*OOOOOOOOOOOOOOD
|
|
`*OOOOOOOOOOP"
|
|
`"OOOP*"
|
|
#+END_SRC
|
|
|
|
thank you trongle! very insightful.
|
|
|
|
** in all seriousness
|
|
|
|
... well the answer is **it doesn't matter**. none is greater than the other.
|
|
|
|
hahahah!! just kidding! yes, of _course_ emacs is better than vim.
|
|
|
|
** can't decide? be EVIL
|
|
|
|
[[./img/yay_evil.png]]
|
|
|
|
if you want to be EVIL and "emulate" vim in emacs, there's EVIL mode.
|
|
|
|
EVIL mode aims to be near 100% compatible with all things vim. Doom Emacs
|
|
and Spacemacs are somewhat sane distributions of Emacs meant for recent
|
|
converts to the Church of Emacs that may know a thing or two about ViM
|
|
bindings.
|
|
|
|
and... a recent convert to being EVIL... take it away, Ethan!
|