1

EDIT: The issue wasn't related to whitespace, rather it was my lack of understanding of how region selection works. The selected answer answers the question clearly.

I'm basically looking for the same behavior as V in VIM so that I can visually select code/text. C-<spc> seems to be the answer for this. However, if I try to do this with some blocks of code it does not work as expected.

Example. Consider the simple function below.

def thingy():
  return 1

If the "point" or "cursor" is on the beginning of the 1st line and you type C-<spc> C-n C-n you will highlight both lines. However, if you try to do the same thing but start on line 2 and go C-<spc> C-p it will only highlight the 1st line and will skip the 2nd line - the one that we started on.

As far as I understand this is due to the whitespace that preceeds return 1.

So what is the recommended way around this?

I know I could try C-<spc> C-e C-n but this also doesn't work since the highlighed line also skips the current line (line 2).

To me it seems as though this would be solved if I knew how to highlight the line that my "point" is on without having to move to either the start or end of the line and then use C-<spc>. Then I could C-n or C-p and still include the line I started on. But C-<spc> doesn't seem to do this unfortunately.

1 Answer 1

2

Things work a bit differently in Emacs. Selections are always defined by the mark, and the current position of the point (i.e. the cursor). You can't select a line explicitly, you select the region between point and mark, and if point and mark are at the beginning/end of lines, you select those lines.

C-<spc> runs the command set-mark-command, which activates the regions making it visible on the display (highlighting).

If you start here:

def thingy():
| return 1

with point at the |, and press C-<spc> C-p, you will get the following:

|def thingy():
| return 1

where everything between the two | symbols is selected. That doesn't include the second line, because it is after the mark.

In other words, the boundaries of your selection are set by individual characters, not whole lines.

To me it seems as though this would be solved if I knew how to highlight the line that my "point" is on without having to move to either the start or end of the line and then use C-<spc>.

That's not how selection works in Emacs, so it's a bit awkward to translate. To accomplish what you want, you need to set the mark at the end of the current line. You can do this with a bit of elisp in your .init file:

(defun grab-eol ()
  (interactive)
  (set-mark (point-at-eol)))

(global-set-key (kbd "C-c SPC") 'grab-eol)

This creates a new keybinding, C-c <SPC>, that you would use when highlighting from the current line backwards. From the first example, when you enter C-c <SPC> C-p, you'll get this:

|def thingy():
  return 1|
  • mark is set at the end of the second line, and you select everything on the first line when you move up with C-p.

This won't do what you want when you move forwards, as it would then effectively skip the first line by setting mark at the end of that line. That's why I created a new keybinding, so you can continue to use C-<SPC> when you want to select forwards.

With a little more involved elisp, you could create a function to do exactly (or very nearly) what you are after, both forwards and backwards. You might want to play around with the usual Emacs approach first though. After a while, C-a and C-e become reflexes, as you use them so often, and it might not be necessary to rewire this behaviour.

1
  • Thanks! That's a very helpful and informative answer. Your suggested keybinding does solve the problem but I will try to do it "Emacs way" as you also recommend.
    – grefl
    Commented Mar 28, 2023 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.