Why not do clojure-jack-in in a hook to clojure-mode? - emacs

I'm using swank-clojure from https://github.com/technomancy/swank-clojure.
I'd like to run clojure-jack-in automatically when a clojure file is opened in emacs. All my projects use lein, so it should always be appropriate.
Presumably you should check that it hasn't been called already. Something like this in ~/.emacs.d/init.el seems to work, but is there a downside or a better way to achieve the same effect?
(defun clojure-jack-in-once ()
"clojure-jack-in if it hasn't been run already,
as indicated by presence of *swank* buffer"
(if (eq nil (get-buffer "*swank*"))
(clojure-jack-in)))
(add-hook 'clojure-mode-hook 'clojure-jack-in-once)

You might want to extend that to check the liveness of the process, using process-status and get-buffer-process, but there is no fundamental reason you can't do that.
A slightly nicer bit of elisp would be:
(unless (get-buffer "*swank*")
(clojure-jack-in))
Adding the check:
(let ((proc (get-buffer-process "*swank*")))
(unless (and proc (eq (process-status proc) 'run))
(clojure-jack-in)))
That should check if the process is still running and automatically restart if required.

(slime-connected-p) is what you're looking for.
Or (and (featurep 'slime) (slime-connected-p)) to be safe.

Related

How to display file while still in find-file-hook

Currently, I use find-file-hook to invoke a lengthy compilation/checking of that file. I have therefore to wait for some time to actually see the file. What I would like to do instead is to be able to view (not edit) the file already while the checker is running, thus creating the illusion of instantaneous compilation. How can I do this?
Using find-file-hook means your code will run on every file you open; are you
sure you want this? It may make more sense to create a new major or minor mode
for the type of file you want to run your validation on and then use the
corresponding mode hook. For instance, if you wanted to check all .chk files
(with your new major mode inheriting from prog-mode):
(define-derived-mode check-mode prog-mode "Checker")
(add-to-list 'auto-mode-alist '("\\.chk\\'" . check-mode))
(add-hook 'check-mode-hook 'check-mode-computation-hook)
As for the actual hook, this code (going off phils' comment) works for me:
;;; -*- lexical-binding: t -*-
(defun slow-computation ()
(dotimes (i 10000000)
(+ i 1)))
(defun check-mode-computation-hook ()
(let ((cb (current-buffer))
(ro buffer-read-only))
(setq-local buffer-read-only t)
(run-at-time .1 nil
(lambda ()
(with-current-buffer cb
(message "Loading...")
(slow-computation)
(setq-local buffer-read-only ro)
(message "Loaded!"))))))
Note, though, that though this will display the file, emacs will still be frozen
until it finishes its processing, as
emacs doesn't actually support multithreading. To get around this, you may
have to use a library like async, deferred, or concurrent.
You should considered using Flycheck which provides async syntax checking for most programming languages and provides a nice API for implementing new/custom checkers.

Is there a flymake mode for Elisp itself?

I use flymake in Emacs to check code written in several languages. However, I can't see any way to use flymake on elisp itself.
I'm aware of elint-current-buffer, and byte-compile-file, which both give useful warnings about undefined variables etc. Oddly, they don't always give the same errors: for example, elint doesn't warn about (require 'cl). I've also tried auto-compile-mode (available on MELPA) but this still writes the warnings to a separate buffer.
I would really like my elisp code to be underlined when I make mistakes, as I type. How do I do this? I've configured flymake before, but that was with external programs, not Emacs itself.
The Emacs wiki has this to say about flymake for emacs lisp, though it doesn't seem very complete.
flycheck supports Emacs Lisp "out of the box", though.
Erefactor is pretty decent, and available from the wiki as well as melpa: http://www.emacswiki.org/emacs/erefactor.el
I also like to run checkdoc post-save:
(defun emagician/run-checkdoc ()
"run checkdoc on save if it is an elisp file"
(if (and (eq major-mode 'emacs-lisp-mode)
(> (length buffer-file-name)
(length package-user-dir))
(not (string= (concat package-user-dir "/")
(substring buffer-file-name 0 (+ 1 (length package-user-dir))))))
(checkdoc)))
(add-hook 'after-save-hook 'emagician/run-checkdoc)
Now there is elisp-flymake-byte-compile backend for flymake built in.
To enable add this to config:
(add-hook 'emacs-lisp-mode-hook #'flymake-mode)

How to run hook depending on file location

I am involved in python project where tabs are used, however i am not using them in every other code i write, it is vital to use them in that particular project. Projects are located in one directory under specific directories. I.E:
\main_folder
\project1
\project2
\project3
...etc
I have couple functions/hooks on file open and save that untabify and tabify whole buffer i work on.
;; My Functions
(defun untabify-buffer ()
"Untabify current buffer"
(interactive)
(untabify (point-min) (point-max)))
(defun tabify-buffer ()
"Tabify current buffer"
(interactive)
(tabify (point-min) (point-max)))
;; HOOKS
; untabify buffer on open
(add-hook 'find-file-hook 'untabify-buffer)
; tabify on save
(add-hook 'before-save-hook 'tabify-buffer)
If i put it in .emacs file it is run on every .py file i open which is not what i want. What i`d like to have is to have these hooks used only in one particular folder with respective subfolders. Tried .dir_locals but it works only for properties not hooks. I can not use hooks in specific modes (i.e. python-mode) as almost all projects are written in python. To be honest i tried writing elisp conditional save but failed.
A very easy solution is to just add a configuration variable that can be used to disable the hooks. For example:
(defvar tweak-tabs t)
(add-hook 'find-file-hook
(lambda () (when tweak-tabs (untabify (point-min) (point-max)))))
(add-hook 'before-save-hook
(lambda () (when tweak-tabs (tabify (point-min) (point-max)))))
Now you can add a .dir-locals.el file in the relevant directories, setting tweak-tabs to nil, disabling this feature there.
(But another problem is that this is a pretty bad way to deal with tabs. For example, after you save a file you do see the tabs in it.)
Just for the record, to answer the literal question in the title (as I reached this question via a web search): one way to add a hook that depends on file location is to make it a function that checks for buffer-file-name. (Idea from this answer.)
For example, for the exact same problem (turn on tabs only in a particular directory, and leave tabs turned off elsewhere), I'm currently doing something like (after having installed the package smart-tabs-mode with M-x package-install):
(smart-tabs-insinuate 'python) ; This screws up all Python files (inserts tabs)
(add-hook 'python-mode-hook ; So we need to un-screw most of them
(lambda ()
(unless (and (stringp buffer-file-name)
(string-match "specialproject" buffer-file-name))
(setq smart-tabs-mode nil)))
t) ; Add this hook to end of the list
(This is a bit inverted, as smart-tabs-insinuate itself modifies python-mode-hook and then we're modifying it back, but it should do as an example.)

Breaking out of .emacs script

I use two emacs (Aquamcs and text based emacs) on my Mac.
I normally use text based emacs for just editing something, so I don't want to load anything with it.
What I came up with is to have the checking code in .emacs to exit/break if it's text based emacs (darwin system but not aquamacs).
(when (and (equal system-type 'darwin) (not (boundp 'aquamacs-version)))
(exit) ??? (break) ????
)
It seems to work, but I don't know how to break out of .emacs. How to do that?
ADDED
I just wanted to speed up in loading text based emacs on my mac, and I thought about breaking out as a solution. Based on the helpful answers, I came up with the following code that runs .emacs only when it's not a text based emacs.
(setq inhibit-splash-screen t)
(unless (null window-system)
I don't know of any way to do exactly what you want. Some workarounds:
You can stop the evaluation of your .emacs by evaluating (error "message") but that's a bit unpleasant.
You can re-order your .emacs so that there's a (unless (CONDITION) ...) around the whole of the file.
You can run emacs -Q FILE when you're at the command line.
Why do you want to do this? Are you concerned at the time it takes to load your .emacs? If so, you might consider using the Emacs client/server instead.
I am not sure how to exit as well but..... I would rather advice another kind of logic for your init file than a flat file with all different configurations.
Take for example your ~/.emacs (or better ~/.emacs.d/init.el) as your controller and files like ~/.emacs.d/aquamacs.el or ~/.emacs.d/textmode.el as your individual configuration files.
That would make your init having something like this :
(defun my-short-hostname()
(string-match "[0-9A-Za-z]+" system-name)
(substring system-name (match-beginning 0) (match-end 0))
)
;Load different config file in text mode or gui mode.
(if (null window-system)
(load-file "~/.emacs.d/texmode-emacs.el")
(load-file "~/.emacs.d/gui.el"))
;Load configuration for this host only, ie ~/.emacs.d/myhostname.el if exist
(if (file-exists-p
(downcase (concat "~/.emacs.d/" (my-short-hostname) ".el")))
(load-file (downcase "~/.emacs.d/" (my-short-hostname) ".el"))))
I suggest having specific, different files to load conditionally from your .emacs, one for one setup, another for another setup.
Alternatively, just wrap the code for each setup in a progn and do the conditional in place, in .emacs itself.

is there an emacs tool to show a directory structure as a tree?

I am aware of Speedbar (I prefer the structure in the same frame as the rest of my work), and dired shows too much information. I'm after something like the svn-status tree representation. Is there anything like that?
Thank you.
EDIT: Here's what I found the most intuitive:
I am using Speedbar with the following hack from here. I had to use the commented "try this" part, FYI.
(require 'speedbar)
(defconst my-speedbar-buffer-name "SPEEDBAR")
; (defconst my-speedbar-buffer-name " SPEEDBAR") ; try this if you get "Wrong type argument: stringp, nil"
(defun my-speedbar-no-separate-frame ()
(interactive)
(when (not (buffer-live-p speedbar-buffer))
(setq speedbar-buffer (get-buffer-create my-speedbar-buffer-name)
speedbar-frame (selected-frame)
dframe-attached-frame (selected-frame)
speedbar-select-frame-method 'attached
speedbar-verbosity-level 0
speedbar-last-selected-file nil)
(set-buffer speedbar-buffer)
(speedbar-mode)
(speedbar-reconfigure-keymaps)
(speedbar-update-contents)
(speedbar-set-timer 1)
(make-local-hook 'kill-buffer-hook)
(add-hook 'kill-buffer-hook
(lambda () (when (eq (current-buffer) speedbar-buffer)
(setq speedbar-frame nil
dframe-attached-frame nil
speedbar-buffer nil)
(speedbar-set-timer nil)))))
(set-window-buffer (selected-window)
(get-buffer my-speedbar-buffer-name)))
So I wanted to just print a tree quickly and all Emacs based solutions seemed either rather old or massive like (ECB/CEDET) which I don't know enough about, so for quick fix I did
sudo apt-get install tree
then from dired buffer
M-! tree --dirsfirst RET
voilĂ ! directory tree without any specific libs, as an added bonus using tree -f outputs tree with full paths, making it obvious to jump to file with C-x C-f directly from the tree output buffer.
There is a tree extension for emacs mode Sunrise Commander. Sunrise Commander is like Midnight Commander.
There's the Emacs Code Browser. Last I heard using it with a current emacs may be tricky or difficult because it makes use of some tools that were recently integrated into Emacs via CEDET.
I'd recommend NeoTree. It's easy to install and easy to use.