I am a beginner in emacs and have become a big fan since I started it. Lately I have been debugging a large code base,and I need to put lots of printf statements to make sense of how the code works.
How can I set shortcut in emacs for writing a printf statement and putting cursor after first double inverted comma, so that i can write my own debug message?
You could use yasnippet (or one of the similar systems)
a printf sinppet would look something like this
# -*- mode: snippet -*-
# name: printf
# key: printf
# --
printf("$0%n");
(if it doesn't already exists I'm not sure what language you are looking for)
I agree with Trudbert that a template system is probably the way to go, since that is exactly the kind of functionality they're aiming to provide. Also, for such a small edit a keyboard macro as recommended in one of the comments is a feasible solution. Still I'd like to add an Emacs Lisp version because (a) for this simple example it's easy enough and (b) it might give you more general insights into how to customize Emacs for other things in the future.
(defun insert-printf ()
(interactive)
(insert "printf(\"\");")
(backward-char 3))
Place the above code in your .emacs file and evaluate it by either
placing the point inside the function and pressing C-M-x to run (eval-defun)
placing the point right after the very last ) and pressing C-x C-e to run (eval-last-sexp)
inside the .emacs buffer type M-x eval-buffer
restart Emacs
After any of these actions, Emacs will now know about the function insert-printf so that you can use it. Let's go through it line-by-line to see what it does.
(defun insert-printf ()
starts a function definition. The name of the function is insert-printf and it takes no arguments, hence the empty ()
(interactive)
this declaration turns the function into a command, meaning that you can invoke it by typing M-x insert-printf. If you didn't include this declaration, the only way you could invoke insert-printf would be from other Lisp code.
(insert "printf(\"\");")
inserts the string printf(""); into the buffer at the current position of the point. Note that we have to quote the " with backslashes.
(backward-char 3))
moves the point three characters to the left. After the insertion of printf(""); the point was located right after the semicolon. Since you want it to be between the double quotes we have to move it left by three characters.
Note that Emacs is single-threaded so you don't have to worry about other threads modifying the point position between the last two lines.
Now, you probably want to bind this function to a keyboard shortcut, so you don't have to type M-x insert-printf every single time. You could do this either globally or for specific modes only. Since printf(); is an expression that only really makes sense in C or C++ code, you will probably be fine with having the shortcut only available in C/C++ buffers.
So, let's put the following code in the .emacs file as well:
(add-hook 'c-initialization-hook
(lambda () (define-key c-mode-base-map "\C-cp" 'insert-printf)))
What this code does is add a callback to Emacs that gets called when cc-mode is first initialized, in which case we define the keyboard shortcut C-c p to invoke our insert-printf function. Note that we define this shortcut specifically inside the keymap c-mode-base-map which serves as the basis from which the keymaps for c-mode and c++-mode inherit. Thus our shortcut will not be available in, say, java-mode.
So now you've seen some general steps for customizing your Emacs:
Define the new functionality in terms of a function
Turn the function into a command by adding the (interactive) declaration
Put the code into your .emacs file so it gets loaded on start-up
Define a keyboard shortcut, either globally or locally in a specific mode
Use initialization hooks or (eval-after-load) to define mode-specific shortcuts only when that mode is actually activated for the first time.
This answer is independent of Emacs, but hopefully someone finds it useful. It's a header that defines some macros that print debug messages on stderr, but more convenient that just a printf(). Obviously you can make snippets or abbrevs or whatever with these too. It might use gcc features that are not available in other compilers.
#ifndef __debug_h__
#define __debug_h__
#include <stdio.h>
#include <errno.h>
#define DEBUG
/* #undef DEBUG */
/* macro that prints (like printf) to stderr, prepending the filename, line number, and function name */
#ifdef DEBUG
#define _DBG(fmt, args...) do { fprintf(stderr, "%s(%u): in func %s: " fmt, __FILE__, __LINE__, __FUNCTION__, ##args); fflush(stderr); } while (0)
#elif
#define _DBG(fmt, args...) do {} while(0)
#endif
/* e.g. DBG("arbitrary string"); */
#define DBG(str) _DBG(str "%s\n", "")
/* e.g. DBGF("formated string ("%s") and int (%d)", "blah", 42); */
#define DBGF(fmt, args...) _DBG(fmt "\n", args)
/* e.g. DBG_VAR("%0x08X", (int)interesting_variable); */
#define DBG_VAR(fmt, x) _DBG("%s = " fmt "\n", #x, x)
#define PERR(str) if (errno) { _DBG("%s", ""); perror(str); fflush(stderr); }
#define DBG_COMPILE_TIMESTAMP(str) _DBG("Compiled on " __DATE__ " at " __TIME__ "%s\n", "")
#endif /* #ifndef __debug_h__ */
Related
In most emacs modes, when typing a closing brace at the end of a block, the brace is automatically pulled back to the indentation level of its respective opening line. For instance, after typing the following:
int main(int argc, char* argv[]) {
// stuff
}
the closing brace is pulled back to the left:
int main(int argc, char* argv[]) {
// stuff
} // <---- pulled back with no additional input
When using web-mode, however, this is not the case, at least with the default setup. The closing brace is not pulled back to the correct indentation until there is certain additional input, e.g. pressing tab or enter while the cursor is on the line of the closing brace. This doesn't work well with a style of coding where one adds the closing brace before adding any block content, which does work well when coding in C in emacs (specifically, I mean typing "{ enter enter } C-p"). In this sequence, there is nothing to trigger the closing braces to pull back one indent level, so my code looks like this:
class Header extends React.Component {
render() {
return (
<div></div>
);
}
}
unless I add a tab press to that sequence ("{ enter enter } tab C-p").
I know it's just one key, and I could just change my habits, but is there a way to change emacs' behavior instead? I don't see any relevant variables to change in web-mode's documentation, but am I missing something?
Edit: After learning a lot more about emacs than I ever thought I would, I realize that what I'm looking for is actually a specific feature of cc-mode. In cc-mode, } is bound to c-electric-brace. From the source:
(defun c-electric-brace (arg)
"Insert a brace.
If `c-electric-flag' is non-nil, the brace is not inside a literal and a
numeric ARG hasn't been supplied, the command performs several electric
actions:
\(a) If the auto-newline feature is turned on (indicated by \"/la\" on
the mode line) newlines are inserted before and after the brace as
directed by the settings in `c-hanging-braces-alist'.
\(b) Any auto-newlines are indented. The original line is also
reindented unless `c-syntactic-indentation' is nil.
\(c) If auto-newline is turned on, various newline cleanups based on the
settings of `c-cleanup-list' are done."
So it seems that to get this feature in web-mode, I need to learn some lisp and submit a PR. That's what I'll be doing, and will submit an answer here if/when I finish. In the meantime, I'd still love input from anyone who knows more about this.
using the defun from web-mode.el try:
(local-set-key (kbd "RET") 'newline-and-indent)
So I did end up submitting a PR with this feature, but the maintainer apparently had the same idea and merged it in himself. It's live as of v14.0.36 (commit 3e74b74).
As I stated in the edit to my question, c-electric-brace is a key binding, so the effect is immediate. This is more difficult to implement in a situation where it might be easily enabled/disabled, so in web-mode, it is added as a post-command hook. As a result, it takes place after blinking the matching parenthesis/brace/bracket if show-paren-mode is enabled. Thus there is a short delay.
This effect is enabled when web-mode-enable-auto-indentation is set to t, as it is by default. Here is the relevant code (the merged addition, not mine):
(when (and web-mode-enable-auto-indentation
(member this-command '(self-insert-command))
(member (get-text-property (point) 'part-side) '(javascript jsx))
(looking-back "^[ \t]+[]})]"))
(indent-according-to-mode)
;;(message "%S" (point))
(when (and web-mode-change-end (> web-mode-change-end (point-max)))
(message "post-command: enlarge web-mode-change-end")
(setq web-mode-change-end (point-max))
)
)
I would like F5 to switch to the most recently used buffer. This functionality is accomplished by running M-x icicle-buffer and then hitting enter to not specify the buffer I want to switch to -- (the default behavior of icicle is to switch to the most recent buffer.)
I have tried editing my .emacs thus:
(defun most-recent-buffer-please ()
(interactive)
(icicle-buffer " "))
(global-set-key [(f5)] 'most-recent-buffer-please)
but when I evaluate this lisp, and then hit F5, I get an error that starts with Wrong number of arguments followed by a lot of gibberish characters. What am I doing wrong?
A function can have mandatory and/or optional arguments, or no arguments at all. When writing elisp, it is usually a good idea to find out what arguments are available for certain functions by typing M-x describe-function RET [name of the function] RET. Drew (the author of Icicles) has indicated in his comment underneath the original question that the function icicle-buffer is not designed to be used in conjunction with any arguments -- therefore, adding " " causes the error message that the original poster experienced.
To switch to the previous buffer, Emacs already has a built-in function called previous-buffer. Since the original poster has indicated a preference for the f5 key, the following is an example of how to configure that keyboard shortcut so that it triggers previous-buffer -- brackets are sufficient and the parentheses used by the original poster around f5 can be omitted:
(global-set-key [f5] 'previous-buffer)
Search-forward seems to not work well inside emacs macros. For example, say I want to use a macro to help replace FOO with BAR in the following string:
aoeuFOOsnutehaFOOsanotehuFOO
I might begin recording a macro, search-forward for FOO, and then hit backspace a few times and type BAR. Then I can replay this macro to replace the rest of the occurrences. Pretty simple.
Suppose I hit the wrong key and search-forward for FOOO. I hit Backspace to remove the extra O, and finish recording the macro. But when I replay it, nothing happens. FOOO is not in the document, so the macro replay is immediately aborted when the search fails.
This gets annoying in longer macros. As it is, whenever I record a macro, I have to make sure I type in the search text for my search-forwards perfectly. If I make even one mistake, I have to cancel recording my macro and start over; otherwise, the macro will just abort when I replay it.
To sum up, if you use search-forward and commit a typo while recording a macro, the macro will not replay properly because it will abort as soon as it replays your typo.
Any workarounds or solutions to this problem?
You don't have to abort the macro: The easiest thing to do is to simply finish recording the macro (typos and all) and then edit it via C-x C-k C-e (kmacro-edit-macro-repeat) to remove the typo(s).
For instance, when you call this command after defining a macro that is supposed to simply search for occurrences of foo in the current buffer but contains a typo in the search (you typed fooo instead of foo before fixing the typo), the buffer for editing it would look like this:
C-s ;; isearch-forward
f ;; self-insert-command
ooo ;; self-insert-command * 3
DEL ;; delete-backward-char
RET ;; newline
To fix the macro, delete one of the os from the third line and remove the fourth line:
C-s ;; isearch-forward
f ;; self-insert-command
oo ;; self-insert-command * 2
RET ;; newline
Note that you don't have to change self-insert-command * 3 to self-insert-command * 2, I just did that to avoid confusion.
When you're done, hit C-c C-c to recompile the macro and close the *Edit macro* buffer.
The documentation of the ding function says (emphasis mine):
(ding &optional ARG)
Beep, or flash the screen.
Also, unless an argument is given, terminate any keyboard macro currently executing.
Digging into the source we can see that all isearch-* functions that call ding do so without passing a non-nil ARG. You could redefine these functions to change the way they call ding (not sure if it would be good idea to remove the calls to ding entirely), but there is an easier way to achieve what you want:
You can make sure ding is always called with a non-nil ARG by advising it as follows:
(defadvice ding (before be-nice activate compile)
(ad-set-arg 0 t))
As documented here, the ad-set-arg macro
sets the value of the actual argument at position to value.
So what the advice does is tell Emacs to set ARG to t before running the body of the original ding function, causing ding to be nice and not terminate keyboard macros anymore.
With the advice in place, you can now transform
aoeuFOOsnutehaFOOsanotehuFOO
into
aoeuBARsnutehaBARsanotehuBAR
with a "faulty" macro that contains a corrected typo:
C-s ;; isearch-forward
F ;; self-insert-command
OOO ;; self-insert-command * 3
DEL ;; delete-backward-char
RET ;; newline
3*DEL ;; delete-backward-char
BAR ;; self-insert-command * 3
EDIT
As #phils mentions in the comments below, allowing macro execution to continue regardless of errors can lead to unwanted consequences, so use this solution with care. If you want to be able to quickly enable or disable the advice so that you can use it selectively (i.e., in situations where you are sure it won't mess things up), define it like this:
(defadvice ding (before be-nice) ; advice not activated by default
(ad-set-arg 0 t))
and add a command for turning it on and off to your .emacs:
(defun toggle-ding-advice ()
(interactive)
(if (ad-is-active 'ding)
(ad-disable-advice 'ding 'before 'be-nice)
(ad-enable-advice 'ding 'before 'be-nice))
(ad-activate 'ding))
(global-set-key (kbd "C-c a") 'toggle-ding-advice)
You can then toggle the advice by simply pressing C-c a.
In emacs, is there a way to get hideshow-mode to recognize multiple regular expressions for hiding?
Taken from the EmacsWiki. If I'm understanding your question right you may be out of luck however "no simple way" might mean there is a complicated way out there to be found.
Good luck
There is no simple way to specify
multiple regexp pairs for a single
language, e.g.,
* Open: {, close: }
* Open: #ifdef, close: #else or #elif or … etc.
I assume you mean in the same mode. This can be done but it will require some elisp and some minor regexp. You will either need to have or create a method of detecting what sub-mode you're in.
Lets take mhtml-mode(HTML/CSS/JS) for example:
;;; .emacs
;; When called this automatically detects the submode at the current location.
;; It will then either forward to end of tag(HTML) or end of code block(JS/CSS).
;; This will be passed to hs-minor-mode to properly navigate and fold the code.
(defun mhtml-forward (arg)
(interactive "P")
(pcase (get-text-property (point) `mhtml-submode)
(`nil (sgml-skip-tag-forward 1))
(submode (forward-sexp))))
;; Adds the tag and curly-brace detection to hs-minor-mode for mhtml.
(add-to-list 'hs-special-modes-alist
'(mhtml-mode
"{\\|<[^/>]*?"
"}\\|</[^/>]*[^/]>"
"<!--"
mhtml-forward
nil))
The function mhtml-forward detects what type of forwarding statement should be used.
Hideshow is then set to recognize the opening expressions { and <tag>, and the closing expressions } and </tag>. It will always match the correct one because the custom forwarding function gets you to the correct closing expression for that particular instance.
I write a lot of short throwaway programs, and one of the things I find myself doing repeatedly is typing out code like
#include <stdio.h>
#include <stdlib.h>
int main(void){
}
To save some tendon hits I was wondering if it was possible to insert a simple template above whenever I create a buffer with the extension of .c.
Put somthing like this in .emacs
(define-skeleton c-throwaway
"Throwaway C skeleton"
nil
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"\n"
"int main(void){\n"
"\n"
"}\n")
And eval (C-x C-e) it. That'll give you a
function (c-throwaway) that inserts your template.
To get this inserting automaticly you'll need to activate
auto-insert-mode. Once you do this you can describe-variable
auto-mode-alist and read up on how emacs does some of its open
file magic. Then define auto-insert-alist to apply it when you
find a new file.
Maybe something like this
(define-auto-insert "\\.\\([Cc]\\|cc\\|cpp\\)\\'" 'c-throwaway)
More detail:
Auto Insert Mode
Autotype
I use template.el from http://emacs-template.sourceforge.net/
Basically, I create a file called ~/.templates/TEMPLATE.c, and then that gets inserted into my .c files. You can also use special markup and arbitrary lisp expressions, if you don't just want to dump text into the buffer. I use this feature so that Perl modules start with "package Foo::Bar" when they are named lib/Foo/Bar.pm. Very handy.
The following function will ask for a filename and then insert a file and change to c-mode. The only problem is that you have to call this function to create the buffer instead of your normal way.
(defun defaultCtemplate(cfilename)
(interactive "sFilename: ")
(switch-to-buffer (generate-new-buffer cfilename))
(insert-file-contents "~/Desktop/test.c")
(c-mode)
)
P.S Thanks for the question, now I know how to do this for myself :)
You can also use the YASnippet template system for Emacs, which just has a builtin template called main. So while writing your code, just type main, hit TAB, and it will expand it to the form you want. (And you can always write your own snippet templates.)
I use following code to create files from templates. There are several templates, that are substitutes with actual file names, etc
This question is old, but this might help someone. Looking at this site, I copied and pasted this part into my .emacs file:
;; automatic insertion of templates
(require 'autoinsert)
(auto-insert-mode) ;;; Adds hook to find-files-hook
(setq auto-insert-directory "~/Documents/Emacs/templates/") ;;; *NOTE* Trailing slash important
;;(setq auto-insert-query nil) ;;; If you don't want to be prompted before insertion
(define-auto-insert "\.tex" "my-latex-template.tex")
(define-auto-insert "\.cpp" "my-cpp-template.cpp")
(define-auto-insert "\.h" "my-cpp-template.h")
After changing the directory and filenames, it works perfectly.
Here's how I do it (because I didn't know about auto insert mode :-)
(require 'tempo)
(setq c-new-buffer-template
'(
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"\n"
"int main(void){\n"
"\n"
"}\n"
))
(defun my-c-style ()
"My editing style for .c files."
(c-mode)
(if (zerop (buffer-size))
(tempo-template-c-skeleton)))
(setq auto-mode-alist
(cons '("\\.c\\'" . my-c-style) auto-mode-alist))
(tempo-define-template "c-skeleton" c-new-buffer-template
nil
"Insert a skeleton for a .c document")
I use a combination of Defaultcontent.el and YASnippet.el. The former fills brand-new files with default content. The latter is a sort of lightweight code-gen macro thing. Key in "for" and hit TAB and the skeleton of a for loop is inserted. Etc. You can define your own snippets pretty easily. "swi TAB" gets you a complete switch statement. And so on.
yasnippet is good at expand template in your file, and is very easy to create your snippets.
auto-insert is good at fill a new file with template, but write your own template is hard. There is a great package yatemplate bridges the gap between YASnippet and auto-insert-mode, i can write auto-insert rules with YASnippet.