Emacs remembers text selection

I decided that after several years of using gEdit for most of my coding needs, I tried to try something new and try to learn Emacs. I knew that it would be difficult, because I heard how complex Emacs were, but I was lured by his power. The hardest thing is getting used to writing ELisp in a .emacs file to change something in the editor. Currently, I cannot do this on my own, but I have found some useful snippets here and there to change some parameters.

I had a lot of problems with Emacs remembering the text that I selected after the command. For example, I usually highlight a section of code for mass indentation. However, if I do this in Emacs, it will move the selected text only once before deselecting all the text. Does anyone know about this?

In any case, I apologize for what seems like an easy question to me, but after an hour of searching Google and looking around here, I thought it was worth it. I have a few more questions about Emacs, but I will save them and ask them separately after I straighten it. Thanks!

UPDATE

Several people asked about which mod I use and what type of text I enter. Although I know little about Emacs modes, I am editing a plain text file for now. Something like that:

Hello, I am a simple text file that is made up of three separate lines. 

If I select all three lines and press TAB, I get the following:

  Hello, I am a simple text file that is made up of three separate lines. 

This is great, however, if I use Cx Cx as shown below to reselect the text and press TAB again, I get the following:

  Hello, I am a simple text file that is made up of three separate lines. 

Hope this helps!

+4
source share
5 answers

Try entering Cx Cx after Emacs deselects it.

Then, instead of hitting the tab (I never knew that the tab doing what you said! It completely hit.), Do M-8 Cx Ci . It is a pity that he has so many keys, but he must do what you want, namely, shove everything in 8 columns. Obviously, replace the M-8 with something else if you want a different number of columns.

+2
source

FWIW, here is the reason for the behavior of your recently added example. (I will not "solve" the problem here, but I am posting it to demystify what you see.)

This was determined using emacs -q , which disables my settings, so emacs 23.2 uses the default behavior.

  • You are in text mode. You should see (Text) or similar in the mode line at the bottom of the screen, and Ch m will tell you (in the list of minor modes) "Text mode: the main mode for editing text written for people to read." Emacs decides (via the auto-mode-alist variable) to switch to text mode if you visit a file name that matches certain extensions (e.g. .txt ).

  • In text mode, pressing TAB with a selected region causes indent-according-to-mode called on each line of the region sequentially. A slightly confusing way to detect this starts with Ch k TAB , which tells us that TAB is bound to indent-for-tab-command , which in this case calls indent-region - this function name is not explicitly specified in the help, but may be in which checks the variable buffer-local indent-region-function , which is nil, and: "The value nil means that indent-according-to-mode is actually executed on each line."

  • indent-according-to-mode checks the indent-line-function variable, which has a local indent-relative buffer value.

  • Use Ch f indent-relative RET to see help for this function. (Read this).

Although you probably haven’t yet had time to learn how to check it (or you’d even want to!) And fully understand everything that it tells you, this is an example of how the self-documenting aspect of Emacs allows the user to understand what is happening (which then makes it possible change of things). I just used Ch k (describe-key), Ch f (describe-function) and Ch v (describe-variable) to follow the documentation. Looking at the source code for indent-for-tab-command was as easy as clicking on the file name shown as part of the help page.

I suggest doing the following to see what happens when indent-relative works on each line:

Mx set-variable x-stretch-cursor t
Mx set-variable ruler-mode-show-tab-stops t
Mx ruler-mode

Now for each line, in turn, position the cursor at the very beginning of the line and press TAB. As a result, you will get all three lines indented to the first tab-stop ("T" in the line).

Now repeat this - make sure once again that you are at the very beginning of each line before the existing indentation.

The first character of the first line (which is currently a tab) again departs from the first tab tab, since there is no previous line for it.

Further, the first character of the second line is indented according to the position of the first non-white space of the previous line. Since the first character of the second line is also a tab, the actual text of the second line then pushes one tab forward.

The third line follows an example. Its first tab character is aligned with the first non-white space of the second line character with the same relative effect as before, giving you the final state in your example.

To emphasize, pay attention to what happens if you now enter the string "abc" above existing lines, and then return to the beginning of the next line (there was the first line before) and press TAB. Now the first tab character will be indented according to "b". Provided that the variable indent-tabs-mode is true (which means that you have valid tabs), this will not have a practical effect on the position of words in the line, since the "indentation" of the tab with spaces will not have effect until as long as the number of spaces exceeds the width of the tab (but this is another whole kettle of fish!)

All of this actually means that text-mode in Emacs does not behave as you would like in this situation. Other main modes can do completely different things when you press TAB, of course.

As always with Emacs, things you don't like can be changed or circumvented with elisp. Some searches (especially in the Emacs Wiki) will often provide useful solutions to the problems you encounter.

+8
source

How do you retreat and in what mode?

Indentation rules in any programming mode should usually be correct. (If they don’t do this, it’s probably more indicative that you want to configure the rules for this mode differently, but I suspect that another question has already been asked that is already asked).

If you are in text mode or similar and just using TAB, I see a problem.

Note that if you use indent-rigidly ( Cx Ci or Cx TAB , which is the same), you can re-retreat in the same region by simply repeating this command, even if the highlight has disappeared from view.

You can also use the arg prefix for indent-rigidly to indent it many times. for example Cu Cu Cx Ci (easier to enter than it looks) 16 spaces will be indented (4 x 4, since the arg prefix is ​​4 by default and is multiplied by each repetition). Similarly, M-8 Cx Ci indents 8 spaces. In some cases, this is normal, and in other cases, it is too cumbersome.

Personally, I suggest putting (cua-selection-mode 1) in your .emacs and use this for hard indentation. Trey Jackson made a handy blog about it . With this, you can C-RET start the selection of the rectangle, down as many lines as you need, TAB several times to back out from the lines, and C-RET to exit the mode.

While the rectangle is active, RET cycles through the corners. For left corners, gaining insets in front. For the right corners, enter the insets after. For a rectangle with one column, the bottom is counted as “left” and the top number is considered “correct” for this purpose.

The Trey blog lists all the features available (or look in the source file: cua-base.el)

Note that indenting in Emacs is usually an unexpectedly tricky question .

+1
source

What I usually do is just type Cx Cx ( exchange-point-and-mark ) after the command that deactivates the area.

+1
source

You can do it something like this:

 (add-hook 'text-mode-hook (lambda () (set (make-local-variable 'indent-region-function) (lambda (se) (indent-rigidly se tab-width)))))
(add-hook 'text-mode-hook (lambda () (set (make-local-variable 'indent-region-function) (lambda (se) (indent-rigidly se tab-width))))) 

Then select the area and press TAB . the tab width will be indented. You can then exchange the point and elevation with Cx Cx and press TAB again to repeat.

However, I agree with the previous answers that suggest directly using indent-rigidly .

+1
source

Source: https://habr.com/ru/post/1316111/


All Articles