0

I'm trying to get Emacs to insert a line break at the end of each sentence as I type. (Why? Makes for easier version control of tex files.)

Looking around I found a few places with some suggestions for how to do something similar.

  • This question's answers are mostly suggestions for how to take a document and insert line breaks after each sentence after the fact.
  • This question is asking for a slightly different feature, viz. having Emacs insert two spaces after each sentence.

In an answer to the second question, abo-abo suggests something like this:

(defun electric-space ()
  (interactive)
  (if (looking-back "\\w\\.")
      (insert " "))
  (self-insert-command 1))

(defvar electric-space-on-p nil)

(defun toggle-electric-space ()
  (interactive)
  (global-set-key
   " "
   (if (setq electric-space-on-p
             (not electric-space-on-p))
       'electric-space
     'self-insert-command)))

A small change to this almost allows me to do what I want: replace insert " " with insert "%\n". One downside of this is that the point always ends up on the second column of the following line. Thus, this is what results if I call toggle-electric-space:

Hello world. %
 This is another line.

Is there an obvious way around this?

Another problem with this approach is that there are cases where . does not come at the end of a sentence (though that's easy to fix by writing, e.g. p.~23 instead of p. 23, which is good practice anyway) as well as cases where a sentence ends with something other than a period (?, !, .), etc.).

Now, it seems to me that these problems should be easy to get around in Emacs, since we have something like forward-sentence around, which is smart enough as far as I can tell to recognize that (This sentence.) ends after the closing parenthesis. But I don't know how to make use of forward-sentence in combination with the definition of electric-space above.

This package manages to do something similar to what I want. The difference is that it makes . electric, so it requires explicitly listing all the possible exceptions, i.e. all cases where a period does not end a new line. And in order to allow for sentences that do not end with a period, the package makes ? and ! electric, but I see no easy way of allowing for .) and ?), etc., to be recognized as ending sentences.

I suppose adding a condition like if (looking-back ".") in making the closing parenthesis electric might work... I'll need to study that package more careful and see how I could modify it to suit my purposes. But being effectively a lisp illiterate, I'd appreciate any pointers you may have.

Update

The way to implement abo-abo's suggestion should instead be this:

(defun electric-space () ; Trying to get Emacs to do semantic linefeeds
  (interactive)
  (if (looking-back (sentence-end))
      (insert " %\n")
       (self-insert-command 1))
       )

(defvar electric-space-on-p nil)

(defun toggle-electric-space ()
  (interactive)
  (global-set-key
   " "
   (if (setq electric-space-on-p
             (not electric-space-on-p))
       'electric-space
     'self-insert-command)))

I don't know if there's a more elegant way to do this, but for now it seems to work.

  • Docstring of function sentence-end: The default value specifies that in order to be recognized as the end of a sentence, the ending period, question mark, or exclamation point must be followed by two spaces, with perhaps some closing delimiters in between. – JeanPierre Nov 15 '19 at 18:29
  • But this can be overridden, I believe, setting sentence-end-double-space to nil, no? – apc Nov 15 '19 at 18:30
  • It seems, yes. Something like (looking-back (sentence-end)) should tell if point it at end of sentence. However, it seems to return t as soon as last char is a .. – JeanPierre Nov 15 '19 at 18:44
  • Instead of electric, you could add to post-self-insert-hook a function that tests if point is at end of sentence and inserts a newline if so. – JeanPierre Nov 15 '19 at 18:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.