GNU bug report logs - #64739
(forward-thing 'number) doesn't work with decimal numbers

Previous Next

Package: emacs;

Reported by: Joseph Turner <joseph <at> breatheoutbreathe.in>

Date: Thu, 20 Jul 2023 06:27:01 UTC

Severity: normal

Merged with 74662

Found in version 29.4

Full log


View this message in rfc822 format

From: Joseph Turner <joseph <at> breatheoutbreathe.in>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 64739 <at> debbugs.gnu.org, winkler <at> gnu.org
Subject: bug#64739: (forward-thing 'number) doesn't work with decimal numbers
Date: Sun, 23 Jul 2023 12:03:50 -0700
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Joseph Turner <joseph <at> breatheoutbreathe.in>
>> Cc: Roland Winkler <winkler <at> gnu.org>, 64739 <at> debbugs.gnu.org
>> Date: Sat, 22 Jul 2023 20:36:16 -0700
>>
>> > By "its own function" I meant that we implement it in Emacs, not that
>> > you implement it in your personal customizations.
>>
>> I see that the definition of number-at-point includes two magic regexps,
>> one matching hex numbers and another matching decimal numbers. Would it
>> make sense to move those regexps into defconsts, and then create a new
>> function forward-number which uses those new constants?
>
> That's probably one idea, yes.  (But note that those regexps don't
> support numbers like "1.0e2".)

I agree that the regexp solution is not ideal.

> Another idea is to define a special-purpose syntax table and use that
> with forward-word.

Did you have something like this in mind?

(defvar number-syntax-table
  (let ((st (make-syntax-table)))
    (modify-syntax-entry ?. "w " st)
    ;; ?- and ?+ could indicate the sign at the beginning of a number or
    ;; they could indicate the sign of an exponent like 1.5e-6
    (modify-syntax-entry ?- "w " st)
    (modify-syntax-entry ?+ "w " st)
    ;; ?# acts as a prefix for integers in bases other than 10.
    (modify-syntax-entry ?# "w " st)
    st)
  "Syntax table used to detect word boundaries for numbers.")

(defun forward-number (&optional n)
  (interactive)
  (with-syntax-table number-syntax-table
    (forward-word-strictly n)))

(defun backward-number (&optional n)
  (interactive)
  (with-syntax-table number-syntax-table
    (forward-word-strictly n)))

;; We don't need the following two lines, since forward-thing uses
;; intern-soft to get these function names anyway.

(put 'number 'forward-op 'forward-number)
(put 'number 'beginning-op 'backward-number)

What would we use for end-op? Is it necessary?

Also I notice that the current implementation of number-at-point fails
to recognize the following as a single number:

-1.5e+6

Could we do something like:

(defun number-at-point (&optional no-properties)
  (with-syntax-table number-syntax-table
    (word-at-point no-properties)))

(put 'number 'thing-at-point 'number-at-point)

I'd appreciate feedback on the syntax table above. It incorrectly
recognizes some non-number strings as numbers:

a-a+a-
#abc#abc

> Yet another idea is to use 'read', since the Lisp reader already knows
> how to read numbers.

Sounds interesting! I'm not sure how to approach a solution like that.
How would you let the Lisp reader know where to start and stop reading?

Joseph




This bug report was last modified 110 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.