Determining window focus in mode-line? - emacs

Is there a proper predicate for determining whether the window has focus in the mode line? I'm trying to do some things in my mode line that require more flexibility than just using mode-line-inactive.
I've been doing:
(defun window-has-focus-p ()
"When called in eval sexp in mode or header line template,
returns true if this is the active window."
(eq
(frame-selected-window)
(get-buffer-window)))
And it worked very well on two of my computers for months (Windows 7 and Debian). However, I tried using it on another Debian box yesterday and it reported t in every mode line for every window... totally broken.
I haven't been able to find a standard predicate call for this purpose, and I can't figure out why this hacked-up one seems to work on some devices and not others. Additionally, I did evaluate (force-mode-line-update t) with M-: and that did not help.
Emacs version is 24.3

While the mode-line-format is evaluated for a given window, this window is temporarily made the selected-window. In Emacs<=24.3 this was made only halfway: selected-window was changed, but not frame-selected-window. This meant that temporarily (frame-selected-window) was not equal to (selected-window) and breaking this (normally) invariant was a source of various corner case bugs. So we fixed it in 24.4, which means that your code broke.
To make it work in 24.4, you need to save the "selected-window" as seen by the user before the mode-line-format is processed.
You can do that with
(defvar my-real-selected-window nil)
(add-function :before pre-redisplay-function
(lambda (_wins) (setq my-real-selected-window (selected-window))))
So you can then use my-real-selected-window in your mode-line-format to know which window is the one that should be highlighted specially.

I have been using this in my configuration
;;; active modeline detection hack
(add-hook 'post-command-hook
(lambda ()
(when (not (minibuffer-selected-window))
(setq powerline-selected-window (selected-window)))))
Maybe the post-command-hook is not the most elegant solution, but is working correctly for me.

Related

How to make emacs switch to *scheme* by default when eval / load from the file?

The problem:
I'm in scheme-mode (simple quack)
scheme is already running
eval expression
it sends the expression to scheme buffer
but! doesn't bring that buffer up in 2nd window = no immediate feedback
and I have to manually switch second buffer to scheme which is annoying
Some (more recent) modes like fsharp-mode or tuareg do that automatically. Tried to read quack.el, but didn't find convenient separate function like "pop scheme". It's tangled within run-scheme which also changes focus. Settings also don't help.
I want to stay in my rkt/scm file and see repl buffer pop up if not already popped. Like this simple build logic in sublime-text but with persistent repl.
Maybe I should try geiser, but quack is ok for now. Just missing few obvious conveniences.
Just rungeiser. It's in MELPA now, so it's a quick install.
You can also try lispy (which uses geiser) for in-place scheme eval.
e will eval current expression and display the result in the minibuffer.
E will eval current expression and insert the result in current buffer.
u is bound to undo, so you can either e or Eu if you prefer.
I ended up writing this:
(setq scheme-program-name "guile")
(defun run-scheme-2.0 ()
"Loads your chosen Scheme implementation for interactive development,
and displays that buffer below your main editing buffer, and makes sure that
your cursor will be on your code."
(interactive)
(if (not (get-buffer "*scheme*"))
(progn
(setq starting-buffer (buffer-name))
(run-scheme scheme-program-name)
(split-window-below)
(other-window 1)
(shrink-window-if-larger-than-buffer)
(other-window 1)
(switch-to-buffer starting-buffer))))
(add-hook 'scheme-mode-hook 'run-scheme-2.0)

fix an auto-complete-mode and linum-mode annoyance

I'm using auto-complete-mode which I think is totally fantastic. I'm also a big fan of linum-mode but I've got a very irritating issue when the two are used together, especially when I'm working in a new buffer (or a buffer with very few lines).
Basically the buffer is 'x' lines long but when auto-complete kicks in it "adds" lines to the buffer, so linum-mode keeps switching, for example, between displaying line numbers on one column or two columns, depending on whether auto-complete is suggesting a completion or not.
So you type a sentence and you see your buffer's content frantically shifting from left to right at every keypress. It is really annoying.
I take it the solution involves configuring the linum-format variable but I don't know how.
Ideally it would be great if my linum-format was:
dynamic
right-aligned
considering there are 'y' more lines to the buffer than what the buffer actually has
My rationale being that auto-complete shall not suggest more than 'y' suggestion and that, hence, the two shall start playing nicely together.
For example, if 'y' is set to 20 and my buffer has 75 lines, then linum should use two columns: because no matter where I am auto-complete shall not make the buffer 'bigger' than 99 lines.
On the contrary, if 'y' is still set to 20 and my buffer has 95 lines, then linum should use three columns because otherwise if I'm near the end of the buffer and auto-complete kicks in my buffer shall start "wobbling" left and right when I type.
I'd rather not hardcode "3 columns wide" for linum.
I guess using "dynamic but always at least two columns" would somehow fix most annoyances but still something as I described would be great.
P.S: I realize that my 'fix' would imply that linum would always display on at least two columns, and I'm fine with that... As long as it stays right-aligned and use 2, 3 or 4 columns depending on the need.
Simply put the following line in .emacs which resolves this issue. It is in auto-complete.el.
(ac-linum-workaround)
I've written a couple of previous answers on modifying the linum-mode output, which you could probably adapt to your purposes.
Relative Line Numbers In Emacs
Colorize current line number
Edit: Here's the most basic version of that code (also on EmacsWiki, albeit somewhat buried), which doesn't modify the default output at all, but uses the techniques from those other answers to be more efficient than the default code. That's probably a more useful starting point for you.
(defvar my-linum-format-string "%4d")
(add-hook 'linum-before-numbering-hook 'my-linum-get-format-string)
(defun my-linum-get-format-string ()
(let* ((width (length (number-to-string
(count-lines (point-min) (point-max)))))
(format (concat "%" (number-to-string width) "d")))
(setq my-linum-format-string format)))
(setq linum-format 'my-linum-format)
(defun my-linum-format (line-number)
(propertize (format my-linum-format-string line-number) 'face 'linum))
Just have the same problem, after seeing 'patching the source' I believe it could be done with advice. Here is what I come up with
(defadvice linum-update
(around tung/suppress-linum-update-when-popup activate)
(unless (ac-menu-live-p)
ad-do-it))
I would like to use popup-live-p as mentioned but unfortunately it requires the variable for the popup, which we couldn't know in advance.
Update:
I ended up patching the source for linum.el. I added an extra hook that runs before updates.
Here's the patched file: linum.el (github)
Here's the code I have in my init.el:
;; Load custom linum.
(load-file "~/.emacs.d/linum.el")
;; Suppress line number updates while auto-complete window
;; is displayed.
(add-hook 'linum-before-update-hook
'(lambda ()
(when auto-complete-mode
(if (ac-menu-live-p)
(setq linum-suppress-updates t)
(setq linum-suppress-updates nil)))))
Hope it helps!

Emacs preview-latex

I use preview-latex for displaying LaTeX results in an Emacs window. I use preview-at-point to toggle back and forth between code and output. However if I am not on Latex code (by mistake, maybe I missed my intended line by one, or two) then preview-at-point tries to compile everything, brings up the "other" window, and fails. All this process slows things down.
My question is how can I disable this compilation (attempt)? If no toggling is possible, then preview should not do anything. Is there a setting for preview-latex for that? Or perhaps a function I can override?
error in process sentinel: LaTeX found no preview images
Thanks,
The real work is done by preview-region so we can advise that to be a noop in certain cases. The following is not perfect since I don't think there is a way to know ahead of time what is going to previewed—the user can specify any environment or macro to be previewed. If, for example, you only care about math previews then you can remove the previewable-environments pieces.
(defvar previewable-environments
"List of environments that should be previewed."
'("tabular" "tabular*" "tikzpicture" "..."))
(defadvice preview-region (around preview-at-point-no-long-pauses activate)
"Make `preview-at-point' a no-op if mark is inactive and point is not on a preview."
(when (or (not (eq this-command 'preview-at-point))
(TeX-active-mark)
(texmathp)
(member (LaTeX-current-environment) previewable-environments))
ad-do-it))
A variation on the accepted answer: The code will trigger preview toggle if it is on an equation, but I would also like the entire document to be previewed when I am not on any math snippet. The code for that is
(defvar previewable-environments
"List of environments that should be previewed."
'("tabular" "tabular*" "tikzpicture" "..."))
(defadvice preview-region (around preview-at-point-no-long-pauses activate)
"Make `preview-at-point' a no-op if mark is inactive and point is not on a preview."
(message "preview-region")
(if (or (not (eq this-command 'preview-at-point))
(TeX-active-mark)
(texmathp)
(member (LaTeX-current-environment) previewable-environments))
ad-do-it
(preview-section)
)
)

First elisp attempt - minor mode for tab key not being invoked on tab?

I've decided to get my toes wet with a bit of lisp, since I want to make emacs behave a little better when I hit TAB. My command works fine. It just performs indent-for-tab-command and if nothing happens, it performs tab-to-tab-stop, on the assumption that it's unlikely I was hitting TAB just to have the point refuse to budge when I'm inside a multi-line string or some such. After the first TAB press, it continues to do tab-to-tab-stop until either editing resumes, or the point is moved elsewhere. AFAIK, my logic is ok, though my lisp code probably isn't!
Originally I just hacked this into my emacs dot files by doing (local-set-key (kbd "TAB") 'tab-dwim) for major modes where I wanted this behaviour. That worked as expected.
Then I decided that what I was doing was basically a minor mode, so I tried to move the key-binding into a minor-mode. For some reason, even though the minor mode is enabled (as indicated in the mode line, and just from toggling it on and off), my tab-dwim function isn't being invoked when I hit the TAB key. I can still invoke it with M-x as expected.
What am I doing wrong with my minor mode's :keymap?
;;;
;; TAB DWIM
; buffer-local before/after point tracking
(setq point-before-tab nil)
(setq point-after-tab nil)
(make-local-variable 'point-before-tab)
(make-local-variable 'point-after-tab)
(defun tab-dwim ()
"Indents normally once, then switches to tab-to-tab-stop if invoked again.
tab-dwim will always perform tab-to-tab-stop if the first TAB press does not
cause the point to move."
(interactive)
(print "in tab-dwim now") ; THIS LINE IS NEVER INVOKED ON TAB?
(setq point-before-tab (point))
(if (eq point-before-tab point-after-tab) ; pressed TAB again
(tab-to-tab-stop)
(indent-for-tab-command))
(if (eq (point) point-before-tab) ; point didn't move
(tab-to-tab-stop))
(setq point-after-tab (point)))
(define-minor-mode tab-dwim-mode
"Toggle tab-dwim-mode.
With a non-nil argument, turns on tab-dwim-mode. With a nil argument, turns it
off.
When tab-dwim-mode is enabled, pressing the TAB key once will behave as normal,
but pressing it subsequent times, will continue to indent, using
tab-to-tab-stop.
If tab-dwim determines that the first TAB key press resulted in no movement of
the point, it will indent according to tab-to-tab-stop instead."
:init-value nil
:lighter " DWIM"
:keymap
'(([TAB] . tab-dwim)))
(provide 'tab-dwim)
Cheers,
Chris
I think you are very close.
Try this for your keymap:
'(("\t" . tab-dwim)))
Yes, use "\t" or the vector format "[(tab)]".
Some additional notes for your elisp development:
Avoid making global variables as much as possible. In this case, I think dynamically binding with let is appropriate. Also have a look at let*.
Understand the difference between make-local-variable and make-variable-buffer-local. The way you've written your code, the buffer-local variable would only exist in the buffer that loads your package.
As Nemo mentioned, it's extemely extremely extremely recommended that you use a common prefix for all variables/functions related to each package. Emacs has only one namespace, this is the "hacky" way to keep it somewhat organized.

Emacs: highlighting TODO *only* in comments

This question is related to another one, Emacs :TODO indicator at left side. I recently came across a minor mode I like a lot called FixmeMode. It supports auto highlighting of TODO marks, and navigating between them. However, I think it makes more sense to recognize the "TODO" strings only in comments, rather than polluting the whole file. Is it possible?
Check out the library fic-mode.el, it has been verified in C++ and Emacs-Lisp.
It was written specifically to answer this question.
The installation is like any standard package:
(require 'fic-mode)
(add-hook 'c++-mode-hook 'turn-on-fic-mode)
Though Wei Hu did ask for an easy way to add it to multiple modes, so here goes:
(defun add-something-to-mode-hooks (mode-list something)
"helper function to add a callback to multiple hooks"
(dolist (mode mode-list)
(add-hook (intern (concat (symbol-name mode) "-mode-hook")) something)))
(add-something-to-mode-hooks '(c++ tcl emacs-lisp) 'turn-on-fic-mode)
It's possible but quite a bit trickier. Fixme mode uses font-lock to do its highlighting, so it works on an as-you-type basis to highlight the keywords. Font-lock hooks in at a very low level, basically running after every change is made to the buffer's contents. It is highly optimized, though, which allows it to appear instantaneous on modern computers.
The TODO indicator in the left fringe is static. Execute the function and all current TODO's are highlighted; change the buffer (adding or removing TODO's) does not change the fringe indicator; that's only changed when the function runs again.
Your approach would have to get into syntax tables, determining first when you're in a comment and then looking for the keywords. The tricky part comes in doing this interactively (i.e. as you type). You should be able to hook into the font-lock constructs to do this, but the function you provide to search for the comment syntax table and then for the keywords better be very efficient, as it will be run each and every time a buffer changes (though it will only run on the changed region, I think). You would want to stuff all of this in font-lock-syntactic-keywords rather than font-lock-keywords because the syntactic-keyword pass happens before the syntactic pass (which happens before the keyword pass), and you need to set TODO inside comments before comments themselves are set.
Sorry it's not a full working-code answer.....
Maybe this will help: there's a fn c-in-literal in
cc-mode, and a similar csharp-in-literal in csharp mode. The
return value is c if in a C-style comment, c++ if in a C++
style comment. You could add that to the code at
Emacs :TODO indicator at left side
to get what you want.
(defun annotate-todo ()
"put fringe marker on TODO: lines in the curent buffer"
(interactive)
(let (lit)
(save-excursion
(goto-char (point-min))
(while (re-search-forward "TODO:" nil t)
(progn
(setq lit (c-in-literal)) ;; or csharp-in-literal
(if (or (eq lit 'c) (eq lit 'c++))
(let ((overlay (make-overlay (- (point) 5) (point))))
(overlay-put overlay 'before-string
(propertize "A"
'display
'(left-fringe ;; right
horizontal-bar
better-fringes-important-bitmap))))))))))
https://github.com/tarsius/hl-todo seems to do exactly what you want. I just tried it and love it.