Emacs truncates some kbd macros during insert-kbd-macro - emacs

I am trying to customize emacs for my needs. In particular I want to define a long keyboard macro and save it for later use. However emacs seems to truncate the definition during saving.
Environment: Emacs 24.5-7 on Fedora 23
My attempts showed that emacs uses two different formats for saving depending on the keyboard input. For pure textual form without control characters it just stores a string; no truncation occurred so far. However when a control character, even a newline, is part of the input emacs stores a vector of character symbols?() with only the first 12 elements, the rest is just indicated by ellipsis (...) and cannot be used later.
I use C-x C-( and C-x C-) to define the macro, C-x C-k n to give it a name, and then save it with M-x insert-kbd-macro:
13 printable characters:
abcdefghijklm
(fset 'str13
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ("abcdefghijklm" 0 "%d")) arg)))
11 printable characters with newline:
abcdefghijk
(fset 'str11nl
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([97 98 99 100 101 102 103 104 105 106 107 return] 0 "%d")) arg)))
12 printable characters with newline:
abcdefghijkl
(fset 'str12nl
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote (97 98 99 100 101 102 103 104 105 106 107 108 ...] 0 "%d")) arg)))
When I load this macro again, e.g. with M-x eval-region and M-x str12nl, only the 12 printable characters are inserted, then an error occurs:
After 0 kbd macro iterations: Keyboard macro terminated by a command ringing the bell
Is there a method to have the full definition saved?
,

Related

How do I set emacs to use 3 spaces instead of tabs in verilog mode?

I am pretty new to emacs (using version 23.3) and I wanted to set the default tab key to insert 3 spaces instead of a tab character in verilog mode. I did find a number of posts regarding this in stack overflow. Some of them are: -
How To Force spaces instead of tabs regardless of major mode
Why might my Emacs use spaces instead of tabs?
Emacs global configuration of tabs
But they do not seem to work in verilog mode. This is how my .emacs file looks like
(custom-set-variables
'(tab-stop-list ('(3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120)))
'(verilog-case-indent 3)
'(verilog-indent-level-directive 0)
'(verilog-indent-level 3)
'(verilog-tab-always-indent nil))
(custom-set-faces
)
(add-hook 'after-change-major-mode-hook
'(lambda ()
(setq-default indent-tabs-mode nil)
(setq tab-width 3)))
(setq-default indent-tabs-mode nil)
(setq-default tab-width 3)
(setq-default standard-indent 3)
If I try to edit a text file, the setup works perfectly and inserts 3 spaces instead of a tab. However it still inserts a tab character when I try to edit a verilog file (.v). I can select the entire text and do M-x untabify to get the required result but is there another direct solution?
In the hook you should use setq instead of setq-default, so you need to rewrite your hook to something like:
(defun my-verilog-hook ()
(setq indent-tabs-mode nil)
(setq tab-width 3))
(add-hook 'verilog-mode-hook 'my-verilog-hook)
P.S. it's better to use dedicated functions in hooks, as it's easier to change them, and you can also remove them from hooks

Emacs align-regexp on = but not ==

I am working in Haskell and frequently come across code similar to the following:
func i j | i == j = i
| otherwise = j
I want to align on the '=' character using align-regexp but don't have the elisp knowhow. I have tried just doing " = " without the quotes, but this inserts an unwanted space character before each '='. I have found a proposed solution here but I can't seem to get that to do anything at all.
Please help me write a function or hard-coded macro that will allow me to set a keybinding for this.
C-u M-x align-regexp RET \(\s-*\) = RET 1 RET 0 RET n
(n.b. there's a space after the '=', but it's not very obvious.)
Which is to say...
Use a prefix argument to tell align-regexp to ask you for more parameters than it does by default.
See C-h f align-regexp and C-h v align-rules-list for details, but in short:
\(\s-*\) is the default 'group' for deletion/expansion. We append our pattern to the end of that: ' = '. (Note that \s- is Emacs regexp syntax for whitespace.)
1 simply refers to parenthesised group 1 (as above). This is the default.
0 for the spacing to use between the two parts of the line. By default this is 1, and is why you were ending up with an additional space.
n to not align any subsequent pattern matches after the first in each line.
edit: Actually, the Q&A you linked to is near identical, and works fine for me on Emacs 23.2.1, so this is a duplicate, but to continue and answer the key-binding aspect:
You can bind that (or any) sequence via keyboard macros. Here's the end result, which you can probably just add to your init file, although I recommend you go through the process yourself. Use whatever you like in place of C-c a for the key. C-c (letter) and F5-F9 are reserved for end-users to bind as they please, so one of those will be safe from being clobbered by a mode's keymap.
(global-set-key (kbd "C-c a") (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([21 134217848 97 108 105 103 110 45 114 101 103 101 120 112 return 32 61 32 return return backspace 48 return 110] 0 "%d")) arg)))
I did that by:
selecting the text.
F3 to start recording.
performing the align-regexp as above (being careful to type everything verbatim, and not use minibuffer history or yanking).1
F4 to stop recording.
C-x C-k n align-single-equals RET to give the macro a name
M-x insert-kbd-macro RET align-single-equals RET to get the lisp.
Wrapping the (lambda) expression with (global-set-key) to bind it. (Although you could also use the (fset 'align-single-equals ...) code as provided, and then bind the key to that symbol.
1 If you make a mistake when recording a complicated macro, don't fret — Emacs provides a really good macro editor which you can use to fix any mistakes after you finish recording (just type C-x C-k e), so you don't need to be perfect.
edit 2: May as well add an example of a function, as per comments.
(defun my-align-single-equals ()
"Align on a single equals sign (with a space either side)."
(interactive)
(align-regexp
(region-beginning) (region-end)
"\\(\\s-*\\) = " 1 0 nil))
(global-set-key (kbd "C-c a") 'my-align-single-equals)

Emacs indentation in Asm mode

I am looking for the equivalent of c-indent-level and ruby-indent-level, for asm-mode. That is, I want to force the indentation to 4 spaces, and I want them to be replaced with blanks.
What I've seen tells me it does not exist for asm-mode. Could someone please tell me this is wrong?
I tried this also: Set 4 Space Indent in Emacs in Text Mode , to no av.
I have tried:
(setq tab-width 4)
(setq indent-line-function 'insert-tab)
(setq asm-indent-level 4)
This works however:
(custom-set-variables
'(tab-stop-list (quote (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120))))
But I wonder if there is a way to define that for asm-mode only. What if I wanted to keep the default tab behaviour for other modes?
asm-mode uses the function tab-to-tab-stop for indentation, that's why tab-stop-list is working. As far I know there is nothing more that you can do. You might consider using some of the "more advanced" asm modes such as - gas-mode or asm86-mode.
Emacs defines hooks for every (?) major mode. If you do H-m in assembly file, you can see at the end of text section that Assembler mode hook is called `asm-mode-hook'. So you can add your code to run when assembler mode is selected for a buffer like this:
(add-hook 'asm-mode-hook (lambda()
(setq tab-width 4)
(setq indent-line-function 'insert-tab)
(setq asm-indent-level 4)))
Note, tab-width and indent-line-function are already buffer local variables, so setting them changes their value only for the current buffer. This is probably what you want. If you setq some other variables, you may want to make them buffer local using (make-variable-buffer-local VARIABLE) function.

Custom Emacs key bindings are not working

The key bindings I've defined in my .emacs file aren't working. Here's the file:
;init modes
(menu-bar-mode 0)
(tool-bar-mode 0)
(cua-mode)
(column-number-mode)
(fset 'perl-mode 'cperl-mode)
(cperl-set-style PerlStyle)
;keymappings
(global-set-key [f12] 'save-buffer)
(global-set-key [S-f12] 'write-file)
(global-set-key [f7] 'ispell)
(global-set-key [up] 'scroll-one-line-up)
(global-set-key [down] 'scroll-one-line-down)
;functions
(defun scroll-one-line-up (&optional arg)
(interactive "p")
(scroll-up (or arg 1)))
(defun scroll-one-line-down (&optional arg)
(interactive "p")
(scroll-down (or arg 1)))
I know Emacs parses the file since everything else seems to work. It's just that the keys are not being bound.
How can I make it work?
You have an error in your .emacs at line:
(cperl-set-style PerlStyle)
It should be written as:
(cperl-set-style 'PerlStyle)
Since it raises an error that stops parsing .emacs at that point, your key bindings won't be evaluated.
To follow up to my previous answer, you would have to change the binding in the local keymap using a hook variable. Here's an example that I use with java-mode:
(defun java-setup ()
(setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92)
indent-tabs-mode nil
tab-width 4
fill-column 96
c-comment-start-regexp "\\(#\\|/\\(/\\|[*][*]?\\)\\)"))
(add-hook 'java-mode-hook 'java-setup)
In your case you would use something like:
(defun mysetup ()
(define-key local-map [f12] 'func))
(add-hook 'your-mode-hook 'mysetup)
Also, fwiw, I do the following to define my global keys:
(defun function-key-help ()
(interactive)
(switch-to-buffer "*Help*")
(erase-buffer)
(insert-file (expand-file-name "~/lib/fkeys.help"))
(message "Type C-x b <nl> to remove help window."))
(define-key global-map [f12] 'function-key-help)
And it works perfectly in my Emacs 23 setup.
It is hard to say what your problem might be without more information, like is it all your keybindings or just one or two that do not work. I will hazard a guess that it is the last two ([up] and [down]). In those cases the on-line documentation below seems to indicate that you might be shadowing the global definitions with local ones defined by the mode.
global-set-key is an interactive
compiled Lisp function in `subr.el'.
(global-set-key key command)
Give key a global binding as command.
command is the command definition to
use; usually it is a symbol naming an
interactively-callable function. key
is a key sequence; noninteractively,
it is a string or vector of characters
or event types, and non-ASCII
characters with codes above 127 (such
as ISO Latin-1) can be included if you
use a vector.
Note that if key has a local binding
in the current buffer, that local
binding will continue to shadow any
global binding that you make with this
function.

Emacs: getting readable keyboard-macros

When using insert-kbd-macro to save a named keyboard macro I get "unreadable" Lisp code like
(fset 'ppsql
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([134217788 134217765 44 return 44 17 10 return 33 134217765 102 102 backspace 114 111 109 return 17 10 102 111 109 backspace backspace 114 111 return 33] 0 "%d")) arg)))
I'd rather have something like the following:
(fset 'move-line-down
[?\C-a ?\C-k delete down ?\C-y return up])
IIRC I used the same method to record, name, and insert both keyboard macros: F3, F4, name-last-kbd-macro.
Is it possible to get the first macro in a readable format?
The keyboard macro functionality in Emacs stands of two modes: macros and kmacros. The former returns the macro in a way you like—the symbol form—, the latter provides the lambda form. So that, if you call name-last-kbd-macro you get a symbol form, if you call kmacro-name-last-macro, you get a lambda form.
Thanks for that!
So the naming of the macro determines the format when inserting?
I've conducted some more experiments and noticed that M-x insert-kbd-macro RET RET would give me the "symbol-form".
Whereas M-x insert-kbd-macro RET pp2sql RET gives the "labmda-form" (after naming with name-last-kbd-macro).
Now I realize that I've all the way used name-last-kbd-macro in my earlier experiments...?
I've never seen the first form. The second form is what I'm used to. Did you try re-recording the first macro to see what happens if you're sure you record, then name, then insert?
The other thing to try is "C-X (", which invokes kmacro-start-macro and "C-X )" kmacro-end-macro, rather than F3/F4,which are doing something extraneous about keeping a counter. Maybe the simpler keyboard macro command will work more straightforwardly.