Change Emacs window appearance when it loses focus - linux

When I program I use two screens with Emacs on both with two buffers split in each window totaling 4 open source files on screen at any one time.
I switch between buffers with C-x b and between Windows with Alt-TAB. I change the appearance of buffers when I switch between them by defining different faces for mode-line and mode-line-inactive. But how do I inactivate a buffer when I switch from the Emacs window completely to another Emacs window via Alt-TAB?
It's probably also relevant that I'm using Emacs 23.2.1 on Ubuntu 11.04 with Gnome 2.32.1.
PS: The question How to automatically save files on lose focus in Emacs is after a different goal but with the same original event of "window losing focus".

It may depend on your window manager and how it manages multiple windows, or frames, in emacs parlance. The code below works like a champ in fvwm but not always in gnome.
I map a keystroke, C-o, to go between frames, this helps when you want to go to the other frame but an alt-tab would take you through a number of superfluous apps on the way.
If you're running a single instance of emacs with two frames you could use something like the following:
(defun pgr-previous-frame ()
"go to the previous frame"
(interactive)
(pgr-switch-frame (previous-frame)))
(defun pgr-next-frame ()
"go to the next frame"
(interactive)
(pgr-switch-frame (next-frame)))
(defun pgr-switch-frame (frame)
"go to the specified frame and raise it"
;; reset the frame properties here
(select-frame frame)
(raise-frame frame)
;;change the display in some manner here
)
You could also try adding some advice to raise-frame and lower-frame haven't tried it but it's worth a try.

I really liked #logoscia answer, which allowed me to do this more generic version. It uses the mode-line-inactive face when no focus.
(add-hook 'focus-out-hook
(lambda ()
(copy-face 'mode-line '--mode-line-backup)
(copy-face 'mode-line-inactive 'mode-line)))
(add-hook 'focus-in-hook
(lambda ()
(copy-face '--mode-line-backup 'mode-line)))

In Emacs 24.4 and later, you can use focus-in-hook and focus-out-hook. This piece of code seems to work, such that the active window of an inactive frame has the same colour as an inactive window:
(defvar my-mode-line-active-background "gray75")
(defvar my-mode-line-inactive-background "gray40")
(defun my-unhighlight-mode-line ()
(set-face-attribute 'mode-line nil
:background my-mode-line-inactive-background))
(add-hook 'focus-out-hook 'my-unhighlight-mode-line)
(defun my-highlight-mode-line ()
(set-face-attribute 'mode-line nil
:background my-mode-line-active-background))
(add-hook 'focus-in-hook 'my-highlight-mode-line)

I don't know if it can be done only with Emacs, but a possible alternative is running wmctrl in a shell script which perodically checks which window has the focus and if there is a change then it lets Emacs know via emacsclient which can send lisp code to a running Emacs for evaluation:
-e'--eval'
Tell Emacs to evaluate some Emacs Lisp code, instead of visiting
some files. When this option is given, the arguments to
`emacsclient' are interpreted as a list of expressions to
evaluate, not as a list of files to visit.

Related

Any editor/IDE that supports or could be hacked to support viewing diffs live while editing?

Is there any editor/IDE that provides a live view of differences (probably using diff) while I am editing a file. The ideal setting would be when I open a file for editing in such a diff-mode, the file is buffered in two independent panes (but put side by side), so that when I edit the contents of one, the differences of the two are highlighted for me.
There doesn't seem to be an existing Emacs mode to do exactly what you want, but a cursory googling turned up this and this.
From the second one (with mildly fixed formatting):
(defun diff-buffer-against-file (context)
"diff the current [edited] buffer and the file of the same name"
(interactive "P")
(let (($file buffer-file-name)
($tempFile "/tmp/emacs.diff")
($tempBuffer "emacs.diff"))
(delete-other-windows)
(push-mark (point) t)
(generate-new-buffer $tempFile)
(copy-to-buffer $tempBuffer (point-min) (point-max))
(set-buffer $tempBuffer)
(write-file $tempFile)
(shell-command (concat (if context "diff -c " "diff ") $file " " $tempFile))
(kill-buffer $tempFile)
(pop-mark)))
(global-set-key "\C-cd" 'diff-buffer-against-file)
The operation looks a bit too intense to bind to a change hook, but there's nothing preventing you from doing so if you're into that sort of thing.
Edit: Stefan points out that diff-buffer-with-file exists, and has the behavior you're looking for (it takes a buffer, and diffs that buffer with its file, showing that output in an unfocused temporary buffer), so you don't even need to define the above. I did try it though, and the naive
(defun diff-current (start end len) (diff-buffer-with-file (current-buffer)))
(add-hook 'after-change-functions 'diff-current)
makes editing too uncomfortable for my tastes. You'll probably want to follow Stefan's suggestion and use a timeout instead of diffing immediately on every change.

Function to evaluate haskell in ghci while editing source file using Emacs

I'm editing a haskell source file. I want to run my main function in my inferior-haskell buffer (already opened in a different frame) and continue editing my source file. To do this, I do
C-c C-l, change frame, main<ret>, change back to original frame
This seems quite inefficient. I'd like an emacs function/key that does it one shot.
There is actually a function to do this already defined in inf-haskell.el: inferior-haskell-load-and-run. This loads your current file and runs :main.
You can bind it to a key in Haskell mode by adding a hook:
(defun my-haskell-mode-hook ()
(local-set-key (kbd "C-x C-r") 'inferior-haskell-load-and-run))
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
However, playing around with this for a bit, it seems to have an odd issue on my computer: sometimes, when it pops to the *haskell* buffer, it doesn't move the point to the end. I find this rather annoying. You can easily fix it by moving the point to the end yourself:
(defun my-haskell-load-and-run ()
"Loads and runs the current Haskell file."
(interactive)
(inferior-haskell-load-and-run inferior-haskell-run-command)
(sleep-for 0 100)
(end-of-buffer))
I believe the sleep-for is necessary because the Haskell command is run asynchronously and takes a little bit of time to return. This whole thing is something of a hack, but it seems to work.
Also, you might want to customize exactly what the inferior-haskell-run-command is. By default, it's :main. However, for me, I think just main would be better because main is affected by :set args ... where :main isn't.
If you want to stay in your current Haskell buffer, you can just do this:
(defun my-haskell-load-and-run ()
"Loads and runs the current Haskell file."
(interactive)
(let ((start-buffer (current-buffer)))
(inferior-haskell-load-and-run inferior-haskell-run-command)
(sleep-for 0 100)
(end-of-buffer)
(pop-to-buffer start-buffer)))
To use interactive-haskell-mode, I found a similar setting than the other answer:
(defun my-haskell-load-and-run ()
"Loads and runs the current Haskell file main function."
(interactive)
(haskell-process-load-file)
(haskell-interactive-mode-run-expr "main"))
(defun my-haskell-mode-hook ()
(local-set-key (kbd "C-x C-r") 'my-haskell-load-and-run))
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
But I have a small issue with it, it always jumps to the end of the source buffer... which can be annoying.

Better window navigation in Emacs?

When I split window in emacs several times (under terminal) the whole screen is divided into several parts with hierarchical arrangement. In vim it is easy to switch between windows intuitively with Control-w + (h,j,k,l), but in Emacs I can only use Control-x + o to switch to "the other window", which probably would require several iterations to finally get to the window I intend. I wonder if there is a better way similar to that in Vim to easily navigate between windows?
Have you tried WindMove? It comes bundled with Emacs 21+. You move around with Shift-up, Shift-down, Shift-left, and Shift-right, though you can change the modifier. From the docs:
;; Installation:
;;
;; Put the following line in your `.emacs' file:
;;
;; (windmove-default-keybindings) ; shifted arrow keys
;;
;; or
;;
;; (windmove-default-keybindings 'hyper) ; etc.
;;
;; to use another modifier key.
;;
;;
;; If you wish to enable wrap-around, also add a line like:
;;
;; (setq windmove-wrap-around t)
I find the default binding for other-window to be really tedious, too. I've defined the following in my .emacs:
(global-set-key [(control ?,)] (lambda () (interactive) (other-window -1)))
(global-set-key [(control ?.)] (lambda () (interactive) (other-window 1)))
Just find some easy-to-reach keybindings (I use a Dvorak layout, so C-, and C-. may not be as easy for you to reach), preferably right next to each other, to bind to those lambdas.
Also, I found the Emacs wiki a few months ago. Nifty Tricks has a nice list of ways to make Emacs easier to use!
In Icicles, by default C-x o is bound to the multi-command icicle-other-window-or-frame, which works this way:
With no prefix arg or a non-zero numeric prefix arg:
If the selected frame has multiple windows, then this is
other-window. Otherwise, it is other-frame.
With a zero prefix arg (e.g. C-0):
If the selected frame has multiple windows, then this is
icicle-select-window with windows in the frame as candidates.
Otherwise (single-window frame), this is icicle-select-frame.
With plain C-u:
If the selected frame has multiple windows, then this is
icicle-select-window with windows from all visible frames as
candidates. Otherwise, this is icicle-select-frame.
Well then, what are icicle-select-window and icicle-select-frame?
They are multi-commands that let you choose a window or frame to select by name. (You can bind them separately, if you want -- they each change their behavior based on their own prefix args.)
Window and frame names are taken from their displayed buffers, with [N] (N=1,2,...) appended if needed for a unique name if the same buffer is displayed in more than one window/frame.
Being multi-commands, you can choose by completing and/or cycling. Completion can be prefix, substring, regexp, or fuzzy.
http://www.emacswiki.org/emacs/Icicles_-_Multi-Commands
See switch-window. It will number windows to let you switch directly to the one you want.
That was also my first experience with emacs. But, using windmove, I can suite it, they way I want it. I use this as the modifier for windmove :
(windmove-default-keybindings 'meta)
I use ALT for the navigation of windmove

How to open files in web browsers (e.g Firefox) within editors like vim or emacs?

How to open files in browsers (e.g Firefox) within editors like vim or emacs? Notepad++ open files in browsers by pressing Ctrl+Shift+Alt+X (Firefox). Is there a way to do this in gVim or Emacs?
browse-url-of-file is an interactive compiled Lisp function in
`browse-url.el'.
It is bound to <menu-bar> <HTML> <Load this Buffer in Browser>, C-c
C-z v.
(browse-url-of-file &optional file)
Ask a WWW browser to display file.
Display the current buffer's file if file is nil or if called
interactively. Turn the filename into a URL with function
browse-url-file-url. Pass the URL to a browser using the
browse-url function then run browse-url-of-file-hook.
In emacs I don't think this is built in, I may be wrong, but if not here is a function to do it:
(defun open-in-browser()
(interactive)
(let ((filename (buffer-file-name)))
(browse-url (concat "file://" filename))))
For whatever reason, my EmacsW32 on WinXP install kept sending browse-url directives to shell with "open file:// alone, and that didn't work so well*. Cutting it off at the knees, and modifying justin's original as below worked for me:
(defun open-in-browser()
"open buffer in browser, unless it is not a file. Then fail silently (ouch)."
(interactive)
(if (buffer-file-name)
(let ((filename (buffer-file-name)))
(shell-command (concat "start firefox.exe \"file://" filename "\"")))))
Needs some improvement. As well as replacement of your favorite browser. d**n you, hard-coding.
* I think the problem was the system-type check in browse-url-default-windows-browser, but not positive.
In gVim:
:!start cmd /c "C:\Users\pierre\AppData\Local\Google\Chrome\Application\chrome.exe" file:///"%:p""
You need the file:// URI to indicate that it is from the file system, this will work with all browsers. %:p produces the full file path for the current file. The quotes are necessary.
Simply map that to whatever you choose. You may need to do set shell=cmd.exe if you've set your shell to bash or something else.
In emacs (quoting justinhj):
(defun open-in-browser()
(interactive)
(let ((filename (buffer-file-name)))
(browse-url (concat "file://" filename))))
You mean you'd like to open the file currently being edited in a web browser?
In Vim, use something like :!firefox %.
Edit: You could, in fact, use nmap <silent> <C-M-X> :!firefox %<CR> to cause Vim to act very much like Notepad++ (though this mapping won't care whether you press shift or not).
Note that not every browser will actually render the file's contents when given the filename on the command line; e.g. Google Chrome will open a "save as" dialogue instead, as if you were downloading the file in question. Look up your browser's docs if in doubt. Firefox will 'just work', though.
Depending what you want to do with this, you might consider Emacs + MozRepl, which basically lets you send javascript commands to Firefox via telnet. Unfortunately I can't seem to write the elisp to make this work, but a related trick for reloading webpages from within emacs is shown by Sard in What's in your .emacs?. More information on integrating emacs and mozrepl from the original source and also here for a cool trick that updates the page in the browser as you type in the emacs buffer - it's pretty nice for getting instant feedback when working with html.
I reckon the same thing would work with vim, but I've only used it in emacs.
I do it an Elisp function using shell command xdg-open.
Then I define a key in html-mode to call the function.
You've gotta be comfortable adding stuff to your .emacs file.
(defun open-html()
"Get the HTML file path & open it"
(interactive)
(let (html-file-path)
(setq html-file-path (buffer-file-name))
(shell-command (format "xdg-open '%s'" html-file-path)))
)
This answer is based on Emacs 26.2
Emacs has the functions for opening a file in a browser built in but the behavior on different platforms may be different. Looking into the source code and documentation of browse-url-of-file by entering C-h f browse-url-of-file you'll see that the variable browse-url-browse-function determines which browser is used. You can then customize this variable to use, say, Chrome, by choosing browse-url-chrome and then apply and save the change. To access the customization page either entering C-h f browse-url-browser-function and then selecting the customize hyperlink, or M-x customize then searching for browse-url-browser-function.

How can I operate on more Emacs buffers at the same time?

I am looking for an equivalent of the :bufdo Vim command in Emacs. :bufdo takes an argument - another command - and executes the command on all open buffers. I have not yet found a similar feature in Emacs.
Depending on what your command is, you can do:
M-: (mapc (lambda (b) (set-buffer b) (*command*)) (buffer-list))
But, I have a feeling you want something not so lispy. Take a look at keyboard macros. Namely, decide what you want to do:
C-x ( <do-your-command> C-x )
M-: (mapc (lambda (b) (set-buffer b) (kmacro-end-and-call-macro)) (buffer-list))
You'd probably want to define that last part as a function if you use it much:
(defun bufdo ()
"execute last macro on all buffers, ala bufdo from vi"
(interactive)
(mapc (lambda (b)
(with-current-buffer b
(kmacro-end-and-call-macro)))
(buffer-list)))
Note: code is untested
You can also checkout ibuffer, it allows you to mark buffers you like to operate on with m and then you can execute something on it with E. Other common operations are also available, e.g. query-replace on Q. Just check out the menu or the mode description (C-h m).
BTW, similar things are also possible from dired, although it doesn't seem to give you an eval command.
Take a look at buffer-list (function). It returns a list of all the open buffers (BUFFER objects). See the manual for a simple example of using it with mapcar (which operates on every element of the list, and accumulates the results). You would probably also find set-buffer, which programatically sets the current buffer from Emacs Lisp, useful.

Resources