Turn off electric indent mode in Emacs by default [duplicate] - emacs

I have few Major modes (like: Yaml and NXML) that I don't want electric-indent-mode (I want it for C like languages) but I'm unable to turn if off. To enable I have:
(electric-indent-mode 1)
from documentation (for variable electric-indent-mode)
Non-nil if Electric-Indent mode is enabled.
See the command electric-indent-mode' for a description of this minor mode.
Setting this variable directly does not take effect;
either customize it (see the info nodeEasy Customization')
or call the function `electric-indent-mode'.
and for a function
Toggle on-the-fly reindentation (Electric Indent mode). With a prefix
argument ARG, enable Electric Indent mode if ARG is positive, and
disable it otherwise. If called from Lisp, enable the mode if ARG is
omitted or nil.
so I try to turn it off in a hook:
(add-hook 'yaml-mode-hook (lambda ()
(electric-indent-mode -1)))
(Actualy I use after-change-major-mode-hook and check (memql major-mode '(yaml-mode python-mode nxml-mode)) where I can add more modes to the list).
But it don't work, I've also try:
(set (make-local-variable 'electric-indent-mode) nil)
No joy. But it work when I eval (electric-indent-mode -1) from .emacs files.

With a recent Emacs (probably Emacs snapshot only) you can use electric-indent-local-mode, e.g.:
(add-hook 'yaml-mode-hook (lambda () (electric-indent-local-mode -1)))
If your Emacs lacks this function, you can still sort of disable the mode via electric-indent-functions, e.g.
(add-hook 'yaml-mode-hook
(lambda ()
(add-hook 'electric-indent-functions
(lambda () 'no-indent) nil 'local)))
And in either case, you may probably want to restore C-j, via
(add-hook 'yaml-mode-hook
(lambda () (local-set-key (kbd "C-j") #'newline-and-indent)))

electric-indent-mode will be enabled by default in 24.4. To turn it off locally, you will be able to use electric-indent-local-mode as mentioned by lunaryorn. But to turn it off locally in 24.3, you can do:
(add-hook 'foo-mode-hook
(lambda () (set (make-local-variable 'electric-indent-mode) nil)))
You mentioned that the first form didn't work for you, but it should (i.e. if it doesn't, it's because of the some other problem).

At least on emacs 24.3 you cannot disable electric indent mode locally, since it is a global-mode. Anyways the issue with yaml-mode is that the electric-indent functionality is built into it i.e. it will be enabled even without electric-indent-mode. The package does not provide a way to turn this behaviour off, maybe you should file an issue on its github repo.
Try this to disable the electric-indent functionality in yaml-mode
(define-key yaml-mode-map "|" nil)
(define-key yaml-mode-map ">" nil)
(define-key yaml-mode-map "-" nil)
(define-key yaml-mode-map "." nil)
(define-key yaml-mode-map [backspace] nil)
To restore the electric-indent behaviour afterwards, you can do
(define-key yaml-mode-map "|" 'yaml-electric-bar-and-angle)
(define-key yaml-mode-map ">" 'yaml-electric-bar-and-angle)
(define-key yaml-mode-map "-" 'yaml-electric-dash-and-dot)
(define-key yaml-mode-map "." 'yaml-electric-dash-and-dot)
(define-key yaml-mode-map [backspace] 'yaml-electric-backspace)

Related

Minor Mode Conditional Emacs Shortcuts

I have an emacs shortcut set up like so:
;; Adding the key mappings to minor mode.
(defvar my-keys-minor-mode-map (make-keymap) "my-keys-minor-mode keymap.")
;; Cancel with one press of escape instead of three.
(define-key my-keys-minor-mode-map (kbd "<escape>") 'keyboard-quit)
(my-keys-minor-mode 1)
(defconst my-minor-mode-alist (list (cons 'my-keys-minor-mode
my-keys-minor-mode-map)))
(setf emulation-mode-map-alists '(my-minor-mode-alist))
This works great to override a shortcut in a truly global way, superseding all other minor modes. However I need a way to have a shortcut behave differently in different minor modes. For example I would like the escape key to run helm-keyboard-quit when helm is running bu run keyboard-quit otherwise. Doing so like:
(eval-after-load "helm"
'(progn
(define-key helm-map (kbd "<escape>") 'helm-keyboard-quit)))
won't work because the global escape shortcut will override it. Is there a way to do this?
Why not use a simple lambda. Something like this (untested):
(global-set-key (kbd "<escape>")
(lambda()
(interactive)
(if helm-mode (helm-keyboard-quit)
(keyboard-quit))))

How to enter minibuffer for editing in Emacs?

When running certain commands, the mini-buffer asks input strings, (e.g. the C-M-s).
Sometimes I need to enter complex strings into minibuffer. Therefore, I need to use movement commands such as C-f, C-b, C-a, etc. However, these does not work when I am entering string inside command C-M-s.
So, what is the general command / key-bindings for me to focus point in mini-buffer for extended movement support?
Edit:
I just discovered that M-e will work for searching commands. But I am not sure whether this command is the general command to "switch from buffer to minibuffer for dedicated editing"
Yes, M-e is what you are looking for, if you want to edit the search string. It lets you perform general editing on it. Just hit C-s or C-M-s again when you are ready to search for the edited string.
However, M-e is only for editing the search string. If you instead want to interrupt isearch to do some editing somewhere, then just end isearch to do that, and then resume isearch when done editing, by using C-s or C-M-s again.
I have been happy using these and I bind them to the function button and arrow keys on my Mac keyboard. I frequently block and copy text and move in and out of the mini-buffer. The following example frees up some of the keymap assignments in the minibuffer-local-map and minibuffer-local-completion-map (i.e., by setting them to nil) so that I can use my own custom keyboard shortcuts to enter and exit the mini-buffer.
From inside the mini-buffer, you can use C-h k and then the type the keyboard shortcut to see what function is bound.
When I switch in and out of the mini-buffer window, I use a custom function that changes the mode-line color, and mini-buffer prompt color, and default color inside the mini-buffer, but that is beyond the scope of your question. [I just add the name of my mini-buffer color change function at the tail end of the following four functions -- i.e., after the if / then statements.]
(defun lawlist-windmove-right ()
(interactive)
(if (window-in-direction 'right)
(select-window (window-in-direction 'right))
(other-window 1)))
(defun lawlist-windmove-left ()
(interactive)
(if (window-in-direction 'left)
(select-window (window-in-direction 'left))
(other-window -1)))
(defun lawlist-windmove-up ()
(interactive)
(if (window-in-direction 'above)
(select-window (window-in-direction 'above))
(other-window 1)))
(defun lawlist-windmove-down ()
(interactive)
(if (window-in-direction 'below)
(select-window (window-in-direction 'below))
(other-window -1)))
(define-key minibuffer-local-map [prior] nil)
(define-key minibuffer-local-map [next] nil)
(define-key minibuffer-local-map [home] nil)
(define-key minibuffer-local-map [end] nil)
(define-key minibuffer-local-completion-map [prior] nil)
(define-key minibuffer-local-completion-map [next] nil)
(define-key minibuffer-local-completion-map [home] nil)
(define-key minibuffer-local-completion-map [end] nil)
(global-set-key (kbd "<end>") 'lawlist-windmove-right)
(global-set-key (kbd "<home>") 'lawlist-windmove-left)
(global-set-key (kbd "<prior>") 'lawlist-windmove-up)
(global-set-key (kbd "<next>") 'lawlist-windmove-down)

How to turn off electric-indent-mode for specific Major mode?

I have few Major modes (like: Yaml and NXML) that I don't want electric-indent-mode (I want it for C like languages) but I'm unable to turn if off. To enable I have:
(electric-indent-mode 1)
from documentation (for variable electric-indent-mode)
Non-nil if Electric-Indent mode is enabled.
See the command electric-indent-mode' for a description of this minor mode.
Setting this variable directly does not take effect;
either customize it (see the info nodeEasy Customization')
or call the function `electric-indent-mode'.
and for a function
Toggle on-the-fly reindentation (Electric Indent mode). With a prefix
argument ARG, enable Electric Indent mode if ARG is positive, and
disable it otherwise. If called from Lisp, enable the mode if ARG is
omitted or nil.
so I try to turn it off in a hook:
(add-hook 'yaml-mode-hook (lambda ()
(electric-indent-mode -1)))
(Actualy I use after-change-major-mode-hook and check (memql major-mode '(yaml-mode python-mode nxml-mode)) where I can add more modes to the list).
But it don't work, I've also try:
(set (make-local-variable 'electric-indent-mode) nil)
No joy. But it work when I eval (electric-indent-mode -1) from .emacs files.
With a recent Emacs (probably Emacs snapshot only) you can use electric-indent-local-mode, e.g.:
(add-hook 'yaml-mode-hook (lambda () (electric-indent-local-mode -1)))
If your Emacs lacks this function, you can still sort of disable the mode via electric-indent-functions, e.g.
(add-hook 'yaml-mode-hook
(lambda ()
(add-hook 'electric-indent-functions
(lambda () 'no-indent) nil 'local)))
And in either case, you may probably want to restore C-j, via
(add-hook 'yaml-mode-hook
(lambda () (local-set-key (kbd "C-j") #'newline-and-indent)))
electric-indent-mode will be enabled by default in 24.4. To turn it off locally, you will be able to use electric-indent-local-mode as mentioned by lunaryorn. But to turn it off locally in 24.3, you can do:
(add-hook 'foo-mode-hook
(lambda () (set (make-local-variable 'electric-indent-mode) nil)))
You mentioned that the first form didn't work for you, but it should (i.e. if it doesn't, it's because of the some other problem).
At least on emacs 24.3 you cannot disable electric indent mode locally, since it is a global-mode. Anyways the issue with yaml-mode is that the electric-indent functionality is built into it i.e. it will be enabled even without electric-indent-mode. The package does not provide a way to turn this behaviour off, maybe you should file an issue on its github repo.
Try this to disable the electric-indent functionality in yaml-mode
(define-key yaml-mode-map "|" nil)
(define-key yaml-mode-map ">" nil)
(define-key yaml-mode-map "-" nil)
(define-key yaml-mode-map "." nil)
(define-key yaml-mode-map [backspace] nil)
To restore the electric-indent behaviour afterwards, you can do
(define-key yaml-mode-map "|" 'yaml-electric-bar-and-angle)
(define-key yaml-mode-map ">" 'yaml-electric-bar-and-angle)
(define-key yaml-mode-map "-" 'yaml-electric-dash-and-dot)
(define-key yaml-mode-map "." 'yaml-electric-dash-and-dot)
(define-key yaml-mode-map [backspace] 'yaml-electric-backspace)

How to disable sticky highlight for repeat isearch forward / backward

Without hacking the source or creating my own isearch-repeat... function, is it possible to disable the default sticky highlight for isearch-repeat-forward and isearch-repeat-backward?
I'm using the latest developer build of Emacs Trunk --with-ns.
Here are some ideas (a work in progress), but they do not resolve the issue -- isearch-mode-end-hook does not seem to be linked to isearch-repeat-forward and isearch-repeat-backward. It would be nice if any keyboard input (escape and/or arrow keys) could momentarily be linked to lawlist-lazy-highlight-cleanup when exiting isearch-repeat.
(add-hook 'isearch-mode-end-hook 'my-isearch-end)
(defun my-isearch-end ()
"Custom behaviors for `isearch-mode-end-hook'."
(when isearch-mode-end-hook-quit
(lawlist-lazy-highlight-cleanup t)))
(defun lawlist-lazy-highlight-cleanup (&optional force)
"Stop lazy highlighting and remove extra highlighting from current buffer.
FORCE non-nil means do it whether or not `lazy-highlight-cleanup'
is nil. This function is called when exiting an incremental search if
`lazy-highlight-cleanup' is non-nil."
(interactive '(t))
(if (or force lazy-highlight-cleanup)
(while isearch-lazy-highlight-overlays
(delete-overlay (car isearch-lazy-highlight-overlays))
(setq isearch-lazy-highlight-overlays
(cdr isearch-lazy-highlight-overlays))))
(when isearch-lazy-highlight-timer
(cancel-timer isearch-lazy-highlight-timer)
(setq isearch-lazy-highlight-timer nil))
(lawlist-isearch-dehighlight))
(defun lawlist-isearch-dehighlight ()
(interactive)
(when isearch-overlay
(delete-overlay isearch-overlay)))
(defun lawlist-isearch-repeat-forward ()
"Repeat incremental search forwards."
(interactive)
(isearch-repeat 'forward)
;; need to add something that says sit-for any keyboard input before cleanup occurs.
;; (read-event) ;; read-char-exclusive | read-char | read-event
(sit-for 60)
(lawlist-lazy-highlight-cleanup))
(defun lawlist-isearch-repeat-backward ()
"Repeat incremental search backwards."
(interactive)
(isearch-repeat 'backward)
;; need to add something that says sit-for any keyboard input before cleanup occurs.
;; (read-event) ;; read-char-exclusive | read-char | read-event
(sit-for 60)
(lawlist-lazy-highlight-cleanup))
While this does not anwswer your question, it may do the thing you ultimately want to solve:
(define-key isearch-mode-map [(control up)] 'isearch-ring-retreat)
(define-key isearch-mode-map [(control down)] 'isearch-ring-advance)
After you type C-S, you may use C-up and C-down to move through search history. So C-S C-up will do what you want: repeat the last search without leaving "sticky" overlays.
See also search-ring-update, to further custom this if you like.
Using the source code of isearch.el as a guide, the following OSX additional key assignments eliminate the problem with sticky highlight as outlined in the question above.
(define-key global-map [?\s-f] 'isearch-forward)
(define-key esc-map [?\s-f] 'isearch-forward-regexp)
(define-key minibuffer-local-isearch-map [?\s-f] 'isearch-forward-exit-minibuffer)
(define-key isearch-mode-map [?\s-f] 'isearch-repeat-forward)
(define-key global-map [?\s-F] 'isearch-backward)
(define-key esc-map [?\s-F] 'isearch-backward-regexp)
(define-key minibuffer-local-isearch-map [?\s-F] 'isearch-reverse-exit-minibuffer)
(define-key isearch-mode-map [?\s-F] 'isearch-repeat-backward)

Remapping SLIME keys

Slime remaps several keys I like to use and have set in global-set-key.
I'd like to avoid directly editing slime.el.
What's the routine to override keys in a given mode?
Update:
In your .emacs, set the mode-map directly:
(define-key slime-mode-map "\M-n" 'next-line)
(define-key slime-mode-map "\M-p" 'previous-line)
It's not too easy to redefine a key for a mode since it can provide several keymaps. And there can be many modes that grab my favorite keys.
I solved it this way: I defined a minor mode that doesn't do anything except it has it's own keymap. I put some keys there i want to be really global.
;; my minor mode for really global keybindings
(defvar my-keys-minor-mode-map (make-keymap) "my-keys-minor-mode keymap.")
(define-minor-mode my-keys-minor-mode
"My minor mode for global keybindings."
:init-value t :lighter "" :keymap 'my-keys-minor-mode-map)
(defun my-minibuffer-setup-hook ()
(my-keys-minor-mode 0))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
(my-keys-minor-mode 1)
;; for example
(define-key my-keys-minor-mode-map (kbd "C-a") 'mark-whole-buffer)
...