33; ; This file is part of Proof General.
44
55; ; Portions © Copyright 1994-2012 David Aspinall and University of Edinburgh
6- ; ; Portions © Copyright 2003-2021 Free Software Foundation, Inc.
6+ ; ; Portions © Copyright 2003-2021, 2023 Free Software Foundation, Inc.
77; ; Portions © Copyright 2001-2017 Pierre Courtieu
88; ; Portions © Copyright 2010, 2016 Erik Martin-Dorel
99; ; Portions © Copyright 2011-2013, 2016-2017 Hendrik Tews
3737(defconst coq-comment-start-or-end-regexp
3838 (concat coq-comment-start-regexp " \\ |" coq-comment-end-regexp))
3939
40- (defconst coq-bullet-regexp-nospace " \\ (-\\ )+\\ |\\ (+\\ )+\\ |\\ (\\ *\\ )+"
40+ (defconst coq-bullet-regexp-nospace " \\ (-\\ )+\\ |\\ (\\ +\\ )+\\ |\\ (\\ *\\ )+"
4141 " Matches single bullet, WARNING: Lots of false positive.
4242
4343No context checking." )
@@ -53,9 +53,9 @@ No context checking.")
5353; ; use of the fact that the file is processed from top to bottom. At
5454; ; each step the point is put just after the last recognized chunk,
5555; ; then spaces are jumped, and THEN the regexp for command end is
56- ; ; searched. Since bullets are are command ends occurring at command
56+ ; ; searched. Since bullets are command ends occurring at command
5757; ; start, we use the "\\= " regexp to tell if we are at the beginning
58- ; ; of a command. We don't car for the presence of comments, as the
58+ ; ; of a command. We don't care for the presence of comments, as the
5959; ; regexp search is launched once coments are passed.
6060; ; On the contrary when going backward we cannot use this trick.
6161
@@ -96,9 +96,11 @@ There are 3 substrings (2 and 3 may be nil):
9696* number 2 is the left context matched that is not part of the bullet
9797* number 3 is the right context matched that is not part of the bullet" )
9898
99- ; ; captures a lot of false bullets, unless called at the first non
100- ; ; space character of a command. The primary use of this variable is
101- ; ; to split the buffer into commands, from top to bottom.
99+ ; ; captures a lot of false bullets, unless called at the first non space character
100+ ; ; of a command. The primary use of this variable is to split the buffer into
101+ ; ; commands, from top to bottom. We use the \= regexp for the special case where we
102+ ; ; match the regexp at the very starting point (in which case we don't look at what
103+ ; ; is before the main regexp)
102104(defconst coq-bullet-end-command-forward
103105 (concat " \\ (?:\\= \\ (?1:" coq-bullet-regexp-nospace " \\ )\\ )" )
104106 " Matches ltac bullets. WARNING: lots of false positive.
@@ -110,7 +112,7 @@ only when searching backward).")
110112
111113; ; Context aware detecting regexp, usefull when search backward.
112114(defconst coq-bullet-end-command-backward
113- (concat " \\ (?:\\ (?2:" coq-bullet-prefix-regexp-backward " \\ )\\ (?1:\\ (-\\ )+\\ |\\ (+\\ )+\\ |\\ (\\ *\\ )+\\ )\\ )" )
115+ (concat " \\ (?:\\ (?2:" coq-bullet-prefix-regexp-backward " \\ )\\ (?1:\\ (-\\ )+\\ |\\ (\\ +\\ )+\\ |\\ (\\ *\\ )+\\ )\\ )" )
114116 " Matches ltac bullets when searching backward.
115117
116118This should match EXACTLY bullets. No false positive should be accepted.
@@ -122,7 +124,7 @@ There are 2 substrings:
122124 (concat
123125 " \\ (?:"
124126 " \\ (?2:"
125- " \\ (?:" coq-bullet-prefix-regexp-forward" \\ )\\ )"
127+ " \\ (?:" coq-bullet-prefix-regexp-forward " \\ )\\ )"
126128 " \\ (?1:\\ (?:" coq-goal-selector-regexp " \\ )?{\\ )"
127129 " \\ (?3:\\ s-*[^|{]\\ )"
128130 " \\ |"
@@ -191,7 +193,6 @@ There are 3 substrings (2 and 3 may be nil):
191193Remark: This regexp is much more precise than `coq-end-command-regexp-forward'
192194but only works when searching backward." )
193195
194- (defconst coq-cmd-end-backward-matcher (concat " \\ (?2:" coq-simple-cmd-ender-prefix-regexp-backward " \\ )\\ .\\ s-" ))
195196
196197(defun coq-looking-at-comment ()
197198 " Return non-nil if point is inside a comment."
@@ -345,9 +346,12 @@ a comment, return nil and does not move the point."
345346; ; )))
346347; ; (when found (point))))
347348
348- ; ; check if we are in the middle of an command ender. Return the
349- ; ; number of shift needed to have to move one char to see the end of a
350- ; ; command. typically if we are ( >< is the cursor). intro.><
349+ ; ; check if we are in the middle of an command ender. Return the number of left
350+ ; ; shifts needed to move to see the whole command ender a command. typically if we
351+ ; ; are ( >< is the cursor):
352+ ; ; intro.><, then we return 1
353+ ; ; intro><., then we return 0
354+ ; ; int><ro., then we return 0
351355(defun coq-is-on-ending-context ()
352356 (cond
353357 ((looking-at " }" ) 0 )
@@ -388,6 +392,32 @@ Comments are ignored, of course."
388392 ))
389393
390394
395+ ; ; Strictly speaking lp:{{ could be a goal selector?
396+ (defun coq-is-at-elpi-block (pos )
397+ (save-excursion (goto-char pos) (and (looking-at " {{" ) (looking-back " lp:" ))))
398+
399+ (defun coq-in-elpi-block (lopen )
400+ (cl-find-if 'coq-is-at-elpi-block lopen))
401+
402+ (defun coq-confirm-cmdend (&optional pos )
403+ " Return t if POS is really a Rocq command end.
404+
405+ WARNING: POS should be looking at a command that matched command end
406+ regexp. This function only checks if it is not a false positive, like
407+ something like a bullet (-,+,*) but actually not at the beginning of a
408+ command, or a regular command end but located in a comment or inside an
409+ elpi block."
410+ (save-excursion
411+ (if pos (goto-char pos))
412+ (let ((ppss (syntax-ppss )))
413+ (cond
414+ ((nth 3 ppss) nil ) ; ; inside a string
415+ ((nth 4 ppss) nil ) ; ; inside a comment
416+ ((coq-in-elpi-block (nth 9 ppss)) nil )
417+ ((looking-at " \\ +\\ |\\ *\\ |-\\ |{\\ |}" ) (coq-empty-command-p))
418+ (t )))))
419+
420+
391421; slight modification of proof-script-generic-parse-cmdend (one of the
392422; candidate for proof-script-parse-function), to allow "{" and "}" to
393423; be command terminator when the command is empty. This function is
@@ -411,36 +441,15 @@ regexp."
411441 (and
412442 (re-search-forward coq-end-command-regexp-forward limit t )
413443 (match-end 1 )))
414- (or
415- (and (not (or (string-equal (match-string 1 ) " ." )
416- (string-equal (match-string 1 ) " ..." )))
417- ; ; Checking that this is really a bullet
418- ; ; command-end that are not a dot are + ++ -
419- ; ; -- etc or { or }. To ensure this is really
420- ; ; a bullet (and not one of the numerous
421- ; ; other possible uses of those tokens) we
422- ; ; check that the command ended by it is
423- ; ; empty. example:
424- ; ; destruct x.
425- ; ; - (* - here ends an empty command*)
426- (save-excursion
427- (goto-char (match-beginning 1 ))
428- (not (coq-empty-command-p))))
429- (and
430- (goto-char foundend)
431- (nth 8 (syntax-ppss )))))
444+ (not (coq-confirm-cmdend (match-beginning 1 ))))
432445 ; ; Given the form of coq-end-command-regexp-forward
433446 ; ; match-end 1 is the right place to start again
434447 ; ; to search backward, next time we start from just
435448 ; ; there
436449 (ignore-errors (goto-char foundend)))
437- (if (and foundend
438- (goto-char foundend) ; move to command end
439- (not (nth 8 (syntax-ppss ))))
440- ; ; Found command end outside string/comment
441- 'cmd
442- ; ; Didn't find command end
443- nil ))))
450+ (if (not foundend) nil
451+ (goto-char foundend)
452+ 'cmd ))))
444453
445454
446455; ; This is not used by generic pg, just by a few functions in here.
@@ -464,31 +473,11 @@ and return nil."
464473 (and
465474 (re-search-backward coq-end-command-regexp-backward limit 'dummy )
466475 (match-beginning 1 )))
467- ; ; Given the form of coq-end-command-regexp-backward
468- ; ; - bullets should be correctly detected
469- ; ; - match-beginning 1 is the right place to start again
470- ; ; to search backward, next time we start from just
471- ; ; there, unless we are in a comment
472- (goto-char foundbeg)
473- (let ((ppss (syntax-ppss )))
474- ; ; If neither within a string nor a comment, just exit the
475- ; ; loop. Otherwise see what kind of syntactic
476- (and (nth 8 ppss)
477- (cond
478- ; ; jump directly out of a comment
479- ((nth 4 ppss)
480- (setq foundbeg (goto-char (nth 8 ppss))))
481- ((nth 3 ppss) t ) ; FIXME: Why?
482- ; ; nil captured before entering the cond
483- (t (message " assert false " ))))))
476+ (not (coq-confirm-cmdend (match-beginning 1 ))))
484477 (ignore-errors (goto-char foundbeg)))
485- (if (and foundbeg
486- (goto-char foundbeg) ; move to command end
487- (not (nth 8 (syntax-ppss ))))
488- ; ; Found command end outside string/comment
489- 'cmd
490- ; ; Didn't find command end
491- nil ))))
478+ (if (not foundbeg) nil
479+ (goto-char foundbeg)
480+ 'cmd ))))
492481
493482
494483(defun coq-find-current-start ()
0 commit comments