Forcing haskell-indent-mode over haskell-indentation-mode in haskell-mode 2.7? - emacs

I'm an Emacs user with no skills with regards to configuring the editor. After I upgraded from haskell-mode 2.4 to 2.7, I've noticed two changes:
Indentation is different somehow, in a way I don't quite like. I can't quite put my finger on what it is.
More importantly: If I have cua-mode enabled and highlight a block of text, backspace/delete does not delete the entire block, just the previous/next character from my marker.
I see that haskell-mode 2.7 uses the minor mode haskell-indentation-mode by default, while 2.4's behaviour has been preserved in the form of haskell-indent-mode. If I first turn off the former, and then on the latter, the behaviour I want is restored (i.e. indentation feels like before, and backspace/delete deletes highlighted blocks).
I can't, however, get this to happen automatically whenever I open a file with a .hs suffix. I've tried various things resembling
(remove-hook 'haskell-mode-hook 'turn-on-haskell-indentation-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent-mode)
and the likes of it, but I either end up with the standard mode or with plain haskell-mode without indent and doc.
Any ideas?
Solution (thanks to nominolo):
(remove-hook 'haskell-mode-hook 'turn-on-haskell-indent)
(remove-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
(defun my-haskell-mode-hook ()
(haskell-indentation-mode -1) ;; turn off, just to be sure
(haskell-indent-mode 1) ;; turn on indent-mode
)

The best way to configure such things is by writing a custom hook:
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
(defun my-haskell-mode-hook ()
(haskell-indentation-mode -1) ;; turn off, just to be sure
(haskell-indent-mode 1) ;; turn on indent-mode
;; further customisations go here. For example:
(setq locale-coding-system 'utf-8 )
(flyspell-prog-mode) ;; spell-checking in comments and strings
;; etc.
)
You could also stick an anonymous function in there, but having a named function is easier if you want to experiment with some settings. Just redefining the function (and re-opening a Haskell file) will give you the new behaviour.

Related

Determining window focus in mode-line?

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.

In Emacs, how to disable auto-fill-paragraph mode when in php-mode?

Normally, I need to enable the auto-fill-mode, so I have it turned on in .emacs. But when editting PHP in php-mode, I'd like to not use auto-fill-mode. Is there way to set it in .emacs such that when I'm in PHP mode, the auto-fill-paragraph mode is automatically turned off and when I leave php-mode, it's automatically turned on, barring other overriding?
Update: a closer examination of the .emacs revealed that auto-fill is set up by
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(column-number-mode t)
...
'(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify)))
...)
Some major-modes inherit certain settings from other modes (e.g., text-mode is used by many popular major modes). The following code snippet can be used to disable a feature for a particular major-mode using its mode hook:
(add-hook 'php-mode-hook (lambda ()
(auto-fill-mode -1) ))
It is sometimes helpful to check and see whether a particular feature has been enabled globally or locally, which in turn can give a clue as to whether that feature has been inherited by a major mode. In this case, the documentation for auto-fill-mode states as follows -- https://www.gnu.org/software/emacs/manual/html_node/emacs/Auto-Fill.html:
"Auto Fill mode is a buffer-local minor mode (see Minor Modes) in which lines are broken automatically when they become too wide. Breaking happens only when you type a <SPC> or <RET>."

Dynamically show/hide menu bar in Emacs

I have menu-bar-open bound on f11 and menu-bar turned off, and because of that, f11 calls tmm-menubar, which is inconvenient and doesn't have mode-specific menu items for some reason (like org and tbl in org-mode). I want it to behave this way: make menu-bar visible, enable user to choose menu item, after that make menu-bar invisible again.
What is the most idiomatic and elegant way to to that?
I thought on writing advices, but Emacs developers usually recommend against it, as it causes problems for debug, and standard Emacs code does not include advices.
I use Emacs 24.1 in GUI.
In Emacs-24 you can simply do this:
(global-set-key [f9] 'toggle-menu-bar-mode-from-frame)
Not sure about versions of Emacs older than 24.
Just be sure that f9 is really available in your installation.
If you're running a graphical Emacs session with menu-bar-mode disabled, then C-<mouse-3> should bring up the entire contents of the menu as a popup dialogue box. If you're running Emacs in a terminal, however, this definitely won't work; you haven't specified which is the case, so I'll try not to make assumptions. It's also possible to create custom mouse bindings (optionally, with keyboard modifiers) to the mouse-popup-menubar and/or mouse-popup-menubar-stuff functions, but ultimately that would only enable you to replicate behavior similar to the standard functionality that I've described above.
Due to the somewhat inflexible and global nature of menu-bar-mode (i.e., the fact that it applies across all Emacs frames and provides for relatively little customization via hooks, etc.), I think it would be very difficult to achieve precisely the behavior you desire with vanilla Emacs. It might be possible to write a custom function to temporarily enable menu-bar-mode and then use something like post-command-hook to disable it again after a selection is made, but I'm not certain. I'll try to investigate further if time allows.
Also, you might wish to look into third-party menu-bar packages, (q.v., the Menu Bar section of EmacsWiki).
Edit: I've hacked together a rather kludgy solution that you may find useful...
(add-hook
'pre-command-hook
(lambda ()
(when (eq menu-bar-mode 42)
(menu-bar-mode -1))))
(defun my-menu-bar-open ()
(interactive)
(unless menu-bar-mode
(menu-bar-mode 1))
(menu-bar-open)
(setq menu-bar-mode 42))
I've tested this in a graphical session and it appears to simulate the behavior that you wanted, as long as you don't perform any action that Emacs registers as a command between executing my-menu-bar-open and making your selection (which is basically anything other than navigating the menu itself). The choice of 42 is a magic number (and a Douglas Adams homage) intended to minimize the risk that the hook function would be activated for more typical values of the menu-bar-mode variable. I don't claim that this is in any way elegant, but, in its decidedly ugly way, it does work. If you decide to use this, simply bind my-menu-bar-open to f11 (or whatever you prefer), i.e.:
(global-set-key [f11] 'my-menu-bar-open)
Alternatively, you can probably achieve very similar functionality by using pre-command-hook in an analogous fashion and instead advising menu-bar-open to perform a temporary toggle of menu-bar-mode.
A small improvement to Greg's answer, which keeps pre-command-hook clean:
(menu-bar-mode -1)
(defun my-menu-bar-open-after ()
(remove-hook 'pre-command-hook 'my-menu-bar-open-after)
(when (eq menu-bar-mode 42)
(menu-bar-mode -1)))
(defun my-menu-bar-open (&rest args)
(interactive)
(let ((open menu-bar-mode))
(unless open
(menu-bar-mode 1))
(funcall 'menu-bar-open args)
(unless open
(setq menu-bar-mode 42)
(add-hook 'pre-command-hook 'my-menu-bar-open-after))))
(global-set-key [f10] 'my-menu-bar-open)
I have tested this in GNU Emacs 25.2 and 26.3:
(menu-bar-mode -1)
(advice-add 'menu-bar-open
:around
(lambda (orig-fun &rest args)
(menu-bar-mode 1)
(apply orig-fun args)
(menu-bar-mode -1)))
Resulting behaviour (assuming that menu-bar-open is bound to F10, which is the default):
The menu bar is not shown by default.
If you press F10, the menu bar will be shown.
Once you leave the menu bar, the menu bar will be gone until the next time you press F10.
Note that this is more like a hack than a proper solution.

How to minify .emacs configuration file?

I was wondering if anyone can provide me with some help on minifying my .emacs file.
Currently I have it set up where each language I use have a custom tab, for example, if I have a hook for Java, it would look like this.
;; Java Hook
(defun e-java-mode-hook ()
(setq tab-width 4)
(setq indent-tabs-mode t)
(define-key java-mode-map (kbd "") 'java-insert-tab))
(defun java-insert-tab (&optional arg)
(interactive "P")
(insert-tab arg))
(add-hook 'java-mode-hook 'e-java-mode-hook)
And if I were to add another language like CSS or JavaScript, I would add another hook for CSS and another hook for JavaScript. So I was wondering if there's a global way of setting it so it would apply to any and all language?
I am currently running GNU Emacs 23.2.1 on Windows 7.
I agree with Tyler; although it's a bit complicated, you would be better off in the long run if you try to understand and customize the default indentation features. The Emacs Wiki has good resources, and there are other relevant Q&As here on Stack Overflow.
Binding the tab key to insert-tab means you completely lose the benefit of the likes of indent-region, and any other intelligent behaviour that a major mode might offer.
To address your specific questions regardless, however:
1) If you are defining (java-insert-tab) and (css-insert-tab) and (javascript-insert-tab) etc, and they all do exactly the same thing... well, hopefully you can see that you don't actually need more than one of those functions. Just give it a more generic name, and re-use it.
2) (local-set-key ...) does the same thing as (define-key (current-local-map) ...), which means you can also have a single generic function to override the tab keybinding, regardless of the major mode.
(defun my-coding-config ()
(setq tab-width 4)
(setq indent-tabs-mode t)
(local-set-key (kbd "<tab>") 'my-insert-tab))
(defun my-insert-tab (&optional arg)
(interactive "P")
(insert-tab arg))
Then you just need to add my-coding-config to each applicable mode hook variable. If there are a lot of them, you might wrap it up in a list like this:
;; Use my coding hook for all programming modes
(mapcar
(lambda (language-mode-hook)
(add-hook language-mode-hook 'my-coding-config))
'(java-mode-hook
javascript-mode-hook
css-mode-hook
...))
3) If you look at C-h v tab-width RET and likewise for indent-tabs-mode, you'll notice that they both say "Automatically becomes buffer-local when set in any fashion."
As an alternative to the customize interface already mentioned, you can use (set-default 'indent-tabs-mode t) to establish the default value for such variables. In the absence of code which sets a buffer-local value, all of your buffers will use the default, which might help you to avoid writing unnecessary mode hooks.
I'm not sure what you're trying to do. If you want to set the tab-width to 4 spaces globally, then you can do that using the customize command:
M-x customize-variable tab-width <ret>
Any changes you make to tab-width in customize will be applied globally. So you won't need to set it individually for each mode with hooks.
If you have different settings you want to apply to different modes, you will necessarily have to have code specific for each mode in your .emacs.
More generally, it looks like you're trying to build your own custom tab insertion commands - does the built-in indentation not do what you need? I think it will be easier to customize the indentation settings in Emacs than to manually insert tabs where you want them.
If you haven't already, take a look at the manual section on indentation and see if you might be able to do what you need without a lot of extra hooks:
C-h r m Indentation
(that is: h-elp, r-ead the manual, m-enu item Indentation)
or:
(info "(emacs)Indentation")
espect.el is doing exactly what you want.
From the docs:
This mode makes it easy to configure settings for individual
buffers with a concice and extensible mini-language. It abstracts
away common configuration selection tasks, like checking the mode
or filename, into a simple declarative syntax. Declare conditions;
run a function when the new buffer matches them. This makes it
easy to do things like turn on flyspell-prog-mode for your favorite
programming languages, or make all text-mode buffers ending in .mkn
have special properties.

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.