Let .emacs.d behaves just like a .d folder - emacs

I want to solve my “.emacs bankruptcy” issue, and I've gone through
https://help.ubuntu.com/community/EmacsHowto
http://www.emacswiki.org/emacs/DotEmacsBankruptcy
http://www.emacswiki.org/emacs/DotEmacsDotD
http://www.gnu.org/software/emacs/manual/html_node/emacs/Init-File.html
and it is still unclear to me whether the .emacs.d folder is the solution. I.e., whether it will behave just like a normal .d folder, e.g., /etc/profile.d/, where you drop you scripts and they will be picked up by the system auto-magically. Please confirm.
If not, can someone give me a script that does that, or give me a solution please?
Thanks

The essential content of my ~/.emacs file is:
(require 'cl)
(loop for src in (directory-files "~/.emacs.d" 'full-path "[0-9].*\\.el$") do
(let ((byte (concat src "c")))
(when (file-newer-than-file-p src byte)
(byte-compile-file src))
(message "Loading %s.elc" byte)
(load-file byte)))
It loads configuration files from ~/.emacs.d which start with a number. If the source file (extension .el) is newer than the byte-compiled version (extension .elc) then it byte-compiles the source. Afterwards it loads the byte compiled file.

Here's my ~/.emacs:
;; base dirs
(defvar dropbox.d "~/Dropbox/")
(defvar emacs.d (concat dropbox.d "source/site-lisp/"))
;; load path
(add-to-list 'load-path emacs.d)
(defun add-subdirs-to-load-path (dir)
(let ((default-directory dir))
(normal-top-level-add-subdirs-to-load-path)))
(add-subdirs-to-load-path emacs.d)
(load "init")
All my other scripts are loaded by ~/Dropbox/source/site-lisp/init.el
and are themselves located in ~/Dropbox/source/site-lisp.
That's how I have the same config on multiple machines.
And here's how .../site-lisp/hooks.el is loaded from init.el:
(load "hooks")
My init.el is about 100 lines, .emacs about 20 lines.
The rest 8000 lines of scripts are sliced into around 20 files.

~/.emacs.d/ does not work like /etc/profile.d/ or /etc/modules-load.d/ or similar directories, i.e. Emacs does not automatically load any Emacs Lisp file in this directory.
In fact, Emacs explicitly advises against placing Emacs Lisp libraries in ~/.emacs.d/. The byte compiler emits a warning if you add ~/.emacs.d/ to the load-path.
Instead, create a new sub-directory, e.g. ~/.emacs.d/lisp. Add this directory to your load-path explicitly, with the following code in init.el:
(add-to-list 'load-path (locate-user-emacs-file "lisp"))
Then, place your Emacs Lisp files in this directory, e.g. ~/.emacs.d/lisp/foo.el, and load them in your init.el:
(load "foo" nil 'no-message)
The best approach to avoid the dreaded .emacs bankruptcy is to actually avoid large customizations! Most notably, try to avoid any custom functions and commands.
Instead, try to a find an ELPA package that comes closest to what you want, and either try to get used to it, or customize it to your needs. If you don't find any, first try to write your own and distribute it on Github, Marmalade or MELPA.
Don't be afraid of maintaining a package in the public. You'll have to maintain your customization anyway, whether in your init.el or not, so you can just as well let other Emacs users help you with this job.
Adding code to your init.el should be your very last resort!

Related

How to declare the location of Emacs's init file as a variable

I use Emacs across a few computers (Linux and Windows boxes) with my .emacs.d synced via ownCloud: .emacs (in ~ or Appdata) just loads {ownCloud directory}/.emacs.d/init.el.
My question is, how do I get that path to the init.el as variable dependent on the OS/username.
For example, the README on the Zenburn theme requires your init includes
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes/")
But as the path from my home directory and .emacs.d varies between machines, this won't work.
I was thinking of something like this to remedy it:
(add-to-list 'custom-theme-load-path "{THE DIRECTORY THAT CONTAINS THIS INIT FILE}/themes/")
Can this be done? I'm only a fortnight's into using Emacs, so don't bite too hard :P
The variable system-type determines between Linux and Windows machines. The variable user-login-name is self explanatory. I use these to load different files depending on which machine I'm in.
(if (eq system-type 'gnu/linux)
(when (string= user-login-name "home user name")
(load-file "/path/to/file"))
(when (string= user-login-name "work user name")
(load-file "/path/to/other-file")))
Honestly though, this is more appropriate for miscellaneous configurations. I wouldn't recommend using this to change your emacs directory location.
Instead, create symlinks on each machine in order to pretend your emacs directory is in the standard place. (I've been doing this on 4 different machines for a couple of years now, and it's going well).
Finally, to answer your last question. The init file already is a variable, and its name is user-init-file. To extract the directory it's located in just do
(file-name-directory user-init-file)
There is user-emacs-directory variable.

Loading packages installed through 'package.el' in Emacs24 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Emacs 24 Package System Initialization Problems
I am using Emacs 24. I have the ELPA and Marmalade repos added. Using 'package' I installed 'auto-complete'. I have the following lines added to my init.el:
(require 'auto-complete-config)
(ac-config-default)
When I start Emacs, I get the error
File error: Cannot open load file, auto-complete-config
But then I use
M-x load-file
and load the same ~/.emacs.d/init.el file, it then works fine with the prompt saying
Loading /home/user/.emacs.d/init.el (source)...done
How is the usual loading different from the 'M-x load-file' command? In the start of the init.el file I do the following, is this somehow effecting the package from loading.
(add-to-list 'load-path "~/.emacs.d")
(load "custom_code")
As mentioned in the comment below: The answer by phils to the duplicate question is probably more helpful than this one
This almost certainly means that your init.el file is getting run before the code that sorts out the packages for package.el. The latter code adds the directory with the auto-complete library to your load path.
I'm still using ELPA, rather than package.el. With elpa, there's a snippet that looks like this that gets installed at the bottom of your .emacs.
;;; This was installed by package-install.el.
;;; This provides support for the package system and
;;; interfacing with ELPA, the package archive.
;;; Move this code earlier if you want to reference
;;; packages in your .emacs.
(when
(load
(expand-file-name "~/.emacs.d/elpa/package.el"))
(package-initialize))
As the comment suggests, you probably want to put your equivalent package.el initialization code before the stuff that loads init.el.
Finally: I notice you mention adding .emacs.d to your load-path. The Emacs load path is not recursive, so that probably won't do what you need (assuming that your libraries live in subdirectories). Years ago, I wrote this snippet to load up various libraries of elisp code that I'd written. You might find it useful. (Obviously, it'll only work on unixy systems with a shell and a find command. It's reasonably slow, but this seems to be shell-command-to-string, which takes several milliseconds even running "echo hello" or the like)
(defun find-elisp-dirs (dir)
"Find all directories below DIR containing elisp sources, ignoring those"
(split-string
(shell-command-to-string
(format "find %s -iname '*.el' -printf '%%h\\n' | sort -u"
(expand-file-name dir t)))))

How to install a Emacs plugin (many times it's a .el file) on Windows platform?

I'm new to Emacs. I found many emacs plugins are released as an .el file. I'm not sure how to install them. Can I just put them in my emacs installation directory?
After placing it, say myplugin.el to your ~/.emacs.d/ directory, add the following in your .emacs file:
(add-to-list 'load-path "~/.emacs.d/")
(load "myplugin.el")
Also, in many cases you would need the following instead of the second line:
(require 'myplugin)
In any case, you should consult the documentation of the package you are trying to install on which one you should use.
If you are unsure where your ~ directory is, you may see it by typing C-x d ~/ and pressing Enter.
As already stated, you'll need the location of the file to be in Emacs' load path.
Read the comments at the top of the file to see if it has any particular installation or usage instructions. Authors often provide this information, and there isn't one single correct way to do it, so it's sensible to look.
Failing that, if the file contains a (provide 'some-name) line (typically at the end of the file), then you would be expected to use (require 'some-name) to load it.
You may also wish to byte-compile the library for speed (but that's a different question).
Many times, an emacs plugin will consist of a directory of elisp files that need to be accessible from the load path. A simple way to ensure that all individual elisp files as well as subdirectories of elisp files are included in the load path and accessible is to do something similar to the following:
Create a directory called ~/.emacs.d/site-lisp.
Install any single elisp files in the ~/.emacs.d/site-lisp directory.
Install any packages that consist of multiple elisp files in a subdirectory under your ~/.emacs.d/site-lisp directory.
Add the following code to your ~/.emacs file to ensure that Emacs "sees" all the elisp files that you have installed:
(add-to-list 'load-path "~/.emacs.d/site-lisp")
(progn (cd "~/.emacs.d/site-lisp")
(normal-top-level-add-subdirs-to-load-path))
This will ensure that all elisp files that are located either in either the ~/.emacs.d/site-lisp directory or in a subdirectory under that directory are accessible.
Some supplementary information:
MATLAB.el comes from http://matlab-emacs.sourceforge.net/
On windows, use the load path that looks like this:
(add-to-list 'load-path' "C:\\Dropbox\\Portable\\emacs\\matlab-emacs")
If you want FULL MATLAB functionality you should use:
;;MATLAB Mode:
(add-to-list 'load-path' "C:\\Dropbox\\Portable\\emacs\\matlab-emacs")
(require 'matlab-load)
if you just want to edit text files:
;;MATLAB Mode:
(add-to-list 'load-path' "C:\\Dropbox\\Portable\\emacs\\matlab-emacs")
(autoload 'matlab-mode "matlab" "Enter MATLAB mode." t)
(setq auto-mode-alist (cons '("\\.m\\'" . matlab-mode) auto-mode-alist))
(autoload 'matlab-shell "matlab" "Interactive MATLAB mode." t)

.emacs, automake and cmake

A long time ago,when I wrote my .emacs setup[1], I used a shell script to compile and join the whole thing. The thing is now very old and "crusty", so I am now rewriting it to replace things such as:
(defmacro make-new-comment( mode face strcom color1 color2)
(list 'progn
`(make-face ',face)
`(if (not (assoc ,strcom ,(intern (concat (symbol-name mode) "-comments-alist"))))
(setf ,(intern (concat (symbol-name mode) "-comments-alist"))
(append ,(intern (concat (symbol-name mode) "-comments-alist")) '((,strcom . ,face)))
)
)
`(modify-face ',face ,color1 ,color2 nil t nil nil nil nil)
)
)
and something occured to me. When compiling I access several environmental variables giving information about the system, for example[2], the full name of most programs called by some mode that uses comint[3]. Rather then reading environmental variables, i could use some autoconf like tool to tweak the .emacs files and then compile them.
The problem is that autoconf is just plain ugly. I considered cmake, but the documentation is very poor especially on constructing your own build system. I'm not familar with alternate systems.
Suggestions?
[1]: To make clear, by .emacs setup I mean the 30 or so files and two subdirs of code that I have. Not to mention several packages that ( well at the time of inclusion ) are not part of the standard emacs distribution.
[2] I've replaced eg with "" since apparently many people do not know that eg means for example. Either that or they don't know what an example is.
[3] Such as diff-mode, and ruby-mode.
which diff?
More details would be useful here. Are these environment variables that you set yourself? or things provided by your distro?
Somewhat ironically, it sounds suspiciously like emacs' incredibly powerful built-in scripting is what you're looking for.
I agree with jkerian: why are you assembling your .emacs from parts? Here is what I do: break it down by language or feature and use require and provide. My .emacs looks like:
; -*- emacs-lisp -*-
(add-to-list 'load-path "~/elisp/personal")
(require 'jdk-generic)
(require 'jdk-haskell)
(require 'jdk-keywiz)
(require 'jdk-lua)
(require 'jdk-ocaml)
(require 'jdk-org)
(require 'jdk-php)
(require 'jdk-tex)
(require 'jdk-text)
(require 'jdk-whitespace)
Each individual file in ~/elisp/personal then sets up support for a language or whatever, then provides jdk-whatever. Here is jdk-lua.el:
(add-to-list 'load-path "~/elisp/packages/lua-mode-20071122")
(add-to-list 'auto-mode-alist '("\\.lua$" . lua-mode))
(autoload 'lua-mode "lua-mode" "Lua editing mode." t)
(provide 'jdk-lua)
Notice that I keep all elisp packages in ~/elisp/packages. This means I can copy my .emacs and ~/elisp directory just about anywhere and have it work straight away.
From what I understand, you want a script to autodetect where are your tools (like diff, grep...) instead of manually telling your .emacs where they are through environment variables.
If you are on a unix-like platform, all your tools like diff, grep, should already be on your PATH and emacs should have no problem finding them. So, in your .emacs you should not use any environment variable and put directly tools name in your configuration.
If your goal is to make a portable .emacs that could be executed on Windows for example, then you should put all the gnuwin32 tools in your PATH too, so that emacs find them without problem. But for Windows, you'll have to do many other tiny arrangements for emacs commands to work properly as on a unix system.
Using a tool like autoconf is something very time-consuming for something that could be well handled by customizing one single .emacs file. If you have specific things to do for a particular system, you could write elisp code like this :
(if (eq window-system 'w32)
(progn ... ))
Also, if you want to automate the byte compilation of all your .el files, you could use a command like this on your shell :
emacs --batch -f batch-byte-compile *.el

Emacs: Where to put the psvn.el file?

I am totally new to emacs and is starting to learn how to use it effectively.
The first thing I wanna use is the svn mode.
I downloaded psvn.el and put it in the ~/.emacs.d directory
Then following the instruction in the comment part of the psvn.el file, I put this line
(require 'psvn)
Into the .emacs file
This is my current .emacs file
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(inhibit-startup-screen t))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
(require 'psvn)
Now when I starts emacs, I got this error message:
An error has occurred while loading `/home/akong/.emacs':
File error: "Cannot open load file", "psvn"
To ensure normal operation, you should investigate the cause
of the error in your initialization file and remove it. Start
Emacs with the `--debug-init' option to view a complete error
backtrace
Did I put the psvn.el in a wrong location?
I am using cygwin + WinXP
This is because Emacs cannot find any file providing psvn on its load-path.
In your shell:
mkdir -p ~/.emacs.d # Make the directory unless it exists
mv /some/path/psvn.el ~/.emacs.d/ # Move psvn.el into that directory
In your Emacs init file (often ~/.emacs):
(add-to-list 'load-path "~/.emacs.d") ; Add this directory to Emacs' load path
(require 'psvn) ; Load psvn
EDIT: I just realized that you are on Windows XP. I'm not sure how Cygwin will handle all of this, but the procedure is pretty much the same outside of Cygwin, just remember that ~ is %APPDATA% on Windows XP, so .emacs.d and .emacs should both be in that directory.
I guess you have problem finding your home directory on Windows? Try C-x d ~ RETURN (run dired on your home directory) to see where you home directory is, then do what the other answers say: put psvn.el in .emacs.d and add ~/.emacs.d in your load-path
First thing you're going to want to do is add .emacs.d to your load path so it knows where to look. Generally most people store .el plugins in ~/.emacs.d/site-lisp so i do this:
;; >>> Configure Load Path <<< ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(setq emacs-config-path "~/.emacs.d/")
(setq base-lisp-path "~/.emacs.d/site-lisp/")
(setq site-lisp-path (concat emacs-config-path "/site-lisp"))
(defun add-path (p)
(add-to-list 'load-path (concat base-lisp-path p)))
;; I should really just do this recursively.
(add-path "")
;; (add-path "some-nested-folder")
Now (require 'psvn) should work out fine.