Function: forward-comment
forward-comment is a function defined in syntax.c.
Signature
(forward-comment COUNT)
Documentation
Move forward across up to COUNT comments. If COUNT is negative, move backward.
Stop scanning if we find something other than a comment or whitespace. Set point to where scanning stops. If COUNT comments are found as expected, with nothing except whitespace between them, return t; otherwise return nil.
Probably introduced at or before Emacs version 27.1.
Aliases
Source Code
// Defined in /usr/src/emacs/src/syntax.c
// Skipping highlighting due to helpful-max-highlight.
{
ptrdiff_t from, from_byte, stop;
int c, c1;
enum syntaxcode code;
int comstyle = 0; /* style of comment encountered */
bool comnested = 0; /* whether the comment is nestable or not */
bool found;
EMACS_INT count1;
ptrdiff_t out_charpos, out_bytepos;
EMACS_INT dummy;
int dummy2;
unsigned short int quit_count = 0;
CHECK_FIXNUM (count);
count1 = XFIXNUM (count);
stop = count1 > 0 ? ZV : BEGV;
from = PT;
from_byte = PT_BYTE;
SETUP_SYNTAX_TABLE (from, clip_to_bounds (PTRDIFF_MIN, count1, PTRDIFF_MAX));
while (count1 > 0)
{
do
{
bool comstart_first;
int syntax, other_syntax;
if (from == stop)
{
SET_PT_BOTH (from, from_byte);
return Qnil;
}
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
syntax = SYNTAX_WITH_FLAGS (c);
code = SYNTAX (c);
comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax);
comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax);
comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0);
inc_both (&from, &from_byte);
UPDATE_SYNTAX_TABLE_FORWARD (from);
if (from < stop && comstart_first
&& (c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte),
other_syntax = SYNTAX_WITH_FLAGS (c1),
SYNTAX_FLAGS_COMSTART_SECOND (other_syntax)))
{
/* We have encountered a comment start sequence and we
are ignoring all text inside comments. We must record
the comment style this sequence begins so that later,
only a comment end of the same style actually ends
the comment section. */
code = Scomment;
comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax);
comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax);
inc_both (&from, &from_byte);
UPDATE_SYNTAX_TABLE_FORWARD (from);
}
rarely_quit (++quit_count);
}
while (code == Swhitespace || (code == Sendcomment && c == '\n'));
if (code == Scomment_fence)
comstyle = ST_COMMENT_STYLE;
else if (code != Scomment)
{
dec_both (&from, &from_byte);
SET_PT_BOTH (from, from_byte);
return Qnil;
}
/* We're at the start of a comment. */
found = forw_comment (from, from_byte, stop, comnested, comstyle, 0,
&out_charpos, &out_bytepos, &dummy, &dummy2);
from = out_charpos; from_byte = out_bytepos;
if (!found)
{
SET_PT_BOTH (from, from_byte);
return Qnil;
}
inc_both (&from, &from_byte);
UPDATE_SYNTAX_TABLE_FORWARD (from);
/* We have skipped one comment. */
count1--;
}
while (count1 < 0)
{
while (true)
{
if (from <= stop)
{
SET_PT_BOTH (BEGV, BEGV_BYTE);
return Qnil;
}
dec_both (&from, &from_byte);
/* char_quoted does UPDATE_SYNTAX_TABLE_BACKWARD (from). */
bool quoted = char_quoted (from, from_byte);
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
int syntax = SYNTAX_WITH_FLAGS (c);
code = SYNTAX (c);
comstyle = 0;
comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax);
if (code == Sendcomment)
comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0);
if (from > stop && SYNTAX_FLAGS_COMEND_SECOND (syntax)
&& prev_char_comend_first (from, from_byte)
&& !char_quoted (from - 1, dec_bytepos (from_byte)))
{
int other_syntax;
/* We must record the comment style encountered so that
later, we can match only the proper comment begin
sequence of the same style. */
dec_both (&from, &from_byte);
code = Sendcomment;
/* Calling char_quoted, above, set up global syntax position
at the new value of FROM. */
c1 = FETCH_CHAR_AS_MULTIBYTE (from_byte);
other_syntax = SYNTAX_WITH_FLAGS (c1);
comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax);
comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax);
}
if (code == Scomment_fence)
{
/* Skip until first preceding unquoted comment_fence. */
bool fence_found = 0;
ptrdiff_t ini = from, ini_byte = from_byte;
if (from > stop)
{
while (1)
{
dec_both (&from, &from_byte);
UPDATE_SYNTAX_TABLE_BACKWARD (from);
c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
if (SYNTAX (c) == Scomment_fence
&& !char_quoted (from, from_byte))
{
fence_found = 1;
break;
}
else if (from == stop)
break;
rarely_quit (++quit_count);
}
}
if (fence_found == 0)
{
from = ini; /* Set point to ini + 1. */
from_byte = ini_byte;
goto leave;
}
else
/* We have skipped one comment. */
break;
}
else if (code == Sendcomment)
{
found = (!quoted || !comment_end_can_be_escaped)
&& back_comment (from, from_byte, stop, comnested, comstyle,
&out_charpos, &out_bytepos);
if (!found)
{
if (c == '\n')
/* This end-of-line is not an end-of-comment.
Treat it like a whitespace.
CC-mode (and maybe others) relies on this behavior. */
;
else
{
/* Failure: we should go back to the end of this
not-quite-endcomment. */
if (SYNTAX (c) != code)
/* It was a two-char Sendcomment. */
inc_both (&from, &from_byte);
goto leave;
}
}
else
{
/* We have skipped one comment. */
from = out_charpos, from_byte = out_bytepos;
break;
}
}
else if (code != Swhitespace || quoted)
{
leave:
inc_both (&from, &from_byte);
SET_PT_BOTH (from, from_byte);
return Qnil;
}
rarely_quit (++quit_count);
}
count1++;
}
SET_PT_BOTH (from, from_byte);
return Qt;
}