How to set a theme for specific project (Projectile) in Emacs - emacs

Is there a possibility to set a specific color theme or just to hook on a specific project to run custom elisp?
So the idea is to automatically set a color theme or background-color when I open a file from a specific project (path)? E.g. I can work with multiple projects in different frames and instantly know where I am. May be this can written in .projectile file somehow ?
Here by frame I mean Frame not just a buffer.

You can't do this as of now but there is a discussion going on here for something similar in the
Projectile issue list. However you can use a .dir-locals.el file to get this done. I am guessing something similar would be implemented for projectile using .projectile file in the future once the devs decide upon it.
dir-locals.el is intended to set local variables for all files in that particular directory you could checkout the docs or this blog post for the details. It's not particularly designed to run elisp code (setting a theme is a load-theme function call I believe) for good reason. However you can use eval variable to work around this and emacs will ask you whether to run the code.
((nil . ((eval . (load-theme 'molokai
)
))))
or you could do something even fancier according to the major modes.
((nil . ((indent-tabs-mode . t)
(tab-width . 4)
(fill-column . 80)))
;; Warn about spaces used for indentation:
(haskell-mode . ((eval . (highlight-regexp "^ *"))))
(c-mode . ((c-file-style . "BSD")))
(java-mode . ((c-file-style . "BSD")))
("src/imported"
. ((nil . ((change-log-default-name . "ChangeLog.local"))))))

The latest projectile (projectile-20140716.416) now supports hooking in arbitrary elisp after project switch, elisp such as:
(load-theme 'zenburn t)
An example script that exploits the hook is here: http://github.com/jfeltz/projectile-load-settings

Related

Is there any structure to .emacs file

I am trying to get into emacs. I have installed it using apt-get install on ubuntu.
Now I want to change the background color, and found some doc on this. The best doc I found is this:
http://www.emacswiki.org/emacs/FrameParameters
But when reading about how to add things to the .emacs file, none of the docs/info I found mention anything about structure, and the .emacs file just looks like a big mess. Do any of you experienced emacs users follow a specific structure when adding to .emacs, or do you just add anywhere?
I want to add the following:
(add-to-list 'default-frame-alist '(foreground-color . "white"))
(add-to-list 'default-frame-alist '(background-color . "black"))
(add-to-list 'default-frame-alist '(cursor-color . "coral"))
When opening the .emacs file, I don't file like just throwing it in, as I like structure. Before I try to make my own, I'd like to hear if there is a convention that I have missed?
Your .emacs file is a piece of Lisp code. There are conventions for how to format Lisp code, but I guess that's not really what you are looking for.
Part of the problem is that your .emacs will tend to grow organically, as you find new things you want to try and new knobs you want to tweak. Over time, it will build up into a huge, monolithic piece of unrelated code snippets.
The usual structuring conventions for code apply -- group related code together, add comments, modularize.
What you can do with the code you posted as an example is mainly to add a comment.
;; Frame colors
(add-to-list 'default-frame-alist '(foreground-color . "white"))
(add-to-list 'default-frame-alist '(background-color . "black"))
(add-to-list 'default-frame-alist '(cursor-color . "coral"))
Some people like to add folding mode markers so they can collapse/expand code sections, but perhaps at that point you should start thinking about breaking it up into smaller files.
Overhauling the rest of your .emacs file is out of scope here, and impossible without access to the full thing. But see http://www.emacswiki.org/emacs/DotEmacsModular for some suggestions. (Disclosure: A snippet of mine is prominently linked.)
Using customize also helps somewhat, but it has its own pros and cons. The customize settings are added programmatically at the end of your .emacs, and has very little by way of structure.

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.

How to set default major mode in directory-local file?

for some complex reason, I would like to open files in certain directory (can have any name, no extension) in C mode, and I don't want to modify them for Emacs (file-local variables are out). I am struggling with Emacs to do it, however. I tried to put this into my dir-locals.el:
((nil . ((major-mode . c-mode))))
Although the major-mode variable is indeed overridden to c-mode when I open file from that directory, the C mode is not enabled on the buffer. What's going on and how do I make it apply?
Alternatively, I could add to the auto-mode-alist just for this directory, but I don't know how to do that via directory locals.
Also, is there some easy way to cause execution of code from dir-locals.el? I know it's unsafe, but it could even be the code that is in config - the point is to call it only when variables from dir-locals are processed (opening a file).
Thanks for help.
Apart from eval, there is also another special variable named mode which can help you. It is the same variable used by file-local variables. You could also write:
((nil . ((mode . c))))
In .dir-locals.el you can only set variables to a certain value. What your code does is set the major-mode variable to the c-mode value. However, this is not the way a mode is activated. To activate it you need to call the function c-mode. There is a special variable that you can set in .dir-locals.el to run a function: eval.
Therefore, the following code works:
((nil . ((eval . (c-mode)))))
i can't answer your first question (and in fact, will like to hear the answer for that myself) but fir the auto-mode-alist you can have
(setq auto-mode-alist (cons '("<your dir path here>\." . c-mode) auto-mode-alist))`
this should give you the result you want

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.

configure emacs variables for a specific function

I run an email client in a separate emacs window (usually connecting to gnuserv), for example,
emacs -f wl
(the email client being Wanderlust, which probably doesn't matter much).
Is it possible to make emacs remember my preferred
window layout,
main window dimensions,
fonts, colours, etc.,
to set these up only when wl is called? Roughly speaking, if I want to have black background in the email client but white otherwise?
I'm especially interested in keeping the window layout because the default one has to be manually adjusted every time wl is loaded.
There is default-frame-alist variable that allows you to specify the default appearance and behavior for a new frame (frame is what you call a seperate Emacs window). Though it overrides the settings for all frame, you can advise your function to mask its global value and set it yours. Something like this:
(defadvice wl (around wl-frame-settings activate)
(let ((default-frame-alist (append
'((width . 82) (height . 36)
(cursor-color . "#ffa200")
(tool-bar-lines . 0)
;; ...
)
default-frame-alist)))
ad-do-it))
As TJ pointed out, this solution might have a drawback that it gets invoked too late. TJ's wlwrapper may be a better way.
Building on Török Gábor's answer, you can use any of a number of packages to store and restore window/frame configurations, many are listed here. The various window layout packages all have their quirks, so you'll have to find which one you like (there are so many packages b/c everyone finds something they don't like about the existing packages and roll their own).
With respect to fonts and colors, some can be customized on a frame-by-frame basis, see the info page for frame parameters.
With respect to how to hook it to the function 'wl, you can use advice if you want (I love using it), but it might be much more straight-forward to just either customize 'wl itself, or write a wrapper which does the frame/window configuration loading and then calls 'wl. Then your invocation might have to change to:
emacs -f wlwrapper
The way your emacsclient is configured (or, for older Emacsen, gnuclient) may be what's causing TG's solution not work. I'd probably use the 'wlwrapper solution, customizing emacsclient to re-use an existing frame, then inside 'wlwrapper modify the 'default-frame-parameters and then call 'wl. That way you ensure you create the frame after the parameters are set.
Something like this untested:
(defun wlwrapper ()
"wrapper for 'wl which sets up window/frame configurations"
(let ((default-frame-alist (append
'((width . 82) (height . 36)
(cursor-color . "#ffa200")
(tool-bar-lines . 0)
;; ...
)
default-frame-alist)))
;; if 'wl doesn't create a frame
(select-frame (make-frame))
(wl)
;; now use which ever window saving package you want
))