Elisp best way to concatenate lists of predicates - emacs

What is the best way to merge predicates like these into one predicate
'(("first" . font-lock-function-name-face))
'(("second" . font-lock-constant-face))
So that the answer would be:
'(("first" . font-lock-function-name-face)
("second" . font-lock-constant-face))

(append '(("first" . font-lock-function-name-face)) '(("second" . font-lock-constant-face)))

Related

Emacs: Is it possible to set specific indentation settings for specific desktops in desktop+?

I have to work on a lot of different projects that all tend to use different indentation amounts (usually just 2 and 4 spaces) for js, php, etc. I manage project sessions using emacs-desktop.
Thank you so much!
Rather than doing this via emacs-desktop, I suggest using Per-directory Local Variables. These are designed for exactly this purpose.
For example, here is the .dir-locals.el that I use for hacking on firefox:
(
;; Generic settings.
(nil .
;; See C-h f bug-reference-prog-mode, e.g, for using this.
((bug-reference-url-format . "https://bugzilla.mozilla.org/show_bug.cgi?id=%s")
(bug-reference-bug-regexp . "\\([Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z-+]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)")))
;; The built-in javascript mode.
(js-mode .
((indent-tabs-mode . nil)
(js-indent-level . 2)))
(c++-mode .
((indent-tabs-mode . nil)
(c-basic-offset . 2)))
(idl-mode .
((indent-tabs-mode . nil)
(c-basic-offset . 2)))
)
This customizes the indentation for a few programming modes, disables indent-tabs-mode where it matters, and arranges to buttonize bug references in the firefox source.

Reuse *compilation* window in another frame

How is it possible to enforce display-buffer-reuse-frames-like behavior for certain frames with display-buffer-alist?
I have tried doing
(setq display-buffer-alist
'(("\\*compilation\\*" .
(display-buffer-reuse-window '((inhibit-same-window . t))))
))
, but to no avail. The documentation is long and cryptic even by Emacs standards, and has no examples.
This is not the same as question 3311577 because (setq-default display-buffer-reuse-frames t) is deprecated.
It sounds like you want to be using the reusable-frames entry in your ALIST argument to display-buffer-reuse-window, rather than inhabit-same-window? (or perhaps you wanted both?)
You also want to be using add-to-list rather than clobbering the entire list with setq.
Edit: My original answer messed up the list structure, as I was using the dotted-pair notation from the documentation, but had omitted one of the dots!
So the correct value is:
(add-to-list
'display-buffer-alist
'("\\*compilation\\*" . (display-buffer-reuse-window
. ((reusable-frames . t)))))
or equivalently:
(add-to-list
'display-buffer-alist
'("\\*compilation\\*" display-buffer-reuse-window
(reusable-frames . t)))
I also notice that there's a good customize interface for configuring this.

How to concat a pattern in Emacs Lisp?

I think the title can't describe the question clearly. But I will try to describe in more detail words.
Here is my Emacs lisp code to set the backup folder:
(setq backup-directory-alist '(("" . "/hom/test/.backups")))
But if I want to do this job by generating the backup path in a dynamic way, which generates the path based on the user's path.
Here is what I am trying to do:
(setq temp-file-folder "/home/test")
(setq backups-save-folder (concat temp-file-folder "/.backups"))
(setq backup-directory-alist '(("" . backups-save-folder)))
But it doesn't work. The final output of above code is:
(("" . backups-save-folder))
I think what I am trying to get should be:
(("" . "/home/test/.backups"))
So, what's the right code to generate the path dynamic? What's the meaning of . in the code?
Thanks
First, a point. You can use the format function instead of concat to do this (it's similar to printf). Here is an example
(let ((home_dir "/home/noufal")
(posts_dir "posts"))
(format "%s/%s" home_dir posts_dir))
evaluates to "/home/noufal/posts"
It's not idiomatic lisp to setq temporary variables. You should work within the scope of a let construct which can bind values to a few temporary symbols and then get your work done.
In your last case, you've used a ' before your second parameter. This will prevent it from being evaluated (it's synonymous to "quote literally") and so, the backups-save-folder will not be replaced with the value. If you want do that, do something like this.
(setq backup-directory-alist (list (cons "" backups-save-folder)))
The . is a way of representing lists whose cdr is not a list. Refer the elisp documentation for more details.
seems you don't need an associated list, designed to store paired values, but a simple list:
get the current user directory (getenv "HOME")
maybe combined with another arbitrary string "-BACKSTAGE-AREA"
(setq my-dir (list (concat (getenv "HOME")"-BACKSTAGE-AREA")))
get the directory name stored that way with
(car my-dir)
According to Noufal Ibrahim's answer, here is my final code:
(setq backup-directory-alist (list (cons ""
(let ((backups_dir "/.backups")
(temp_folder desktop-temp-file-folder))
(format "%s/%s" temp_folder backups_dir)))))
It works.
Thanks

CLISP - Reversing a simple list

I have to reverse the elements of a simple (single-dimension) list. I know there's a built-in reverse function but I can't use it for this.
Here's my attempt:
(defun LISTREVERSE (LISTR)
(cond
((< (length LISTR) 2) LISTR) ; listr is 1 atom or smaller
(t (cons (LISTREVERSE (cdr LISTR)) (car LISTR))) ; move first to the end
)
)
Output pretty close, but is wrong.
[88]> (LISTREVERSE '(0 1 2 3))
((((3) . 2) . 1) . 0)
So I tried to use append instead of cons:
(t (append (LISTREVERSE (cdr LISTR)) (car LISTR)))
But got this error:
*** - APPEND: A proper list must not end with 2
Any help?
I can give you a couple of pointers, because this looks like homework:
The base case of the recursion is when the list is empty (null), and not when there are less than two elements in the list
Consider defining a helper function with an extra parameter, an "accumulator" initialized in the empty list. For each element in the original list, cons it at the head of the accumulator. When the input list is empty, return the accumulator
As an aside note, the above solution is tail-recursive.
As a follow-up to Óscar López (and fighting the temptation to just write a different solution down):
Using both append and length makes the posted solution just about the least efficient way of reversing a list. Check out the documentation on cons and null for some better ideas on how to implement this.
Please, please indent properly.
Tail recursion really is both more efficient and reasonably simple in this case. Try it if you haven't already. labels is the form you want to use to define local recursive functions.
It may be worth your while to flip through The Little Schemer. It'll give you a better feel for recursion in general.
It's ok what you did. You only missed the composition of the result list.
Think about it: You have to append the 1-element list of the CAR to the end of the list of the reversed CDR:
(defun LISTREVERSE (LISTR)
(cons
((< (length LISTR) 2) LISTR) ; listr is 1 atom or smaller
(t (append (LISTREVERSE (cdr LISTR)) (list (car LISTR))))))
(defun listreverse (list)
(let (result)
(dolist (item list result)
(push item result))))
Don't use recursion in Common Lisp when there is a simple iterative way to reach the same goal. Common Lisp does not make any guarantees about tail recursion, and your tail recursive function invocation may not be optimized to a jump at the discretion of the compiler.
push prepends the item to the result
dolist has an optional third argument which is the value returned. It is evaluated when the loop is exited.

How do I set buffer local variable from Eval: in .dir-local.el?

Why this works
((nil . ((compilation-directory . "/home/vava/code_directory/")
(compilation-command . "rake"))
))
and this doesn't?
((nil . ((Eval . (setq compilation-directory "/home/vava/code_directory"))
(compilation-command . "rake"))
))
What I'm doing wrong here?
I have set enable-local-eval in .emacs.
Emacs Lisp is case-sensitive: try lower-case "eval":
((nil . ((eval . (setq compilation-directory "/home/vava/code_directory"))
(compilation-command . "rake"))))
Also, the name of the file for directory-local variables is .dir-locals.el, not .dir-local.el as in the question headline.
Obviously you're assuming that "eval" has the same special meaning in directory-local variables that it does in file-local variables; and yet the documentation doesn't seem to confirm this. So my guess is: you simply can't do it.