I'm trying to get ido to work with evil ex commands (such as :vsp ... or :b ...), but it doesn't seem to be working automatically. Currently I have:
(require 'ido)
(setq ido-everywhere t)
(ido-mode t)
(use-package ido-ubiquitous
:ensure ido-ubiquitous
:demand ido-ubiquitous
:init
(progn
(ido-ubiquitous-mode 1)))
And then later I require evil:
(use-package evil
:ensure evil
:config
(progn
(evil-mode 1)
;; ....
))
As a work around I can use stuff like (define-key evil-ex-map "e " 'ido-find-file) and some custom ones for the splits but this isn't ideal. Why doesn't the above work automatically?
I'm using the graphical version of Emacs 25.0.50.1
from the ido-ubiquitous source:
ido-ubiquitous is here to enable ido-style completion for (almost)
every function that uses the standard completion function
'completing-read'
Evil uses completion-at-point rather than completing-read for ex commands. While completion-at-point merely tries to complete what's before the cursor, completing-read brings up its own prompt with its own behavior. Since evil adds its own keybindings in the ex prompt, using completing-read for ex commands isn't feasible.
Related
I have the code block:
(use-package dired
:config
(setq dired-auto-revert-buffer t))
I want this to instead be indented like:
(use-package dired
:config
(setq dired-auto-revert-buffer t))
How do I do this?
Pretty sure that's not possible. The closest I could get was (put 'use-package 'lisp-indent-function '2), which gave me
(use-package dired
:config
(setq dired-auto-revert-buffer t))
This just makes it indented the same was as
(if cond
a
b)
I don't think there's a way to make it indented like you wanted, since that's not a standard way to indent lisp code.
In coffee-mode RET is bound to coffee-newline-and-indent which works fine.
I also use evil-mode to have Vim emulation. evil-mode uses the standard newline-and-indent so the indentation is not correct for some vim commands such as o or O.
What would be the best way to rebind newline-and-indent to coffee-newline-and-indent ?
I'm still a newbie in ELisp and tried the line below but it doesn't work.
(add-hook 'coffee-mode-hook
(lambda ()
(setq newline-and-indent '(funcall coffee-newline-and-indent))))
Here's my attempt. It should work, but I don't really like it.
(add-hook
'coffee-mode-hook
(lambda ()
(defalias
'newline-and-indent
(lambda()
(interactive)
(if (eq major-mode 'coffee-mode)
(coffee-newline-and-indent)
(delete-horizontal-space t)
(newline)
(indent-according-to-mode))))))
I wish I could use something more elegant that just copying the source
of newline-and-indent, but make-variable-buffer-local doesn't work for this case,
and I couldn't get a deep copy for symbol-function either.
I'd be happy to see a better method.
The standard way to accomplish what you seem to be asking for is
(autoload 'coffee-newline-and-indent "coffee-mode") ; (or whatever)
(define-key evil-mode-map (kbd "RET") 'coffee-newline-and-indent)
EDIT: to enable coffee-newline-and-indent only in coffee-mode:
(define-key evil-mode-map (kbd "RET")
(lambda ()
(interactive)
(if (eq major-mode 'coffee-mode)
(coffee-newline-and-indent)
(newline-and-indent))))
Try the following:
(define-key evil-mode-map (kbd "RET") nil)
I know it looks overly simple, but if evil-mode works the way I think it does then it should work.
This will wipe the ret key from your evil-mode-map, which will let the binding of coffee-mode-map shine through.
In non-coffee buffers, the ret key will still work, because it's still bind in the global map.
I found the solution.
Evil-mode actually uses coffee-indent-line. The problem comes from coffee-indent-line which doesn't indent correctly. Evil-mode works correctly after patching it to behave like coffee-newline-and-indent:
(defadvice coffee-indent-line (after wants-indent activate)
(let ((tabs-needed (- (/ (coffee-previous-indent) coffee-tab-width) 1)))
(when (> tabs-needed 0)
(insert-tab tabs-needed)))
(when(coffee-line-wants-indent)
(insert-tab)))
if you want to remap a func, but only if some major mode is active
- create a func which defines an alias
and run the func (A)
- another func (B) calls (A)
- finally, a major mode can advice the func A to set the correct
func. It has to test major mode.
let's say A is define-my-indent-f
then it says (defalias my-indent 'newline-and-indent)
the func b runs A then run command my-indent.
finally coffe mode does defadice A to say
(if eq major mode coffee defalais my-indent 'coffe-newline-and-indent)
of course this is super heavy to define, but then
- each major mode can add its piece
- only loaded major mode will advice
I want my C/M-h keys to be a binding for delete.
The usual solution of global-set-key doesn't work for me, as I want these keys to behave as delete everywhere including the minibuffer and various modes, and be able to work between my various Linux/OS X/Windows emacs installations.
I have the following near solution:
(when (>= emacs-major-version 23)
(setq help-char (string-to-char "<f1>")) ;; Bind ONLY F1 to help, not C-h
(define-key input-decode-map (kbd "C-h") (kbd "DEL")) ;; Translate C-h to DEL ;; FIXME: Should be in emacs 22, doens't work.
(define-key input-decode-map (kbd "M-h") (kbd "M-<DEL>")) ;; Translate M-h to M-DEL
;; (define-key input-decode-map (kbd "<backspace>") 'version) ;; Stop me using backspace for a while
)
But this obviously only works with Emacs > 22, due to input-decode-map.
Would someone be able to help me find a solution that works in 22, maybe even 21? (Not a priority however). Cheers!
Edit: My Solution:
It's not quite there yet, but this has solved most of my issues:
(setq help-char [f1]) ;; I don't want help when I'm just trying to backspace!
(define-key isearch-mode-map "\C-h" 'isearch-delete-char)
;; (define-key isearch-mode-map "\M-h" 'my-isearch-delete-word)
(defvar my-overriding-binding-mode-map
(let ((map (make-sparse-keymap)))
(define-key map [?\C-h] 'delete-backward-char)
(define-key map [?\M-h] 'backward-kill-word)
map))
(define-minor-mode my-overriding-binding-mode
"Personal global key-bindings."
:global t)
(my-overriding-binding-mode 1)
There's probably some caveats for some misbehaving modes that need to be written - I'll do that as I come across them. The only real problem now seems to be M-h in isearch, which I'll post as a seperate question.
Thanks again guys, you've been a great help.
Here's the first, and most important, part of the answer, with the explanations all given in the elisp comments. This has been tested mostly in X11 environments, but including with a Mac keyboard. It has been tested starting with v19.28, and up to and including v23.3. I think it works with v24, but I have not yet used v24 very much.
You can find my complete (though not always 100% up-to-date) ~/.emacs.el in the following repository of initialization and configuration files:
https://github.com/robohack/dotfiles
and so specifically ~/.emacs.el is at:
https://github.com/robohack/dotfiles/blob/master/.emacs.el
;;; first off, we do some fancy stuff to make C-h work "properly," but still
;;; have good access to the help functions!
;;;
;;; Using C-h for "help" might seem OK to some folks, but since it's also the
;;; ASCII standard value for the "backspace" character, one typically used ever
;;; since the days of the typewriter to move the cursor backwards one position
;;; and in computing normally to erase any character backed over, a vast amount
;;; of stupidity is needed in emacs to continue to (ab)use as the "help"
;;; character. Instead it is still quite intuitive, and often much easier in
;;; zillions of environments, to use M-? for help.
;;;
;;; So, we can set C-h and C-? and friends to sensible bindings...
;;
;; Remember to call override-local-key-settings in the appropriate hooks to fix
;; up modes which violate global user preferences....
;;
(global-set-key "\C-h" 'delete-backward-char)
(global-set-key "\C-?" 'delete-char)
(global-set-key "\e\C-h" 'backward-kill-word)
(global-set-key "\e\C-?" 'kill-word)
;;; and then we diddle with help to make it work again....
;;
;; Oddly, the help interface in emacs is extremely scatter-brained, with
;; several slightly different ways of doing the same thing. This is probably
;; due to the fact that several different programmers have implemented various
;; bits and pieces of the help systems. See help.el and help-macro.el, but try
;; not to tear your hair out when you find out help-event-list in 19.34 is
;; essentially bogus, since it is simply an extension to a "standard" list.
;;
;; Remember to call override-local-key-settings in the appropriate hooks to fix
;; up modes which violate global user preferences....
;;
(global-set-key [f1] 'help-command) ; first do this for 19.28.
(global-set-key "\e?" 'help-command) ; this is the first step to set up help
(global-set-key "\e?F" 'view-emacs-FAQ) ; in 19.34 it needs more help...
;; should help-char be just ? instead?
(setq help-char ?\M-?) ; this should "fix" the rest.
;; one more handy help-related binding...
;;
(define-key help-map "?" 'describe-key-briefly) ; also C-x? for Jove compat
;;; Now for function key mappings...
;;;
;;; I USUALLY EXPECT THE BACKSPACE KEY TO WORK LIKE AN ASCII BACKSPACE!
;;
;; For some entirely un-fathomable reason the default function bindings make
;; the 'backspace' and 'delete' keys synonymous!
;;
;; NOTE: this *should* work by simply reading termio for current erase char.
;;
;; As of emacs-21.2 a note was added to the NEWS file which says "** On
;; terminals whose erase-char is ^H (Backspace), Emacs now uses
;; normal-erase-is-backspace-mode." Unfortunately this does EXACTLY the WRONG
;; thing, and in a totally bizzare, disruptive, subversive, and stupid
;; backwards way. With every major release it's gotten worse and worse and
;; worse; more convoluted, and ugly.
;;
;; So, we must do something to kill that horrible stupid broken poor
;; useless excuse for a feature, normal-erase-is-backspace-mode....
;;
;; seems 23.1 changes function-key-map radically....
;;
;; Unfortunately 23.1 also still has function-key-map so we can't make that
;; (function-key-map) an alias for the new local-function-key-map that we need
;; to use in 23.1 to modify key translations. Sigh.
;;
;; Instead make a new alias that can be used transparently as the desired map.
;;
(eval-and-compile
(if (functionp 'defvaralias) ; since 22.1
(if (boundp 'local-function-key-map)
(defvaralias 'my-function-key-map 'local-function-key-map
"Special variable alias to allow transparent override of
`local-function-key-map' for 23.1 vs 22.3(?).")
(defvaralias 'my-function-key-map 'function-key-map
"Special variable alias to allow transparent override
of `function-key-map' for 22.3(?) vs. older,"))
;; XXX is this right? it works (maybe?)
(defvar my-function-key-map function-key-map)))
;;
;; First undo (local-)function-key-map weirdness.
;;
;; luckily on Mac OS-X X11, at least with the mini-wireless keyboard and on the
;; large USB keyboard, the big "delete" key on the main block is actually
;; sending <backspace> by default, else one would have to first change the X11
;; keyboard map!
;;
(define-key my-function-key-map [delete] [?\C-?])
(define-key my-function-key-map [S-delete] [?\C-h])
(define-key my-function-key-map [M-delete] [?\C-\M-?])
(define-key my-function-key-map [kp-delete] [?\C-?])
(define-key my-function-key-map [backspace] [?\C-h])
(define-key my-function-key-map [S-backspace] [?\C-?])
;;(define-key my-function-key-map [C-backspace] [?\C-h]) ; sometimes *is* DEL....
(define-key my-function-key-map [M-backspace] [?\e?\C-h])
(define-key my-function-key-map [M-S-backspace] [?\e?\C-?])
(define-key my-function-key-map [kp-backspace] [?\C-h])
;;
;; Next, zap the keyboard translate table, set up by
;; normal-erase-is-backspace-mode (in simple.el), which can do nothing
;; but confuse!
;;
(setq keyboard-translate-table nil)
;;
;; Finally, kill, Kill, KILL! the input-decode-map added in 23.x, and set
;; up by normal-erase-is-backspace-mode (in simple.el) which can do
;; nothing but confuse!
;;
;; This is TRULY _E_V_I_L_!!!! HORRID!!! MASSIVELY STUPID!!!!
;;
;; input-decode-map is poorly documented, and causes things above and
;; below to fail with the most confusing errors!
;;
;; (This probably only needs to be blown away on window systems, and
;; perhaps only for X, but doing it here now is apparently early enough
;; to allow for terminal mode specific settings to be re-applied to it
;; and so it seems safe to just blow away the asinine stupid attempt to
;; transpose backspace and delete. RMS is a pedantic idiot on this!)
;;
(if (boundp 'input-decode-map)
(setq input-decode-map (make-sparse-keymap)))
;; finally here's a little function to help fix up modes which don't honour default
;; bindings in sensible ways. Use this in any init hooks for modes which cause problems
;;
(defun override-local-key-settings ()
"User defined function. Intended to be called within various hooks to
override the value of buffer-local key map settings which may have been
overridden without consideration by the major mode."
(local-set-key "\C-?" 'delete-char) ; many modes
(local-set-key "\C-h" 'delete-backward-char) ; sh-mode
;; the rest are *not* overridden by cc-mode, but are by c-mode
(local-set-key "\e\C-h" 'backward-kill-word) ; text-mode
(local-set-key "\e?" 'help-command) ; nroff-mode
(local-set-key "\eh" 'mark-c-function)
(local-set-key "\e\C-?" 'kill-word)
(local-set-key "\e\C-e" 'compile)
;; try this on for size...
(local-set-key "\C-x\e\C-e" 'recompile)
)
(add-hook 'isearch-mode-hook
(function
(lambda ()
"Private isearch-mode fix for C-h."
(define-key isearch-mode-map "\C-h" 'isearch-delete-char))))
;;; OK, that's the end of the stuff to fix GNU Emacs' C-h brain damage. Phew!
Then I recommend you use a minor-mode:
(defvar my-overriding-binding-mode-map
(let ((map (make-sparse-keymap)))
(define-key map [?\C-h] 'delete-backward-char)
(define-key map [?\M-h] 'backward-kill-word)
map))
(define-minor-mode my-overriding-binding-mode
"Personal global key-bindings."
:global t)
(my-overriding-binding-mode 1)
Is there a difference between setting things for a mode using eval-after-load and using the mode hook?
I've seen some code where define-key is used inside a major mode hook, and some other code where define-key is used in eval-after-load form.
Update:
For better understanding, here is an example of using eval-after-load and mode hooks with org-mode. The code can run before (load "org") or (require 'org) or (package-initialize).
;; The following two lines of code set some org-mode options.
;; Usually, these can be outside (eval-after-load ...) and work.
;; In cases that doesn't work, try using setq-default or set-variable
;; and putting them in (eval-after-load ...), if the
;; doc for the variables don't say what to do.
;; Or use Customize interface.
(setq org-hide-leading-stars t)
(setq org-return-follows-link t)
;; "org" because C-h f org-mode RET says that org-mode is defined in org.el
(eval-after-load "org"
'(progn
;; Establishing your own keybindings for org-mode.
;; Variable org-mode-map is available only after org.el or org.elc is loaded.
(define-key org-mode-map (kbd "<C-M-return>") 'org-insert-heading-respect-content)
(define-key org-mode-map (kbd "<M-right>") nil) ; erasing a keybinding.
(define-key org-mode-map (kbd "<M-left>") nil) ; erasing a keybinding.
(defun my-org-mode-hook ()
;; The following two lines of code is run from the mode hook.
;; These are for buffer-specific things.
;; In this setup, you want to enable flyspell-mode
;; and run org-reveal for every org buffer.
(flyspell-mode 1)
(org-reveal))
(add-hook 'org-mode-hook 'my-org-mode-hook)))
Code wrapped in eval-after-load will be executed only once, so it is typically used to perform one-time setup such as setting default global values and behaviour. An example might be setting up a default keymap for a particular mode. In eval-after-load code, there's no notion of the "current buffer".
Mode hooks execute once for every buffer in which the mode is enabled, so they're used for per-buffer configuration. Mode hooks are therefore run later than eval-after-load code; this lets them take actions based upon such information as whether other modes are enabled in the current buffer.
When doing a M-x describe-mode in a .el file, I noticed that the Emacs-Lisp mode actually does code completion. However, lisp-complete-symbol is bound to M-TAB. In Windows, this key binding is taken by Windows for switching the active window. Most IDE's use C-SPC, but that's taken in Emacs as well. What is a good, fairly common key binding for code completion?
If you like completion of all kinds, I recommend M-/ and binding that to hippie-expand.
(global-set-key (kbd "M-/") 'hippie-expand)
It does a variety of completions, which are controlled by the variable hippie-expand-try-functions-list. In the .el files, you can set that to do the 'try-complete-lisp-symbol first to get the behavior you're asking for above, along with all the other expansions hippie-expand provides.
This would do that for you:
(add-hook 'emacs-lisp-mode-hook 'move-lisp-completion-to-front)
(defun move-lisp-completion-to-front ()
"Adjust hippie-expand-try-functions-list to have lisp completion at the front."
(make-local-variable 'hippie-expand-try-functions-list)
(setq hippie-expand-try-functions-list
(cons 'try-complete-lisp-symbol
(delq 'try-complete-lisp-symbol hippie-expand-try-functions-list)))
(setq hippie-expand-try-functions-list
(cons 'try-complete-lisp-symbol-partially
(delq 'try-complete-lisp-symbol-partially hippie-expand-try-functions-list))))
As Trey Jackson mentioned, hippie-expand is the way to go, but along with binding it to M-/, I also like having the TAB key do all my completion work for me. So I have this from the Emacs-Wiki in my .emacs file:
;;function to implement a smarter TAB (EmacsWiki)
(defun smart-tab ()
"This smart tab is minibuffer compliant: it acts as usual in
the minibuffer. Else, if mark is active, indents region. Else if
point is at the end of a symbol, expands it. Else indents the
current line."
(interactive)
(if (minibufferp)
(unless (minibuffer-complete)
(hippie-expand nil))
(if mark-active
(indent-region (region-beginning)
(region-end))
(if (looking-at "\\_>")
(hippie-expand nil)
(indent-for-tab-command)))))
(global-set-key (kbd "TAB") 'smart-tab)
You could have hippie expand settings as follows:
;;settings for hippie-expand
(setq hippie-expand-try-functions-list
'(try-complete-lisp-symbol
try-complete-lisp-symbol-partially
try-expand-dabbrev
try-expand-dabbrev-from-kill
try-expand-dabbrev-all-buffers
try-expand-line
try-complete-file-name-partially
try-complete-file-name))
C-M-i; no customization required.
I use:
(define-key function-key-map [(control tab)] [?\M-\t])
I use M-. and M-/ for the 2 completion modes - hippie-expand and the standard emacs one.
Put this in your .emacs to make Windows give Emacs the use of M-TAB:
(when (fboundp 'w32-register-hot-key) (w32-register-hot-key [M-tab]))