From: fabrice nicol <fabrnicol@gmail.com>
To: 47408@debbugs.gnu.org
Subject: bug#47408: Etags support for Mercury [v0.3]
Date: Sat, 27 Mar 2021 11:51:22 +0100 [thread overview]
Message-ID: <5ba2fec3-3f61-fb7e-35eb-7188fa6064a4@gmail.com> (raw)
In-Reply-To: <ccb782a9-e9bf-67f8-ebef-a03bdd83f75d@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 445 bytes --]
Hi,
I'm sending a new patch for this Mercury feature request.
The attached patch fixes a previously unnoticed regression that affects
Objective C parsing (Mercury and Objective C have same file extensions .m).
I had to resort to an added heuristics (implemented in
`test_objc_is_mercury') to disambiguate Mercury from Objective C source
files with extension .m.
The patch is cumulative and replaces the former one.
Best,
Fabrice Nicol
[-- Attachment #2: 0001-Fixed-regressions-caused-by-Objc-Mercury-ambiguous-f.patch --]
[-- Type: text/x-patch, Size: 20603 bytes --]
From 50f3f9a0d46d11d0ac096f79f0d5aa1bc17b7920 Mon Sep 17 00:00:00 2001
From: Fabrice Nicol <fabrnicol@gmail.com>
Date: Sat, 27 Mar 2021 10:16:44 +0100
Subject: [PATCH] Fixed regressions caused by Objc/Mercury ambiguous file
extension .m.
---
doc/man/etags.1 | 25 ++-
etc/NEWS | 9 +
lib-src/etags.c | 444 ++++++++++++++++++++++++++++++++++++++++++++---
lisp/speedbar.el | 2 +
4 files changed, 455 insertions(+), 25 deletions(-)
diff --git a/doc/man/etags.1 b/doc/man/etags.1
index c5c15fb182..903e38a145 100644
--- a/doc/man/etags.1
+++ b/doc/man/etags.1
@@ -1,5 +1,5 @@
.\" See section COPYING for copyright and redistribution information.
-.TH ETAGS 1 "2019-06-24" "GNU Tools" "GNU"
+.TH ETAGS 1 "2021-03-25" "GNU Tools" "GNU"
.de BP
.sp
.ti -.2i
@@ -50,9 +50,9 @@ format understood by
.BR vi ( 1 )\c
\&. Both forms of the program understand
the syntax of C, Objective C, C++, Java, Fortran, Ada, Cobol, Erlang,
-Forth, Go, HTML, LaTeX, Emacs Lisp/Common Lisp, Lua, Makefile, Pascal, Perl,
-Ruby, PHP, PostScript, Python, Prolog, Scheme and
-most assembler\-like syntaxes.
+Forth, Go, HTML, LaTeX, Emacs Lisp/Common Lisp, Lua, Makefile, Mercury, Pascal,
+Perl, Ruby, PHP, PostScript, Python, Prolog, Scheme and most assembler\-like
+syntaxes.
Both forms read the files specified on the command line, and write a tag
table (defaults: \fBTAGS\fP for \fBetags\fP, \fBtags\fP for
\fBctags\fP) in the current working directory.
@@ -270,6 +270,23 @@ prints detailed information about how tags are created for LANG.
.B \-V, \-\-version
Print the current version of the program (same as the version of the
emacs \fBetags\fP is shipped with).
+.TP
+.B \-, \-\-version
+Print the current version of the program (same as the version of the
+emacs \fBetags\fP is shipped with).
+.TP
+.B \-M, \-\-no\-defines
+For the Mercury programming language, tag both declarations and
+definitions. Declarations start a line with \fI:\-\fP optionally followed by a
+quantifier over a variable (\fIsome [T]\fP or \fIall [T]\fP), then by
+a builtin operator like \fIpred\fP or \fIfunc\fP.
+Definitions are first rules of clauses, as in Prolog.
+Implies \-\-language=mercury.
+.TP
+.B \-m, \-\-declarations
+For the Mercury programming language, tag declarations as with \fB\-M\fP, but do not
+tag definitions. Implies \-\-language=mercury.
+
.SH "SEE ALSO"
"\|\fBemacs\fP\|" entry in \fBinfo\fP; \fIGNU Emacs Manual\fP, Richard
diff --git a/etc/NEWS b/etc/NEWS
index 68812c64cc..4af4e76371 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -93,6 +93,15 @@ useful on systems such as FreeBSD which ships only with "etc/termcap".
\f
* Changes in Emacs 28.1
+---
+** Etags support for the Mercury programming language (https://mercurylang.org).
+** New etags command line options '-M/-m' or --declarations/--no-defines'.
+Tags all Mercury declarations. For compatibility with Prolog etags support,
+predicates and functions appearing first in clauses will be tagged if etags is
+run with the option '-M' or '--declarations'. If run with '-m' or
+'--no-defines', declarations will be tagged but definitions will not.
+Both options imply --language=mercury.
+
+++
** New command 'font-lock-update', bound to 'C-x x f'.
This command updates the syntax highlighting in this buffer.
diff --git a/lib-src/etags.c b/lib-src/etags.c
index b5c18e0e01..53e04794dd 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -142,7 +142,13 @@ Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2021 Free Software
# define CTAGS false
#endif
-/* Copy to DEST from SRC (containing LEN bytes), and append a NUL byte. */
+/* Define MERCURY_HEURISTICS_RATIO as it was necessary to disambiguate
+ Mercury from Objective C, which have same file extensions .m */
+#ifndef MERCURY_HEURISTICS_RATIO
+# define MERCURY_HEURISTICS_RATIO 0.02
+#endif
+
+/* COPY to DEST from SRC (containing LEN bytes), and append a NUL byte. */
static void
memcpyz (void *dest, void const *src, ptrdiff_t len)
{
@@ -359,6 +365,7 @@ #define xrnew(op, n, m) ((op) = xnrealloc (op, n, (m) * sizeof *(op)))
static void Lisp_functions (FILE *);
static void Lua_functions (FILE *);
static void Makefile_targets (FILE *);
+static void Mercury_functions (FILE *);
static void Pascal_functions (FILE *);
static void Perl_functions (FILE *);
static void PHP_functions (FILE *);
@@ -378,6 +385,7 @@ #define xrnew(op, n, m) ((op) = xnrealloc (op, n, (m) * sizeof *(op)))
static bool nocase_tail (const char *);
static void get_tag (char *, char **);
static void get_lispy_tag (char *);
+static void test_objc_is_mercury(char *, language **);
static void analyze_regex (char *);
static void free_regexps (void);
@@ -621,7 +629,6 @@ #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
"In Java code, all the tags constructs of C and C++ code are\n\
tagged. (Use --help --lang=c --lang=c++ --lang=java for full help.)";
-
static const char *Cobol_suffixes [] =
{ "COB", "cob", NULL };
static char Cobol_help [] =
@@ -683,10 +690,22 @@ #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
"In makefiles, targets are tags; additionally, variables are tags\n\
unless you specify '--no-globals'.";
+/* Mercury and Objective C share the same .m file extensions. */
+static const char *Mercury_suffixes [] =
+ {"m", /* Use option -l mercury to switch from Objective C to Mercury. */
+ NULL};
+static const char Mercury_help [] =
+ "In Mercury code, tags are all declarations beginning a line with :-\n\
+and optionally Prolog-like definitions (first rule for a predicate or \
+function).\n\
+To enable this behavior, run etags using -M or --declarations.";
+static bool with_mercury_definitions = false;
+double mercury_heuristics_ratio = MERCURY_HEURISTICS_RATIO;
+
static const char *Objc_suffixes [] =
- { "lm", /* Objective lex file */
- "m", /* Objective C file */
- NULL };
+ {"lm",
+ "m", /* By default, Objective C will be assumed. */
+ NULL};
static const char Objc_help [] =
"In Objective C code, tags include Objective C definitions for classes,\n\
class categories, methods and protocols. Tags for variables and\n\
@@ -773,7 +792,6 @@ #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
'TEXTAGS' to a colon-separated list like, for example,\n\
TEXTAGS=\"mycommand:myothercommand\".";
-
static const char *Texinfo_suffixes [] =
{ "texi", "texinfo", "txi", NULL };
static const char Texinfo_help [] =
@@ -824,7 +842,9 @@ #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
{ "lisp", Lisp_help, Lisp_functions, Lisp_suffixes },
{ "lua", Lua_help,Lua_functions,Lua_suffixes,NULL,Lua_interpreters},
{ "makefile", Makefile_help,Makefile_targets,NULL,Makefile_filenames},
+ /* objc listed before mercury as it is a better default for .m extensions. */
{ "objc", Objc_help, plain_C_entries, Objc_suffixes },
+ { "mercury", Mercury_help, Mercury_functions, Mercury_suffixes },
{ "pascal", Pascal_help, Pascal_functions, Pascal_suffixes },
{ "perl",Perl_help,Perl_functions,Perl_suffixes,NULL,Perl_interpreters},
{ "php", PHP_help, PHP_functions, PHP_suffixes },
@@ -1061,6 +1081,17 @@ print_help (argument *argbuffer)
which you like.");
}
+ puts ("-m, --declarations\n\
+ For the Mercury programming language, only tag declarations.\n\
+ Declarations start a line with :- \n\
+ Implies --language=mercury.");
+
+ puts ("-M, --no-defines\n\
+ For the Mercury programming language, include both declarations and\n\
+ definitions. Declarations start a line with :- while definitions\n\
+ are first rules for a given item, as for Prolog.\n\
+ Implies --language=mercury.");
+
puts ("-V, --version\n\
Print the version of the program.\n\
-h, --help\n\
@@ -1111,7 +1142,7 @@ main (int argc, char **argv)
/* When the optstring begins with a '-' getopt_long does not rearrange the
non-options arguments to be at the end, but leaves them alone. */
- optstring = concat ("-ac:Cf:Il:o:Qr:RSVhH",
+ optstring = concat ("-ac:Cf:Il:Mmo:Qr:RSVhHW",
(CTAGS) ? "BxdtTuvw" : "Di:",
"");
@@ -1202,9 +1233,20 @@ main (int argc, char **argv)
case 'Q':
class_qualify = 1;
break;
+ case 'M':
+ with_mercury_definitions = true; FALLTHROUGH;
+ case 'm':
+ {
+ language lang =
+ { "mercury", Mercury_help, Mercury_functions, Mercury_suffixes };
+
+ argbuffer[current_arg].lang = ⟨
+ argbuffer[current_arg].arg_type = at_language;
+ }
+ break;
/* Etags options */
- case 'D': constantypedefs = false; break;
+ case 'D': constantypedefs = false; break;
case 'i': included_files[nincluded_files++] = optarg; break;
/* Ctags options. */
@@ -1298,19 +1340,19 @@ main (int argc, char **argv)
analyze_regex (argbuffer[i].what);
break;
case at_filename:
- this_file = argbuffer[i].what;
- /* Input file named "-" means read file names from stdin
- (one per line) and use them. */
- if (streq (this_file, "-"))
- {
- if (parsing_stdin)
- fatal ("cannot parse standard input "
- "AND read file names from it");
- while (readline_internal (&filename_lb, stdin, "-") > 0)
- process_file_name (filename_lb.buffer, lang);
- }
- else
- process_file_name (this_file, lang);
+ this_file = argbuffer[i].what;
+ /* Input file named "-" means read file names from stdin
+ (one per line) and use them. */
+ if (streq (this_file, "-"))
+ {
+ if (parsing_stdin)
+ fatal ("cannot parse standard input "
+ "AND read file names from it");
+ while (readline_internal (&filename_lb, stdin, "-") > 0)
+ process_file_name (filename_lb.buffer, lang);
+ }
+ else
+ process_file_name (this_file, lang);
break;
case at_stdin:
this_file = argbuffer[i].what;
@@ -1775,6 +1817,11 @@ find_entries (FILE *inf)
if (parser == NULL)
{
lang = get_language_from_filename (curfdp->infname, true);
+
+ /* Disambiguate file names between Objc and Mercury */
+ if (lang != NULL && strcmp(lang->name, "objc") == 0)
+ test_objc_is_mercury(curfdp->infname, &lang);
+
if (lang != NULL && lang->function != NULL)
{
curfdp->lang = lang;
@@ -6019,6 +6066,361 @@ prolog_atom (char *s, size_t pos)
return 0;
}
+\f
+/*
+ * Support for Mercury
+ *
+ * Assumes that the declarationa starts at column 0.
+ * Original code by Sunichirou Sugou (1989) for Prolog.
+ * Rewritten by Anders Lindgren (1996) for Prolog.
+ * Adapted by Fabrice Nicol (2021) for Mercury.
+ * Note: Prolog-support behavior is preserved if
+ * -M/--declarations is used, corresponding to
+ * with_mercury_definitions=true.
+ */
+
+static ptrdiff_t mercury_pr (char *, char *, ptrdiff_t);
+static void mercury_skip_comment (linebuffer *, FILE *);
+static bool is_mercury_type = false;
+static bool is_mercury_quantifier = false;
+static bool is_mercury_declaration = false;
+
+/* To robustly disambiguate between Objective C and Mercury, parse file
+ with the following heuristics hook:
+ (number of occurrences of non-blank, non-fully-commented lines
+ comprising ':-' at the start of line)/ number of lines > mercury_heuristics_ratio */
+
+static void test_objc_is_mercury(char *this_file, language **lang)
+{
+ if (this_file == NULL) return;
+ FILE* fp = fopen(this_file, "r");
+ if (fp == NULL) return;
+ int c;
+ uint64_t lines = 1;
+ uint64_t mercury_decls = 0;
+ bool blank_line = false;
+ bool start_of_line = true;
+
+ while ((c = fgetc(fp)) != EOF)
+ {
+ switch (c)
+ {
+ case '\n':
+ if (! blank_line) ++lines;
+ blank_line = true;
+ start_of_line = true;
+ break;
+ case '%': FALLTHROUGH;
+ case ' ': FALLTHROUGH;
+ case '\t':
+ start_of_line = false;
+ break;
+ case ':':
+ if (! start_of_line) break;
+ start_of_line = false;
+ c = fgetc(fp);
+ if (c == '-') ++mercury_decls;
+ break;
+ default:
+ start_of_line = false;
+ blank_line = false;
+ }
+ }
+
+ double ratio = 0;
+ ratio = ((double) mercury_decls ) / lines;
+ if (ratio > mercury_heuristics_ratio)
+ {
+ /* Change the language from Objective C to Mercury */
+ static language lang0 = { "mercury", Mercury_help, Mercury_functions,
+ Mercury_suffixes };
+ *lang = &lang0;
+ }
+}
+
+static void
+Mercury_functions (FILE *inf)
+{
+ char *cp, *last = NULL;
+ ptrdiff_t lastlen = 0, allocated = 0;
+ if (declarations) with_mercury_definitions = true;
+
+ LOOP_ON_INPUT_LINES (inf, lb, cp)
+ {
+ if (cp[0] == '\0') /* Empty line */
+ continue;
+ else if (c_isspace (cp[0]) || cp[0] == '%')
+ /* a Prolog-type comment or anything other than a declaration */
+ continue;
+ else if (cp[0] == '/' && cp[1] == '*') /* Mercury C-type comment. */
+ mercury_skip_comment (&lb, inf);
+ else
+ {
+ is_mercury_declaration = (cp[0] == ':' && cp[1] == '-');
+
+ if (is_mercury_declaration
+ || with_mercury_definitions)
+ {
+ ptrdiff_t len = mercury_pr (cp, last, lastlen);
+ if (0 < len)
+ {
+ /* Store the declaration to avoid generating duplicate
+ tags later. */
+ if (allocated <= len)
+ {
+ xrnew (last, len + 1, 1);
+ allocated = len + 1;
+ }
+ memcpyz (last, cp, len);
+ lastlen = len;
+ }
+ }
+ }
+ }
+ free (last);
+}
+
+static void
+mercury_skip_comment (linebuffer *plb, FILE *inf)
+{
+ char *cp;
+
+ do
+ {
+ for (cp = plb->buffer; *cp != '\0'; ++cp)
+ if (cp[0] == '*' && cp[1] == '/')
+ return;
+ readline (plb, inf);
+ }
+ while (perhaps_more_input (inf));
+}
+
+/*
+ * A declaration is added if it matches:
+ * <beginning of line>:-<whitespace><Mercury Term><whitespace>(
+ * If with_mercury_definitions == true, we also add:
+ * <beginning of line><Mercury item><whitespace>(
+ * or <beginning of line><Mercury item><whitespace>:-
+ * As for Prolog support, different arities and types are not taken into
+ * consideration.
+ * Item is added to the tags database if it doesn't match the
+ * name of the previous declaration.
+ *
+ * Consume a Mercury declaration.
+ * Return the number of bytes consumed, or 0 if there was an error.
+ *
+ * A Mercury declaration must be one of:
+ * :- type
+ * :- solver type
+ * :- pred
+ * :- func
+ * :- inst
+ * :- mode
+ * :- typeclass
+ * :- instance
+ * :- pragma
+ * :- promise
+ * :- initialise
+ * :- finalise
+ * :- mutable
+ * :- module
+ * :- interface
+ * :- implementation
+ * :- import_module
+ * :- use_module
+ * :- include_module
+ * :- end_module
+ * followed on the same line by an alphanumeric sequence, starting with a lower
+ * case letter or by a single-quoted arbitrary string.
+ * Single quotes can escape themselves. Backslash quotes everything.
+ *
+ * Return the size of the name of the declaration or 0 if no header was found.
+ * As quantifiers may precede functions or predicates, we must list them too.
+ */
+
+static const char *Mercury_decl_tags[] = {"type", "solver type", "pred",
+ "func", "inst", "mode", "typeclass", "instance", "pragma", "promise",
+ "initialise", "finalise", "mutable", "module", "interface", "implementation",
+ "import_module", "use_module", "include_module", "end_module", "some", "all"};
+
+static size_t
+mercury_decl (char *s, size_t pos)
+{
+ if (s == NULL) return 0;
+
+ size_t origpos;
+ origpos = pos;
+
+ while (s + pos != NULL && (c_isalnum (s[pos]) || s[pos] == '_')) ++pos;
+
+ uint8_t decl_type_length = pos - origpos;
+ char buf[decl_type_length + 1];
+ memset(buf, 0, decl_type_length + 1);
+
+ /* Mercury declaration tags. Consume them, then check the declaration item
+ following :- is legitimate, then go on as in the prolog case. */
+
+ memcpy(buf, &s[origpos], decl_type_length);
+
+ bool found_decl_tag = false;
+
+ if (is_mercury_quantifier)
+ {
+ if (strcmp(buf, "pred") != 0 && strcmp(buf, "func") != 0) /* Bad syntax */
+ return 0;
+ is_mercury_quantifier = false; /* Beset to base value. */
+ found_decl_tag = true;
+ }
+ else
+ {
+ for (int j = 0; j < sizeof(Mercury_decl_tags)/sizeof(char*); ++j)
+ {
+ if (strcmp(buf, Mercury_decl_tags[j]) == 0)
+ {
+ found_decl_tag = true;
+ if (strcmp(buf, "type") == 0)
+ is_mercury_type = true;
+
+ if (strcmp(buf, "some") == 0
+ || strcmp(buf, "all") == 0) {
+ is_mercury_quantifier = true;
+ }
+
+ break; /* Found declaration tag of rank j. */
+ }
+ else
+ /* 'solver type' has a blank in the middle,
+ so this is the hard case */
+ if (strcmp(buf, "solver") == 0)
+ {
+ ++pos;
+ while (s + pos != NULL && (c_isalnum (s[pos]) || s[pos] == '_'))
+ ++pos;
+
+ decl_type_length = pos - origpos;
+ char buf2[decl_type_length + 1];
+ memset(buf2, 0, decl_type_length + 1);
+ memcpy(buf2, &s[origpos], decl_type_length);
+
+ if (strcmp(buf2, "solver type") == 0)
+ {
+ found_decl_tag = false;
+ break; /* Found declaration tag of rank j. */
+ }
+ }
+ }
+ }
+
+ /* If with_mercury_definitions == false
+ * this is a Mercury syntax error, ignoring... */
+
+ if (with_mercury_definitions)
+ {
+ if (found_decl_tag)
+ pos = skip_spaces (s + pos) - s; /* Skip len blanks again */
+ else
+ /* Prolog-like behavior
+ * we have parsed the predicate once, yet inappropriately
+ * so restarting again the parsing step */
+ pos = 0;
+ }
+ else
+ {
+ if (found_decl_tag)
+ pos = skip_spaces (s + pos) - s; /* Skip len blanks again */
+ else
+ return 0;
+ }
+
+ /* From now on it is the same as for Prolog except for module dots */
+
+ if (c_islower (s[pos]) || s[pos] == '_' )
+ {
+ /* The name is unquoted.
+ Do not confuse module dots with end-of-declaration dots. */
+
+ while (c_isalnum (s[pos])
+ || s[pos] == '_'
+ || (s[pos] == '.' /* A module dot */
+ && s + pos + 1 != NULL
+ && (c_isalnum (s[pos + 1]) || s[pos + 1] == '_')))
+ ++pos;
+
+ return pos - origpos;
+ }
+ else if (s[pos] == '\'')
+ {
+ ++pos;
+ for (;;)
+ {
+ if (s[pos] == '\'')
+ {
+ ++pos;
+ if (s[pos] != '\'')
+ break;
+ ++pos; /* A double quote */
+ }
+ else if (s[pos] == '\0') /* Multiline quoted atoms are ignored. */
+ return 0;
+ else if (s[pos] == '\\')
+ {
+ if (s[pos+1] == '\0')
+ return 0;
+ pos += 2;
+ }
+ else
+ ++pos;
+ }
+ return pos - origpos;
+ }
+ else if (is_mercury_quantifier && s[pos] == '[') /* :- some [T] pred/func */
+ {
+ for (++pos; s + pos != NULL && s[pos] != ']'; ++pos) {}
+ if (s + pos == NULL) return 0;
+ ++pos;
+ pos = skip_spaces (s + pos) - s;
+ return mercury_decl(s, pos) + pos - origpos;
+ }
+ else
+ return 0;
+}
+
+static ptrdiff_t
+mercury_pr (char *s, char *last, ptrdiff_t lastlen)
+{
+ size_t len0 = 0;
+ is_mercury_type = false;
+ is_mercury_quantifier = false;
+
+ if (is_mercury_declaration)
+ {
+ /* Skip len0 blanks only for declarations. */
+ len0 = skip_spaces (s + 2) - s;
+ }
+
+ size_t len = mercury_decl (s , len0);
+ if (len == 0) return 0;
+ len += len0;
+
+ if (( (s[len] == '.' /* This is a statement dot, not a module dot. */
+ || (s[len] == '(' && (len += 1))
+ || (s[len] == ':' /* Stopping in case of a rule. */
+ && s[len + 1] == '-'
+ && (len += 2)))
+ && (lastlen != len || memcmp (s, last, len) != 0)
+ )
+ /* Types are often declared on several lines so keeping just
+ the first line */
+ || is_mercury_type
+ )
+ {
+ make_tag (s, 0, true, s, len, lineno, linecharno);
+ return len;
+ }
+
+ return 0;
+}
+
\f
/*
* Support for Erlang
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index 12e57b1108..63f3cd6ca1 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -3534,6 +3534,8 @@ speedbar-fetch-etags-parse-list
speedbar-parse-c-or-c++tag)
("^\\.emacs$\\|.\\(el\\|l\\|lsp\\)\\'" .
"def[^i]+\\s-+\\(\\(\\w\\|[-_]\\)+\\)\\s-*\C-?")
+ ("^\\.m$\\'" .
+ "\\(^:-\\)?\\s-*\\(\\(pred\\|func\\|type\\|instance\\|typeclass\\)+\\s+\\([a-z]+[a-zA-Z0-9_]*\\)+\\)\\s-*(?^?")
; ("\\.\\([fF]\\|for\\|FOR\\|77\\|90\\)\\'" .
; speedbar-parse-fortran77-tag)
("\\.tex\\'" . speedbar-parse-tex-string)
--
2.26.3
next prev parent reply other threads:[~2021-03-27 10:51 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <25b8baef-11f2-7079-69d8-3207a24658fc@gmail.com>
2021-03-26 7:09 ` bug#47408: Emacs etags support for Mercury [v0.2] fabrice nicol
2021-03-27 10:51 ` fabrice nicol [this message]
2021-03-28 13:11 ` bug#47408: Etags support for Mercury [v0.3] Eli Zaretskii
2021-03-28 15:49 ` fabrice nicol
2021-03-28 16:22 ` Eli Zaretskii
2021-03-29 11:53 ` bug#47408: Etags support for Mercury [v0.4] fabrice nicol
[not found] ` <70503251-f8ea-9006-b7e7-b13b93bb71de@gmail.com>
2021-05-15 8:31 ` bug#47408: Fwd: " Eli Zaretskii
[not found] ` <53162dfb-0715-3077-78d1-3a8340943f2f@gmail.com>
2021-05-29 8:01 ` Eli Zaretskii
[not found] ` <CANTSrJtDMu=4SWUcBRt51X8n42mOfB6_sFi8mNoZ0YgYdtE-DA@mail.gmail.com>
2021-05-29 10:22 ` Eli Zaretskii
2021-06-01 2:38 ` bug#47408: Etags support for Mercury [v0.5] fabrice nicol
2021-06-06 9:48 ` Eli Zaretskii
2021-06-06 13:34 ` fabrice nicol
2021-06-06 18:18 ` Francesco Potortì
2021-06-06 20:49 ` fabrice nicol
2021-06-06 21:04 ` Francesco Potortì
2021-06-07 12:13 ` Eli Zaretskii
2021-06-08 0:38 ` Fabrice Nicol
2021-06-08 10:53 ` Francesco Potortì
2021-06-08 11:47 ` Eli Zaretskii
2021-06-08 12:47 ` Francesco Potortì
2021-06-10 13:59 ` Eli Zaretskii
2021-06-10 16:52 ` fabrice nicol
2021-06-10 17:05 ` Francesco Potortì
2021-06-10 17:20 ` Eli Zaretskii
2021-06-10 19:15 ` Eli Zaretskii
2021-06-10 20:39 ` bug#47408: Etags support for Mercury -- fix explicit tags for existentially-quantified procedures fabrice nicol
2021-06-11 5:56 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5ba2fec3-3f61-fb7e-35eb-7188fa6064a4@gmail.com \
--to=fabrnicol@gmail.com \
--cc=47408@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).