viper-auto-indent breaks inferior modes - emacs

As a vim convert, I've gotten fairly used to viper mode. One issue that I've discovered, however, is that viper-auto-indent breaks all inferior modes. What happens is when I enter any sort of inferior mode (sql-mode, ess-mode, etc.) and hit Enter, the Enter key doesn't actually send the command off to the inferior process and gives the appearance of the process just hanging.
Without setting viper-auto-indent I have the problem that the Enter key doesn't automatically indent when writing code, meaning that I need to always hit tab after entering a new line, which is annoying. The workaround I've been using is to have viper-auto-indent enabled by default (since I spend most of my time programming), and then disabling it when I enter an inferior-mode buffer.
Does anyone know how to fix this problem? Alternatively, can anyone help supply me with the elisp to disable viper-auto-indent when switching to an interior mode buffer, and enabling it when in a non-inferior mode buffer? Thanks.

I think Emacs' intent is to have you use "C-j" for newline-and-indent, and let Enter be left alone.
If that is not yet acceptable to you, then this untested code may work:
(add-hook 'inferior-ess-mode-hook
'(lambda () (set (make-local-variable 'viper-auto-indent) nil))

I'm not able to reproduce your problem. I tried every level of viper-mode (1-5), and a number of inferior processes. That said, from your actual question, this code appears like it should fit the bill. If/when 'viper-autoindent is called, if the current buffer has a process, it calls the original binding for the keys just pressed. If there's no process, the original viper-autoindent is called.
(defadvice viper-autoindent (around viper-autoindent-but-not-when-buffer-has-process activate)
"work around reported user problem"
(if (and (this-command-keys)
(get-buffer-process (current-buffer)))
(let* ((viper-mode nil)
(thiskey (key-binding (this-command-keys))))
(when thiskey
(call-interactively thiskey)))
ad-do-it))

Related

Keep Emacs Evil from switching to normal mode when exiting minibuffer

I'm an evil Emacs user. However, I really only use the normal mode for fancy Vim style edits when I find them more convenient than regular Emacs commands. (Mostly fancy bulk editing/yanking/deleting). However, I'm also a huge user of the minibuffer (I do a lot of M-x with ido and flx so I can avoid remembering the more esoteric commands). When I do, evil switches to normal mode automatically after I exit. I find that very annoying/confusing. How can I get it to stop? (preferably in an elegant, non-hackish way).
Thanks,
PythonNut
EDIT:
It appears that the switch to normal mode happens in all windows and in all frames.
I cannot reproduce your issue; maybe knowing your versions could help anyone to identify your issue. Can you reproduce your issue with "emacs -q" (plus adding evil to load-path)?
Here is an approach to identify the evil (traditional English meaning) piece of code, if any, that is calling to evil-normal-state:
(defadvice evil-normal-state (before debug-issue activate)
(setq debug-on-error t)
(inexisting-function-will-fail))
Eval this just after setting a buffer in the evil-state you want it to be, then go to to the minibuffer with M-x. Is there an stacktrace?
You may reactivate evil-mode by adding whatever function you use to activate it to minibuffer-exit-hook.

how to change variables for specific fundamental-mode buffers

Goal: I want to have show-trailing-whitespace enabled for all buffers save a few. Exceptions posing a problem are *Shell Command Output* and its cousin *Async Shell Command*.
I usually have show-trailing-whitespace customized to t. Therefore it is active in all new buffers.
I would also like to have it turned off for certain buffers, foremost amongst them *Shell Command Output*. This poses a problem for me:
The output buffer doesn't use a special mode; it is still in fundamental-mode. There is no fundamental-mode-hook that I could hook this setting into.
There is the after-major-mode-change-hook which is run when the major mode is changed to fundamental-mode, but the buffer starts out in that mode and therefore this hook is not run.
There doesn't seem to be a way to hook into get-buffer-create.
I know I can always advise the function get-buffer-create for this particular example, but I try to avoid that as much as possible.
Any hints?
You might be better off looking at the problem from the other side, and only set the var in those modes where you want to see trailing whitespace.
But I think you have a good point: these shell output buffers should not use fundamental-mode. It's probably time for M-x report-emacs-bug
In accordance with the accepted answer, here's a code snippet that enables trailing whitespaces highlighting for specific modes only:
(setq-default show-trailing-whitespace nil)
(defun namespace/show-trailing-whitespace ()
"Highlight trailing whitespaces in this buffer."
(setq-local show-trailing-whitespace t))
(dolist (hook '(prog-mode-hook text-mode-hook))
(add-hook hook 'namespace/show-trailing-whitespace))
This snippet is essentially taken from Steve Purcell's configuration.

Different results when elisp function is run different ways; why?

EDIT: Perhaps (in original post) I used the term "transient" incorrectly (I'm not familiar enough with the jargon yet). What I really mean is that the highlighted region will disappear immediately when the user presses a navigation keys eg. arrow-keys... (2nd EDIT: I've removed the word "transient")
The particular issue of selecting a region so the user gets "cursor-key movement will make highlighting disappear" has been the bane of my existance recently. I get differnt results depending on how I run the following script.
Why does it give different results, and more specifically, is there a way to make it produce "cursor-keys make highlighting disappear" regardless of which mode is running, or whether it is being evaluated while testing? .. CUA mode has this behaviour, but I really need that non CUA mode does it too (and eval, if possible)...
Here are the results, followed by the code. (GNU Emacs 23.1.1)
CUA mode enabled
Evaluate via C-x C-e — both (call-trans-hi) and (trans-hi)
NO-GO: Both set mark and move point to EOL, but nothing is highlighted.
Execute M-x call-trans-hi
ok: Works fine; the region is highlighted and then disappears the first time a key is pressed.
Via key binding C-f1
ok: Works fine; the region is highlighted and then disappears the first time a key is pressed.
no CUA mode (pretty much std emacs)
Evaluate via C-x C-e
NO-GO: Same as 1. when CUA is enabled.
Execute M-x call-trans-hi
NO-GO: The line is highlighted, but it is sticky! and requires C-g (keyboard-quit) to clear it.
Via key binding C-f1
NO-GO: The line is highlighted, but it is sticky! and requires C-g (keyboard-quit) to clear it.
;test (trans-hi) EOL
(defun trans-hi ()
"transient highlight"
(beginning-of-line)
(push-mark (point))
(end-of-line)
(activate-mark))
;test (call-trans-hi) EOL
(defun call-trans-hi ()
"call transient highlight"
(interactive)
(trans-hi))
(global-set-key [C-f1] 'call-trans-hi)
When you look at the source of activate-mark, you can see that it's just setting some variables. I suppose that's why you don't see the mark in both 1., because the actual highlighting happens in some stuff that's done when executing functions interactively instead of just calling them.
In the other cases of no CUA-mode, that just how transient highlighting works outside of CUA-mode. If you want the CUA-mode behaviour, use CUA-mode resp. that part of it.
EDIT:
Does this change (the addition of the setq line) to trans-hi make the highlighting work the way you want?
(defun trans-hi ()
"transient highlight"
(beginning-of-line)
(push-mark (point))
(end-of-line)
(setq transient-mark-mode (cons 'only transient-mark-mode))
(activate-mark))
If you want to see the region highlighted when you mark it, you need
to activate the minor mode transient-mark-mode.
When a region is highlighted and a character insterted the default is
to disable the highlighting and insert the character at the cursor.
If you wish you can delete the selected region by activating the minor
mode delete-selection-mode.

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.

How configure delete-selection-mode to only delete?

I am using GNU Emacs 22.3.1 on Windows.
In my Emacs I have enabled delete-selection-mode, and it's very useful to select a region and delete or replace it. But I have a drawback.
When I write or press DEL over the selection, Emacs does not only remove the text, but it kills (a.k.a. send to the clipboard*). This is very annoying for me, because I don't have control of my kill-ring (a.k.a. clipboard) and may cause unexpected effects.
There is a way that delete-selection-mode does not kill the text, just delete it? Perhaps modify the source code?
(*: I have synchronized the kill-ring and the Windows clipboard, so for me (for practical purposes) it's the same)
Edit[Jun 24, 2009]
Thanks, danielpoe. Even with the idea of Trey Jackson the selection is still killing. And I found the reason.
I discovered that the problem was not in delete-selection-mode. The problem is, when I selected the region, I did it with the mouse. And never have imagined that it was the mouse who was copying the text. Using the set-mark command and the arrow keys the text finally aren't killed, only deleted.
I disabled this behavior writing this in my .emacs:
(require 'delsel)
(setq mouse-drag-copy-region nil)
(global-unset-key (kbd "<mouse-2>"))
(global-unset-key (kbd "<mouse-3>"))
Thanks for the advice. If this method of disable this mouse behavior can cause conflicts with other options, please comment.
Have you tried starting emacs with -Q. If I do so and only enable M-x: delete-selection-mode, I can't reproduce what you describe. Nothing is killed only deleted?! Can you check?
It looks as though you just need to modify a small part of the source, namely make this change:
(defun delete-active-region (&optional killp)
(delete-region (point) (mark))
t)
The original code looked at the argument killp and used that to decide whether to add the region to the kill-ring, and you said you don't ever want that. This change forces the region to always be deleted.
Now, you don't need to actually modify the source, just place that function definition after the (require 'delsel) in your .emacs (or after the (delete-selection-mode)).