Emacs Lisp
Emacs Lisp
Beginner — Fundamentals
Q1: What is Emacs Lisp?
A dialect of Lisp that serves as the extension language of Emacs. The Emacs editor is largely written in it, and you use it to configure and extend Emacs. It is a dynamically-typed, primarily dynamically-scoped (historically) Lisp with deep integration into the editor (buffers, windows, text properties).
Q2: How do I evaluate an Elisp expression interactively?
C-x C-eevaluates the expression before point (eval-last-sexp).M-x eval-expression(M-:) prompts for an expression in the minibuffer.M-x eval-buffer/eval-regionevaluate larger chunks.ielmopens an interactive Elisp REPL.
Q3: What is the difference between a "form" and an "expression"?
They are used almost interchangeably. A form is any Lisp object meant to be evaluated. Self-evaluating forms (numbers, strings, keywords), symbol forms (variables), and list forms (function/macro/special-form calls) are the categories.
Q4: How do you write a comment in Elisp?
With a semicolon ;. Conventions:
;inline comment after code.;;comment aligned to the code's indentation.;;;top-level/section comment.;;;;heading.
Q5: What are the basic data types?
Integers, floats, symbols, strings, characters (which are integers), cons cells/lists, vectors, hash tables, and more specialized types like markers, buffers, and overlays.
Q6: How do I define a variable?
(defvar my-var 10 "A docstring.") ; only sets if currently unbound (defconst my-pi 3.14159 "Pi.") ; intended as a constant (setq my-var 20) ; assignment
Q7: What is the difference between defvar and setq?
defvar declares a special (dynamic) variable and assigns a default only if
it is not already bound. setq simply assigns a value to an existing binding.
Use defvar for global configuration variables so re-evaluating a file doesn't clobber a user's value.
Q8: How do I define a function?
(defun my-add (a b) "Return the sum of A and B." (+ a b))
Q9: What makes a function a "command"?
Adding (interactive ...) as its first form.
Commands can be invoked via M-x and bound to keys.
(defun my-greet () (interactive) (message "Hello!"))
Q10: What does message do?
Displays a formatted string in the echo area and logs it to the *Messages* buffer.
Uses format-style directives: %s, %d, %S, etc.
Q11: What is nil and t?
nil is the canonical false value and also the empty list ().
t is the canonical true value.
Everything other than nil is truthy.
Q12: Is the empty list the same as nil?
Yes. () and nil are identical objects in Elisp.
Q13: How do I create a list?
(list 1 2 3) ; => (1 2 3) '(1 2 3) ; quoted literal (cons 1 '(2 3)) ; => (1 2 3)
Q14: What is the difference between quote and list?
(list 1 (+ 1 1)) evaluates its arguments → (1 2).
'(1 (+ 1 1)) does not evaluate → (1 (+ 1 1)). 'x is shorthand for (quote x).
Q15: What are car and cdr?
car returns the first element of a cons cell; cdr returns the rest.
For a list (1 2 3): (car list) → 1, (cdr list) → (2 3).
Q16: How do I get the Nth element of a list?
(nth 2 '(a b c d)) ; => c (zero-based) (nthcdr 2 '(a b c d)) ; => (c d) (elt '(a b c) 1) ; => b (works on sequences)
Q17: How do I add an element to the front of a list?
(cons 0 '(1 2 3)) ; => (0 1 2 3) (push 0 my-list) ; destructively updates the variable
Q18: How do I check equality?
eq— identity (same object); good for symbols, small integers.eql— likeeqbut also compares numbers of the same type.equal— structural equality (lists, strings).=— numeric equality (numbers only).string=— string equality.
Q19: How do I write an if statement?
(if (> x 0) (message "positive") ; then (single form) (message "non-positive")) ; else (any number of forms)
Q20: What is when and unless?
when runs its body if the condition is non-nil (no else).
unless runs its body if the condition is nil. Both allow multiple body forms without progn.
Q21: What is progn?
Evaluates several forms in sequence and returns the value of the last. Useful where a single form is expected but you need several.
Q22: How does cond work?
A multi-branch conditional:
(cond ((< x 0) "negative") ((= x 0) "zero") (t "positive"))
Q23: What is let vs let*?
let binds all variables in parallel (initializers can't see each other).
let* binds sequentially so later bindings can reference earlier ones.
(let* ((a 1) (b (+ a 1))) b) ; => 2 (let would error: a unbound)
Q24: How do I loop over a list?
(dolist (item '(1 2 3)) (message "%d" item))
Q25: How do I loop N times?
(dotimes (i 5) (message "%d" i)) ; i goes 0..4
Q26: How do I write a while loop?
(let ((i 0)) (while (< i 5) (message "%d" i) (setq i (1+ i))))
Q27: How do I format a string?
(format "Name: %s, Age: %d" "Bob" 42)
format-message additionally translates quote characters for messages.
Q28: What is the difference between %s and %S in format?
%s uses princ-style (human-readable, no quotes on strings).
%S uses prin1-style (a readable, re-parseable representation with quotes/escapes).
Q29: How do I concatenate strings?
(concat "foo" "-" "bar") ; => "foo-bar"
Q30: How do I read documentation for a function or variable?
C-h f(describe-function)C-h v(describe-variable)C-h k(describe-key)C-h o(describe-symbol) — function or variable.
Q31: What is a symbol?
A first-class named object with four cells: name, value (variable binding), function (function binding), and property list.
Symbols are interned in obarray so identical names refer to the same object.
Q32: What is the difference between a symbol's value cell and function cell?
A symbol can simultaneously name a variable and a function.
(foo) uses the function cell; foo as a value uses the value cell. This is why Elisp is a "Lisp-2".
Q33: How do I get/set a symbol's value programmatically?
(symbol-value 'my-var) (set 'my-var 5) ; like setq but evaluates the symbol arg (symbol-function 'my-fn) (fset 'my-fn (lambda () 1))
Q34: What is a keyword symbol?
A symbol starting with : (e.g. :foo). It is self-evaluating and used as a constant marker, frequently in plists and keyword arguments.
Q35: How do I convert between strings, symbols, and numbers?
(intern "foo") ; string -> symbol (symbol-name 'foo) ; symbol -> string (number-to-string 42) ; -> "42" (string-to-number "42") ; -> 42
Beginner/Intermediate — Working with Emacs
Q36: What is the "current buffer"?
The buffer that Elisp functions operate on by default. Most editing functions implicitly act on it. current-buffer returns it.
Q37: What is "point"?
The location of the cursor / insertion position in a buffer, between two characters.
(point) returns its integer position; point-min and point-max give the buffer boundaries.
Q38: How do I move point?
(goto-char (point-min)) (forward-char 5) (forward-line 2) (beginning-of-line)
Q39: How do I insert text at point?
(insert "Hello, world") (insert-char ?* 3) ; inserts ***
Q40: How do I read text from the buffer?
(buffer-string) ; whole buffer (buffer-substring start end) ; with properties (buffer-substring-no-properties s e) ; plain text (thing-at-point 'word)
Q41: What is save-excursion?
A macro that saves point (and the current buffer) and restores them after its body runs — even on non-local exit. Use it when you move point temporarily.
(save-excursion (goto-char (point-min)) (insert "header\n"))
Q42: What is save-restriction?
Saves and restores the buffer's narrowing state (the visible region set by narrow-to-region / widen).
Q43: How do I switch the buffer Elisp operates on?
(with-current-buffer "*scratch*" (insert "hi")) (set-buffer buf) ; lower-level, no automatic restore
Q44: How do I create a new buffer?
(get-buffer-create "*my-buffer*") (generate-new-buffer "*my-buffer*") ; guarantees a fresh, uniquely-named one
Q45: What is the difference between switch-to-buffer and set-buffer?
switch-to-buffer makes a buffer visible in the selected window (interactive,
display-oriented). set-buffer only changes the current buffer for Elisp; it
does not change what is displayed and is not preserved after the command.
Q46: How do I read a file into a string?
(with-temp-buffer (insert-file-contents "/path/to/file") (buffer-string))
Q47: How do I write a string to a file?
(with-temp-file "/path/to/file" (insert "content"))
Q48: What is with-temp-buffer?
Creates a temporary buffer, makes it current for the body, and kills it afterward. Ideal for text processing that shouldn't touch user buffers.
Q49: How do I bind a key globally?
(global-set-key (kbd "C-c g") #'my-greet) (keymap-global-set "C-c g" #'my-greet) ; modern API (Emacs 29+)
Q50: How do I bind a key in a specific mode?
(define-key emacs-lisp-mode-map (kbd "C-c r") #'my-run) (keymap-set emacs-lisp-mode-map "C-c r" #'my-run) ; Emacs 29+
Q51: What is kbd and why use it?
kbd converts a human-readable key description ("C-c C-x") into the internal
key sequence representation. It's portable and clearer than raw string/vector forms.
Q52: How do I prompt the user for input?
(read-string "Name: ") (read-number "Count: ") (completing-read "Choose: " '("a" "b" "c")) (yes-or-no-p "Continue? ") (y-or-n-p "Continue? ")
Q53: What is the interactive spec code "p" vs "P"?
p passes the numeric prefix argument as a number. P passes the raw prefix
argument (e.g. nil, (4), a number). Many codes exist: s string, n
number, r region, b buffer name, etc.
Q54: How do I get the region's text?
(buffer-substring-no-properties (region-beginning) (region-end))
For commands, declare (interactive "r") to receive start and end.
Q55: How do I run code only after Emacs starts up?
Use after-init-hook or emacs-startup-hook:
(add-hook 'emacs-startup-hook #'my-startup-fn)
Intermediate — Functions, Scope, Data
Q56: What is a lambda?
An anonymous function:
(lambda (x) (* x x)) (funcall (lambda (x) (* x x)) 5) ; => 25
Q57: What is the #' reader macro?
#'foo is shorthand for (function foo). It quotes a function, and for
lambdas it signals to the byte-compiler that the form is a function (enabling compilation of the lambda).
Q58: What is the difference between funcall and apply?
funcall calls a function with individual arguments. apply calls it with the
last argument being a list that is spread into the remaining arguments.
(funcall #'+ 1 2 3) ; => 6 (apply #'+ 1 2 '(3 4)) ; => 10
Q59: How do optional and rest arguments work?
(defun f (a &optional b &rest c) (list a b c)) (f 1) ; => (1 nil nil) (f 1 2 3 4) ; => (1 2 (3 4))
Q60: What is dynamic scope vs lexical scope?
Dynamic scope: a variable's binding is visible to all code called during the binding's extent. Lexical scope: a variable is visible only within the textual region where it's defined. Modern Elisp files should enable lexical binding.
Q61: How do I enable lexical binding?
Put this as the first line of the file:
;;; -*- lexical-binding: t; -*-
It is the default in Emacs 30+ for new files but should be declared explicitly.
Q62: Why does lexical binding matter for closures?
Only with lexical binding do lambdas capture their surrounding variables to form true closures.
(defun make-adder (n) (lambda (x) (+ x n))) ; n captured lexically (funcall (make-adder 3) 10) ; => 13
Q63: What still uses dynamic scope?
Variables declared with defvar=/=defconst (special variables) remain dynamically scoped even under lexical binding.
This is intentional — it's how let-rebinding of configuration variables works.
Q64: What is a property list (plist)?
A flat list of alternating keys and values:
(setq pl '(:name "Bob" :age 42)) (plist-get pl :name) ; => "Bob" (plist-put pl :age 43)
Q65: What is an association list (alist)?
A list of cons cells (key . value):
(setq al '((a . 1) (b . 2))) (assq 'a al) ; => (a . 1) (alist-get 'b al) ; => 2 (cdr (assoc "k" al))
Q66: When should I use a hash table instead of an alist?
For large collections or frequent lookups — hash tables give O(1) access vs alists' O(n).
(let ((h (make-hash-table :test 'equal))) (puthash "k" 1 h) (gethash "k" h)) ; => 1
Q67: What :test options exist for hash tables?
eq, eql, equal (built-in), and you can define custom ones with define-hash-table-test.
Use equal for string keys.
Q68: How do I iterate a hash table?
(maphash (lambda (k v) (message "%s=%s" k v)) h)
Or (hash-table-keys h) / (hash-table-values h) from subr-x=/=map.
Q69: What is mapcar vs mapc vs mapcan?
mapcar— applies fn to each element, returns a new list of results.mapc— applies fn for side effects, returns the input list.mapcan— like mapcar but destructively concatenates the (list) results.
Q70: How do I filter a list?
(seq-filter #'cl-evenp '(1 2 3 4)) ; => (2 4) (cl-remove-if-not #'cl-evenp '(1 2 3 4))
Q71: How do I reduce/fold a list?
(seq-reduce #'+ '(1 2 3 4) 0) ; => 10 (cl-reduce #'+ '(1 2 3 4)) ; => 10
Q72: What is the seq library?
A generic sequence-manipulation library (seq.el) that works uniformly across
lists, vectors, and strings: seq-map, seq-filter, seq-find, seq-reduce,
seq-do, seq-uniq, etc.
Q73: What is dash.el?
A popular third-party functional library providing -map, -filter,
-reduce, threading macros -> / -->, etc. Many prefer built-in seq now,
but dash remains common in the wild.
Q74: How do I sort a list?
(sort '(3 1 2) #'<) ; => (1 2 3) (sort my-list :key #'car :lessp #'<) ; Emacs 30+ keyword form
Note: sort may be destructive; copy first if you need the original.
Q75: How do I reverse a list?
(reverse '(1 2 3)) ; => (3 2 1) non-destructive (nreverse my-list) ; destructive, faster
Q76: What is the difference between destructive and non-destructive functions?
Destructive functions (nreverse, nconc, setcar, delete) modify their arguments' structure in place;
non-destructive ones (reverse, append, remove) return fresh copies.
Destructive variants are faster but risk aliasing bugs.
Q77: How do I copy a list or sequence?
(copy-sequence lst) ; shallow copy (copy-tree lst) ; deep copy of the cons structure
Q78: What is cl-lib?
The Common Lisp compatibility library shipped with Emacs.
It provides cl-loop, cl-defun, cl-destructuring-bind, cl-case,
generic sequence functions, structures (cl-defstruct), and more.
Always (require 'cl-lib).
Q79: How do I do a case / switch?
(cl-case x (1 "one") ((2 3) "two or three") (t "other"))
pcase is the more powerful, idiomatic modern choice.
Q80: What is pcase?
A pattern-matching case. It destructures and matches by structure, type, predicate, etc.
(pcase value ((pred stringp) "a string") (`(,a . ,b) (format "cons %s %s" a b)) ((or 1 2 3) "small number") (_ "anything else"))
Q81: How do I destructure a list?
(cl-destructuring-bind (a b &optional c) '(1 2) (list a b c)) ; => (1 2 nil) (pcase-let ((`(,x ,y) '(1 2))) (+ x y)) ; => 3 (seq-let (a b) '(1 2 3) (list a b)) ; => (1 2)
Intermediate — Macros, Errors, Control Flow
Q82: What is a macro?
A function that runs at expansion time, receiving unevaluated code and returning new code to be evaluated. Macros let you extend the language syntax and control evaluation.
Q83: How do I define a macro?
(defmacro my-unless (cond &rest body) `(if ,cond nil (progn ,@body)))
Q84: What is the backquote (`), comma (,), and ,@?
- Backquote starts a template where most things are literal.
,unquotes — evaluates and inserts the value.,@splices a list's elements into the surrounding list.
Q85: How do I see what a macro expands to?
(macroexpand '(my-unless t (foo))) (macroexpand-1 ...) ; one level (macroexpand-all ...) ; fully
M-x emacs-lisp-macroexpand or pp-macroexpand-last-sexp for interactive use.
Q86: What is variable capture / hygiene in macros?
When a macro introduces a binding whose name collides with user code, causing bugs.
Avoid it by generating unique symbols with gensym=/=cl-gensym or make-symbol.
(defmacro my-swap (a b) (let ((tmp (gensym))) `(let ((,tmp ,a)) (setf ,a ,b) (setf ,b ,tmp))))
Q87: When should I use a macro vs a function?
Use a function by default. Use a macro only when you must control evaluation
(delay/repeat/skip arguments), introduce binding forms, or generate code at
compile time. Macros don't compose like functions (can't funcall them).
Q88: How do I signal an error?
(error "Bad value: %s" x) (user-error "Please select a region") ; for user mistakes, no debugger (signal 'wrong-type-argument (list 'stringp x))
Q89: How do I catch errors?
(condition-case err (risky-operation) (file-missing (message "No file: %s" err)) (error (message "Failed: %s" (error-message-string err))))
Q90: What is unwind-protect?
Guarantees cleanup forms run whether or not the protected body exits normally or via error/non-local exit — like try/finally.
(unwind-protect
(do-something)
(cleanup))
Q91: What is ignore-errors and with-demoted-errors?
ignore-errors evaluates body and returns nil on any error.
with-demoted-errors turns errors into messages (useful in hooks/init so one failure doesn't abort everything).
Q92: What are catch and throw?
A non-local exit mechanism by tag:
(catch 'found (dolist (x list) (when (match-p x) (throw 'found x))))
Q93: What is cl-block / cl-return?
A lexical exit construct from cl-lib. cl-return-from exits a named block;
cl-defun establishes an implicit block named after the function.
Q94: How do I define a custom error type?
(define-error 'my-error "My custom error" 'error) ;; then: (signal 'my-error (list "details"))
Q95: What is cl-loop?
A very powerful iteration macro from cl-lib:
(cl-loop for i from 1 to 5 when (cl-oddp i) collect (* i i)) ; => (1 9 25)
Intermediate/Advanced — Buffers, Text, Regexp
Q96: How do I search forward for a regexp?
(when (re-search-forward "foo\\(bar\\)?" nil t) (match-string 0))
The third arg t means "return nil instead of erroring on failure."
Q97: Why are backslashes doubled in Elisp regexps?
Because the regexp is written as a string, and string syntax also uses
backslash escapes. So a regexp group \(...\) must be written \\(...\\) in the string literal. rx avoids this.
Q98: What is rx?
A macro that builds regexps from readable s-expressions, eliminating backslash soup:
(rx bol (group (+ digit)) "-" (group (+ alpha)) eol)
Q99: How do I get the matched text after a search?
(match-string 0) ; whole match (from buffer) (match-string 1) ; first group (match-string-no-properties 1) (match-beginning 1) (match-end 1)
Q100: How do I replace text matching a regexp programmatically?
(while (re-search-forward "foo" nil t) (replace-match "bar")) ;; or on strings: (replace-regexp-in-string "foo" "bar" "foofoo")
Q101: What is the difference between looking-at and re-search-forward?
looking-at tests whether text starting at point matches a regexp without
moving point. re-search-forward scans forward and moves point past the match.
Q102: How do I narrow the buffer?
(narrow-to-region start end) ; restrict visible/operable text (widen) ; restore
Wrap in save-restriction when narrowing temporarily.
Q103: What are markers?
Objects that point to a position in a buffer and move automatically as text is inserted/deleted, unlike plain integer positions. Use them when you need a position to stay valid across edits.
Q104: What are text properties?
Attributes attached to characters in a buffer/string (e.g. face, read-only, custom keys). They travel with the text.
(put-text-property start end 'face 'bold)
(propertize "hi" 'face 'warning)
(get-text-property pos 'face)
Q105: What is the difference between text properties and overlays?
Text properties are part of the buffer text (copied/saved with it). Overlays are separate objects layered over a region, independent of the text, ideal for transient highlighting (e.g. search, flycheck). Overlays can be slower in large numbers.
Q106: How do I create an overlay?
(let ((ov (make-overlay start end)))
(overlay-put ov 'face 'highlight))
Q107: How do I delete a region of text?
(delete-region start end) (delete-char 1) ; at point (kill-region s e) ; deletes and saves to kill ring
Q108: How do I process a buffer line by line?
(goto-char (point-min)) (while (not (eobp)) (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) ;; process line (forward-line 1)))
Q109: What do bobp and eobp mean?
bobp → point is at beginning of buffer; eobp → point is at end of buffer.
Also bolp / eolp for line beginning/end.
Q110: How do I make a buffer read-only temporarily during code?
(let ((inhibit-read-only t)) (insert "text")) ; bypass read-only for the body
Advanced — Modes, Hooks, Customization
Q111: What is a major mode?
A mode that defines the primary behavior of a buffer (syntax, keymap,
font-locking, indentation). Each buffer has exactly one major mode. Defined
with define-derived-mode.
Q112: What is a minor mode?
A toggleable feature that augments behavior independently of the major mode
(e.g. flyspell-mode). Many minor modes can be active at once. Defined with
define-minor-mode.
Q113: How do I define a minor mode?
(define-minor-mode my-mode "Toggle My mode." :init-value nil :lighter " My" :keymap (make-sparse-keymap) (if my-mode (message "enabled") (message "disabled")))
Q114: How do I define a derived major mode?
(define-derived-mode my-mode prog-mode "MyLang" "Major mode for MyLang." (setq-local comment-start "# ") (setq-local font-lock-defaults '(my-keywords)))
Q115: What is a hook?
A variable holding a list of functions run at a defined point (e.g.
prog-mode-hook, before-save-hook). Add functions with add-hook.
Q116: How do I add a function to a hook?
(add-hook 'prog-mode-hook #'display-line-numbers-mode) (add-hook 'prog-mode-hook #'my-fn 90) ; depth/append control (remove-hook 'prog-mode-hook #'my-fn)
Q117: Why use #' when adding to a hook?
It makes the intent (a function reference) explicit and lets the byte-compiler warn if the function is undefined. Plain symbols work too, but lambdas in hooks are hard to remove and should generally be avoided.
Q118: What is setq-local vs setq-default?
setq-local sets a buffer-local value. setq-default sets the default value
that buffers without a local binding see. make-local-variable /
make-variable-buffer-local control buffer-locality.
Q119: What is a buffer-local variable?
A variable whose value can differ per buffer. Mode code commonly uses
setq-local to configure per-buffer behavior without affecting other buffers.
Q120: What is defcustom?
Declares a user-customizable variable integrated with the Customize UI, including a type, group, and docstring.
(defcustom my-width 80 "Preferred width." :type 'integer :group 'my-group)
Q121: What is defgroup and defface?
defgroup declares a customization group to organize options. defface
declares a customizable face (font/color set) used for text display.
Q122: How do I make a variable safe as a file-local variable?
Set its safe-local-variable property with a predicate, or use the
:safe keyword in defcustom:
(defcustom my-opt 1 "..." :type 'integer :safe #'integerp)
Q123: What is add-to-list and how does it differ from push?
add-to-list adds an element only if not already present (using equal by
default) and evaluates its arguments; it's meant for list-valued variables.
push always prepends and is a generalized-variable macro. For defcustom
lists, prefer setting via Customize or add-to-list.
Q124: What is use-package?
A macro (built into Emacs 29+) for declarative, organized package configuration — deferring loading, binding keys, setting variables, and adding hooks in one tidy form.
(use-package magit :bind ("C-x g" . magit-status) :config (setq magit-diff-refine-hunk t))
Q125: How does autoloading work?
An autoload registers a function name so that calling it loads the defining
file on demand. Created via the ;;;###autoload magic comment and generated
autoload files, or autoload directly. It speeds startup by deferring loads.
Advanced — Performance, Compilation, Async
Q126: What is byte-compilation?
Compiling .el to .elc bytecode for faster loading/execution and earlier
warnings. byte-compile-file, M-x byte-recompile-directory. Warnings catch
undefined functions, unused vars, etc.
Q127: What is native compilation?
Emacs 28+ can compile Elisp to native machine code via libgccjit
(native-comp), giving significant speedups. .eln files are produced and
cached. Triggered automatically (native-comp-jit-compilation) or via
native-compile.
Q128: How do I benchmark Elisp code?
(benchmark-run 1000 (my-function)) ; => (total-time gc-count gc-time) (benchmark-elapse (my-function))
Q129: How do I profile Elisp?
Use the built-in profiler:
(profiler-start 'cpu) ;; ... do work ... (profiler-report) (profiler-stop)
Q130: Why can lists be slow, and what's the alternative?
nth=/=length on long lists are O(n). For random access use vectors; for
keyed lookup use hash tables. Building a list with repeated append is O(n2);
prefer push + nreverse.
Q131: What is the purpose of nreverse after push in loops?
push prepends (O(1)), building the list in reverse. nreverse flips it to
the intended order at the end — an idiomatic, efficient way to accumulate a
list.
Q132: How do I avoid garbage and speed up tight loops?
Use lexical binding, prefer built-in primitives, avoid consing in loops,
preallocate vectors, use cl-loop with collect, and byte/native compile.
Raise gc-cons-threshold temporarily for bulk work.
Q133: Is Elisp single-threaded?
Effectively yes for Lisp execution. Emacs 26+ has cooperative threads
(make-thread) but they don't run truly in parallel — they yield at blocking
points. Long computations still block the UI.
Q134: How do I run things asynchronously without blocking Emacs?
run-with-timer/run-with-idle-timerfor deferred work.- Process-based async via
make-process/start-processwith filters and sentinels. url-retrievefor async HTTP; libraries likeasync.elfor subprocess Lisp.
Q135: What is a process filter and sentinel?
A filter function receives output chunks from an asynchronous process. A sentinel is called when the process changes state (e.g. exits). Together they let you handle subprocess I/O without blocking.
(make-process :name "ls" :command '("ls") :filter (lambda (proc out) (message "%s" out)) :sentinel (lambda (proc ev) (message "done: %s" ev)))
Q136: How do I run a shell command and get its output?
(shell-command-to-string "echo hi") (call-process "ls" nil t nil "-l") ; synchronous, into current buffer
Q137: What is a timer?
A scheduled callback. run-with-timer fires after a delay (optionally
repeating); run-with-idle-timer fires when Emacs has been idle for a period.
Cancel with cancel-timer.
Q138: What is debouncing and how do I implement it in Elisp?
Delaying an action until input settles. Implement by canceling a pending timer and rescheduling on each event:
(defvar my--timer nil) (defun my-debounced () (when my--timer (cancel-timer my--timer)) (setq my--timer (run-with-idle-timer 0.5 nil #'my-do-work)))