emacs ERC commands conditional only if file exists - emacs

I have the following in my emacs init file:
(if (file-readable-p "~/.ercpass") (load "~/.ercpass"))
(setq erc-nickserv-passwords
`((freenode (("jacob" . ,freenode-nickone-pass)))))
Only if ~/.ercpass (its contents being (setq freenode-nickone-pass "mypassword")) is readable do I want the file to be loaded and the ERC password to used. If the file exists, everything works. But if it doesn't exist, the second line throws an error:
Symbol's value as variable is void: freenode-nickone-pass
How can I make the second line also conditional on whether ~/.ercpass is readable?

(if (file-readable-p "~/.ercpass")
(progn
(load "~/.ercpass")
(setq erc-nickserv-passwords
`((freenode (("jacob" . ,freenode-nickone-pass)))))))

Related

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"))

How to create an empty file by elisp?

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

Emacs folding mode error

I want to be able to use the emacs folding mode provided by folding.el from http://www.emacswiki.org/emacs/FoldingMode
I put the following in my .emacs file:
(setq load-path (cons (concat (getenv "HOME") "/.emacs.d") load-path))
(load "folding")
(folding-mode-add-find-file-hook)
(folding-add-to-marks-list 'latex-mode "%{" "%}" nil t)
Then, when I select a region and run
M-x folding-fold-region
I get the error
Wrong type argument: char-or-string-p, nil
There are two problems :
you don't have to re-declare marks for latex-mode as this is already done in folder.el line 4411. Thus you should remove the line (folding-add-to-marks-list 'latex-mode "%{" "%}" nil t)
You get the error Wrong type argument: char-or-string-p, nil when the folder-mode is not enabled. Adding the line (folding-mode-add-find-file-hook) is not enough to open a file in folder-mode by default. To open in folder-mode, you should also place the folded-file local variable in the first line of the file you want to open, for example, in lisp :
;; -*- folded-file: t; -*-
With this local variable, and the (folding-mode-add-find-file-hook) command in your .emacs the folder-mode is enabled and you don't have problem anymore when calling folding-fold-region on a region.
Do a C-h f folding-mode-add-find-file-hook RET to have the explanation of this mechanism.

Emacs custom command line argument

From the documentation I can see I can access command line arguments (command-line-args).
I'd like to add my own arguments but Emacs complains at start up that it doesn't recognize them.
E.g.
emacs -my_argument
I get:
command-line-1: Unknown option `-my_argument'
What's a proper way to define my custom arguments and provide information to my Emacs session?
Is there a way to pop an argument from a command line?
Add something like this to your ~/.emacs, ~/.emacs.el, or ~/.emacs.d/init.el file:
(defun my-argument-fn (switch)
(message "i was passed -my_argument"))
(add-to-list 'command-switch-alist '("-my_argument" . my-argument-fn))
Then you can execute emacs -my_argument and it should print i was passed -my_argument to the minibuffer. You can find more information in the GNU elisp reference.
As stated in another post you can add your custom switches to command-switch-alist and emacs will call the handler function for any matching switch passed in on the command line. However, this operation is done after your .emacs file has been evaluated. This is fine for most cases but you may wish for a command line argument to alter the execution path or behaviour of your .emacs evaluation; I often do this to enable/disable configuration chunks (mainly for debugging).
To achieve this you can read command-line-args and check for your switch manually and then delete it from the list, this will stop emacs complaining about an unknown argument.
(setq my-switch-found (member "-myswitch" command-line-args))
(setq command-line-args (delete "-myswitch" command-line-args))
Which can alter your .emacs evaluation like so:
(unless my-switch-found
(message "Didn't find inhibit switch, loading some config.")
...)
And you could build this into a single step:
;; This was written in SO text-box, not been tested.
(defun found-custom-arg (switch)
(let ((found-switch (member switch command-line-args)))
(setq command-line-args (delete switch command-line-args))
found-switch))
(unless (found-custom-arg "-myswitch")
(message "Loading config...")
...)
For those who are interested, here is a code snip to show how to process custom arguments in Emacs lisp. In this case, I am processing an argument --suffix / -S to variable _suffix.
I pulled the idea from a BSD-Lite Script Emacs script.
(setq _suffix nil)
;; Process cli args
(while command-line-args-left
(setq k (car command-line-args-left))
(setq command-line-args-left (cdr command-line-args-left))
(setq command-line-args (delete k command-line-args))
(cond
(or (string-equal k "--cs-suffix")
(string-equal k "-S"))
(setq _suffix (intern (car command-line-args-left)))
(setq command-line-args-left (cdr command-line-args-left))
(setq command-line-args (delete _suffix command-line-args))
)))
This will roll through command-line-args-left and remove them all from command-line-args which will prevent Emacs from complaining.