Emacs: select multiple regions and switch to inverse - emacs

I know there are a few different packages for selecting multiple regions in gnu emacs. What I'm looking for is a way to select multiple regions, operate on them, and then select the inverse of the previously marked regions in order to then operate on them.
As an example, suppose that I have the following data in a buffer:
Line A
Line B
Line C
Line D
Line E
Line F
What I want to do is the following:
Mark lines A, C, and E as multiple regions
Apply some elisp to the text within these marked regions
Tell emacs to switch the marked and unmarked regions. Now, lines B, D, and F should be the ones that are marked as multiple regions
Apply some other elisp to the text within these other regions
Steps 1, 2, and 4 are trivial, and they simply depend on the choice of multiple-region-marking code I decide to use.
But what about step 3? Is there any multiple-region-marking package which allows me to switch to the inverse of what was previously marked?

Your question is general. My answer will likely fit some of it, but maybe not all.
Library zones.el (see Zones) lets you define and manipulate multiple zones (in effect, multiple regions) of text, across multiple buffers. You can do these kinds of things with them:
Sort them.
Unite (coalesce) adjacent or overlapping zones (which includes sorting them).
Complement them if they have been united.
Intersect them.
Narrow the buffer to zones in the list - see MultipleNarrowings.
Select zones in the list as the active region. Cycle among regions.
Search them (they are automatically united first). For this you need library isearch-prop.el (see Isearch+).
Highlight and unhighlight them. (For this you need the Highlight library (highlight.el) or library facemenu+.el (see Facemenu+).
Add the active region to a list of zones.
Add the region to a list of zones, and then unite (coalesce) the zones.
Delete a zone from a list of zones.
Clone a zones variable to another one, so the clone has the same zones.
Clone a zones variable and then unite the zones of the clone.
Make a list-of-zones variable persistent, in a bookmark. Use the bookmark to restore it in a subsequent Emacs session. For this you need library Bookmark+.
Library Isearch+ (including isearch-prop.el) lets you search both zones as defined by zones.el and zones defined by text or overlay properties (any properties), and it facilitates applying properties to zones of text.
You can also search the complement of a set of zones, which I think is what your question is really about. The areas not being searched can optionally be dimmed during search.
You can search various "THINGS" as zones. Things can be anything you can define syntactically. They include the usual Emacs "things", and if you use library thingatpt+.el then you can easily define additional things.
If you use Icicles then you can use Icicles search on a set of search contexts in buffers or files. You can define search contexts in various ways, including using a regexp. There too you can search the complement of a set of search contexts. And you can use incremental narrowing of matching search contexts, and when doing that you can also subtract sets of matches using complementing.
UPDATED after your remarks -
You apparently want to complement a list of non-basic zones (what I call "izones"), which are each a number as identifier followed by the two zone limits. (Basic zones have only the limits and not the identifier, and function zz-zones-complement returns a list of basic zones.)
This is how I would define that complement function:
(defun zz-complement-izones (izones &optional beg end)
"Complement IZONES, which is a list like `zz-izones'.
Such a list is also returned, that is, zones that have identifiers."
(zz-izones-from-zones
(zz-zones-complement (zz-zone-union (zz-izone-limits izones nil t)))))
That just uses predefined function zz-zones-complement after stripping the zone identifiers and coalescing the zones. Predefined function zz-izones-from-zones gives the zones identifiers, making the result a list of izones.
And you want a function that maps a function over a list of zones, applying it to each zone in the list - what your function traverse-zones does.
Here is a version (untested) of such a map function that expects zones of the form that you are using, that is, izones (zones that have a number identifier) and maps a 3-ary function over them. It is similar to your traverse-zones (but see the comment):
(defun map-izones (function &optional izones)
"Map 3-ary FUNCTION over IZONES.
FUNCTION is applied to the first three elements of each zone.
IZONES is a list like `zz-izones', that is, zones with identifiers."
;; Do you really want this? It prohibits mapping over an empty list of zones.
;; (unless izones) (setq izones zz-izones)
(when (and (functionp function) (zz-izones-p izones))
(setq izones (zz-unite-zones izones))
(dolist (izone izones) (funcall function (car izone) (cadr izone) (caddr izone)))))
And here is an (untested) version that maps a binary function over a list of zones. The zones in the list can be either all basic zones or all izones. This seems more useful to me, as the identifiers are generally not very useful in such a context.
(defun map-zones (function &optional zones)
"Map binary FUNCTION over ZONES, applying it to the limits of each zone.
ZONES can be a list of basic zones or a list like `zz-izones', that
is, zones that have identifiers."
(when (functionp function)
(when (zz-izones-p zones)
(setq zones (zz-izone-limits zones nil 'ONLY-THIS-BUFFER)))
(setq zones (zz-zone-union zones))
(dolist (zone zones) (funcall function (car zone) (cadr zone)))))
Hope this helps.

I just discovered a preliminary answer. I say "preliminary", because I haven't done any in-depth testing yet. However, the "zones.el" package officially offers the functionality I'm looking for.
It creates a list of selected regions, which it calls "zones". It offers a function called zz-zones-complement which will return the complement of the "coalesced" list of current zones, which can be gotten as follows: (zz-zones-complement (zz-zone-union zz-izones)).
I'm confident that this will give me all of the functionality that I'm looking for. However, if I hit any issues, I'll come back and post again.

Thank you, Drew.
It turns out that zones is closest to what I need, although icicles and isearch+ are also both useful.
As for zones, it turns out that its zz-zones-complement function doesn't seem to return correct information.
However, I wrote my own function which I can use in its place.
I now do this to run arbitrary lisp code on the complement of all the zones that were previously added via zones.el ...
(defun my-complement-zones (&optional zones)
(unless zones
(setq zones zz-izones))
(zz-unite-zones 'zones)
(let ((result ())
(end (copy-marker (point-min)))
(n 0)
(a nil)
(b nil))
(dolist (item (reverse zones))
(setq n (1+ n))
(setq a (cadr item))
(setq b (caddr item))
(setq result (append (list (list n end a)) result))
(setq end b))
(when (< (marker-position end) (point-max))
(setq result (append (list (list (1+ n) end (copy-marker (point-max)))) result)))
result))
;; Each element has three values: an index followed by the start
;; and end markers for each region. To traverse this structure,
;; do the following ...
(dolist (region (my-complement-zones))
(let ((idx (car region))
(start (cadr region))
(end (caddr region)))
;; At this point, "start" is a marker pointing to the
;; beginning of the given zone, and "end" is a marker pointing
;; its endpoint. I can use these for inputs to any region-aware
;; elisp commands, or for any functions that I might want to
;; write which operate on each given region.
;;
;; ... etc. ...
))
... and here's a function I wrote which will traverse a zones list and apply a lambda to each zone. It works equivalently, whether we're using the original zz-izones or its complement as generated with my function:
;; Helper function
(defun funcallable (func)
(and func
(or (functionp func)
(and (symbolp func)
(fboundp func)))))
;; Traverse a list of zones such as zz-izones, and apply a lambda
;; to each zone in the list. Works equivalently with the output of
;; `my-complement-zones'.
(defun traverse-zones (func &optional zones)
(when (funcallable func)
(unless zones
(setq zones zz-izones))
(zz-unite-zones 'zones) ;; not sure if this is really necessary
(dolist (zone zones)
(let ((i (car zone))
(s (cadr zone))
(e (caddr zone)))
(funcall func i s e)))))
To illustrate the difference in structure between zz-izones and the output of zz-zones-complement, here's an example of a zz-izones structure I created in a buffer called "foo":
((4 #<marker at 1202 in foo> #<marker at 1266 in foo>) (3 #<marker at 689 in foo> #<marker at 1132 in foo>) (2 #<marker at 506 in foo> #<marker at 530 in foo>) (1 #<marker at 3 in foo> #<marker at 446 in foo>))
Here's what (zz-zones-complement zz-izones) looks like for this same zz-izones list ...
((1 4) (#<marker at 1202 in foo> 3) (#<marker at 689 in foo> 2) (#<marker at 506 in foo> 1) (#<marker at 3 in foo> 1266)
Note that each entry in zz-izones consists of an index and two markers. However, in its complement, each entry is either two integers or a marker and an integer. These structures are not isomorphic.
ADDITIONAL INFO
For (zz-zone-union (zz-izone-limits zz-izones nil t)) ...
((#<marker at 3 in foo> #<marker at 446 in foo>) (#<marker at 506 in foo> #<marker at 530 in foo>) (#<marker at 689 in foo> #<marker at 1132 in foo>) (#<marker at 1202 in foo> #<marker at 1266 in foo>)
For (zz-zones-complement (zz-zone-union (zz-izone-limits zz-izones nil t)))
((1 #<marker at 3 in foo>) (#<marker at 446 in foo> #<marker at 506 in foo>) (#<marker at 530 in foo> #<marker at 689 in foo>) (#<marker at 1132 in foo> #<marker at 1202 in foo>) (#<marker at 1266 in foo> 1266))
I guess I could use this complement if I convert the "1" in the first entry to (copy-marker (point-min)) and the "1266" in the final item to (copy-marker (point-max)) ... unless I'm dealing with a specific case where it doesn't matter whether I'm dealing with markers or points.
Markers are ideal, because then I can change the buffer after generating the complement, and I won't have to worry about the numeric point value within the complement structure no longer pointing to where it originally pointed.

Related

S-expressions and keeping track of source location

Lisp s-expressions are a concise and flexible way to represent code as an abstract syntax tree. Relative to the more specialized data structures used by compilers for other languages, however, they have one drawback: it is difficult to keep track of the file and line number corresponding to any particular point in the code. At least some Lisps end up just punting the problem; in the event of an error, they report source location only as far as function name, not file and line number.
Some dialects of Scheme have solved the problem by representing code not with ordinary cons cells, but with syntax objects, which are isomorphic to cons cells but can also carry additional information such as source location.
Has any implementation of Common Lisp solved this problem? If so, how?
The Common Lisp standard says very little about these things. It mentions for example that the function ed may take a function name and then open the editor with respective source code. But there is no mechanism specified and this feature is entirely provided by the development environment, possibly in combination with the Lisp system.
A typical way to deal with that is to compile a file and the compiler will record the source location of the object defined (a function, a variable, a class, ...). The source location could for example be placed on the property list of the symbol (the name of the thing defined), or recorded in some other place. Also the actual source code as a list structure can be associated with a Lisp symbol. See the function FUNCTION-LAMBDA-EXPRESSION.
Some implementations do more sophisticated source location recording. For example LispWorks can locate a specific part of a function which is currently executed. It also notes when the definition comes from an editor or a Listener. See Dspecs: Tools for Handling Definitions. The debugger then can for example locate where the code of a certain stack frame is located in the source.
SBCL also has a feature to locate source code.
Notice also that the actual 'source code' in Common Lisp is not always a text a file, but the read s-expression. eval and compile - two standard functions - don't take strings or filenames as arguments. They use the actual expressions:
CL-USER 26 > (compile 'foo (lambda (x) (1+ x)))
FOO
NIL
NIL
CL-USER 27 > (foo 41)
42
S-expressions as code are not bound to any particular textual formatting. They can be reformatted by the pretty printer function pprint and this may take available width into account to generate a layout.
So, noting the structure maybe be useful and it would be less useful to record source lines.
My understanding is that whatever data Scheme stores in the AST is data that can be associated to expressions in a CL environment.
Scheme
(defun my-simple-scheme-reader (stream)
(let ((char (read-char stream)))
(or (position char "0123456789")
(and (member char '(#\newline #\space #\tab)) :space)
(case char
(#\) :closing-paren)
(#\( (loop
with beg = (file-position stream)
for x = (my-simple-scheme-reader stream)
until (eq x :closing-paren)
unless (eq x :space)
collect x into items
finally (return (list :beg beg
:end (file-position stream)
:items items))))))))
For example:
(with-input-from-string (in "(0(1 2 3) 4 5 (6 7))")
(my-simple-scheme-reader in))
returns:
(:BEG 1 :END 20 :ITEMS
(0 (:BEG 3 :END 9 :ITEMS (1 2 3)) 4 5 (:BEG 15 :END 19 :ITEMS (6 7))))
The enriched tree represents syntax objects.
Common-Lisp
(defun make-environment ()
(make-hash-table :test #'eq))
(defun my-simple-lisp-reader (stream environment)
(let ((char (read-char stream)))
(or (position char "0123456789")
(and (member char '(#\newline #\space #\tab)) :space)
(case char
(#\) :closing-paren)
(#\( (loop
with beg = (file-position stream)
for x = (my-simple-lisp-reader stream environment)
until (eq x :closing-paren)
unless (eq x :space)
collect x into items
finally
(setf (gethash items environment)
(list :beg beg :end (file-position stream)))
(return items)))))))
Test:
(let ((env (make-environment)))
(with-input-from-string (in "(0(1 2 3) 4 5 (6 7))")
(values
(my-simple-lisp-reader in env)
env)))
Returns two values:
(0 (1 2 3) 4 5 (6 7))
#<HASH-TABLE :TEST EQL :COUNT 3 {1010524CD3}>
Given a cons cell, you can track back its original position. You can add more precise information if you want to. Once you evaluate a defun, for example, the source information can be attached to the function object, or as a symbol property, which means the information is garbage collected on redefinitions.
Remark
Note that in both cases there is no source file to keep track of, unless the system is able to track back to the original string in the source file where the reader is called.

LISP - Splitting string with delimiter also included in new list

I have a list of elements following
("(aviyon" "213" "flyingman" "no))") as list
What i want is that I want to split this list containing strings using parentheses as splitter but also want to include these parentheses in a new list without breaking the order
My desired output of new list(or same list modified)
("(" "aviyon" "213" "flyingman" "no" ")" ")")
I am coming from imperative languages and this would be 15 minute job in Java or C++. But here i'm stuck what to do. I know i have to
1- Get a element from list in a loop
I think this is done with (nth 1 '(listname) )
2- separate without removing delimiter put in to a new list
I found functions such as SPLIT-SEQUENCE but i can't do without removing it and without breaking original order.
Any help would be appreciated.
You can use cl-ppcre library to do the job.
For example:
CL-USER> (ql:quickload :cl-ppcre)
CL-USER> (cl-ppcre:split "([\\(\\)])" "(aviyon" :with-registers-p t)
("" "(" "aviyon")
CL-USER> (cl-ppcre:split "([\\(\\)])" "no))" :with-registers-p t)
("no" ")" "" ")")
CL-USER>
However, it makes empty-strings in a list. Use remove-if function to get rid of them:
CL-USER> (defun empty-string-p (s) (string= s ""))
EMPTY-STRING-P
CL-USER> (remove-if 'empty-string-p
(list "no" ")" "" ")"))
("no" ")" ")")
Finally, you can construct a function which does both, and run it in an imperative loop (yes, Common Lisp is not functional as many think):
CL-USER> (defun remove-empty-strings (l)
(remove-if 'empty-string-p l))
REMOVE-EMPTY-STRINGS
CL-USER> (defun split (s)
(cl-ppcre:split "([\\(\\)])"
s
:with-registers-p t))
SPLIT
CL-USER> (defparameter *the-list* '("(aviyon" "213" "flyingman" "no))"))
*THE-LIST*
CL-USER> (loop for item in *the-list*
for splitted = (split item)
for cleaned = (remove-empty-strings splitted)
append cleaned)
("(" "aviyon" "213" "flyingman" "no" ")" ")")
Let's have another answer, without external libraries.
Like you already did, we can split in the problem into smaller parts:
define a function which builds a list of tokens from a string, all-tokens
apply this function on all strings in your input list, and concatenate the result:
(mapcan #'all-tokens strings)
The first part, taking a state and building a list from it, looks like an unfold operation (anamorphism).
Fold (catamorphism), called reduce in Lisp, builds a value from a list of values and a function (and optionally an initial value).
The dual operation, unfold, takes a value (the state), a function, and generate a list of values.
In the case of unfold, the step function accepts a state and returns new state along with the resulting list.
Here, let's define a state as 3 values: a string, a starting position in the string, and a stack of tokens parsed so far.
Our step function next-token returns the next state.
;; definition follows below
(declare (ftype function next-token))
The main function which gets all tokens from a string just computes a fixpoint:
(defun all-tokens (string)
(do (;; initial start value is 0
(start 0)
;; initial token stack is nil
(tokens))
;; loop until start is nil, then return the reverse of tokens
((not start) (nreverse tokens))
;; advance state
(multiple-value-setq (string start tokens)
(next-token string start tokens))))
We need an auxiliary function:
(defun parenthesisp (c)
(find c "()"))
The step function is defined as follows:
(defun next-token (string start token-stack)
(let ((search (position-if #'parenthesisp string :start start)))
(typecase search
(number
;; token from start to parenthesis
(when (> search start)
(push (subseq string start search) token-stack))
;; parenthesis
(push (subseq string search (1+ search)) token-stack)
;; next state
(values string (1+ search) token-stack))
(null
;; token from start to end of string
(when (< start (1- (length string)))
(push (subseq string start) token-stack))
;; next-state
(values string nil token-stack)))))
You can try with a single string:
(next-token "(aviyon" 0 nil)
"(aviyon"
1
("(")
If you take the resulting state values and reuse them, you have:
(next-token "(aviyon" 1 '("("))
"(aviyon"
NIL
("aviyon" "(")
And here, the second return value is NIL, which ends the generation process.
Finally, you can do:
(mapcan #'all-tokens '("(aviyon" "213" "flyingman" "no))"))
Which gives:
("(" "aviyon" "213" "flyingman" "no" ")" ")")
The above code is not fully generic in the sense that all-tokens knows too much about next-token: you could rewrite it to take any kind of state.
You could also handle sequences of strings using the same mechanism, by keeping more information in your state variable.
Also, in a real lexer you would not want to reverse the whole list of tokens, you would use a queue to feed a parser.
solution
Since you didn't understood Alexander's solution and since I anyway wrote my solution:
;; load two essential libraries for any common lisper
(ql:quickload :cl-ppcre)
(ql:quickload :alexandria)
;; see below to see how to install quicklisp for `ql:quickload` command
;; it is kind of pythons `import` and if not install `pip install`
;; in one command for common-lisp
(defun remove-empty-string (string-list)
(remove-if #'(lambda (x) (string= x "")) string-list))
(defun split-parantheses-and-preserve-them (strings-list)
(remove-empty-string
(alexandria:flatten
(mapcar #'(lambda (el) (cl-ppcre:split "(\\(|\\))"
el
:with-registers-p t))
strings-list))))
;; so now your example
(defparameter *list* '("(aviyon" "213" "flyingman" "no))"))
(split-parantheses-and-preserve-them *list*)
;; returns:
;; ("(" "aviyon" "213" "flyingman" "no" ")" ")")
how this works
(cl-ppcre:split "(\\(|\\))" a-string)
splits the string by ( or ). Because in regex pattern ( or ) are used for capturing the match - like here too (the outer parantheses captures) - you have to escape them. \\( or \\).
So with cl-ppcre:split you can split any string in common lisp by regex-pattern. Super cool and super efficient package written by Edi Weitz. He wrote several super sophisticated packages for common lisp - they are also called ediware or edicls in the community.
By the way - cl-ppcre is even more efficient and faster than gold-standard for regex: the perl regex engine!
:with-regiesters-p t option then preserves the matched delimiter - which has to be captured by parentheses like this: (<pattern>) in the pattern.
mapcar this over the list to apply it on each string element in your string list.
However, what you got after that is a list of lists.
(Each inner list containing the splitted result for each string-element of the list).
Flatten the list by alexandria:flatten.
For many functions not in the standard of lisp, but which you think they are basic - like flatten a list - look always first in alexandria - mostly it has a function you desire - it is a huge library. That is why you need it anyway as a common lisper ;) .
But still, there will be empty strings around to be removed.
That is why I wrote remove-empty-string which uses remove-if - which together with remove-if-not is the standard filtering function for lists.
It takes a predicate function - here (lambda (x) (string= x "")) which gives T if string is an empty string and NIL if not.
It removes all elements in the resulting flattened list in our function, which are empty strings.
In other languages it will be named filter but yeah - sometimes function names in common-lisp are not very well chosen. Sometimes I think we should create alias names and move over to them and keep the old names for backward-compatibility. Clojure has nicer names for functions ... Maybe cl people should overtake clojure function names ...
quicklisp
#Alexander Artemenko wrote exactly my solution - he came first. I will add:
If you are so new to common lisp, maybe you don't know how to use quicklisp.
Do in terminal (linux or macos):
wget https://beta.quicklisp.org/quicklisp.lisp
Otherwise manually download in windows from the address.
I put it into ~/quicklisp folder.
Then in clisp or sbcl do:
(load "~/quicklisp/quicklisp.lisp") ;; just path to where downloaded
;; quicklisp.lisp file is!
;; then install quicklisp:
(quicklisp-quickstart:install)
;; then search for cl-ppcre
(ql:system-apropos "cl-ppcre")
;; then install cl-ppcre
(ql:quickload "cl-ppcre")
;; and to autoload everytime you start sbcl or clisp
;; in linux or mac - sorry I don't now windows that well
;; I have the opinion every programmer should us unix
;; as their OS
;; you have to let quicklisp be loaded when they start
;; by an entry into the init file
;; mostly located in ~/.sbclrc or ~/.clisprc.slip or such ...
;; respectively.
;; quicklisp does an entry automatically if you do:
(ql:add-to-init-file)
;; after installation do:
(quit)
;; If you then restart sbcl or clisp and try:
(ql:quickload :cl-ppcre)
;; it should work, - if not, you have to manually load
;; quicklisp first
(load "~/quicklisp/setup.lisp") ;; or wherever quicklisp's
;; setup.lisp file has been stored in your system!
;; and then you can do
(ql:quickload :cl-ppcre)
;; to install alexandria package then, do
(ql:quickload :alexandria) ;; or "alexandria"
;; ql:quickload installs the package from quicklisp repository,
;; if it cannot find package on your system.
;; learn more about quicklisp, since this is the package
;; manager of common lisp - like pip for python

Elisp: How to push-back to a list

Is there a way to push-back to a list in elisp?
The closest thing I found was
(add-to-list 'myList myValue t) ;; t tells it to put to back of the list
The problem, however, is that add-to-list enforces uniqueness. The other alternative is (push 'myList myVal) but that can only push to the front of a list. I tried using (cons myList myVal) but IIRC that returns something other than a list.
The only thing that has worked is
(setq myList (append myList (list myVal)))
but that syntax is hideous and feels like a lot of extra work to do something simple.
Is there a faster way to push to the back of a list. It's clearly possible as seen in (add-to-list), but is there a way to do it without enforcing uniqueness?
In other words, a good old push-back function like with C++ and the <List> class
Lisp lists vs "lists" in other languages
Lisp lists are chains of cons cells ("linked lists"), not specialized sequential containers like in C, and not a weird blend of lists and vectors like in Perl and Python.
This beautiful approach allows the same methodology to be applied to code and data, creating a programmable programming language.
The reasons Lisp does not have a "push-back" function are that
it does not need it :-)
it is not very well defined
No need
Adding to the end is linear in the length of the list, so, for
accumulation, the standard pattern is to combine
push while iterating and
nreverse when done.
Not well defined
There is a reason why add-to-list takes a symbol as the argument (which makes it useless for programming).
What happens when you are adding to an empty list?
You need to modify the place where the list is stored.
What happens when the list shares structure with another object?
If you use
(setq my-list (nconc my-list (list new-value)))
all the other objects are modified too.
If you write, like you suggested,
(setq my-list (append my-list (list new-value)))
you will be allocating (length my-list) cells on each addition.
Try this:
(defun prueba ()
(interactive)
(let ((mylist '(1 2 3)))
(message "mylist -> %s" mylist)
(add-to-list 'mylist 1 t)
(message "mylist -> %s" mylist)
(setq mylist '(1 2 3))
(add-to-list 'mylist 1 t '(lambda (a1 a2) nil))
(message "mylist -> %s" mylist)
))
adding a compare function that always returns nil as the fourth argument to add-to-list allows you
to add duplicates.

How to distinguish between different overlays at point

ORIGINAL QUESTION:  I'm looking for some assistance, please, to distinguish between overlays that may exist at point. If the overlays-at point is made with the lawlist-red-face then do X. If the overlays-at point is made with calendar-holiday-marker, then do Y. The overlays are made with these two functions.
(calendar-mark-visible-date (car holiday) lawlist-red-face)
(calendar-mark-visible-date (car holiday) calendar-holiday-marker)
EDIT (January 1, 2014):  #Drew wrote a nice test for this in calendar+.el ( http://www.emacswiki.org/emacs/calendar%2B.el ):
(when
(memq lawlist-red-face
(mapcar (function (lambda (ovr)
(overlay-get ovr 'face))) (overlays-at (point))))
... )
EDIT (February 13, 2014):  The above-listed snippet can also be used in conjunction with something like (while (re-search-backward "[0-9]" nil t) to create a combined list of dates with overlays -- month, day and year are extracted with calendar-extract-day, calendar-extract-month and calendar-extract-year -- the date is obtained with (calendar-cursor-to-nearest-date):
;; modified with the help of #phils based on comments down below.
(setq lawlist-mouse-marked
(append lawlist-mouse-marked
`((holiday-sexp '(list ,month ,day ,year) ""))))
That list can then be used with something like calendar-holiday-list (or the modified code below) to remark dates on a new calendar layout after it has been generated. This is useful if the user has manually marked dates (e.g., with the mouse) and wants those dates to reappear after scrolling the calendar forwards / backwards. The library holidays.el contains the function holiday-sexp which uses a filtering function holiday-filter-visible-calendar to edit the list of dates so that only those that are visible on the new calendar get marked:
(dolist (holiday
(let (res h err)
(sort
(dolist (p lawlist-mouse-marked res)
(if (setq h (eval p))
(setq res (append h res))))
'calendar-date-compare)))
(calendar-mark-visible-date (car holiday) lawlist-mouse-calendar-face))
Ok, let's try to figure this out (without really knowing anything about the calendar).
(overlays-at) returns a list of overlays. I will keep this simple and only handle the first, if you want to examine all of them, simply loop over them until you find one that is suitable.
Also, the face property can be more complex than simply the name of the face, if that is the case you would need to handle that as well.
But anyway, here is a simple piece of code that (hopefully) does what you want:
(let ((overlays (overlays-at (point))))
(if overlays
(let ((face (overlay-get (car overlays) 'face)))
(cond ((eq face 'lawlist-red-face)
;; Do something
)
((eq face 'holiday)
;; Do another thing
)
(t
;; Do something else)))))

How could I implement the push macro?

Can someone help me understand how push can be implemented as a macro? The naive version below evaluates the place form twice, and does so before evaluating the element form:
(defmacro my-push (element place)
`(setf ,place (cons ,element ,place)))
But if I try to fix this as below then I'm setf-ing the wrong place:
(defmacro my-push (element place)
(let ((el-sym (gensym))
(place-sym (gensym)))
`(let ((,el-sym ,element)
(,place-sym ,place))
(setf ,place-sym (cons ,el-sym ,place-sym)))))
CL-USER> (defparameter *list* '(0 1 2 3))
*LIST*
CL-USER> (my-push 'hi *list*)
(HI 0 1 2 3)
CL-USER> *list*
(0 1 2 3)
How can I setf the correct place without evaluating twice?
Doing this right seems to be a little more complicated. For instance, the code for push in SBCL 1.0.58 is:
(defmacro-mundanely push (obj place &environment env)
#!+sb-doc
"Takes an object and a location holding a list. Conses the object onto
the list, returning the modified list. OBJ is evaluated before PLACE."
(multiple-value-bind (dummies vals newval setter getter)
(sb!xc:get-setf-expansion place env)
(let ((g (gensym)))
`(let* ((,g ,obj)
,#(mapcar #'list dummies vals)
(,(car newval) (cons ,g ,getter))
,#(cdr newval))
,setter))))
So reading the documentation on get-setf-expansion seems to be useful.
For the record, the generated code looks quite nice:
Pushing into a symbol:
(push 1 symbol)
expands into
(LET* ((#:G906 1) (#:NEW905 (CONS #:G906 SYMBOL)))
(SETQ SYMBOL #:NEW905))
Pushing into a SETF-able function (assuming symbol points to a list of lists):
(push 1 (first symbol))
expands into
(LET* ((#:G909 1)
(#:SYMBOL908 SYMBOL)
(#:NEW907 (CONS #:G909 (FIRST #:SYMBOL908))))
(SB-KERNEL:%RPLACA #:SYMBOL908 #:NEW907))
So unless you take some time to study setf, setf expansions and company, this looks rather arcane (it may still look so even after studying them). The 'Generalized Variables' chapter in OnLisp may be useful too.
Hint: if you compile your own SBCL (not that hard), pass the --fancy argument to make.sh. This way you'll be able to quickly see the definitions of functions/macros inside SBCL (for instance, with M-. inside Emacs+SLIME). Obviously, don't delete those sources (you can run clean.sh after install.sh, to save 90% of the space).
Taking a look at how the existing one (in SBCL, at least) does things, I see:
* (macroexpand-1 '(push 1 *foo*))
(LET* ((#:G823 1) (#:NEW822 (CONS #:G823 *FOO*)))
(SETQ *FOO* #:NEW822))
T
So, I imagine, mixing in a combination of your version and what this generates, one might do:
(defmacro my-push (element place)
(let ((el-sym (gensym))
(new-sym (gensym "NEW")))
`(let* ((,el-sym ,element)
(,new-sym (cons ,el-sym ,place)))
(setq ,place ,new-sym)))))
A few observations:
This seems to work with either setq or setf. Depending on what problem you're actually trying to solve (I presume re-writing push isn't the actual end goal), you may favor one or the other.
Note that place does still get evaluated twice... though it does at least do so only after evaluating element. Is the double evaluation something you actually need to avoid? (Given that the built-in push doesn't, I'm left wondering if/how you'd be able to... though I'm writing this up before spending terribly much time thinking about it.) Given that it's something that needs to evaluate as a "place", perhaps this is normal?
Using let* instead of let allows us to use ,el-sym in the setting of ,new-sym. This moves where the cons happens, such that it's evaluated in the first evaluation of ,place, and after the evaluation of ,element. Perhaps this gets you what you need, with respect to evaluation ordering?
I think the biggest problem with your second version is that your setf really does need to operate on the symbol passed in, not on a gensym symbol.
Hopefully this helps... (I'm still somewhat new to all this myself, so I'm making some guesses here.)