replay "script" of keystrokes in Emacs - emacs

I would like to record a medium-length screencast of some Emacs functionality using asciinema in a terminal. I could just start asciinema, then emacs -nw, do the recording, then stop. But I find that I always make multiple mistakes.
So I thought that it would be great if I could just write a "script" of keystrokes in some format, that would be fed to Emacs. Like replaying a keyboard macro, but a fairly long one, and with delays between keys (otherwise the recording goes way too fast).
Is this possible somehow? I am willing to do some elisp programming, but don't know where to start. Eg I could record my script as a list,
(list (kbd "C-x C-f") "filename.el" (kbd "C-e") (kbd "C-x C-e") ...)
and iterate through it, converting keystrokes and sending strings by character verbatim, but how do I "send" the result to Emacs?
It would be great if buffer switching etc would work.

You can record a sequence of user actions (keyboard, menus, etc.), creating a keyboard macro.
In a nutshell, you use <f3> to start recording and <f4> to stop recording. Then you can use <f4> (same key) to play back the recording. You can do all kinds of fancy things, in addition, but those are the basics.
See the Emacs manual, node Keyboard Macros for details.
You can show which keys are being used during your screencast in a tooltip, using mode showkey-tooltip-mode from library showkey.el - see ShowKey.
To show the keys recorded by the macro you will need to set or bind option showkey-tooltip-sleep-time to a number of seconds greater than zero. (By default it is zero, so that you can prevent some key display by typing quickly.)
Option showkey-tooltip-key-only-flag controls whether to show only the key, or the key and its command, in the tooltip.
Alternatively, you can show an incremental log of the keys using mode showkey-log-mode.

Related

Finding all the functions in various modes assigned to a specific shortcut

I'd like to find all the modes which do assign a function to some specific shortcut.
For example if I'm not mistaken a stock Emacs simply assigns (or defaults to) newline for S-return but while in org-mode S-return does invoke org-table-copy-down.
Is there an easy way to figure out which modes (both major and minor) do map a function to a specific shortcut? I can find all the shortcuts of one major mode using describe-mode but I'd like to find those for all the various modes. I don't mind if it were to only work for all the currently loaded modes.
Basically I'd like to find "free" or "relatively rarely re-mapped" key shortcuts, which are also easy to type (i.e. I'm not after doing "C-c a" because for a start C-c is a very convoluted key to reach and then having to then hit another key is one key too many for me. I'm more after re-mapping C-o, S-return, M-/ and other combo trivial and fast to reach).
You can find the current-mode bindings using C-h b.
You can get all of the keymaps currently available, using accessible-keymaps. You can find all the features loaded via variable features. But you would have to work to find all possible bindings for all possible modes from all files that you have loaded so far.
I recommend that you do it for a particular mode, one mode at a time. It's easy to check a given mode's key bindings.
You can even check the bindings of keymaps (such as minibuffer maps or the Isearch map) that are hard to see otherwise, if you use command C-h M-k (describe-keymap) from library `help-fns+.el. I use that when I want to see what keys are still available in a given keymap etc.
You can use
M-x describe-unbound-keys
to find out the free keys.
This is from third party library as said in comments.
I don't know the answer to your specific question, but I can give you my solution to getting easy-to-type keybindings that don't conflict with other modes.
In my set up, I've remappped CAPS-LOCK to Alt. Most people map it to CTRL, but I can hit CTRL relatively easily, while ALT is difficult. With this set-up, one of the easiest key combos to hit is M-space. So I use this as my own private keymap:
(define-prefix-command 'ty-keymap)
(global-set-key "\M- " ty-keymap)
(define-key ty-keymap " " 'just-one-space)
(define-key ty-keymap "j" 'join-next-line)
(define-key ty-keymap "s" 'mark-sexp)
(define-key ty-keymap "c" 'org-capture)
...
Note: by default, M-space is bound to just-one-space, which is useful. I've moved that to M-space-space. Bouncing my thumb twice on the spacebar is only a fraction slower than hitting it once, so it's not a big loss.
Since M-space isn't a keymap by default, this setup allows me to use all the keys on the keyboard, without further modification. That's a lot of real-estate, guaranteed to be free of any conflict with other packages - since well-behaved packages won't clobber a basic Emacs keybinding.
You might prefer another key combo, but the idea is the same. You could even use a function key as your prefix-command, so you could do <f5> followed by a letter for your commands.

Refactoring a big file in emacs

I'm refactoring a big piece of code in one file in Emacs.
What is the best way to simplify jumping to several places in a big emacs buffer?
Currently I'm using search (C-S) and custom comments - "markers".
This becoming quiclkly unreliable.
Ideally I would like to have the same file open in several buffers, so I can switch between them using C-X B.
What are your solutions?
It seems that what you are looking for is Indirect-Buffers.
Personally, I find that splitting my window (C-x 2) is a great help.
Also bookmarks come to mind.
See Emacs Bookmarks.
Going to a particular bookmark switches to the correct buffer automatically (a bookmark is associated to a buffer).
Registers are useful for marking and jumping to positions. If you only have a small number of spots to mark and remember at any time, it may be faster to use single-character registers than named bookmarks.
C-xrSPC runs point-to-register
C-xrj runs jump-to-register
When prompted for the register, you can type any character.
Use autonamed bookmarks. No need to specify a name each time you create a bookmark -- just hit a key. Like using C-SPC to set a mark, but bookmarks are (by default) persistent; marks are not.
With Bookmark+ you can also organize bookmarks (including autonamed bookmarks) into sets etc. Tag them in various ways, for instance.
Visual bookmarks is extremely useful for this case. You can get it from here or install it using
M-x package-install RET bm
and add this to your config.
(global-set-key (kbd "<f5>") 'bm-toggle)
(global-set-key (kbd "<f7>") 'bm-next)
(global-set-key (kbd "<f6>") 'bm-previous)
Now, any where in your file press f5 and it creates a mark there. If you want to remove it, just press f5 again.
You can create any number of markers and now using f6 & f7 you can quickly go to any point you want.

Emacs Lisp: How to, an interactive buffer with REPL?

Imagine the dunnet.el game, the eliza doctor or the IELM mode...; This is, evaluating answers and prompting new questions on the main buffer, then making some actions according to their elisp rules.
I would to create something like an interactive assistant, BUT NOT prompting from minibuffer as (interactive) does (not doing M-x)... I need a kind of REPL loop. So the question i how to get interaction on the working buffer (the main screen), like any text conversational/adventure, but for call my defun'ed functions on this way.
So i need a basic elisp skeleton, to make a custom REPL. The target is to make an assistant with a natural language, then parsing the anwsers, and making some actions according the rules.
Thank you for your time,
Steve,
Check out ielm, which is an elisp repl included with emacs.
Depending on what can go on in your buffer, can you just give it a major mode with an appropriate re-binding of return? (This answer vaguely inspired by Lisp-Interaction-Mode's C-j)
You should bind all keys that use for moving in buffer like C-p C-n, Up Down Arrows/ page up/down just bind them to (lambda ()). change function for C-b and C-f (Left Right Arrows) if cursor position is in beginning or end of the line. And bind Return key to function that read current line from end to optional prompt (you can use Regex to remove the prompt) do whatever you want with that string, and then go to the next line in the buffer and print your result.

Simple Emacs keybindings

I have two operations that I do all the time in Emacs:
Create a new buffer and paste the clipboard. C-S-n
Close the current buffer. C-S-w
Switch to the last viewed buffer. C-TAB
I feel like a keyboard acrobat when doing the first two operations. I think it would be worth trying some custom key bindings and macros.
A few questions about this customization:
How would I make a macro for #1?
Are these good key bindings? (I know this is a bit subjective, but they might be used by something popular that I don't use.)
Has anyone found a C-TAB macro that will act like Alt+Tab in Linux/Windows? Specifically, I want to have a stack of buffers according to the last viewed timestamp (most recent on top). I want to continue cycling through the stack until I let go of the Ctrl key. When the Ctrl key is released, I want the current buffer to get an updated position on the stack.
Have you tried using vertically or horizontally split windows for this (via C-x 3 or C-x 2)? It seems like it would give you fewer steps - even if you implement something like you're talking about.
I find split windows really speed up copy and pasting operations. I use the arrow keys on my num pad to switch among windows (windmove-left/-right/-up/-down), so it's only one key to press and you go to the window you want.
I guess this is a little different from what you're asking for, but it sounds like it might help speed things along a bit.
C-x left and C-x right cycle through buffers, but you have to hit it multiple times, you can't just keep the key pressed down.
For creating a macro for #1, you just start a macro, hit the keys you usually do to create a new buffer, and stop the macro.
So it would be something like:
C-x ( C-x b NEW RET C-x )
You can then save NEW to a file once you're done pasting, so you can use the macro again to create a new buffer. C-x e to try out the macro. If it works you can save it into your init.el file. This is done with:
M-x name-last-kbd-macro
Then you'll get a prompt to enter the name of your choice. This is only good for the current session. Then you save the named macro to your initialization file. First you open your .emacs or init.el file. Then you place point where you want the macro definition to go, then you type:
M-x insert-kbd-macro
Now you can run your macro using its name via M-x <macroname> . You can bind your macro to keys too (in your .emacs or init.el file):
(global-set-key (kbd "C-c a") '<macroname>)
For example this is how your init.el would look after creating a macro that opens a new buffer called NEW that is not associated with a file and binding this macro to C-c n:
;; Creates a new unassociated buffer called NEW
(fset 'new-buffer "\C-xbNEW\C-m");
;; Shortcut for new-buffer
(global-set-key (kbd "C-c n") 'new-buffer)
You can also throw in the paste, buffer close, and buffer switching operations. I guess you'd have to save the buffer to a file manually.
Some resources
Information about macros on EmacsWiki
Possibly useful: Swap text between buffers
start by invoking start-kbd-macro, finish by with end-kbd-macro. Afterwards you may immediately test the new macro with call-last-kbd-macro. If you're happy with the result you might want to save the macro.
Emacs generally doesn't use C-S keybindings and they are easy to use, so I'd call them good. They might cause problems if you're using the terminal version of Emacs, but I assume that's not the case with you.
I use this simple snippet:
(global-set-key (kbd "<C-tab>") 'bury-buffer)
bury-buffer basically makes the current buffer the last in the buffer-list so you'll be able to cycle buffers in a predictable order.
I wouldn't make a macro for that but write a function like someone else posted on this page. Instead of (cua-paste nil) you could also use (yank). I'm not sure which one's better and why.
I don't like them that much. For things that I use often I'd like to do as little finger acrobatics as possible, so that would mean modifier+key instead of modifier1+modifier2+key.. or use a function key if you don't feel tied to the homerow.
no comment

Does Emacs has word and line completion (like Vim's insert mode completion)?

Vim completes words and lines with CTRL-X P and CTRL-L. There's a Emacs plugin called Company mode but this plugin interfere and cause conflicts with lots of things within Emacs (with global linum and yasnippets). I know that I can complete words with CTRL-/ in Emacs. But it is possible to take previously written lines to complete code?
Maybe you're looking for hippie-expand? From that web page (as of this writing, anyway):
HippieExpand looks at the word before
point and tries to expand it in
various ways including expanding from
a fixed list (like expand-abbrev),
expanding from matching text found in
a buffer (like dabbrev-expand) or
expanding in ways defined by your own
functions. Which of these it tries and
in what order is controlled by a
configurable list of functions.
For a comprehensive list of completion options visit the emacs wiki page on completion.
There are a gazillion ways to do completion in Emacs. Some are mode specific, some inline, some configurable and what not. Here is a list of modes that might help you.
Use numberic argument to complete by line, say M-5 M-/ will complete by line, while M-/ alone still complete the normal way.
hippe-expend function has a very useful feature which is :
With a positive numeric argument, jumps directly to the ARG next function in this list. With a negative argument or just C-u, undoes the expansion.
Customize the expansion functions in hippie-expand-try-functions-list and put the function try-expand-line as 5th list element, then you could use M-5 M-/ to complete by line.
This tip is very handy and useful and I highly recommend it.
Also worth noting: if your window manager does not steal Alt-tab, emacs will auto-complete with Alt-tab (I set up my window manager to user the "windows key" instead of alt for this very reason).
If you are using evil, this is the most vim-like solution I use:
(defun my-expand-lines ()
(interactive)
(let ((hippie-expand-try-functions-list
'(try-expand-line-all-buffers)))
(call-interactively 'hippie-expand)))
(define-key evil-insert-state-map (kbd "C-x C-l") 'my-expand-lines)
This way you can use our old friend C-x C-l in insert mode for whole line all buffers completion.
Thanks #ymln for the suggestion of using try-expand-line-all-buffers.