Conditionally set `dired-listing-switches` locally, but `nil` remotely - emacs

The following setting works great locally (OSX), but prevents Emacs from properly displaying directories/ files on the remote server (Linux):
(setq dired-listing-switches "-aBhl --group-directories-first")
I log in to the remote server with:
C-x C-f /ssh:user#server:/home/user/
So dired-listing-switches needs to be set locally, but nil remotely. How can this be accomplished programmatically?

As much as I wanted to use a hook, none of the dired hooks seemed to allow this customization because dired tries to be a little lazy as to how it loads things.
Advice will allow you to switch the value of dired-listing-switches programmatically by allowing us to surround the body of the `dired' function with more code.
The first value passed into dired is the directory, so you can use file-remote-p to determine if it's a server location. You access the args to the function you are advising by using ad-get-arg <index>
(defadvice dired (around no-switches-for-server-file activate)
"When opening dired for a remote location, use the default switches"
(let ((dired-listing-switches (if (file-remote-p (ad-get-arg 0))
"-al" ;; the default switches
dired-listing-switches)))
ad-do-it))
If this is your first encounter with function advice give the docs a read.
M-: (info "(elisp) Advising Functions") enter
I do not believe you want the variable to be nil, rather the default value. When I tried using nil, dired would give me an error. If you don't even want the default value, switch it out for an empty string.

If you are doing this only for interactive use of dired and not also for programmatic calls to function dired, then you do not need to (and so should probably not) advise dired.
Instead, just define a new command, my-dired, which tests its arg using file-remote-p and then calls dired using the appropriate switches. Then remap dired to your command, for key bindings. Similarly, for dired-other-window.
If you want to allow for similar prefix arg behavior to that of dired, you can do that as well. E.g., if current-prefix-arg then read and use the switches provided by the user, else do as described above: test arg and set switches accordingly.
For example (untested):
(defun my-dired (dirname &optional switches)
"..."
(interactive
(let* ((dir (if (next-read-file-uses-dialog-p)
(read-directory-name "Dired (directory): "
nil default-directory nil)
(read-file-name "Dired (directory): "
nil default-directory nil)))
(sws (if current-prefix-arg
(read-string "Dired listing switches: "
dired-listing-switches)
(if (file-remote-p dir)
"-al"
"-aBhl --group-directories-first"))))
(list dir sws)))
(switch-to-buffer (dired-noselect dirname switches)))
Remember that advising changes the function you advise. Ask yourself whether you want to do that in general or just for interactive use of the function. If the latter, then you typically do not need or want to advise the function - just define and use a different command.

Related

Emacs/AUCTeX prefix arguments

In LaTeX mode C-c C-c is bound to:
(TeX-command-master &optional OVERRIDE-CONFIRM)
Normally this interactive function runs a command, perhaps a LaTeX compilation, asking for confirmation.
In tex-buf.el it reads:
If a prefix argument OVERRIDE-CONFIRM is given, confirmation will
depend on it being positive instead of the entry in `TeX-command-list'.
This is a bit cryptic for me and reading C-h v TeX-command-list didn't help.
How can I pass the prefix argument to "TeX-command-master" so that I avoid all the confirmation requests?
Take a look at Emacs' documentation to find out about prefix arguments. In general, you can pass a command a prefix argument with C-u followed by a number. For one-digit numbers, you can also just type Meta followed by the digit. Thus to pass a positive prefix argument to TeX-command-master you could type:
M-1 C-c C-c
However, this will actually add another minibuffer confirmation, namely about the shell command to be used to compile the LaTeX source. Without the prefix argument, a command-dependent default is used for that.
If you want to avoid the question about the command to use, you can bind the undocumented variable TeX-command-force to "LaTeX" via:
(setq TeX-command-force "LaTeX")
However, this will have the downside that you're basically binding C-c C-c to the "latex" command, you cannot use any of the other commands such as "bibtex" or "view".
Other than that, LaTeX-mode does not allow for any customization of C-c C-c. Your best options are to either advise the function TeX-command-query or to bind C-c C-c to a wrapper function to set TeX-command-force dynamically. The latter would probably be the preferred option if you also want to auto-save the buffer.
It seems that the mystery of the OVERRIDE-CONFIRM continues. In the meantime a fellow suggests that, if we are unable to manage TeX-command-master, we can simply rewrite it.
In my version, based on his, if the buffer is not modified, the external viewer is launched; if the buffer is modified the compiler is run.
Everything with no confirmation for saving or running the given command.
(defun my-run-latex ()
(interactive)
(if (buffer-modified-p)
(progn
(setq TeX-save-query nil)
(TeX-save-document (TeX-master-file))
(TeX-command "LaTeX" 'TeX-master-file -1))
(TeX-view)))
Of course one can bind my-run-latex to whatever keybinding.
On the user's point of view this is a solution to my own question.
Do I click the close tag? Well, on the curious guy point of view I am still interested in understanding the mysterious TeX-command-master technicalities.
If someone should happen to know...
P.S.
Yes, TeX-save-query overrides the save-file request, also with TeX-command-master, that is C-c C-c. But you will still be asked to confirm the command action.
Build & view
Again, this solution, instead of modifying the behaviour of the TeX-command-master, rewrites it. The rewritten version of the command, named build-view, follows a rather straightforward logic.
If the LaTeX file buffer is not-modified, it runs the default viewer;
If the buffer is dirty, it runs the default LaTeX compiler and, after the build, opens the output in the default viewer.
Here's the code:
(defun build-view ()
(interactive)
(if (buffer-modified-p)
(progn
(let ((TeX-save-query nil))
(TeX-save-document (TeX-master-file)))
(setq build-proc (TeX-command "LaTeX" 'TeX-master-file -1))
(set-process-sentinel build-proc 'build-sentinel))
(TeX-view)))
(defun build-sentinel (process event)
(if (string= event "finished\n")
(TeX-view)
(message "Errors! Check with C-`")))
You can now type M-x build-view and start the told build-view process or associate it with a new keybinding such as “F2”:
(add-hook 'LaTeX-mode-hook '(lambda () (local-set-key (kbd "<f2>") 'build-view)))
Note: As suggested by Tyler, TeX-save-query variable is changed locally, therefore the old C-c C-c/ TeX-command-master is unaffected and will keep asking confirmations.
Do edit this code to make it better or easier to read!
I puzzled over the OVERRIDE-CONFIRM bit for a while, and couldn't figure out how it was supposed to work. If you want to automatically run Latex on your file, without being bothered about saving it first, or confirming that you want latex (rather than view, bibtex etc), you could use a function like this:
(defun my-run-latex ()
(interactive)
(TeX-save-document (TeX-master-file))
(TeX-command "LaTeX" 'TeX-master-file -1))
Bind this to something handy, and you'll still have C-c C-c for when you want to use the default processing commands. You may want to modify the TeX-command line if "Latex" isn't the processor you want to call.
If you are just looking to compile the latex source without a confirmation dialog, just add the following to your .emacs:
(setq TeX-command-force "")
You can then compile the source with C-c C-c and it won't ask to confirm. The only problem with this solution is that you can no longer change the command, but with most documents you won't want to. I might suggest that at the same time you can add this to your .emacs for even more flexibility, giving you a C-c C-c equivalent to the former behavior:
(define-key LaTeX-mode-map "\C-c\C-a"
;;; 'a' for ask, change to anything you want
(lambda (arg) (interactive "P")
(let ((TeX-command-force nil))
(TeX-command-master arg))))
You can then just work away at your document, do a C-x C-s, C-c C-c and then C-c C-v to see it. Like others have suggested you can also do the same for the save command and have it compile automatically on save, but some of my documents are in CVS and so I avoid putting hooks on that.
Credit to Ivan for some help on this one - don't know if he is on StackOverflow
I think the gist of this question is "how do I quickly compile my TeX document from AUCTeX without all the key presses and confirmations?"
My answer to that is to use the latexmk command rather than trying to coerce AUCTeX to do it.
latexmk -pdf -pvc myfile.tex
latexmk will monitor the file in question and rebuilt it as soon as you save it. If you use a good pdf viewer, it will notice the change in PDF and re-display it immediately. On OS X, skim works well for this.

Execute a particular command on multiple emacs buffers

Is there a way to execute emacs command on multiple buffers without having to selecting them individually and executing it on each individual buffer.
I usually open multiple files matching a particular regex, e.g. ~/*.py and wish to enable a particular mode, say hs-minor-mode or glasses-mode on each, or say execute C-c # C-M-h on each. Currently I have to select each one of them and do it individually. So is there a hack or a loop to automate the task.
Lets say I mark the buffers from the buffer-list and then run the command for all those marked.
I tried this but after executing the commands in eval-expression I completely lost access to my minibuffer, meaning whenever I typed M-x the minibuffer returned this
unable to access the minibuffer emacs error "Process Menu Mode doesn't support Hideshow Minor Mode"
and I was forced to actually kill the entire emacs process because the C-x C-s wasn't working neither was the End Task.
PS: I have no experience in elisp
You can use ibuffer mode for this (It is part of the default Emacs distribution).
(global-set-key "\C-x\C-b" 'ibuffer) ;; make ibuffer the default
In *Ibuffer* you can mark the required buffers with m and then
execute a form in each with E.
Generally, ibuffer is a lot more flexible then the usual buffer list and I think ibuffer should really be the default buffer-list in Emacs.
If you do this often, you might want to switch those particular modes on every time you enter python mode by attaching them to the mode-hook:
(add-hook 'python-mode-hook 'hs-minor-mode)
(add-hook 'python-mode-hook 'glasses-mode)
I didn't know ibuffer had that feature!
Anyway, for those who are more familiar with dired, here is a command that do the same. Select the files in dired with m or any other more powerful method. Then do, M-xdired-do-command and write a form or a command just as in M-x.
(defun dired-do-command (command)
"Run COMMAND on marked files. Any files not already open will be opened.
After this command has been run, any buffers it's modified will remain
open and unsaved."
(interactive
(list
(let ((print-level nil)
(minibuffer-history-position 0)
(minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
(unwind-protect
(read-from-minibuffer
"Command: " (prin1-to-string (nth 0 command-history))
read-expression-map t
(cons 'command-history 0))
;; If command was added to command-history as a
;; string, get rid of that. We want only
;; evaluable expressions there.
(if (stringp (car command-history))
(setq command-history (cdr command-history)))))))
(dolist (filename (dired-get-marked-files))
(with-current-buffer (find-file-noselect filename)
(if (symbolp command)
(call-interactively command)
(eval command)))))

before defadvice not executing before the function?

[I apologize for the poor title, but couldn't come up with a better one.]
bin chen asked on Google+:
How to input relative path of (buffer-file-name) in minibuffer after M-! in #emacs?
I thought if the buffer-file-name is saved in a register, it should be accessible by invoking insert-register (C-x r i) while at the shell-command prompt.
(defun save-buffer-file-name-in-register ()
(set-register ?F (buffer-file-name))
(set-register ?D (file-name-directory buffer-file-name)))
(defadvice shell-command (before save-buffer-file-name)
"Save buffer-file-name to register F before running shell-command"
(save-buffer-file-name-in-register))
(ad-activate 'shell-command)
When I invoke shell-command (M-!) followed by insert-register (C-x r i), I get the error message: Register does not contain any text.
But when I run list-registers I do see that the registers F and D are set with the appropriate values. If I run the shell-command again, I can access the values from the registers previously saved.
Is it possible that the registers are being set too late for the first time? How can I fix the code to do what I want?
Edit: Changed around to before (Thanks to #phils)
n.b. You have defined around advice, not before advice.
Around advice acts as a wrapper, and must include the token ad-do-it to execute the code of the function it is wrapping.
You have effectively replaced the body of the shell-command function with a call to save-buffer-file-name-in-register
As to your main question, I'd need to check the documentation, but I suspect that because the arguments to the advised function are available to advice, the original function's interactive declaration probably executes before the advice does, which would explain why your register values are not visible at the interactive shell-command prompt.
(If the around in the above code is indeed what you were using, the fact that you were still being prompted for a shell command would seem to verify this sequence.)
When the interactive form runs, your advice hasn't executed yet. See: this question
You need to specify an interactive form in your advice that redefines the original if you want to stick with this approach. However, this approach is a little fancy-pants for the sake of fancy-pants-ness.
Just define your own interactive function which does what you want without registers.
(defun insert-cur-dir ()
(interactive)
(let ((dir-name (file-name-directory (buffer-file-name (window-buffer (minibuffer-selected-window))))))
(insert (or dir-name ""))))
(define-key minibuffer-local-map (kbd "C-c i") 'insert-cur-dir)
An alternative, but way awesomer approach is to use yasnippet.

"Touch" current file in emacs

Im emacs, I want to run "touch" on the file referenced by the current buffer (specifically want to change the modification time). I use guard to run some tests after files are changed, but sometimes I want to invoke it manually. I don't care about running the actual shell utility touch so long as mtime is set.
Of course, this assumes that you have a command named touch on your path.
(defun touch ()
"updates mtime on the file for the current buffer"
(interactive)
(shell-command (concat "touch " (shell-quote-argument (buffer-file-name))))
(clear-visited-file-modtime))
In dired-mode there is a touch command bound by default to T. That command isn't so easy to use though because it prompts the user for a timestamp. I suppose that's very general, but it isn't a very convenient way to do what is typically intended by "touch."
Maybe more keystrokes than a custom function, but you can do this out the box with C-u M-~ then C-x C-s.
M-~ is bound by default to not-modified, which clears the buffer's modification flag, unless you call it with an argument (C-u prefix), in which case it does the opposite. Then just save the buffer.
Here is a pure emacs way to do it:
(defun touch-file ()
"Force modification of current file, unless already modified."
(interactive)
(if (and (verify-visited-file-modtime (current-buffer))
(not (buffer-modified-p)))
(progn
(set-buffer-modified-p t)
(save-buffer 0))))
I do it like this: insert a space, end then I delete the space again and save. This changes the mtime.
8 years later, the useful "f" library in melpa provides f-touch.
See: https://github.com/rejeep/f.el

Disable ido-mode for specific commands?

I've been using ido-mode for a few months, with ido-everywhere turned on, and am generally pretty happy with it. There's one thing I wish I could change, though. When I type C-u M-x shell to create a new shell buffer with a specific name, ido offers me a completion list of all of my open buffers. If I choose one, a new shell is launched in that buffer and it's put into shell-mode, no matter what it contains. It's hard to imagine a useful use case for this.
Is there a way to deactivate ido-mode for the shell command only? (As well as any other similar commands I may stumble across in the future, of course.)
Heh, it turns out you'll get the same completion choices whether or not you have ido-everywhere enabled.
There's no built-in way to do what you want. ido-mode only provides hooks for you to be able to override whether or not the find-file behavior is taken over by ido or not. The read-buffer is currently always overridden by ido-everywhere.
Luckily, a little Emacs lisp can get what you want:
(put 'shell 'ido 'ignore)
(defadvice ido-read-buffer (around ido-read-buffer-possibly-ignore activate)
"Check to see if use wanted to avoid using ido"
(if (eq (get this-command 'ido) 'ignore)
(let ((read-buffer-function nil))
(run-hook-with-args 'ido-before-fallback-functions 'read-buffer)
(setq ad-return-value (apply 'read-buffer (ad-get-args 0))))
ad-do-it))
And for any other command you don't want following ido-everywhere for buffer selection can be customized by simply adding a new expression to your .emacs:
(put 'other-command-i-want-untouched 'ido 'ignore)