I am reading about the kill-emacs-hook variable in the emacs manual.
It says:
kill-emacs-hook is a variable defined in `C source code'.
Its value is
(org-babel-remove-temporary-directory migemo-pattern-alist-save)
This variable is potentially risky when used as a file local variable.
Documentation:
Hook to be run when `kill-emacs' is called.
...abbr...
I do not understand this sentence: "a file local variable". What does this "a file local variable" mean?
Emacs has a facility for specifying buffer variables in a file's contents. http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html#Specifying-File-Variables
This is frequently used to specify the file's mode -*- python -*- or e.g. the preferred indentation style or tab width; but it potentially can give the file's author complete control over your Emacs, if you allow it. However, for variables deemed to be unsafe, the default behavior is to ask the user for confirmation before permitting the settings to take effect. See the manual for further discussion.
By defaul, when you set a variable with setq the value is global. It means that all the buffers will see the new value.
However, certain variables, called buffer local variables, work differently. When a buffer local variable is set, its value changes only for the buffer where the setq happened. The other buffers do not see the change.
These buffer local variables can take their value from the content of the file currently visited by the buffer. If the file contains a properly formatted string (see #tripleee's answer) then a buffer local variable will be initialized with the value when the file is open.
As a side note, directory local variables also exist which set a buffer local variable for every buffer visiting a file in the directory.
Related
I'm currently using this template
(setq org-capture-templates
`(("e" "ethz studies tasks"
entry (file+function ,(concat org-directory "/ethz-tasks.org") (lambda ()
(print (f-filename default-directory))
(search-forward (f-filename default-directory))
(move-end-of-line)
(newline)))
"** TODO %t [[file:%F][%f]]\n%?\n")))
In an attempt to get the template to file a little todo note about the current file, under a heading which is the name of that files parent directory
i.e.
* directory
** TODO <date> [[file:...][file]]
some extra info
The problem with my current snippet is that it uses default-directory, which in the context of the capture, seems to be "org". I want to get the name of the directory I was in before invoking the capture.
Which function should I be using for this ?
Is there maybe some easier way to do this in org capture than the way I'm going about it ?
org-capture stores bits and pieces of information in a dynamically-scoped variable org-capture-plist. Once the capture process starts and creates the capture buffer, the global value is copied to a local buffer variable org-capture-current-plist. This is where the values for all the formats in the template are stored and are fetched from (%f, %F, etc).
I have not tested any of this, so you might have to adjust according to what you find out, but I believe that you will need to query the local variable (although if you find that's nil, then you can try querying the global one). In either case, the original pathname is stored under the property :original-file, which you can get using
(org-capture-get :original-file t) ; query the local plist
OR
(org-capture-get :original-file) ; query the global plist
depending on which plist you want to query. You can then get the directory name by calling file-name-directory on the result.
One or the other of these should give you the directory which you can then use as a heading. I'm not sure though whether the heading needs to exist already: if it has to exist beforehand, then you must do additional work, work that is not covered by this answer.
Completely and utterly untested, if that's not clear already.
EDIT: Here's a slightly more detailed explanation of the global vs local plist.
When you call org-capture, the various values are saved on the global plist, then eventually a capture buffer is created and the values are copied to the buffer-local plist. At that point, the capture buffer is waiting for input, so you can initiate a different capture: that goes through the same process, so now the global plist has the information for the second capture (until its buffer is created etc).
So it really depends at what point in the sequence you try to access the value you want: if it happens before the capture buffer is created (as it seems to in your case), then you get it out of the global plist; but if it happens afterwards, you have to get it off the local plist, because the global one may be referring to a different capture.
So you should probably be doing something like this:
(let ((path (file-name-directory
(or (org-capture-get :original-file t)
(org-capture-get :original-file)))))
...
i.e. try to get it off the local plist first and fall back to the global plist only if the local one is nil. That way, you avoid the problem of getting the value from the wrong capture context.
I hope that clarifies the situation.
In Emacs, I am putting on the menu an item to load the init.el file, since I am in there almost daily.
menu code is working fine, but the file isn't loading.
So in a buffer, for troubleshooting, I enter:
(load user-init-file)
and use C-x C-e to execute it.
Turns out if fails because it needs double backslashes in the path.
user-init-file resolves to "c:\steve\emacs\init.el"
But should be `
"c:\\steve\\emacs\\init.el"
is there a function already to convert to the double backslashes?
Or how do I do that with a search/replace?
This is similar to other search questions I found except this is for replacing within a string instead of within a buffer.
I think you probably just want (load-file user-init-file). load-file does not use load-path, and it does not try to append .elc or .el.
(If you use MS Windows notation for a file name then you can see what Emacs really thinks the file name is, by calling file-truename on it.)
If you really want to use load, try (load user-init-file nil nil t).
load tries to expand its FILE arg, automatically adding .elc and .el. The 4th argument is NOSUFFIX, which if non-nil prevents that behavior.
C-h f load:
**load-** is a built-in function inC source code`.
(load FILE &optional NOERROR NOMESSAGE NOSUFFIX MUST-SUFFIX)
Execute a file of Lisp code named FILE.
First try FILE with .elc appended, then try with .el,
then try FILE unmodified (the exact suffixes in the exact order are
determined by load-suffixes). Environment variable references in
FILE are replaced with their values by calling substitute-in-file-name.
This function searches the directories in load-path.
If optional second arg NOERROR is non-nil,
report no error if FILE doesn't exist.
Print messages at start and end of loading unless
optional third arg NOMESSAGE is non-nil (but force-load-messages
overrides that).
If optional fourth arg NOSUFFIX is non-nil, don't try adding
suffixes .elc or .el to the specified name FILE.
If optional fifth arg MUST-SUFFIX is non-nil, insist on
the suffix .elc or .el; don't accept just FILE unless
it ends in one of those suffixes or includes a directory name.
If NOSUFFIX is nil, then if a file could not be found, try looking for
a different representation of the file by adding non-empty suffixes to
its name, before trying another file. Emacs uses this feature to find
compressed versions of files when Auto Compression mode is enabled.
If NOSUFFIX is non-nil, disable this feature.
The suffixes that this function tries out, when NOSUFFIX is nil, are
given by the return value of get-load-suffixes and the values listed
in load-file-rep-suffixes. If MUST-SUFFIX is non-nil, only the
return value of get-load-suffixes is used, i.e. the file name is
required to have a non-empty suffix.
When searching suffixes, this function normally stops at the first
one that exists. If the option load-prefer-newer is non-nil,
however, it tries all suffixes, and uses whichever file is the newest.
Loading a file records its definitions, and its provide and
require calls, in an element of load-history whose
car is the file name loaded. See load-history.
While the file is in the process of being loaded, the variable
load-in-progress is non-nil and the variable load-file-name
is bound to the file's name.
Return t if the file exists and loads successfully.
I have a folder /var/~/. In config .emacs I wanna load some files from this folder.
I try to use (load-file "/var/~/foobar.el"), but emacs alerts File error: Cannot open load file, ~/foobar.el.
Furthermore I couldn't even open the files under this folder with c-x c-f. In minibuffer the path will auto be redirected to my home.
How could I load files in that folder?
You need to rename your directory.
load-file is a simple wrapper around load, which passes the given file name through substitute-in-file-name. From the docstring of substitute-in-file-name (emphasis mine):
Substitute environment variables referred to in FILENAME. `$FOO' where FOO is an environment variable name means to substitute
the value of that variable. The variable name should be terminated
with a character not a letter, digit or underscore; otherwise, enclose
the entire variable name in braces.
If `/~' appears, all of FILENAME through that `/' is discarded. If `//' appears, everything up to and including the first of those `/' is discarded.
In other words, substitute-in-file-name throws away everything before /~, turning /var/~/foo.el into ~/foo.el.
I completely fail to see any reason in this behaviour, but it is what it is, and you cannot (easily) work around it, so renaming is your best way out of this dilemma.
It's a reasonable thing to do, anyway. Using ~ as directory name is bad idea on Unix systems generally, not just for Emacs alone.
lunaryorn explained your problem well, and I agree with his suggestion that not using ~ in file paths is the best solution. However, If you can't rename these paths for whatever reason, I believe you can work around substitute-in-file-name by loading a relative file path as documented here.
Basically, you need to add nil to your load-path variable, then set your default-directory variable to the troublesome path, finally then load the file using a relative name. e.g.:
; adding nil causes load to also search your 'default-directory'
(setq load-path (append '(nil) load-path))
(setq default-directory "/tmp/~/")
(load "foobar.el")
Note that if you suspect the file name might exist (be loaded from) elsewhere in your load-path you would need to ensure the file you want is first in the load-path.
See How programs do loading.
When I open the file zenburn-theme.el from github.com/bbatsov/zenburn-emacs.git in Emacs 24.3, I get the following warning in a buffer:
Why? Also, why would it not be safe to open (not load or run) a file?
A file, even if opened and not loaded, might contain some configuration values to be applied. Some of them are considered unsafe and Emacs asks you about them unless told otherwise. See Local Variables in Files for details.
How can I check the identity of someone who has created a buffer in Emacs and then later on check whether is the same user accessing that buffer? I mean something like "Who Am I?" in Unix command.. and then check if the same user is accessing that document? --> I want a function or a way to this in my own code
Note the difference between a buffer and a file: A file is something that sits on your hard disk, such as a .jpg image file or a .mp3 aufio file or a .txt file. Some of those files - typically text files - you might want to edit with Emacs. To do so, you can load the file into Emacs - this is called "visiting" a file in Emacs lingo. The contents of the file are displayed in a buffer. But note that you could also have a buffer that is not associated with a file at all - for instance the *scratch* buffer that gets displayed if you start up Emacs without specifying a file.
Thus files and buffers are pretty much orthogonal concepts, although often times you create buffers by visiting a file, and you save the contents of a buffer by writing to a file. (You can create a buffer that is not associated with a file by typing C-x b buffer-name where buffer-name is an identifier not used by any of the already existing buffers.)
A buffer exists only inside a running Emacs. This is why the comments and answers you have gotten so far may not have been what you're looking for: the notion of the creator/owner of the buffer is confusing, because it is obviously the person who's sitting at the keyboard at that particular moment.
Speaking of the owner/creator of a file makes much more sense. In a multi-account setup, more than one user can write to the same disk, and so they might have access to the same files. Now it can be interesting to know who has access, and in particular who owns the file or when it was last modified. In Elisp, you can use the function
(file-attributes FILENAME &optional ID-FORMAT)
to get a list of attributes associated with the file. If your current buffer is visiting a file at all, you can combine that function with the function
(buffer-file-name &optional BUFFER)
which returns the file the buffer is visiting. For a buffer that is not visiting a file, this function returns nil.
Note, however, that some information you might be interested in is not available through (file-attributes ...), such as who last accessed the file and/or who last modified it. This is not so much Emacs' fault, but comes from the fact that the operating system does not store such information.
Also note that the current owner of a file might not necessarily be the person who created it as someone with the required privileges can chown a file after its creation.
To receive information about the current user in the sense of whoami, you can check out the variables
user-login-name
user-real-login-name
user-full-name
by typing C-h v variable-name.
AFAIK seen from system, Emacs is a single process, owned by the user who started it
(getenv "USER")
is the respective to
echo $USER