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

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.

Related

Is there a way to make regions in term modes respect line wrapping?

When using a term mode derivative (like ansi-term or multi-term), I often want to select a region and copy it someplace else. If that region includes a line which wraps at the edge of the terminal window, pasting that region in another buffer always inserts a hard newline at the place where term wrapped the line. This means I often have to go back and clean up pasted text. Is there a way to avoid doing this? I tried both term-line-mode and term-char-mode; both do the same thing.
I do not want to write a yank hook which strips out all newlines, since I want to preserve existing hard newlines in the original content.
This works for me:
(setq term-suppress-hard-newline t)

Emacs: abbrev-mode not expanding simple abbrev, possible causes?

I would like to assign the string 'target="_blank"' to the abbreviation 'tgt' as I use this a lot and it's annoying to have to type out each time.
The string above probably needs escapes and so on, so as a simpler starting point I have tried to assign 'target' to 'tgt'. Despite switching on abbrev-mode and defining this as a global abbrev, if I type 'tgt' and hit space, nothing happens. If I do M-x list-abbrevs I get this:
(global-abbrev-table)
"target" 1 "tgt"
So it seems to be recorded. I would have expected tgt to be expanded to target when I hit a space after tgt, but that doesn't happen. What am I missing? Have I completely misunderstood the nature of abbrevs? I have looked at the Emacs wiki page but like many Emacs pages it gives a number of complex solutions and annoyingly sparse coverage of the basics.
EDIT: embarassingly enough this looks like it was a combination of the wrong abbrev file and an assignment that was reversed, so that typing 'target' produced 'tgt'. I now have 'tgt' producing 'target="_blank"' as desired. Apologies everybody.
However, I now have a related question. This abbreviation expands when I hit space and typically I do not want a space after the 'target="_blank"' string. Is there a way to automatically remove the space?
You have to define the abbrev the other way around. The way you did it will expand "target" into "tgt".
To do the right thing, first type into a buffer what you want the abbrev to expand into. In your case that would be "target". Then, with the point right after the word, type C-x a g. This will prompt you for an abbrev for which you would type "tgt".
Et voilĂ : if abbrev-mode is turned on, typing tgt will now expand into "target".
There are other ways to define an abbrev, e.g. via M-x define-global-abbrev, thus it's best to check out the documentation.
The problem with removing the space after the abbrev is that Emacs will insert it after the abbrev has been expanded. So hitting space will basically two things: trigger the expansion of the abbrev and then run the normal self-insert command.
One simple way to avoid this is to type C-x ' or C-x a e to explicitly expand an abbrev rather then turning on abbrev-mode. Except, that's a bit annoying. If we look at the documentation again, however, we find:
Function: define-abbrev table name expansion &optional hook count
[...]
If hook is a non-nil symbol whose no-self-insert property is
non-nil, hook can explicitly control whether to insert the
self-inserting input character that triggered the expansion. If hook
returns non-nil in this case, that inhibits insertion of the
character. By contrast, if hook returns nil, expand-abbrev also
returns nil, as if expansion had not really occurred.
This means that if you put the following lines in, say, your ".emacs" file:
(defun my-after-abbrev-expand ()
(when (looking-back "\"\"\\|''\\|()\\|\\[\\]\\|{}")
(backward-char 1))
t)
(put 'my-after-abbrev-expand 'no-self-insert t)
then you can define an abbrev like so:
(define-abbrev global-abbrev-table "tgt" "target=\"\"" 'my-after-abbrev-expand)
to avoid the insertion of the space character. Also, the my-after-abbrev-expand function will move the point one position to the left if the expansion ends in two double quotes, two single quotes, or a pair of round, square or curly braces.

emacs move forward by n commas

Can anyone advise how I can move forward (or back) by n commas in emacs?
I am trying to navigate my way through a CSV file
I am aware I can do something like:
C-u 100 M-f
but being able to do something more reg-exp like specifically on commas would be more accurate
The other thing I tried was combining C-u # and C-s , but that didn't work
It will with a keyboard macro, which you can define interactively.
C-x( -- start recording
C-s,RET -- search for a comma (the RET is important; see below)
C-x) -- stop recording
You can now execute that macro again with C-xe (and then just e for continued single repetitions), or use a prefix argument to repeat it a given number of times:
C-u 100 C-xe
Keyboard macros are tremendously useful, and can be easily bound to keys, or even added to your .emacs file in elisp form if you want to keep one for future use. See the manual for details.
edit:
More seamlessly for ad-hoc macros, you can supply the prefix argument when you stop the recording to get exactly that many repetitions, including the one used to record it:
C-x(C-s,RETC-u 100 C-x)
I was seeing some unexpected behaviour with that sequence before I added the RET to explicitly invoke isearch-exit before stopping recording. It behaved as if it was only recording and repeating the comma key (leading to the comma being inserted many times instead of being searched for many times).
Using edit-last-kbd-macro after recording, I could see there was a quirk when using isearch in a macro, such that the C-x typed when stopping the recording is actually included in the macro definition, which was presumably causing the problem for this particular method of invocation. Similarly with the alternate F3 and F4 bindings (in that case, F4 ends up in the definition). I don't know whether this is a bug or a feature, but apparently it pays to exit the isearch before stopping the macro recording!
p.s. Although the two sets of macro recording bindings aren't identical in all respects, everything here also works with F3 and F4, so for this example you could slightly more concisely use F3C-s,RETC-u 100 F4
With
iy-go-to-char you
can do M-3C-cf, to go to
the third comma.
Use CSV mode which will give you convenient functions to do what you want and more
You could record a macro with C-u C-u M-f or C-u C-u C-f and use that. If it's infrequently used, record it using PF3 and play it back by pressing PF4.

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

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}.

Emacs remember text selection

I decided that I was ready to try something new, after a few years of using gEdit for most of my coding needs, and try to learn using Emacs. I knew this would be difficult, as I have heard how complex Emacs can be, but I was lured by its power. The hardest thing has been getting used to writing ELisp in the .emacs file to change things about the editor. I can't currently do it myself, but I have found a few helpful snippets here and there to change some options.
One thing I have been having a lot of problems with is getting Emacs to remember the text I have selected after a command. For instance, I commonly highlight a section of code to mass indent it. However, if I do this in Emacs, it will move the selected text only once before unselecting all of the text. Does anyone know a way around this?
Anyway, I apologize for what seems to me to be an easy question, but after an hour of Google searching and looking around here on SO, I thought it was worth asking. I have a few more questions about Emacs, but I will save them and ask separately after I get this straightened out. Thanks!
UPDATE
A few people have asked about what mod I am using and what type of text I am entering. While I don't know much about Emacs modes, I am editing a pure text file at the moment. Something like this:
Hello, I am a simple text file
that is made up of three separate
lines.
If I highlight all three lines and hit TAB, I get this:
Hello, I am a simple text file
that is made up of three separate
lines.
This is great, however, if I use C-x C-x like some suggest below to reselect the text and hit TAB again, I get this:
Hello, I am a simple text file
that is made up of three separate
lines.
I hope this helps!
FWIW, here is the reason for the behaviour of your newly-added example. (I'm not 'solving' the issue here, but I'm posting it to demystify what you're seeing.)
This was determined with emacs -q which disables my customisations, so the following is default behaviour for emacs 23.2.
You are in text-mode. You should see (Text) or similar in the mode line at the bottom of the screen, and C-h m will tell you (under the list of minor modes) "Text mode: Major mode for editing text written for humans to read." Emacs decides (by way of the auto-mode-alist variable) that it should switch to text-mode if you visit a filename matching certain extensions (such as .txt).
In text-mode pressing TAB with a region highlighted causes indent-according-to-mode to be called on each line of the region in sequence. The slightly convoluted path to finding this out starts at C-h k TAB, which tells us that TAB is bound to indent-for-tab-command, which in this instance calls indent-region -- that function name is not stated explicitly in the help, but can be seen in the code -- which checks the buffer-local indent-region-function variable, which is nil, and: "A value of nil means really run indent-according-to-mode on each line."
indent-according-to-mode checks the indent-line-function variable, which has the buffer-local value indent-relative.
Use C-h f indent-relative RET to see the help for this function. (Read this).
Although you probably won't yet have had the experience to know how to check all that (or necessarily even want to!), and fully understand everything it tells you, this is an example of how the self-documenting aspect of Emacs enables a user to figure out what is going on (which then makes it feasible to change things). I essentially just used C-h k (describe-key), C-h f (describe-function), and C-h v (describe-variable) to follow the documentation. Looking at the source code for indent-for-tab-command was as simple as clicking the file name shown as part of its help page.
I suggest doing the following to help see what is happening when indent-relative runs on each line:
M-x set-variable x-stretch-cursor t
M-x set-variable ruler-mode-show-tab-stops t
M-x ruler-mode
Now for each line in turn, put the cursor at the very start of the line and press TAB. You'll end up with all three lines indented to the first tab-stop ('T' in the ruler).
Now repeat this -- again, ensure you are at the very start of each line, in front of the existing indentation.
The first character of the first line (which is currently a tab) is once again indented to the first tab-stop, as there is no preceding line for it to examine.
Next, the first character of the second line is indented to match the position of the first non-white-space character of the preceding line. Because the first character of the second line is also a tab, the actual text of the second line is pushed one tab further along.
The third line follows suit. Its first tab character is lined up with the first non-white-space character of the second line, with the same relative effect as before, giving you the final state in your example.
To emphasise, note what happens if you now put enter the line "a b c" above the existing lines, then move back to the start of the next line (what was previously the first line) and press TAB. The first tab character will now be indented in line with the 'b'. Provided that the indent-tabs-mode variable is true (meaning you have actual tab characters), then this will have no practical effect on the position of the words in the line, as 'indenting' a tab with spaces will not have an effect until the number of spaces exceeds the width of the tab (but that's another kettle of fish entirely!)
All this really means is that text-mode in Emacs doesn't behave the way you'd like it to in this situation. Other major modes can do completely different things when you press TAB, of course.
As is invariably the case with Emacs, things you don't like can be changed or circumvented with elisp. Some searching (especially at the Emacs Wiki) will frequently turn up useful solutions to problems you encounter.
Try typing C-x C-x after Emacs unselects it.
Then, instead of hitting tab (I never knew that tab does what you said! That's totally whacked.), do M-8 C-x C-i. Pity it's so many keys, but it ought to do what you want -- namely, shove everything over 8 columns. Obviously replace the M-8 with something else if you want some other number of columns.
What I usually do is simply type C-x C-x (exchange-point-and-mark) after a command that deactives the region.
How are you indenting, and in which mode?
The indentation rules in any programming mode should generally just get it right. (If they don't, that's probably more indicative that you want to configure the rules for that mode differently, but I suspect that's a different question which has been asked already).
If you're in text-mode or similar and just using TAB, then I can see the problem.
Note that if you're using indent-rigidly (C-x C-i, or C-x TAB which is the same thing) then you can repeatedly indent the same region simply by repeating the command, even if the highlighting has disappeared from view.
You can also use a prefix arg to indent-rigidly to make it indent many times. e.g. C-u C-u C-x C-i (easier to type than it looks) will indent 16 spaces (4 x 4, as the prefix arg defaults to 4, and it multiplies on each repeat). Similarly, M-8 C-x C-i indents 8 spaces. This is fine in some circumstances, and way too cumbersome in others.
Personally I suggest putting (cua-selection-mode 1) into your .emacs and using that for rigid indentation. Trey Jackson made a handy blog about it. With this, you can C-RET to start rectangle selection, down as many lines as you need, TAB repeatedly to indent the lines, and C-RET to exit the mode.
While the rectangle is active, RET cycles through the corners. For left-hand corners, typing inserts in front. For right-hand corners, typing inserts after. For the single-column rectangle, bottom counts as 'left' and top counts as 'right' for this purpose.
Trey's blog lists all the available features (or look in the source file: cua-base.el)
Be warned that indentation in Emacs is generally an unexpectedly complicated topic.
You can do this with something like the following:
(add-hook 'text-mode-hook (lambda ()
(set (make-local-variable 'indent-region-function)
(lambda (s e)
(indent-rigidly s e tab-width)))))
Then selecting a region and hitting TAB. will indent the region by a tab-width. You can then exchange point and mark with C-x C-x and hit TAB again to repeat.
I do, however, agree with the previous answers that suggest using indent-rigidly directly.