Stop abbrev from expanding on newline

I have always I wanted to fix a particular behavior with abbrev expansion: by default abbrev will skip newlines when looking for a word to expand. Let me illustrate. I had an abbrev, "args", that expanded into "arguments". If I typed in the docstring below where the carrot is, the symbol "args" in the previous line would expand into "arguments".

;; The cursor would be on the ^ symbol would cause args to expand to
;; `arguments'.
(defun foo (a b &rest args)
  "^")

Curiously, this would even get around oo-use-text-abbrev-p which I use as the :enable-function property because point is still in a string even though the symbol args is outside of it. In practice this means that there could be 10 newlines between your cursor and the previous abbrev and it would still be expanded. This is not what I want. Such expansions cause me unexpected and more often than not undesired abbrev expansions.

;; The cursor would be on the ^ symbol would cause args to expand to
;; `arguments'.
(defun foo (a b &rest args)



  "^")

To find the root of the problem I looked inside expand-abbrev and then the abbrev-expand-function, which was set to abbrev–default-expand, until finally I found the culprit, abbrev–before-point. The body of abbrev--before-point is long but the only part that concerns this problem is the following chunk.

(let ((re (abbrev-table-get table :regexp)))
  (if (null re)
      ;; We used to default `re' to "\\<\\(\\w+\\)\\W*"
      ;; but when words-include-escapes is set, that
      ;; is not right and fixing it is boring.
      (let ((lim (point)))
        (backward-word 1)
        (setq start (point))
        (forward-word 1)
        (setq end (min (point) lim)))
    (when (looking-back re (line-beginning-position))
      (setq start (match-beginning 1))
      (setq end   (match-end 1)))))

If the abbrev table has no :regexp property (the default) it uses backward-word to find the previous expansion. Therein lies the problem. The function backward-word finds the last word regardless of how many lines it is behind point. It has no boundaries. However, as is apparent from the call to looking-back in (looking-back re (line-beginning-position)), using any regexp will automatically bound the search to the beginning of the current line1

In any case, this suggests that what I need to do is provide a regexp and it will automatically be bounded. Conveniently the comment in the code provides a good regexp to go by2.

And voilĂ .

(abbrev-table-put global-abbrev-table :regexp "\\<\\(\\sw+\\)\\Sw*")

Footnotes:

1

I do not know if this was intentional. If you bound looking-back why not bound backward-word?

2

Sure, I know it mentions words-include-escapes but to be honest I do not really care about that. I have words-include-escapes set to nil have do not plan on enabling it any time soon.