How can I modify emacs' Search and Replace to perform a more complicated task? - emacs

total Emacs noob here. So right now I'm working on a fairly big LaTeX project in Emacs in which there are couple of places where I need to index some words, using the makeidx package. Because I also wanted indexed words to be bold, I created my own command \ind{} which would make the argument go bold and indexed. But right now I'm dissatisifed with this command so I'd like to change every instance of \ind{whatever} in my text by \textbf{whatever}\index{whatever by default}.
The thing is I know exactly what I want :
Go through the text, look for any instance of \ind{ and replace by \textbf{ using search-and-replace
Save the argument of \ind ("whatever" in this case) in memory
Ask me the user what should the argument of \index be. By default (by striking enter), it should be the first argument, but I can also change my mind and enter something different ("whatever by default" in this case). If there's no input (only a space " " for example) stop the program.
Write down \index{, the new argument and }.
Go to next occurance in the text.
But, alas!, I know not how to achieve this, so I need someone's help. If it should take too much time to explain how to do such a thing, would you please send me some tutorial about writing my own functions?
I hope I'm being clear, and thanks for your patience!

This approach seems vaguely unorthodox to me, but it works and seems sufficient for a one-off job...
In the replacement text for replace-regexp and query-replace-regexp (C-M-%), one newer escape sequence is \,(...), where ... can be any Lisp expression. There's a Lisp function read-from-minibuffer which reads arbitrary text typed by the user, with an optional default. Therefore:
C-M-%: Start query-replace-regexp.
\\ind{\([^}]+?\)}: The pattern to search for.
\\textbf{\1}\\index{\,(read-from-minibuffer "index content? " \1)}: The replacement text. The user will be prompted for the text to put in the braces following the \index{} element, using the original text between the braces following the \ind{} element as a default.
Note that when using query-replace-regexp, you'll have to confirm each choice by typing y after each. Use M-x replace-regexp if you want to avoid this step.

Vlad give you the LaTeX answer to your problem. An Emacs solution is the key-macro: start with
C-x (
to define a new macro, then do one step of your change, say:
C-s \ind{
<left>ex
Then copy and paste the argument in the \textbf macro... You have to be careful to move in a way that will be repeatable. Once the standard modification is done, you let the cursor after the whatever by default and end the definition by
C-x )
now C-x e will call the macro you just define, letting your cursor at the correct place to change the part you want to change You can also repeat the e to call the macro several time at once.

Why not just redefine the \ind so that it can get an optional argument?
For example:
\newcommand{\ind}[2][]{%
\def\first{#1}%
\ifx\first\empty
\textbf{#2}\index{#2}%
\else
\textbf{#2}\index{#1}%
\fi
}
This way you can use \ind{whatever} or \ind[whatever-else]{whatever}.

Related

how could I using query-replace like isearch-forward while typing something

while isearch-forward run as a command, the context I had typed will hightlight in the current buffer, but while run query-replace don't hightlight that, how can i make it hightlight?
Use isearch-query-replace. It highlights the string to be replaced.
It sounds like you are saying that query-replace does not highlight all of the matching occurrences. Is that right? It should highlight them. If it does not, then try starting Emacs without your init file: emacs -Q. If that shows no lack of highlighting then recursively bisect your init file to find the culprit.
#Rocky mentioned isearch-query-replace. That doesn't change highlighting (which should already be turned on), but what it does do is let you start query-replacing while you are isearching, using the last search string as the pattern for the text to be matched by query-replace.
An alternative to query-replace, useful especially if you have relatively few replacements you want to make and there are lots of matches, is to use on-demand replacement while isearching. For that you need library Isearch+.
To replace any given search hit on demand, just hit C-M-RET. With a prefix arg, C-M-RET prompts you for the replacement text (the default is to replace with no text, which means to delete the hit). You can thus change the replacement text anytime, within the same Isearch invocation.
After replacing the search hit, C-M-RET moves to the next one. So you can just use it repeatedly if you want to replace several successive search hits. Or use C-s to skip replacing the current hit and move to the next one.
On-demand Isearch replacement works also for regexp searching, and just as for query-replacing, the replacement text can be either inserted literally, as is, or interpreted as in query-replace-regexp. In the latter case, you can use \&, \=\N, \#, \, and \?. You can use C-M-` anytime during Isearch to toggle whether replacement text is used literally or interpreted per the special regexp-replacement constructs.
The following packages provide live highlighting and replacement previewing for query replacing, as well as additional features:
https://github.com/syohex/emacs-anzu
https://github.com/benma/visual-regexp.el
https://github.com/benma/visual-regexp-steroids.el
I currently use visual-regexp-steroids.el.
All three packages can be installed from MELPA.

In emacs, make dabbrev-expand only do partial completions like minibuffer-expand?

Currently, in C-mode, if I start typing a word such as:
namespace_module_
dabbrev-expand will cycle through a million full completions of this identifier...
namespace_module_typea_foo <TAB>
namespace_module_typea_bar <TAB>
namespace_module_typea_goo_start <TAB>
...
With many possible words, it is tedious to navigate through all of these. However, minibuffer completion seems to work differently. It only completes until the first difference among the possible matches. It would have completed to (assuming there were no other matches to something like typeb_, etc):
namespace_module_typea_
At this point, I need only type one character to remove the ambiguity, and it is very likely that autocompletion's next guess will be correct. Is it possible to use this completion mode in-buffer with dabbrev-expand? Or hippie-expand? Or even icicles? I've not been able to find anything.
Have you tried dabbrev-completion (bound to C-M-/ by default)? It should do just what you're asking.
Yes, icicle-dabbrev-completion, which by default is bound to C-M-/ (replacing dabbrev-completion) gives you what dabbrev-completion gives you, but with Icicles completion features whenever there is more than one completion. IOW, you can match using a substring, regexp etc.; you can use progressive completion; you can sort and cycle candidates; and so on.
See the doc about this, here.

Emacs incremental search - auto remove from the search string the characters that could not be found

It's not that convenient when you do a typo during an incremental search and the search string receives the wrongly typed character. Is there a way to prevent this. As if control-g was pressed automatically on error.
For example we have the following text:
keywords
keys
Default emacs behavior:
We start incremental search and search for "keyz"
The "keyz" is displayed in the search echo area and the "key" part in "keywords" is higlighted
We press s
"keys" won't be found, the cursor stays on the "keywords" line, search echo area displays "keyzs", which is not convenient
Needed behavior:
We start incremental search and search for "keyz"
The "key" is displayed in the search echo area and the "key" part in "keywords" is higlighted
We press s
"keys" is found and highlited
You could try something like
(defadvice isearch-printing-char (before drop-mismatches-on-next-char activate)
(while (or (not isearch-success) isearch-error)
(isearch-pop-state)))
Emacs keeps the incorrect part, because it happens very often that you search for a string and it is not found, but not because it's incorrect, only the search string is found before the cursor. In this case it is very convenient that you can press C-s and the search starts from the beginning of the file.
It is very useful behavior and it happens to me more often than mistyping the search string. If there is indeed an error in the search string then you can simply press C-g to go back to last good search string.
I think the problem is that you're not thinking about searching in a way that's congruent with the way isearch has been designed to work, and so your question doesn't really make sense within the context of isearch as it currently exists.
Isearch does already give you exactly the feature what you want, but you have to tell it that you want it to happen by typing that C-g you seem so vehemently opposed to typing. If you don't tell isearch what you want to do, and when you want it to do it, how is it supposed to know what to do?
As #Tom tried to explain, the default way isearch starts from the current position in the buffer, and can restart at the beginning of the buffer if you've typed some failed characters and then press C-s, is a very valuable feature. I'm sure many people rely on this behaviour. Your method of using a macro to always start an isearch at the beginning of the buffer would confound and confuse many of us, though of course it's not a bad thing for someone such as yourself who is accustomed to it. It does mean though that the rest of us are quite confused by your dislike for having to press C-g to delete the non-matching text.
Think also for a moment about what a second C-s does if you press it immediately after starting isearch (any time but the first time in a session) (i.e. before you type any other character). Note in particular what happens if your previous search string would only partly match something in the current buffer, and then you press C-g (and also note how the failed search string is presented, regardless of whether it would partly match something in the current buffer or not).
Think also about how your feature might adversely affect the use of multi-isearch-next-buffer-function.
Claiming that other editors can do what you want isearch to do in emacs doesn't really help your case much.
I think what you really want is some slightly different type of search function which only allows you to search for text that it is possible to find in the current buffer, instead of isearch's ability to search for anything whether that text happens to exist in the current buffer or not.
Perhaps isearch-mode could be adapted to do what you want it to do, but one way or another I think you'll have to write some elisp code. Perhaps you could implement your new search mode as an option within isearch-mode that can be toggled on and off in the same way case sensitivity can be toggled on and off; and that can be set by default, again in the same way that case sensitivity can be turned on or off by default.
If you make a typo during incremental search all you need to do it press backspace to correct the typo.
We start incremental search and search for "keyz"
The "keyz" is displayed in the search echo area and the "key" part in "keywords" is higlighted
We press backspace
We press s
"keys" is found and highlited
As with most of the other answers, I'm just pointing out another feature which helps mitigate the described problem. This one is particularly useful if you've continued to type several would-have-been-good characters after the bad one.
M-e is the binding for editing the isearch string, and in the case where there are no matches for the current string, it rather helpfully places point at the first non-matching character.
So if you have made a small typo, you can quickly type M-e, fix the mistake, and type RET to return to isearch using the corrected search string.

Retaining tab-to-tab-stop with Emacs replace-regexp

I have a very large text file with nearly 20 columns. Unfortunately the program which produced the file did not properly handle columns which began with a -10 (it only properly spaced data which had a total of 5 characters, not 6). Essentially I ended up with something that looks like this:
-10.072-10.179-10.2190.002
I want it to look like:
-10.072 -10.179 -10.219 0.002
and was almost able to do so with:
M-x replace-regexp RET -10\.... RET \&TAB RET
When I use TAB however, it only replaces with a space rather than tab- ideally a tab-to-tab-stop. If I manually go to one of these situations in the file and type TAB it properly does a tab-to-tab-stop to align the data with the proper column. How do I retain the tab-to-stop function within the replace-regexp?
The search and replace certainly ought to be inserting a tab. The apparent size of a tab can vary, of course, which is the only reason I can think of for it appearing to be a space. You could use whitespace-mode to make the difference more obvious.
As for tab-to-tab-stop, that's a dynamic function rather than a special kind of tab character, so you can't do that with a search and replace1. I would suggest using a keyboard macro instead, to get the same dynamic behaviour as manual typing.
F3
M-C-s -10.... RET
M-x tab-to-tab-stop RET
F4
or perhaps just: F3M-C-s -10.... RETTABF4
Then you can run the macro until it fails with C-0F4
(If you only want to run it on a portion of the buffer, you can simply narrow to the relevant region first.)
1 Not strictly true, as Emacs lets you evaluate arbitrary elisp as part of a replacement pattern; but it's not just a case of calling the tab-to-tab-stop function, so the macro is really much simpler.

In Emacs, how can I jump between functions in the current file?

I'd like to quickly move point to a function in my Emacs buffer. I'd like to run some function and get a prompt asking me for the function name, with completion provided for every function defined in the current buffer.
I generally use etags to navigate around, but sometimes I'm looking for a framework method that's been overridden in several files. In these cases, I can find the file I need but then I'd like to quickly jump to the function there. There is a similar feature in TextMate where you can select a definition from a list in the bottom right of the editor.
Just to jump around functions in the current file? Use imenu. It's the simplest and lightest of all the alternatives listed so far and might be enough for what you want. It's also built into Emacs and has minimum setup hassle. It features graphical and textual interfaces. Anything extra and you'll be better off using one of the other excellent suggestions made here.
speedbar comes standard, and gives you a collapsible menu for each file in the current directory, by default middle clicking on an entry for a function definition jumps to that def. With emacs23 this was changed to the more normal leftclick.
You can use etags-select to select from multiple matching tags. But the answer to what you asked is imenu.
Icicles is probably closer to what you are looking for:
http://www.emacswiki.org/emacs/Icicles_-_Tags_Enhancements
It's an enhancement to etags and includes (among other things) the file name with the tag so you can tell if it's the one you are looking for.
try CEDET. It is a bit difficult to set up the first, but here is an excellent tutorial: by Alex ott
And when he gets installed, you can use semantic-complete-jump. pressed tab couple times, and it is also brings up symbol definitions.
If M-. brings up the wrong method, you can type C-u M-. to find the next one with the same name.
global gtags is very good
To navigate within the current file or a set of files that you select, you do not need a TAGS file. You can use Imenu. But it is better to use Icicles imenu commands.
Why? Because they let you use completion. Substring, regexp, prefix, or fuzzy completion. Combine simple patterns to match, or subtract them.
Command icicle-imenu is bound in Icicle mode to C-c =. Butyou can also look up just a command or just a non-command function (non-interactive), using command icicle-imenu-command or icicle-imenu-non-interactive-function.
These commands are multi-commands, meaning that they are actually browsers: you can trip among function definitions using keys C-RET or C-mouse-2 (direct jumps) and C-down (cycle). Hit RET or click mouse-2 to settle down at a final destination.
I use C-M-a and C-M-e to jump between the beginning and end of functions.
Otherwise, open up Speedbar and click the + icon next to a file name to view a list of functions contained in the file. Then click on the function names to jump to them directly.