emacs how to bind "LEFT-POINTING DOUBLE ANGLE QUOTATION MARK" to a keystroke - emacs

I want to type a single keystroke to insert unicode brackets #xab and #xbb.
This works (for a different unicode bracket):
(global-set-key (kbd "C-c [") "⟨")
But this doesn't work:
(global-set-key (kbd "C-c [") "«")
How do I coax emacs into inserting "«" with a single keystroke?
(I happen to be on MacOS, but intend to use ubuntu in Parallels)

I`m not sure what is expected, double ⟨ or one «, but hope this can help
check function and loop
(defun my-insert ()
"test something"
(interactive)
(dotimes (i 2)
(insert "⟨"))
)
(defun my-insert2 ()
"test something"
(interactive)
(insert "«")
)
(global-set-key (kbd "C-c [") 'my-insert)
(global-set-key (kbd "C-c ]") 'my-insert2)

There is a more general solution which works everywhere, making it more convenient (as you may not want to open an emacs instance each time you need a particular character), which is the compose key. Compose key is specific to Linux, but there is a way to install an equivalent solution on MacOS, and you can even convert existing Compose Key bindings, which is useful because there are a lot of predefined sequences out there in the wild, for instance the default ones.
E.g. on Ubuntu you probably just need to enable it in the settings, and then with the default configuration typing Compose < < will produce «.

Related

Is it possible to collapse a function in emacs?

So, for a lisp homework assignment I have, it has a long defparameter expression that's a large data set. What I'm wondering is, does emacs or SLIME have anything to "collapse" that large defparameter into a single line, like, say, MATLAB does?
Like Bertfred mentioned, hideshow works great, and it comes build in with more recent versions of emacs. To use it simply add the following snippet to your init file:
(add-hook 'prog-mode-hook #'hs-minor-mode)
(global-set-key (kbd "C-c <right>") 'hs-show-block)
(global-set-key (kbd "C-c <left>") 'hs-hide-block)
The first line enables the functionality in any major mode associated with programming. Once there, C-c <left> and C-c <right> should do what you expect - just be mindful of where point is.
https://www.emacswiki.org/emacs/HideShow
There's also a package on Melpa called vimish-fold (or the equivalent evil version of it - evil-vimish-fold).
It is not as "automatic" as hideshow or outline in the sense that you have to select the lines you want to fold, but the advantage is that you can fold any lines. And the folds don't disappear the when you close your file.
You can define your keybindings for creating/deleting folds and for unfolding/refolding folds, and there you go!
(global-set-key (kbd "your-keybinding") 'vimish-fold)
(global-set-key (kbd "your-keybinding") 'vimish-fold-delete)
(global-set-key (kbd "your-keybinding") 'vimish-fold-toggle)

How to make $ as an alias for a specific keyboard macro in emacs

Suppose that I have defined a macro in emacs (24.2), say xyz.
I would like to associate the shortcut $ to this macro, i.e. to run the macro xyz whenever I type $.
How I can do it?
I tried all of the following without success:
(global-set-key [$] 'xyz)
(global-set-key ["$"] 'xyz)
(global-set-key [?$] 'xyz)
(global-set-key [s-4] 'xyz)
(global-set-key "$" 'xyz)
(global-set-key (kbd "$") 'xyz)
(The last three ones were suggested by bleeding-fingers, abo-abo and Chris).
From your comments, it is now clear that you've defined a macro that includes using the key $. If you do this, you can't then bind the macro to the $, because that makes it recursive - every time you get to the $ in your macro, you are in effect calling the macro again.
You could, however, define the actions you want performed as an elisp function, which you could then bind to $. If we knew what you were actually doing with your macro we might be able to show you how.
EDIT: how about this:
(global-set-key (kbd "$") #'(lambda () (interactive) (insert " $")))
That should work, but lambdas can be a bit confusing. A little clearer for elisp beginners might be:
(defun my-dollars ()
"Insert a dollar sign with a space in front."
(interactive)
(insert " $"))
(global-set-key (kbd "$") 'my-dollars)

How to bind text insertion in isearch

I'd like to have M-u to insert an underscore when I am in isearch (isearch-regexp and also the reverse variants).
Neither
(define-key isearch-mode-map (kbd "M-u") 'insert-underscore)
nor
(add-hook 'isearch-mode-hook
(lambda ()
(local-set-key (kbd "M-u") 'insert-underscore)
))
insert-underscore is my function that simply inserts "_". It works in the main frame and also in minibuffer, but I can't get it working in isearch...
Thank you!
Isearch doesn't use regular commands. (kbd "_") along with every other
printable character is bound to a special command in isearch-mode-map. It's
not obvious, but a lot of things happen in "isearch-mode" when you press a
key. Display is refreshed with new results, wrapping is a possibility, etc, etc,
You'd have to manipulate raw keyboard events to get this to work.
(defun underscore ()
(interactive)
(isearch-unread-key-sequence (list ?_)))
(define-key isearch-mode-map (kbd "M-u") 'underscore)
Note that this code is not robust; for example, numeric prefix does not work.
EDIT: After letting percolate in my mind for a while, it occured to me that this is the exact use-case for translation keymaps
(define-key key-translation-map (kbd "M-u") (kbd "_"))
Ain't Emacs grand?

How do I bind C-= in emacs?

This s-expression in my .emacs file does not produce the desired result:
(define-key global-map (kbd "C-=") 'djhaskin987-untab-to-tab-stop)
Why can't I bind a command to Ctrl+=?
EDIT for clarification:
I am using emacs23-nox on the standard build of urxvt-256colors for Debian, except that I have recompiled with --disable-iso405776 (or something to that effect) it so that Ctrl+Shift doesn't do the weird 'insert character' thing. I don't know if this affects anything. For example, C-M-i sends M-TAB, which I don't understand.
EDIT II:
I apologize for not making this clear. The function djhaskin987-untab-to-tab-stop has the line (interactive) in it. This part works.
The accepted answer in combination with the link in the first comment to it is enough to get started on a complete solution. The steps are:
make your terminal output escape codes for the key
make Emacs recognise the escape codes as a standard keypress
bind the keypress in a mode map
The first is very terminal and/or operating system dependent.
The link in the first comment shows some examples for X Window System. The key names are available in /usr/X11R6/include/X11/keysymdef.h (or try locate keysymdef.h), prefixed with XK_ (which should be removed for our purposes). I read that symbolic names are preferred over key literals.
I don't currently run X but I think it should look like this in your case:
XTerm.VT100.Translations: #override \
Ctrl ~Meta ~Shift <Key> equal: string(0x1b) string("[emacs-C-=")\n
The first string is the escape, the second is of your choosing.
In iTerm you can use Preferences->Keys and choose Send Escape Sequence as the Action. For example, I have:
Emacs Wiki lists some configuration methods for other terminals.
Now you can teach Emacs to recognize it as a C-=. First define-key into input-decode-map. I have a couple of helper functions:
(defun my/global-map-and-set-key (key command &optional prefix suffix)
"`my/map-key' KEY then `global-set-key' KEY with COMMAND.
PREFIX or SUFFIX can wrap the key when passing to `global-set-key'."
(my/map-key key)
(global-set-key (kbd (concat prefix key suffix)) command))
(defun my/map-key (key)
"Map KEY from escape sequence \"\e[emacs-KEY\."
(define-key function-key-map (concat "\e[emacs-" key) (kbd key)))
So then:
(my/global-map-and-set-key "C-=" 'some-function-to-bind-to)
Some keys (currently: ()\|;'`"#.,) will need escaping in the string, like C-\..
In a terminal, TAB is represented by the same byte sequence as C-i. And typically the terminal has no special byte-sequence for C-=, so it will just send a =. There is nothing that Emacs can do about it. But you might be able to teach your terminal emulator to send some special byte sequence of your choice (check the documentation of your terminal emulator for that), after which you can teach Emacs to recognize it as a C-= (with something like (define-key input-decode-map "...thebytes..." [?\C-=])).
The problem is that you use emacs in the terminal.
The terminal does not allow "C-=".
Try your function in the graphical emacs and it will work.
You will have to find another keybinding for the terminal.
You can map C-= using the default ascii codes: ^[[61;5u. Then you can bind it in Emacs either using:
(global-set-key (kbd "C-=") 'djhaskin987-untab-to-tab-stop))
or let use-package do it, e.g.:
(use-package expand-region
:ensure t
:bind (("C-=" . er/expand-region)))
I do want to thank Sam Brightman, for his wonderful solution. It's a very clean, albeit heavy-handed, approach that will work for any keys that cannot be sent via normal ascii codes. I've been wanting to get C-TAB working inside iterm2 for a long time. I was able to do it by deleting the builtin preferences keys for C-TAB/C-S-TAB and using his approach. With the following, I can be ssh'd into remote Linux boxes and quickly switch through lots of open buffers in projects, just like a desktop editor.
(use-package nswbuff
:defer 1
:after (projectile)
:commands (nswbuff-switch-to-previous-buffer
nswbuff-switch-to-next-buffer)
:config
(progn
(my/global-map-and-set-key "C-TAB" 'nswbuff-switch-to-previous-buffer)
(my/global-map-and-set-key "C-S-TAB" 'nswbuff-switch-to-next-buffer))
:init
(setq nswbuff-display-intermediate-buffers t
nswbuff-exclude-buffer-regexps '("^ "
"^\*.*\*"
"\*Treemacs.*\*"
"^magit.*:.+")
nswbuff-include-buffer-regexps '("^*Org Src")
nswbuff-start-with-current-centered t
nswbuff-buffer-list-function '(lambda ()
(interactive)
(if (projectile-project-p)
(nswbuff-projectile-buffer-list)
(buffer-list)))))
The function you're binding must be interactive. Try:
(define-key global-map (kbd "C-=")
(lambda () (interactive) (djhaskin987-untab-to-tab-stop)))

Is there a better way to switch between multiple windows in emacs gdb besides C-x-o?

I'm using gdb-many-windows, which contains five windows to switch between. Is there a shortcut I can use to get to a specific window?
You probably already know that C-x o gets you to the next window. You can extend this to go to any arbitrary window with C-u <windowoffset> C-x o.
So, you can use C-u 2 C-x o to switch to the second window ahead of your current one.
This wraps around the window list (so in your case of 5 windows you could do C-u 4 c-x o to go back one.
You can also use negative numbers as well to go backwards.
Lastly, it takes a bit more setup, but Thomas's suggestion to use WindMove is very useful. It wasn't configured by default for me to any useful key binding. I add the following snippet to my (mac) .emacs file, whch lets me switch windows via control-arrow (you will need to reload .emacs by starting up or via 'M-x load-file')
(global-set-key (kbd "M-[ 5 d") 'windmove-left)
(global-set-key (kbd "M-[ 5 c") 'windmove-right)
(global-set-key (kbd "M-[ 5 a") 'windmove-up)
(global-set-key (kbd "M-[ 5 b") 'windmove-down)
Some people find WindMove more convenient than C-x o. It allows you to navigate between windows using Shift + arrow keys.
Possibly useful links:
http://www.emacswiki.org/emacs/WindowNumberingMode
http://www.emacswiki.org/emacs/NumberedWindows
Edit: If you decide to use WindowNumberingMode (that's what I use) you might find it useful to pin buffers to windows (so, for instance, Meta-1 switches to the buffer you expect it to switch to, not just the first window). One way of pinning is described in Pin Emacs buffers to windows (for cscope).
Window switching is so important in emacs, I have these settings.(Still feel these are not good enough)..
may help someone else..
(global-set-key "\M-t" 'other-window) ;; was transpose words
(global-set-key (kbd "C-x O") (lambda () (interactive) (other-window -1))) ;; back one
(global-set-key (kbd "C-x C-o") (lambda () (interactive) (other-window 2))) ;; forward t
I use switch-window.el.
You can choose a window by visual way with 'switch-window'.
Image of using switch-window