9

Org-mode, which is included with Emacs, has a plist merge function: (defun org-combine-plists (&rest plists) "Create a single property list from all plists in PLISTS. The process starts by copying the first list, and then setting properties from the other lists. Settings in the last list are the most significant ones and overrule settings in the ...


6

Reading the manual and browsing the list from C-u C-h a plist RET doesn't turn up any function to merge two property lists. The Common Lisp extensions don't provide any function specifically to act on property lists, only place (getf/setf/…) support. So you either need to rely on a third-party library or roll your own. Rolling your own isn't too difficult. ...


5

You could use: (pcase-defmacro plist (&rest args) `(and (pred listp) ,@(mapcar (lambda (elt) (if (consp elt) `(app (pcase--flip plist-get ,(car elt)) ,(cadr elt)) `(app (pcase--flip plist-get ',elt) ,(if (keywordp elt) ...


4

I am certain that the answer is no, and that variables are the only kind of buffer-local bindings provided by elisp. (I'm sure one of the elisp language maintainers will correct me if I'm wrong about this.) There are a handful of other kinds of "local" values (such as frame parameters, and terminal-local variables), and other things may also be associated ...


4

It isn't difficult to make your own let-plist by referring to let-alist.el, here is my attempt, the mainly difference is let-plist--list-to-sexp. (require 'let-alist) (defun let-plist--list-to-sexp (list var) "Turn symbols LIST into recursive calls to `plist-get' on VAR." `(plist-get ,(if (cdr list) (let-plist--list-to-sexp (cdr list)...


4

According to the doc-string for assoc, it is used to: "Return non-nil if KEY is equal to the car of an element of LIST. The value is actually the first element of LIST whose car equals KEY." The manual contains a few examples: https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html The function plist-get appears to be ...


4

There's no difference to my knowledge. You can see :foo as an auto-quoting 'foo. Keyword arguments show more clearly that they are constants, so you should use them if you want to do that. You can also experiment with this if you like: (let (cands) (mapatoms (lambda (x) (when (string-match "foobarbaz" (symbol-name x)) (push ...


3

I know this has been answered already, but incase anybody is interested, I took the org implementation and played a bit of code golf on it (defun plist-merge (&rest plists) "Create a single property list from all PLISTS. Inspired by `org-combine-plists'." (let ((rtn (pop plists))) (dolist (plist plists rtn) (setq rtn (plist-put rtn ...


3

See Symbol Type: A symbol whose name starts with a colon (:) is called a keyword symbol. These symbols automatically act as constants, and are normally used only by comparing an unknown symbol with a few specific alternatives. See Constant Variables.


3

You've already received tips on what to use instead of assoc, but just to answer your original question: assoc expects a list of cons cells as input: (setq testvar '((:type "http") (:path "//pygments.org/docs") (:format bracket) (:raw-link "http://pygments.org/docs") (:application nil))) (assoc :path testvar)...


3

Some things to consider wrt your code (in no special order): Why use a plist instead of an alist? Either choice is OK, but at least ask yourself the question. What final plist do you expect to get? Plists generally use symbols, not strings, as the keys. So if you have strings you will want to use intern to get symbols. If your input is a buffer of such ...


2

The option that I have resorted to previously is converting the plist to an alist using the kv package (kvplist->alist): (let-alist (kvplist->alist '(:foo "bar" :baz (:bat "blah")) .foo) However, this only addresses the shallow case; it doesn't offer nested access via .baz.bat.


1

org-transform-table/org-tree-buffer-from-org-table only works if the table contains outlines, so for your example it would have to look like this: | 1 | 2 | 3 | |-----+---+---| | * a | b | c | | * l | m | n | One way to transform your table is to put point in the first content cell (in your example on a) and then type M-: (org-table-eval-formula most-...


1

The lazy way is to override the relevant functions from the org-html exporter by advices. Put the following stuff into your init-file and restart emacs. You should get quite exactly what you want. (defun my-org-html-property-drawer (_property-drawer contents _info) "Transcode a PROPERTY-DRAWER element from Org to HTML. CONTENTS holds the contents of the ...


1

See xuchunyang's for the more canonical and complete answer; the following is merely a somewhat handy trick specific to property lists, for completeness. Given: the underlying structure of lists in Elisp; a non-empty plist variable; and the destructive nature of plist-put on non-empty lists, you can modify a plist variable via plist-put directly, without ...


1

If I were you, I would use (setq org-format-latex-options (cdr '(_ :foreground auto ; default :background default :scale 1.5 ; 1.0 :html-foreground "Black" :html-background "Transparent" :html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" ...


1

EIEIO does come with some support for marshalling/unmarshalling, since that was needed for CEDET (the main drive behind the implementation of EIEIO, AFAIK). The base function for that is object-write. And it seems that eieio-persistent-convert-list-to-object will convert it back. This said, EIEIO objects are represented as Elisp vectors which you can ...


1

Fundamentally the explanation is historical. Lisp 1 stored the definition of a function on the function symbol's plist, and stored the values of all dynamically scoped variables (the only kind) in a big alist. It could have been done in any of the other three ways. By convention, many people treat alists as persistent (mutation-free) whereas "...


1

I think to get this to work the way you want you have to change the elisp reader. There is a proof of concept here: https://github.com/mishoo/elisp-reader.el To use it, we define a new syntax like the one you want from clojure anyway. Then, while reading it define the keywords on the fly. (require 'elisp-reader) (def-reader-syntax ?{ (lambda (in ch) ...


1

You can do something like this with a lexical closure also. #+BEGIN_SRC emacs-lisp :lexical t :results raw (let ((data '(:keyword "value" :keyword2 'value2))) (defalias 'd (lambda (key) (plist-get data key)))) (d :keyword2) #+END_SRC #+RESULTS: (quote value2)


1

I don't believe it's possible to teach Elisp to default to this behavior, but you can write a function that does the job for a defined set of keywords: (defun defgetters (&rest keywords) (when-let ((this-keyword (car keywords))) (defalias this-keyword (lambda (plist) (plist-get plist this-keyword))) (apply #'defgetters (cdr keywords))))


Only top voted, non community-wiki answers of a minimum length are eligible