Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User context handling #102

Draft
wants to merge 83 commits into
base: 2.0-integration
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
b71c30c
Fix links to point to current repo home at drym-org
countvajhula Feb 25, 2023
2588a52
Deprecate the Hydra modal provider
countvajhula Feb 25, 2023
88a016f
remove a leftover reference to `symex-modal-backend`
countvajhula Feb 25, 2023
7c10bc9
make a sentence a bit more clear
countvajhula Mar 7, 2023
caac021
note todo re: `symex-define-command`
countvajhula Sep 15, 2022
ecc9cfa
Add a basic `symex-define-command` macro
countvajhula Sep 15, 2022
b9d7921
abstract "tidy" operation over lisp and ts
countvajhula Sep 15, 2022
79ae4c5
define "clear" using `symex-define-command`
countvajhula Sep 15, 2022
73e5858
move/rename some interfaces to better reflect abstraction level
countvajhula Sep 15, 2022
313aca6
define "replace" as a proper primitive operation
countvajhula Sep 15, 2022
6490b64
Add `symex-define-insertion-command` macro
countvajhula Sep 15, 2022
cfaa4b6
define "open after" as an insertion command
countvajhula Sep 15, 2022
518697c
define "open before" as an insertion command
countvajhula Sep 15, 2022
3e3b164
note some todos
countvajhula Sep 29, 2022
e33e649
extract ts tidying and selection since it's in the wrapping command m…
countvajhula Sep 29, 2022
3f716ea
define deletion using the command macro
countvajhula Sep 29, 2022
00558f4
define more insertion commands using the macro
countvajhula Oct 7, 2022
e9f88ad
avoid startup issue with macro being undefined
countvajhula Oct 8, 2022
4f41375
reuse deletion code in `change`
countvajhula Feb 25, 2023
529190d
undo `change` with single undo, and follow this for all commands
countvajhula Feb 25, 2023
f3b51c9
declare emacs indent style for command macros
countvajhula Feb 25, 2023
d57b3a2
declare most transformations formally as symex commands
countvajhula Feb 25, 2023
eeff17d
fix symex-replace so undo works in one step
countvajhula Feb 25, 2023
f909f67
fix a selection issue affecting most commands wrt indented symexes
countvajhula Mar 1, 2023
bed2cf3
Improve primitive Lisp parsers
countvajhula Mar 7, 2023
d80a89d
improve primitive "up" motion to ensure valid posterior selection
countvajhula Mar 7, 2023
5ede7bb
Improve Lisp paste primitives
countvajhula Mar 7, 2023
051d05b
Simplify lisp tidy feature
countvajhula Mar 7, 2023
1b8053f
fix paste-after to select the pasted expression
countvajhula Mar 7, 2023
45bb156
a "hack" to enter strings
countvajhula Mar 9, 2023
acc34c3
don't stray from line on visual line motions
countvajhula Mar 9, 2023
f9009d5
fix hanging whitespace in append-newline
countvajhula Mar 9, 2023
ee470d5
fix infinite loop in shifting forward "the most" at the top level
countvajhula Mar 9, 2023
02557fc
fix join joining to previous on last expression (do nothing instead)
countvajhula Mar 9, 2023
2dc61c9
fix some calls to symex-tidy
countvajhula Mar 9, 2023
e948219
fix eval-print which was printing the next expression
countvajhula Mar 9, 2023
8ca5d31
simplify join-lines implementation
countvajhula Mar 9, 2023
cf3184d
tidy all affected symexes after joining lines
countvajhula Mar 9, 2023
67d0195
fix infinite loop in tidy-affected when on last symex
countvajhula Mar 9, 2023
6b1e09c
improve tidy-affected implementation, don't mutate point
countvajhula Mar 9, 2023
f052466
tidy affected symexes in appending newlines too
countvajhula Mar 9, 2023
119ca59
commit low-level utility that was left out
countvajhula Mar 9, 2023
0c996b7
improve lisp deletion primitive to handle a case better
countvajhula Mar 9, 2023
b6b763d
fix trailing whitespace in tidying
countvajhula Mar 9, 2023
55f7ebf
better handle another case in deletion
countvajhula Mar 9, 2023
a288ff4
fix open line below in the presence of an inline comment
countvajhula Mar 9, 2023
1bf6856
remove unused function
countvajhula Mar 9, 2023
2fe0076
rename functions to reflect toplevel private/public correctly
countvajhula Mar 9, 2023
f779d28
fix name
countvajhula Mar 9, 2023
fdd0945
handle a corner case in lisp primitive forward motion
countvajhula Mar 9, 2023
5a618cf
improve tidy-affected implementation, esp fix initial behavior
countvajhula Mar 9, 2023
c036020
improve paste implementation, handle some edge cases better
countvajhula Mar 9, 2023
973e673
add an extra newline in pasting at the toplevel for "island" symexes
countvajhula Mar 9, 2023
1e9599e
refine condition for adding newline padding while pasting
countvajhula Mar 9, 2023
dda2909
further refine toplevel newline padding criteria during paste
countvajhula Mar 10, 2023
d464a96
fix handling of some edge cases in paste
countvajhula Mar 10, 2023
4e8c05f
docs: some tips on debugging with macros present
countvajhula Mar 10, 2023
5d9503d
handle a case more naturally in lisp primitive deletion
countvajhula Mar 10, 2023
7dfa83e
Handle an edge case in adjusting point, at ( | abc ...)
countvajhula Mar 10, 2023
959b1b3
simplify "clear" implementation, handle more cases
countvajhula Mar 10, 2023
0dcc055
improve replace, fix some existing cases and handle more cases
countvajhula Mar 10, 2023
055c833
fix an edge case in join-lines at eol
countvajhula Mar 11, 2023
60ea788
handle more cases in symex-replace
countvajhula Mar 11, 2023
f54bec4
fix: nothing needs to be done in clear if already empty
countvajhula Mar 11, 2023
95726d6
fix some cases involving the use of quantifiers in paste-before
countvajhula Mar 11, 2023
6472a16
shed evil-cleverparens dependency
countvajhula Mar 11, 2023
a3f08ed
shed lispy dependency
countvajhula Mar 11, 2023
f189d13
update some docs
countvajhula Mar 13, 2023
4b95c1e
fix capture backwards when on first symex
countvajhula Mar 14, 2023
9e29994
fix a bug in paste-after that was causing an infinite loop
countvajhula Mar 14, 2023
c55260d
a couple of comments
countvajhula Mar 14, 2023
2ae554b
restore proper handling of deletion at eol
countvajhula Mar 15, 2023
e824c9d
fix handling of strings in deleting the last element in a multi-line …
countvajhula Mar 15, 2023
6482e0f
fix handling of empty forms in nearest selection
countvajhula Mar 15, 2023
926b325
fix selection after tidy-remaining
countvajhula Mar 15, 2023
6f0e4aa
improve another case in paste-after
countvajhula Mar 15, 2023
0ffbab0
make a note about behavior in an edge case
countvajhula Mar 15, 2023
89d191f
handle eob better in paste-after
countvajhula Mar 21, 2023
824be59
use forward-line instead of next-line (as advised by docs)
countvajhula Mar 21, 2023
5042eb3
Proof-of-concept for setting user context
countvajhula Mar 19, 2023
c172f82
fix function-valued variable issue
countvajhula Mar 20, 2023
afb2cc2
set default eval function to error
countvajhula Mar 20, 2023
a355b7a
docstring
countvajhula Mar 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions DSL-Docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Symex DSL
Introduction
------------

The Symex.el Emacs package consists of three things: (1) A high-level language (or DSL) for tree operations, (2) A low-level tree abstraction layer, and (3) An Evil modal UI. The modal UI is documented in the `README <https://github.com/countvajhula/symex.el/blob/master/README.rst>`_, and the low-level abstraction layer is fulfilled by third party packages like Paredit and Lispy. This is the documentation for the DSL.
The Symex.el Emacs package consists of three things: (1) A high-level language (or DSL) for tree operations, (2) A low-level tree abstraction layer, and (3) An Evil modal UI. The modal UI is documented in the `README <https://github.com/drym-org/symex.el/blob/master/README.rst>`_, and the low-level abstraction layer is fulfilled by third party packages like Paredit and Tree-Sitter. This is the documentation for the DSL.

The Symex DSL allows you to specify arbitrary tree traversals in a cursor-oriented manner. That is, instead of describing traversals from an absolute reference point such as a root node, it allows you to describe traversals from the first-person vantage point of the cursor -- what would you do if you were where this cursor is right now? It allows you to describe what you'd like to do in intuitive terms that make sense for movement in a tree. Symex is the language a squirrel might use to describe a traversal to another squirrel.

Expand Down Expand Up @@ -443,6 +443,10 @@ To use it, first evaluate the ``symex-execute-traversal`` function for debugging

There are also lots of other features like setting and unsetting breakpoints (``b`` and ``u``), seeing a backtrace (``d``), evaluating expressions in the evaluation context (``e``), and lots more, making it an indispensible tool for ELisp debugging.

Note that if you are attempting to debug a feature implemented as a macro like ``symex-define-command``, you may need to copy the contents of the command to a new function and call that function from the macro, in order to be able to debug it. You would need to evaluate the function for debugging rather than the macro. Naively, if you attempt to debug the macro, the debugger is triggered at compile time (i.e. as soon as you attempt to evaluate it for debugging!) and not at runtime when you're actually interested in using it.

Sometimes, the debugger appears to get overridden by Evil keybindings, complaining that the "Buffer is read-only" when you attempt to ``s`` to step forward. Saving the buffer (as opposed to debugging an unsaved buffer) seems to solve these issues, and if not, killing and reopening the buffer does.

When you're done debugging, you can remove the debugger hooks by just evaluating the debugged functions in the usual way (e.g. via ``M-x eval-defun``).

Also see `this series on ELisp debugging <https://endlessparentheses.com/debugging-emacs-lisp-part-1-earn-your-independence.html>`__ for more tips.
Expand All @@ -457,7 +461,7 @@ Minimizing Complexity

Symex uses `advice <https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html>`_ to implement some features such as branch memory. To minimize complexity while debugging, it may be advisable (so to speak) to disable such advice. To do this, find the place in the code where the advice is added and execute the corresponding function to remove it, something like ``(advice-remove #'symex-go-down #'symex--remember-branch-position)``. Of course, if disabling the advice causes the error to go away, then you can focus your efforts on debugging the advice itself in isolation.

It may also be advisable to comment out macros like ``symex-save-excursion`` to see if the problem persists.
It may also be advisable to comment out macros like ``symex-save-excursion`` to see if the problem persists. Commenting out macros like ``symex--with-undo-collapse`` will also help you use the debugger in code wrapped by such macros.

Gotchas
^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ lint+less:
@$(MAKE) -f $(THIS_FILE) lint 2>&1 | less

lint-no-noise:
@$(MAKE) -f $(THIS_FILE) lint 2>&1 | grep -v "start with.*prefix" |grep -v "lexical-binding" |grep -v "non-snapshot.*racket" |grep -v "non-snapshot.*clever" |grep -v "Version.*header is missing" |grep -v "Package-Version"
@$(MAKE) -f $(THIS_FILE) lint 2>&1 | grep -v "start with.*prefix" |grep -v "lexical-binding" |grep -v "non-snapshot.*racket" |grep -v "Version.*header is missing" |grep -v "Package-Version"

lint-noiseless:
@$(MAKE) -f $(THIS_FILE) lint-no-noise 2>&1 | less
Expand Down
62 changes: 12 additions & 50 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. image:: https://github.com/countvajhula/symex.el/actions/workflows/test.yml/badge.svg
:target: https://github.com/countvajhula/symex.el/actions
.. image:: https://github.com/drym-org/symex.el/actions/workflows/test.yml/badge.svg
:target: https://github.com/drym-org/symex.el/actions

.. image:: https://melpa.org/packages/symex-badge.svg
:alt: MELPA
Expand Down Expand Up @@ -33,7 +33,7 @@ Symex (pronounced sym-ex, as in symbolic expression) is a modal (like Vim but si
- Implementing new structure-related features in general is easy [1]_.
- Keybindings are short and memorable

At the moment, symex mode uses ``paredit``, ``lispy``, and `evil-cleverparens <https://github.com/luxbock/evil-cleverparens>`_ to provide much of its low level functionality. In the future, this layer of primitives may be replaced with a layer that explicitly uses the abstract syntax tree, for still greater precision.
Under the hood, Symex mode uses ``paredit`` and Tree-Sitter for parsing the code syntax tree.

As of Jan 2023, there is "alpha" support for non-Lisp languages via ``tree-sitter``. While motions and a couple of basic transformations should work across languages (i.e. not only Lisp), it should be considered an early preview rather than production-worthy. Full support is planned for completion as part of the `2.0 release coming in Spring '23 <https://github.com/drym-org/symex.el/pull/71>`__.

Expand All @@ -50,7 +50,7 @@ Installation

1. Install the package the usual way via MELPA (e.g. :code:`M-x package-install`).

2. Then, assuming you're using `use-package <https://github.com/jwiegley/use-package>`__ to manage your configuration, add the following config to your ``init.d`` (note these instructions have changed as of `version 0.9 <https://github.com/countvajhula/symex.el/releases/tag/0.9>`__):
2. Then, assuming you're using `use-package <https://github.com/jwiegley/use-package>`__ to manage your configuration, add the following config to your ``init.d`` (note these instructions have changed as of `version 0.9 <https://github.com/drym-org/symex.el/releases/tag/0.9>`__):

::

Expand All @@ -69,33 +69,19 @@ The Animated Guide

The best way to learn how to use Symex is to read the `Animated Guide <https://countvajhula.com/2021/09/25/the-animated-guide-to-symex/>`_. Besides animations, it also contains lots of helpful field notes. Go check it out!

Evil or Hydra?
Symex and Evil
--------------

Symex provides both an evil state as well as a hydra-based modal interface. Which one should you use?
At the moment, Symex uses an Evil state to implement its modal interface. Does that mean it's only for Evil users? No! It's just an implementation detail that you needn't be aware of, as Symex does not assume that you are an actual user of Evil.

**TL;DR**: Use the evil option -- this is the default, and it is available to both evil and vanilla emacs users. If you're learning and would like some hand-holding as you familiarize yourself with the keybindings, use the hydra option, but it is likely that hydra will eventually be deprecated here.
If you do happen to be an Evil user, using Symex should feel familiar, but while there are many similarities to Evil, it's also fairly different.

The evil option is less obtrusive and allows you to, for instance, execute ``M-x`` commands without leaving symex mode. It should feel very similar to using Normal state, and doesn't interfere with normal Emacs usage including any custom keybindings you may be using.

The hydra operates almost identically to the evil state, but it provides a comprehensive menu that can be toggled on and off, and can therefore help you learn the keybindings as you go along. On the other hand, the drawback is that the hydra will exit if you do something not specifically connected to symex mode -- for instance, if you run an ``M-x`` command, or do a text search, or save the buffer, or run a custom command of some kind. You could customize the hydra so that it is more persistent (e.g. "pink" or "amaranth" hydra) but doing so could cause it to interfere with normal Emacs functions, as hydra keybindings take precedence over everything else.

In short, evil provides a more seamless experience, but hydra may be a good option while you are learning to use symex.

Depending on your choice, put one of these in the ``:custom`` `section <https://github.com/jwiegley/use-package#customizing-variables>`__ (not the ``:config`` section) of your ``use-package`` form:

::

(symex-modal-backend 'evil)

::

(symex-modal-backend 'hydra)
Symex has a modal interface, but one that's simpler than Evil. In Evil, the paradigm is composing verbs with nouns (or operators with motions, in Vim parlance), whereas Symex has a "point free" design where the noun is fixed (i.e. it assumes you mean to perform operations on symexes) so you only need to worry about what you are trying to do without bothering about composition. For more on this style of UI, see `Rigpa <https://github.com/countvajhula/rigpa>`_.

Key Bindings
------------

The table below lists the key bindings in Symex mode for Evil Symex users. You don't need this with the hydra frontend since you can lookup the keybindings at any time by pulling up the hydra menu (default binding: ``H-m``). Also for the evil frontend, while you don't have the menu, you can always use Emacs's ``C-h k`` to learn what a key does, as another way of learning the bindings.
The table below lists the key bindings in Symex mode. You can also always use Emacs's ``C-h k`` to learn what a key does, as another way of learning the bindings.

Movement
~~~~~~~~
Expand Down Expand Up @@ -321,21 +307,12 @@ Control
- exit
-

The Menu (Hydra-only)
---------------------

Entering the symex modal interface (via e.g. :code:`s-;`) using the hydra option shows you a comprehensive menu of all possible actions, by default. This is helpful initially, but over time you may prefer to dismiss the menu and bring it up only on demand, in order to conserve screen real estate. To do this, either run ``symex-toggle-menu`` via the menu entry point (``H-m``) while in symex mode, or add this to your ``init.d`` (e.g. in the ``:config`` section of the ``use-package`` form):

::

(symex-hide-menu)

Up and Down
-----------

The default keybindings in symex mode treat increasingly nested code as being "higher" and elements closer to the root as "lower." Think going "up" to the nest and "down" to the root. But symex allows you to modify these or any other keybindings to whatever you may find most natural.

If you're using evil, put something resembling this in your configuration *before* the call to ``(symex-initialize)``:
Put something resembling this in your configuration *before* the call to ``(symex-initialize)``:

::

Expand All @@ -347,21 +324,6 @@ If you're using evil, put something resembling this in your configuration *befor
("M-j" . symex-goto-highest)
("M-k" . symex-goto-lowest)))

If you're using hydra, put something resembling this in your configuration *after* the call to ``(symex-initialize)``:

::

(defhydra+ hydra-symex (:columns 4
:post (symex-exit-mode)
:after-exit (symex--signal-exit))
"Symex mode"
("j" symex-go-up "up")
("k" symex-go-down "down")
("C-j" symex-climb-branch "climb branch")
("C-k" symex-descend-branch "descend branch")
("M-j" symex-goto-highest "go to highest")
("M-k" symex-goto-lowest "go to lowest"))

Branch Memory
-------------

Expand Down Expand Up @@ -420,7 +382,7 @@ Tips
Escaping to Symex Instead of Normal State
-----------------------------------------

For evil users, when you "escape" from Insert state, you may prefer to enter Symex state rather than Normal state while in Lisp buffers. You could write one-off keybindings to do this (e.g. `this recipe <https://github.com/countvajhula/symex.el/issues/24#issuecomment-815110143>`__ by user @tommy-mor), but if you'd like a more structured and flexible alternative, use `Rigpa <https://github.com/countvajhula/rigpa>`_.
For evil users, when you "escape" from Insert state, you may prefer to enter Symex state rather than Normal state while in Lisp buffers. You could write one-off keybindings to do this (e.g. `this recipe <https://github.com/drym-org/symex.el/issues/24#issuecomment-815110143>`__ by user @tommy-mor), but if you'd like a more structured and flexible alternative, use `Rigpa <https://github.com/countvajhula/rigpa>`_.

Also see `Easy Entry Into Symex State`_, below, for another option.

Expand Down Expand Up @@ -471,7 +433,7 @@ You could think of "w" as "wrap" in this context, as in, "to wrap with parenthes
Learn More
==========

Read the documentation for the `Symex DSL <https://github.com/countvajhula/symex.el/blob/master/DSL-Docs.rst>`_.
Read the documentation for the `Symex DSL <https://github.com/drym-org/symex.el/blob/master/DSL-Docs.rst>`_.

Learn more about the implementation and see some usage examples in the video overview (given at an `Emacs SF <https://www.meetup.com/Emacs-SF/>`_ meetup in 2019):

Expand Down
2 changes: 1 addition & 1 deletion symex-computations.el
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
;;; symex-computations.el --- An evil way to edit Lisp symbolic expressions as trees -*- lexical-binding: t -*-

;; URL: https://github.com/countvajhula/symex.el
;; URL: https://github.com/drym-org/symex.el

;; This program is "part of the world," in the sense described at
;; https://drym.org. From your perspective, this is no different than
Expand Down
154 changes: 154 additions & 0 deletions symex-context.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
;;; symex-context.el --- An evil way to edit Lisp symbolic expressions as trees -*- lexical-binding: t -*-

;; URL: https://github.com/drym-org/symex.el

;; This program is "part of the world," in the sense described at
;; https://drym.org. From your perspective, this is no different than
;; MIT or BSD or other such "liberal" licenses that you may be
;; familiar with, that is to say, you are free to do whatever you like
;; with this program. It is much more than BSD or MIT, however, in
;; that it isn't a license at all but an idea about the world and how
;; economic systems could be set up so that everyone wins. Learn more
;; at drym.org.
;;
;; This work transcends traditional legal and economic systems, but
;; for the purposes of any such systems within which you may need to
;; operate:
;;
;; This is free and unencumbered software released into the public domain.
;; The authors relinquish any copyright claims on this work.
;;

;;; Commentary:

;; Generic context setting in terms of predicates and actions.

;;; Code:

(defvar contextualize-contexts
(make-hash-table :test 'equal)
"A context is a pair (condition, handler).

When `contextualize-set-context` is called with
the category name, all contexts registered for that
category are checked for the condition, which if met
calls the corresponding handler.

The condition and the handlers are defined by the
client rather than in contextualize.")

(defvar symex-category 'symex
"An identifier to pull up any contexts relevant for Symex.")

(defun symex-contextualize-elisp-p ()
"Check if the context is Elisp."
(and (member major-mode symex-elisp-modes)
'elisp))

(defun symex-contextualize-racket-p ()
"Check if the context is Racket."
(and (member major-mode symex-racket-modes)
'racket))

(defun symex-contextualize-common-lisp-p ()
"Check if the context is Common Lisp."
(and (equal major-mode 'lisp-mode)
'lisp))

(defun symex-contextualize-scheme-p ()
"Check if the context is Scheme."
(and (equal major-mode 'scheme-mode)
'scheme))

(defun symex-contextualize-clojure-p ()
"Check if the context is Clojure."
(and (member major-mode symex-clojure-modes)
'clojure))

(defun symex-contextualize-arc-p ()
"Check if the context is Arc."
(and (equal major-mode 'arc-mode)
'arc))

(defun symex-contextualize (language)
"Set the environment for Symex for LANGUAGE."
(cond ((eq 'elisp language)
(setq symex-eval-function #'symex-eval-elisp))
((eq 'racket language)
(setq symex-eval-function #'symex-eval-racket))
((eq 'lisp language)
(setq symex-eval-function #'symex-eval-common-lisp))
((eq 'scheme language)
(setq symex-eval-function #'symex-eval-scheme))
((eq 'clojure language)
(setq symex-eval-function #'symex-eval-clojure))
((eq 'arc language)
(setq symex-eval-function #'symex-eval-arc))))

(defun contextualize-register-context (category context)
"Register a new CONTEXT for Symex."
(let ((contexts (gethash category
contextualize-contexts
nil)))
(puthash category
(push context contexts)
contextualize-contexts)))

(defun symex-initialize-contexts ()
"Register all built-in contexts."
(let ((contexts
(list (cons #'symex-contextualize-elisp-p
#'symex-contextualize)
(cons #'symex-contextualize-racket-p
#'symex-contextualize)
(cons #'symex-contextualize-common-lisp-p
#'symex-contextualize)
(cons #'symex-contextualize-scheme-p
#'symex-contextualize)
(cons #'symex-contextualize-clojure-p
#'symex-contextualize)
(cons #'symex-contextualize-arc-p
#'symex-contextualize))))
(dolist (context contexts)
(contextualize-register-context symex-category
context))))

(defun symex-disable-contexts ()
"De-register any symex-related contexts."
(contextualize-remove-category symex-category))

(defun contextualize-remove-category (category)
"Unregister CATEGORY."
(remhash category contextualize-contexts))

(defun contextualize-predicate (context)
"Get the predicate for CONTEXT."
(car context))

(defun contextualize-handler (context)
"Get the handler for CONTEXT."
(cdr context))

(defun contextualize-list-categories ()
"List all categories currently registered."
(hash-table-keys contextualize-contexts))

(defun contextualize-list-contexts (category)
"List all contexts in CATEGORY."
(gethash category contextualize-contexts))

(defun contextualize-set-context (category)
"Set context for CATEGORY.

Loop through all contexts configured for CATEGORY,
check the condition for each and call the corresponding
handler if the condition is met."
(dolist (ctx (gethash category contextualize-contexts))
(let ((p (contextualize-predicate ctx))
(h (contextualize-handler ctx)))
(let ((result (funcall p)))
(when result (funcall h result))))))


(provide 'symex-context)
;;; symex-context.el ends here
7 changes: 1 addition & 6 deletions symex-custom.el
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
;;; symex-custom.el --- An evil way to edit Lisp symbolic expressions as trees -*- lexical-binding: t -*-

;; URL: https://github.com/countvajhula/symex.el
;; URL: https://github.com/drym-org/symex.el

;; This program is "part of the world," in the sense described at
;; https://drym.org. From your perspective, this is no different than
Expand Down Expand Up @@ -45,11 +45,6 @@
:type 'boolean
:group 'symex)

(defcustom symex-modal-backend 'evil
"Whether to use hydra or evil as the backend for the modal interface."
:type 'symbol
:group 'symex)

(defcustom symex-quote-prefix-list (list "'" "`")
"List of prefixes to cycle through while using `symex-cycle-quote`."
:type 'list
Expand Down
Loading