Emacs: Calling cua-mode cua-set-rectangle-mark from within custom function - emacs

Currently I use cua-mode for its column/rectangle facilities like so (I don't used it for copy/pasting):
M-x cua-mode ; Enable cua-mode
<C-return> ; Call cua-set-rectangle-mark
Then when I'm done with my rectangle:
C-g ; Call cua-cancel
The bindings for CUA mode clash with other mode bindings (e.g. in org mode) so I sometimes find myself having to turn cua-mode on/off. I only ever use it for its rectangles - so I would like to solve this nuisance by doing two thing:
1) Bind a key (say f6) to a function which enables cua-mode if it is not already enabled and calls cua-set-rectangle-mark so I can create my rectangle.
2) Override C-g whilst cua-mode is active so that when pressed not only does it exit any rectangle but it also exits cua-mode.
So then my workflow would be:
<f6> ; Enter cua-mode and call cua-set-rectangle-mark
C-g ; Call cua-cancel and disable cua-mode
That way I would not need constantly toggle cua-mode on/off when there are clashes.
For part 1 I've come up with:
(defun cua-activate-plus-set-rectangle-mark()
(interactive)
(cua-set-rectangle-mark))
(global-set-key (kbd "<f6>") 'cua-activate-plus-set-rectangle-mark)
Pressing f6 works when cua-mode is already enabled but does not when cua-mode is not enabled. If I change it to be like so:
(defun cua-activate-plus-set-rectangle-mark()
(interactive)
(cua-mode)
(cua-set-rectangle-mark))
then it doesn't work at all regardless of whether I started with cua-mode enabled or not.
For part 2 I have:
(defun cua-mode-off()
"Cancels any open active region/rectangle and turns CUA mode off"
(interactive)
(cua-cancel)
(setq cua-mode nil))
The function does exactly what I want it to but I do not know how to bind it to C-g when cua-mode is enabled.
So my questions:
1) How can I write the function to enter cua-mode and call cua-set-rectangle-mark so it works as expected?
2) How can I override C-g only whilst cua-mode is active to call my custom function?

I think the behavior you're looking for already exists. Take a look at cua-rectangle-mark-mode. From the manual:
CUA mode provides enhanced rectangle support with visible rectangle
highlighting. Use C-RET to start a rectangle, extend it using the
movement commands, and cut or copy it using C-x or C-c. RET moves the
cursor to the next (clockwise) corner of the rectangle, so you can
easily expand it in any direction. Normal text you type is inserted to
the left or right of each line in the rectangle (on the same side as
the cursor).
You can use this rectangle support without activating CUA by calling
the cua-rectangle-mark-mode command. But see also the standard
rectangle-mark-mode. See Rectangles.

Related

`C-[` does not escape from insert mode in evil local mode

I just started to use vim in my emacs. While most of the docs/wikis suggest turn on evil mode globally, I, being a emacs user at the first beginning, really prefer to keep evil mode local. That means, when I need model editing I will turn on the evil mode in that local buffer. I wrote a piece of elisp to toggle on/off evil mode for this purpose:
(defun toggle-evil-local-mode ()
"Toggle on and off evil mode in local buffer."
(interactive)
(if evil-local-mode
(turn-off-evil-mode)
(turn-on-evil-mode)))
(global-set-key (kbd "s-e") 'toggle-evil-local-mode)
However, there is one thing bothers me. I can not use C-[ to escape from insert or visual mode to normal mode (emacs reads the keystroke as ESC- and waiting for more input in the echo area ), Esc key works fine though. But if I turn on the evil mode globally, C-[ just work the same as Esc key.
You might notice that I am using a Mac from the keybinding. While I can use Esc key currently, but what if I upgrade to a new MBP with those evil touch bar in the future? So is there any way to fix this problem? Any suggestion will be appreciated.
Looks like a bug in Evil. Let me know if this works:
(defun turn-on-evil-mode-fixed-escape ()
"Turn on Evil in the current buffer AND `evil-esc-mode'. This makes C-[ work
like <escape> when using `evil-local-mode'."
(interactive)
(turn-on-evil-mode)
(evil-esc-mode 1))

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.

Emacs: setting doc-view-continuous doesn't work with modified key-bindings

I work in Emacs with ergoemacs minor mode turned on. This minor mode changes C-n and C-p to M-k and M-i correspondingly.
In doc-view mode I can move up and down inside one page with M-i and M-k but when the end (beginning) of the page is reached the scrolling stops.
I have set doc-view-continuous variable to t. Here is the result:
continuous scrolling with M-k and M-i doesn't work if ergoemacs minor mode is turned on
continuous scrolling with C-n and C-p works if ergoemacs minor mode is turned off
next page C-x,] and previous page C-x,[ always work
continuous scrolling with mouse wheel always works
PS:
While writing this post I've found out the following:
in doc-view mode C-p is bound to doc-view-previous-line-or-previous-page function which behaves in different ways depending on doc-view-continuous
in doc-view mode + ergoemacs minor mode M-i is bound to image-previous-line function
This difference is the reason of the problem. I will try to use doc-view-mode-hook.
Edited:
Here is the startup code that works for ergoemacs mode:
;; adjust docview mode
(setq doc-view-continuous t)
(defun adjust-doc-view ()
(ergoemacs-local-set-key (kbd "M-i")
'doc-view-previous-line-or-previous-page)
(ergoemacs-local-set-key (kbd "M-k")
'doc-view-next-line-or-next-page)
)
(add-hook 'doc-view-mode-hook 'adjust-doc-view)
The thing I don't understand is why doc-view functions are bound to standard keys but are not bound to ergoemacs keys.
Apparently doc view binds its commands explicitly to C-n and C-p. My guess would be that ergoemacs remaps the usual commands that are bound to those keys, to the keys M-k and M-i instead. Ergoemacs probably does not know about the doc-view commands in question.
Consider filing an enhancement request for ergoemacs, so that it provides a user option whose value is the list of commands to remap this way. That way, instead of doing what you do above, you can just customize the option.
For an example of code that defines such an option, you can refer Xah Lee (author of ergoemacs) to file icicles-opt.el, option icicle-top-level-key-bindings.

How to force emacs recolor

Every once and a while Emacs fails at syntax highlighting and the coloring gets all funky in a buffer. Is there any way to force Emacs to "recolor" the syntax? Just try over? I don't mind if it takes a moment.
I think M-x font-lock-fontify-buffer will do what you are looking for. Or select a region and do M-o M-o (or M-x font-lock-fontify-block).
I once wrote the following simple function to reset the buffer to its natural mode, refontify it, bring the line where the cursor is to the center of the screen, disable the menu-bar, disable the tool-bar and move the scroll-bar left.
(defun --normal-mode-no-gimmicks ()
"Enable buffer `normal-mode' and refontify.
Disable frame menu, toolbar, scrollbars."
(interactive)
(menu-bar-mode 0)
(tool-bar-mode 0)
(set-scroll-bar-mode 'left)
(toggle-scroll-bar 1)
(normal-mode) (recenter-top-bottom)
(font-lock-fontify-buffer))
This can be very useful when the mode changes, Emacs suddenly displays the menubar or something else goes wrong. Then I just press M-g g to heal it.
(global-set-key [?\M-g ?g] '--normal-mode-no-gimmicks)
I didn't know about M-o M-o; it seems as if this could be a better key binding for this function.

Is there any way to get Ediff to not open its navigation interface in an external window?

Not being using Emacs all that long (v23, windows) and just discovered M-x ediff. Fantastic.
Although I'm not to keen on the fact it opens its help/navigation in a separate frame/window, meaning that if I lose focus to that window, the single key shortcuts don't work.
For example as soon as I press ? to expand the window, it shifts over top of my current window, so I have to pick up my mouse and move it to another screen. Then if I lose focus to that window and press p / n / j or any other key to work with the diff, it inserts it into my document. So i have to undo, grab mouse, focus to other window, and repeat.
Is there any way to configure these options to show in a split instead?
I didn't know how to do it but it is usually easy to learn with Emacs. First I asked about ediff customizations:
M-x customize-apropos
ediff
I saw there is something called Ediff Window Setup Function which takes the values Multi Frame, Single Frame, or Other Function. Mine was set to Multi Frame and changed it to Single Frame and saved it for future sessions. And Voila! as they say somewhere.
Simply:
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
M-x describe-variable ediff-window-setup-function will enlighten you
further.
For reference my ediff customisation is fairly simple:
(if (locate-library "ediff")
(progn
(autoload 'ediff-files "ediff")
(autoload 'ediff-buffers "ediff")
(eval-after-load "ediff" '(progn
(message "doing ediff customisation")
(setq diff-switches "-u"
ediff-custom-diff-options "-U3"
ediff-split-window-function 'split-window-horizontally
ediff-window-setup-function 'ediff-setup-windows-plain)
(add-hook 'ediff-startup-hook 'ediff-toggle-wide-display)
(add-hook 'ediff-cleanup-hook 'ediff-toggle-wide-display)
(add-hook 'ediff-suspend-hook 'ediff-toggle-wide-display)))))
From chapter Window and Frame Configuration in Ediff User's Manual:
The following variable controls how
windows are set up:
ediff-window-setup-function
The multiframe setup is done by the ediff-setup-windows-multiframe
function, which is the default on
windowing displays. The plain setup,
one where all windows are always in
one frame, is done by
ediff-setup-windows-plain, which is
the default on a non-windowing display
(or in an xterm window). In fact,
under Emacs, you can switch freely
between these two setups by executing
the command ediff-toggle-multiframe
using the Minibuffer of the Menubar.
(custom-set-variables
...
'(ediff-window-setup-function (quote ediff-setup-windows-plain))
...)
Not that you would set the variable this way, but it allows you to know these things:
The variable you are interested in is ediff-window-setup-function
The value it needs to be set to is ediff-setup-windows-plain
You can configure the variable from customize: M-x customize-group RET ediff-window
Ediff Window Setup Function: Menu Single Frame
Note: you can avoid using the mouse to go back to the ediff control window by using M-x other-frame. Also found on C-x 5 o.
This no longer works in 2017 gnu emacs (24.5, 25.2, 2017) on windows
(setq ediff-window-setup-function 'ediff-setup-windows-plain) ; stopped working
Even
ediff-toggle-multiframe ; no longer has any effect now.
It works in emacs22.3 on windows, so I have use older emacs from 2008!

Categories