Emacs: 'Find file' without changing working directory - emacs

My c/c++ projects tend to have fairly straightforward directory structures which separate out src, include, bin, etc. I also tend to have a master makefile in the uppermost directory. When working like this in Emacs, I always have to issue M-x cd uppermost-dir in order for my compilation shortcuts to work as expected.
Is there a way to keep the current directory the same as the one from which I launch Emacs? That is, can I stop Emacs from changing it's working directory when I open a file?
Alternatively, is there something crucial I'm missing about the typical workflow with a directory hierarchiy like this exclusively in Emacs?

One way you can do this:
Make a file in the root directory of your project call .dir-locals.el
This will be read whenever you open a file in the directory or it's sub-directories.
In order to back up to the root folder and run make as your compile command, just put this in the .dir-locals.el file.
((nil . ((compile-command . "cd ~/mycode/c/; make"))))
nil is the mode to set local variables for (nil means any), so to do this for only C++ mode you could do this instead ...
((c++-mode . ((compile-command . "cd ~/mycode/c/; make"))))
Obviously you can set up a list with more options, say running ant for java files and so on.
emacs manual entry for directory locals

Invoke make with the --directory argument to force it to change to that directory before doing anything:
make --directory /path/to/your/project

Change to the project directory (where the Makefile is located) and call compile:
(defun my-compile ()
(interactive)
(when-let (default-directory (locate-dominating-file default-directory "Makefile"))
(call-interactively 'compile)))

The current directory associated with a buffer that's associated with a file is normally the directory containing the file. You can change it, but it's not necessary for what you want to do.
Set the variable compilation-directory through a file-local variable (typically relative to the current file, e.g. "../..") or through .dir-locals.el.

I used to M-x compile <RET> cd /path/to/project && make -j8 but prefer the method by Ben nowadays.

Related

My .emacs.el file is not loading, how can I get it to load? [duplicate]

I tried looking for the .emacs file for my Windows installation for Emacs, but I could not find it. Does it have the same filename under Windows as in Unix?
Do I have to create it myself? If so, under what specific directory does it go?
Copy and pasted from the Emacs FAQ, http://www.gnu.org/software/emacs/windows/:
Where do I put my init file?
On Windows, the .emacs file may be called _emacs for backward compatibility with DOS and FAT filesystems where filenames could not start with a dot. Some users prefer to continue using such a name, because Windows Explorer cannot create a file with a name starting with a dot, even though the filesystem and most other programs can handle it. In Emacs 22 and later, the init file may also be called .emacs.d/init.el. Many of the other files that are created by Lisp packages are now stored in the .emacs.d directory too, so this keeps all your Emacs related files in one place.
All the files mentioned above should go in your HOME directory. The HOME directory is determined by following the steps below:
If the environment variable HOME is set, use the directory it indicates.
If the registry entry HKCU\SOFTWARE\GNU\Emacs\HOME is set, use the directory it indicates.
If the registry entry HKLM\SOFTWARE\GNU\Emacs\HOME is set, use the directory it indicates. Not recommended, as it results in users sharing the same HOME directory.
If C:\.emacs exists, then use C:/. This is for backward compatibility, as previous versions defaulted to C:/ if HOME was not set.
Use the user's AppData directory, usually a directory called Application Data under the user's profile directory, the location of which varies according to Windows version and whether the computer is part of a domain.
Within Emacs, ~ at the beginning of a file name is expanded to your HOME directory, so you can always find your .emacs file with C-x C-f ~/.emacs.
There's further information at HOME and Startup Directories on MS-Windows.
It should be stored in the variable user-init-file. Use C-H v user-init-file RET to check. You can also open it directly by using M-x eval-expression RET (find-file user-init-file) RET
Open the file like this in Emacs for Windows:
C-x C-f ~/.emacs
More information in the Emacs Wiki
On my Vista box it's in C:\Users\<USER>\AppData\Roaming\
Note that it may NOT be enough to just type Ctrl-x Ctrl-f ~/.emacs and create the file.
It may be that your Emacs application uses a different place to store your init file, and if so, then creating the file ~/.emacs simply creates a useless file which your Emacs application ignores.
Also, you may want to do more than just access the .emacs init file, but you may want to know where it is, i.e., its pathname.
To get at this there are two methods:
Easy way: type Ctrl + H V user-init-file Return
Slightly trickier way:
You can find out where your system is storing its own .emacs file by:
Click options and scroll down to "Set Default Font..."
Change the font setting and click okay
On the options menu, go down to "Save Options"
When the options are saved, the system saves its .emacs file,
and you can read the file path in the minibuffer at the bottom of the Emacs screen
In Windows 7 put your init.el file in C:\Users\user-name\AppData\Roaming\.emacs.d\, where user-name is your user/login folder.
Take care so your init.el file won't be named init.el.txt. This is something Windows does if you create your file with some editor like Notepad.
On versions of Emacs on Windows above 22, it seems to have moved to
~/.emacs.d/init.el
, ~ being the value of your environment variable HOME (see Control Panel → System → Advanced → Environment variables).
The file itself might not exist. In that case just create it.
You must create an emacs initialization file. One is not automatically created.
I had a similar issue and this answer tracks down what I did.
My issue was my ~/.emacs.el file was not loading. Strange because this has always worked for me.
This question/answer helped me but I had to put my init file in the %USERPROFILE%\AppData\Roaming\.emacs.d\init.el because this is apparently the default behavior on Windows.
To troubleshoot this, I ran the following in the emacs *scratch* buffer.
user-emacs-directory
"~/.emacs.d/"
When I saw user-emacs-directory was ~/.emacs.d, I simply moved my .emacs.el file to %USERPROFILE%\.emacs.d\init.el. But this still didn't work.
I continued with expand-file-name as shown below:
(expand-file-name user-emacs-directory)
"c:/Users/pats/AppData/Roaming/.emacs.d/"
Got to love how Windows works. (not) So I moved my emacs.el file to the %USERPROFILE%\AppData\Roaming\.emacs.d\init.el and this worked. The file was now being read. But I got other errors because my initialization file loaded other (personal emacs) files (in ~/myenv/emacs/*.el.
Warning (initialization): An error occurred while loading ‘c:/Users/pats/AppData/Roaming/.emacs.d/init.el’:
Hum... Seems like all my files ~/myenv/emacs/*.el would need to be moved in order for this to work but I didn't want to do that. Then I realized that because the HOME environment variable was not set, emacs was performing its default behavior.
SOLUTION
Once I set my windows HOME environment variable to %USERPROFILE% everything began to work like it has for the past 25 years. :-)
To set the HOME environment variable, I typed WindowsKey+"edit environment variables for your account" to open the Environment Variables dialog box, and entered HOME=%USERPROFILE%.
Now my emacs initialization file .emacs.el is is back to its rightful place $HOME/.emacs.el and not in %USERPROFILE%\AppData\Roaming\.emacs.d\init.el
To be fair, if Windows had just one place to put files for user installed packages the solution of making HOME=%USERPROFILE\AppData\Roaming might be acceptable, but because some applications use %USERPROFILE%, some use %USERPROFILE\AppData\Roaming and others use %USERPROFILE\AppData\Local it just makes it difficult to know where to find your configuration files.
I prefer having everything in my %USERPROFILE% or $HOME directory.
Another similar question was here:
Emacs init.el file doesn't load
As kanja answered, the path to this file is stored in the user-init-file variable (or if no init file exists, the variable contains the default value for where to create it).
So regardless of which of the possible init file names you are using, and which directory it is in, you should be able to visit your init file with:
M-: (find-file user-init-file) RET
Or display its full path in the echo area with:
M-: (expand-file-name user-init-file) RET
On Emacs 23 and Windows 7 it only works if you set:
HKCU\SOFTWARE\GNU\Emacs\HOME
After Emacs 27.1, emacs has started respecting the $XDG_CONFIG_HOME. The init file or the init directory can now be found in $XDG_CONFIG_HOME/emacs/init.el.
In Windows $XDG_CONFIG_HOME could translate to %LOCALAPPDATA%.
In any case you can use the following emacs variables to find out the location of the your initialization file by M-x eval-expression
user-init-file
or the emacs configuration directory
user-emacs-directory
I've found that Emacs 22 will occasionally open either "C:\Documents and Settings\username\Application Data\.emacs", or just "C:\Documents and Settings\username\.emacs" on my XP machine. I haven't found an explanation for why it occasionally changes it's mind.
~ will always point to whatever the current instance of emacs thinks is HOME, but kanja's tip (C-h v user-init-file) will always tell you what ~/.emacs actually maps to.
On Windows 8.1, if Emacs is started from Windows Explorer, a shortcut or from cmd console it uses C:\Users\<USER>\AppData\Roaming.emacs init file. When I start Emacs from PowerShell, Emacs looks for its init file in C:\Users\<USER> folder. The fix to this issue was to set the HOME user environment variable (Control Panel\System and Security\System->Advanced system settings->Advanced->Environment variables) to C:\Users\<USER>. After this change, no matter how I start Emacs, it uses the same init file (see the accepted answer of this question)
On Windows XP it's:
C:\Documents and Settings\yourusernamehere\Application Data\
There is a list of directories based on your Windows version and extra information:
http://www.gnu.org/software/emacs/manual/html_node/emacs/Windows-HOME.html
For WIndows7& Emacs26.3:
if HOME environment is set, then the .emacs file should be in that folder.
otherwise, it should be in c:\.
In both cases, if .emacs is not there, _emacs should be used.
This is because we cannot create .emacs file according to the windows file naming rules.(but we can download or copy it from somewhere else).

emacs compile-command find makefile in superior directory

This seems like such an obvious hack I hate to write it myself, but I've had no luck finding it.
I would like an approach to M-x compile that will search upward in the directory tree from cwd to the first directory with a Makefile, after which it runs the make command. So, it's basically
if ./Makefile exists, run the make command
otherwise, cd .. and try again
Stop at $HOME.
The following code defines compile-parent, which locates the nearest Makefile and creates a make command to use that Makefile. It behaves like compile in that it still prompts, showing you the command that it will use, and giving you a chance to edit it, e.g. by specifying a specific target.
(defun compile-parent (command)
(interactive
(let* ((make-directory (locate-dominating-file (buffer-file-name)
"Makefile"))
(command (concat "make -k -C "
(shell-quote-argument make-directory))))
(list (compilation-read-command command))))
(compile command))
You may also want to look at the Projectile extension, which provides a minor mode to detect projects by the presence of VCS metadata or specific build files, with several commands to work from the project root directory, including a projectile-compile command, that runs M-x compile from the project root.

Placing .emacs config file under version repo

Where does emacs look for the .emacs file? Is it simply looking for the file that is accessible anywhere in the PATH? Right now I simply have it in my user home directory on OS X. I have read that it is wise to place this file under version repo, which would mean moving it to a new directory and putting a .git in there (my VCS preference). Is this fine? How does emacs know where the file is located?
The simplest thing to do is move your ~/.emacs file to ~/.emacs.d/init.el. Emacs will find ~/.emacs.d/init.el automatically.
Then you can put all of .emacs.d/ under version control.
For example:
cd ~
mkdir .emacs.d
mv .emacs .emacs.d/init.el
cd .emacs.d
git init
Starting with Emacs 23, the variable user-emacs-directory holds the location of .emacs.d
You can get a more detailed explanation here
Putting your configuration file under a git repository is good. Just use .gitignore to the files you don't want to track!
My suggestion is to put your custom configuration Emacs lisp file under some directory and then load them in your Init file (~/.emacs.d/init.el) like this:
(load "~/myconfig/my_emacs_config.el")

Change .emacs directory in Ubuntu

Currently my .emacs file is found in /home
So is my .emacs.d folder and I suppose some other files like diary, notes etc will be created in this folder.
I find this really messy and I want all my emacs related files(including the .emacs) and folders in a single folder, say /home/EmacsHome
How do I do that in Ubuntu 12.04? In windows I did this by setting an environment variable HOME to the path of EmacsHome. But, in Ubuntu, the HOME variable will be used for several other programs as well, so I dont want to change that.
Emacs already supports a config directory for holding everything Emacs-related: ~/.emacs.d. Just use that.
Rename ~/.emacs to ~/.emacs.d/init.el, and you're virtually done.
If you have any other emacs-specific files outside of that directory, you might need to set a variable here or there to relocate them, or simply rename the file -- these days the defaults tend to automatically be within ~/.emacs.d, but an older filename in the home directory might still take precedence.
e.g.: the bookmarks file used to be ~/.emacs.bmk but if you haven't customized the variable then you can simply rename it to ~/.emacs.d/bookmarks. See C-h f locate-user-emacs-file RET and M-x find-variable RET bookmark-default-file RET for details.
If you're not sure how to proceed for any given file(s), you could just update the question with the details.
And as Alberto Zaccagni said, just create a symlink if you want an alternative name to access the directory. Although personally I would suggest retaining ~/.emacs.d as the real directory, and making the alternative name the link, like so:
ln -s ~/.emacs.d /home/EmacsHome
You could create a symbolic link to them, like so
ln -s /home/EmacsHome ~/.emacs.d
The first argument is the folder where you want the folders to be, the second one is where emacs usually looks for its configuration files, so with this approach you can put the folder wherever you like.
This works for OSX, so perhaps for you too . . . just change the paths to whatever suits your needs. The user-emacs-directory is where you would set the equivalent of .emacs.d. I have everything related to Emacs in my user-emacs-directory. If you use package manager, the elpa directory would be automatically crated there also.
(setq default-directory "~/.0.data/")
(setq user-emacs-directory "~/.0.data/.0.emacs/")
(setq diary-file "~/emacs/diary")
There's also another solution:
cd your-directory
HOME=$PWD emacs -L .
taken from https://github.com/capitaomorte/yasnippet#important-note-regarding-bug-reporting

How to change the virtualenv for emacs virtualenv.el

I tried to use virtualenv virtualenv.el file posted here.
But I set the wrong directory. (Moreover, it seems that it requires I put my virtualenvs in the .virtualenv directory, not in the disparate directories where I've written them on my machine.)
How can I change this back? Now when I run M-x virtualenv-workon I don't have the same intro prompt I had the first time.
Update
Following the note left in the comments and the documentation, I added the following file to my project folder:
/home/fred/projectname/.dir-locals.el
this contains the following:
((nil . ((virtualenv-workon . "venv")
(virtualenv-default-directory . "/home/fred/projectname/venv"))))
However, still when I open emacs in my project directory and type M-x virtualenv-workon it only finds local (default) not venv. What am I missing?
I just had the same problem. I know the post is older and virtualenv.el is depricated, but in case anybody else also stumbles across this:
When you run M-x virtualenv-workon for the first time, it creates an entry in your .emacs file. The file should be found in your home directory. The entry is under custom-set-variables and is called virtualenv-root. You can open the file and adjust the path manually to whatever location you would like.