How to create an empty file by elisp? - emacs

I set an explicit file to customization created via the UI. It's named custom.el. Currently, I use the followed snippets to create this file if not exist.
(defconst custom-file (expand-file-name "custom.el" user-emacs-directory))
(unless (file-exists-p custom-file)
(shell-command (concat "touch " custom-file)))
There is an ugly shell-command touch in, any other elisp functions can do this?

You can use (write-region "" nil custom-file) not sure that is the ideal solution.

Perhaps a simpler solution to the underlying problem would be:
(defconst custom-file (expand-file-name "custom.el" user-emacs-directory))
;; NOERROR to ignore nonexistent file - Emacs will create it
(load custom-file t)
In other words, instead of manually creating custom.el, simply don't error when you try to load it (optional arg NOERROR is only for file existence error). Emacs will create the file the first time it writes out custom variables.
This is what I'm currently using in my init.el

I write this function below based on Joao Tavara anwser in this post: How do I create an empty file in emacs?
(defun fzl-create-empty-file-if-no-exists(filePath)
"Create a file with FILEPATH parameter."
(if (file-exists-p filePath)
(message (concat "File " (concat filePath " already exists")))
(with-temp-buffer (write-file filePath))))

(make-empty-file custom-file)
Check help to know more about it: C-h f make-empty-file

Related

Getting "root" folder of orgmode package installation in emacs via elisp

How can I get the folder in which org-mode is installed in emacs? Depending on the way it was installed, it will be different. Is there a variable which holds this value?
I would need it to access a file which is part of the org-mode installation.
I am not looking for a particular library, but an .R file, which is an R file which I want to load programmatically into R (from elisp code).
So using
(locate-library "ob-R")
"/Users/rainerkrug/.emacs.d/org-mode/lisp/ob-R.elc"
I would then have to use the following:
(concat (locate-library "ob-R") "/../etc/")
"/Users/rainerkrug/.emacs.d/org-mode/lisp/ob-R.elc/../etc/"
And I still have to get rid of the ob-R.elc
This works, but I am looking for a function which gives me the path
(IS-THERE-SOMETHING-LIKE-THIS "org")
"/Users/rainerkrug/.emacs.d/org-mode/"
Thanks
Emacs provides a rich set of file name manipulation functions which easily solve your problem:
(expand-file-name "../etc/R" (file-name-directory (locate-library "ob-R")))
M-x locate-library RET org RET
or, if you would like to open:
M-x find-library RET org RET
You can use this:
(org-find-library-dir "org")
Or, in your case:
(concat (org-find-library-dir "org") "etc/R")
If you don't need to do this programmatically, you could use M-x describe-mode and in the description one of first lines is Org mode defined in org.el The link to org.el is clickable, and leads to org-mode's directory.
I found a solution which is efectively using locate-library and to truncate the not-needed elements (file name and last dir) and assembles them again as a path:
(locate-library "org")
"/Users/rainerkrug/.emacs.d/org-mode/lisp/org.elc"
(split-string (locate-library "org") "/")
("" "Users" "rainerkrug" ".emacs.d" "org-mode" "lisp" "org.elc")
(butlast (split-string (locate-library "org") "/") 2)
("" "Users" "rainerkrug" ".emacs.d" "org-mode")
(append (butlast (split-string (locate-library "org") "/") 2) '("etc" "R"))
("" "Users" "rainerkrug" ".emacs.d" "org-mode" "etc" "R")
(mapconcat 'identity
(append (butlast (split-string (locate-library "org") "/") 2) '("etc" "R"))
"/")
"/Users/rainerkrug/.emacs.d/org-mode/etc/R"
As pointed out in the comments, the usage of split-string is suboptimal. Please see accepted answer for the best approach.

Adding hook on elisp function

I'm using Emacs.
Is there any way to add hook on a function?
Assume that there is a markdown-export function.
It is designed to export HTML file into current directory where current working 'markdown file' exsits.
But, I want to export HTML file into another directory. How can I do that without modification on Emacs markdown plugin (markdown-mode.el)?
This is markdown-mode.el's export function:
(defun markdown-export (&optional output-file)
"Run Markdown on the current buffer, save to file, and return the filename.
If OUTPUT-FILE is given, use that as the filename. Otherwise, use the filename
generated by `markdown-export-file-name', which will be constructed using the
current filename, but with the extension removed and replaced with .html."
(interactive)
(unless output-file
(setq output-file (markdown-export-file-name ".html")))
(when output-file
(let* ((init-buf (current-buffer))
(init-point (point))
(init-buf-string (buffer-string))
(output-buffer (find-file-noselect output-file))
(output-buffer-name (buffer-name output-buffer)))
(run-hooks 'markdown-before-export-hook)
(markdown-standalone output-buffer-name)
(with-current-buffer output-buffer
(run-hooks 'markdown-after-export-hook)
(save-buffer))
;; if modified, restore initial buffer
(when (buffer-modified-p init-buf)
(erase-buffer)
(insert init-buf-string)
(save-buffer)
(goto-char init-point))
output-file)))
=====================================================================
I have made an advice to save exported HTML at temp directory
Here is the code.
(defadvice markdown-export (around set-temp-path-for-exported-file activate)
(ad-set-arg 0 (format "%s/%s" "~/.emacs.d/temp-dir" (file-name-nondirectory buffer-file-name)))
ad-do-it)
Thanks!!!!!!!!!!!!!!
In this case you do not need to hook on this function since it already accepts the filename as an argument, unfortunately it does not accept the filename when called interactively. As a workaround you can define a simple wrapper around the function like follows
(defun my-markdown-export (&optional file)
(interactive (list (ido-read-file-name "Export as: ")))
(markdown-export file))
The advice mechanism is a bit like having hooks for any arbitrary function, but here you have actual hooks you can use, as well as a function argument which addresses your requirement directly.
So you can:
(a) Pass the function any arbitrary output filename.
(b) Use the provided markdown-before-export-hook to setq whichever variables you need to (which at a glance looks like output-file, output-buffer, and output-buffer-name).

How do I get the path from which init.el was loaded?

I am looking to create a custom config for emacs to use for Erlang work and I want to refer to my custom EDTS repo as being under the directory from which init.el was loaded. Right now I have this:
(add-to-list 'load-path "~/.emacs-edts/edts/")
But I would rather not hardcode it and refer to it by variable.
Suggestions?
Strictly speaking the answer is (file-name-directory user-init-file), but instead see C-hv user-emacs-directory
I have the following snippet in my init.el:
(setq my-init-dir
(file-name-directory
(or load-file-name (buffer-file-name))))
This has the advantage of working whether init.el is in your emacs.d directory or not.
I have the following in my init file:
(defun my-file-name-basename (s)
"The directory name, without the final part.
For example:
(my-file-name-basename \"alpha/beta/gamma\") => \"alpha/beta\""
(substring (file-name-directory s) 0 -1))
;; Note: Normally, it's not possible to find out the file a specific
;; function is defined in. However, it's possible to save the file
;; name at the time this file was loaded.
(defvar my-load-file-name load-file-name
"The file name of this file.")
(defun my-start-directory (&optional path)
"The root directory that contains this module.
When PATH is specified, return the start directory concatenated with PATH.
Otherwise return the directory with a trailing slash."
;; Note: Try to figure out where we are, so that we can add the
;; subdirectories. `load-file-name' only works when the file is
;; loaded. Picking up the file from the symbol works when this is
;; evaluated later.
(let ((file-name (or my-load-file-name
(symbol-file 'my-start-directory)
;; Default value. (This is used, for example,
;; when using `eval-buffer' or `eval-region'.)
"~/emacs")))
(let ((start (concat (my-file-name-basename
(my-file-name-basename file-name))
"/")))
(if path
(concat start path)
start))))
In addition to finding out where the file containing the above above code is located (which does not have to be the init file), it provides a convenient way to create paths based on it. For example:
(setq custom-file (my-start-directory "init/custom.el"))

Emacs in place filename / path insertion

I am looking for a way to insert a filename/path inline while editing. Something like an inline ido-style file selection would be perfect. Is there anything like that out there?
I always use comint-dynamic-complete-filename for this. This does not seem to be loaded by default, but provided by comint-mode. Thus you could put something like
(autoload 'comint-dynamic-complete-filename "comint" nil t)
(global-set-key "\M-]" 'comint-dynamic-complete-filename)
in your ~/.emacs or the like. Use your own prefered keybinding of course.
Okay, if you want to just insert the current file name at point, then
(insert (expand-file-name (buffer-file-name)))
should do it.
If you want to be able to find a file at any path, then you'll want to replicate some of the code in find-file-noselect in files.el at about line 1714 .
In either case, if you want to bind this a a function, you'll probably want
(defun insert-file-name-at-point ()
(interactive) .... )
(defun insert-file-name (file &optional relativep)
"Read file name and insert it at point.
With a prefix argument, insert only the non-directory part."
(interactive "fFile: \nP")
(when relativep (setq file (file-name-nondirectory file)))
(insert file))

How can I hide the backup files that emacs creates?

I just started using emacs after having used vi for a long time. :)
One thing which is annoying me is that whenever I modify a file, save it and exit emacs, I see a backup file created in the same directory named filename~ (if the file I edited was filename).
Is there any way I can get rid of this? Or hide these files? It is very annoying to see tons of backup files when I do ls of the directory.
You can either move them to their own folder with the following code:
;; Don't clutter up directories with files~
(setq backup-directory-alist `(("." . ,(expand-file-name
(concat dotfiles-dir "backups")))))
;; Don't clutter with #files either
(setq auto-save-file-name-transforms
`((".*" ,(expand-file-name (concat dotfiles-dir "backups")))))
Or you can remove them completely, like so:
(setq make-backup-files nil)
(setq auto-save-default nil)
Personally I would be wary of removing them as they can come in useful. Further discussion is here:
http://www.emacswiki.org/emacs/BackupDirectory
http://www.emacswiki.org/emacs/AutoSave
I would recommend checking out the emacs-starter-kit it sorts out a load of issues that people have when coming to emacs, and is pretty heavily used.
http://github.com/technomancy/emacs-starter-kit/blob/master/starter-kit-misc.el
Update:
There seems to be much confusion over how to use the functions. I'm going to have a little play around later but here is some more information. Note that auto-save-file-name-transforms:
lets you specify a series of regular expressions and replacements to transform the auto save file name
[emacs-manual]
so it's not just as simple as adding in a folder name. That said it seems from a quick google search the following might just do what you all want:
;;; backup/autosave
(defvar backup-dir (expand-file-name "~/.emacs.d/backup/"))
(defvar autosave-dir (expand-file-name "~/.emacs.d/autosave/"))
(setq backup-directory-alist (list (cons ".*" backup-dir)))
(setq auto-save-list-file-prefix autosave-dir)
(setq auto-save-file-name-transforms `((".*" ,autosave-dir t)))
http://www.google.com/codesearch?hl=en&lr=&q=auto-save-file-name-transforms&sbtn=Search
The following lines in ~/.emacs will put all of the auto-save and backup files in /tmp:
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
In your .emacs:
(setq make-backup-files nil)
Edit:
If you're unfamiliar with the .emacs file, it's a file named .emacs that resides in your user $HOME directory. If you don't have one already, you can just create it and emacs will load it on startup.
Here is a link to the same question answered on SuperUser and my response. And a StackOverflow question entitled Emacs: Don’t create #these# files when not saving modified buffer
And for completeness, as stated by others; to stop the backup files being created put this in your .emacs
(setq make-backup-files nil)