mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-25 23:10:47 -08:00
merge master, fix conflicts
This commit is contained in:
commit
cc7cb20d6a
169 changed files with 4063 additions and 4344 deletions
19
ChangeLog
19
ChangeLog
|
|
@ -1,3 +1,22 @@
|
|||
2015-01-11 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Default to 'configure --enable-silent-rules'
|
||||
This greatly shortens the 'make' output, making it more readable
|
||||
and useful. For example, on my platform it shortens a
|
||||
4125-character line "gcc -std=gnu99 -c -Demacs -I. -I. -I../lib
|
||||
... emacs.c" -- a line so long that it's hard to see what's going
|
||||
on or where the diagnostics are -- to just "CC emacs.o".
|
||||
* INSTALL: Document this.
|
||||
* configure.ac: Add AM_SILENT_RULES([yes]).
|
||||
(AM_DEFAULT_VERBOSITY): Remove now-unnecessary initialization.
|
||||
Fixes: bug#19501
|
||||
|
||||
2015-01-06 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Merge from gnulib
|
||||
* lib/stdio.in.h, m4/stdio_h.m4: Update from gnulib, incorporating:
|
||||
2015-01-05 stdio: fix use of PRIdMAX on modern mingw
|
||||
|
||||
2015-01-04 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* INSTALL: Mention 'make WERROR_CFLAGS='.
|
||||
|
|
|
|||
7
INSTALL
7
INSTALL
|
|
@ -316,10 +316,9 @@ generated warnings may still be useful, though you may prefer building
|
|||
with 'make WERROR_CFLAGS=' so that the warnings are not treated as
|
||||
errors.
|
||||
|
||||
Use --enable-silent-rules to cause 'make' to chatter less. This is
|
||||
helpful when combined with options like --enable-gcc-warnings that
|
||||
generate long shell-command lines. 'make V=0' also suppresses the
|
||||
chatter.
|
||||
Use --disable-silent-rules to cause 'make' to give more details about
|
||||
the commands it executes. This can be helpful when debugging a build
|
||||
that goes awry. 'make V=1' also enables the extra chatter.
|
||||
|
||||
Use --enable-link-time-optimization to enable link-time optimizer. If
|
||||
you're using GNU compiler, this feature is supported since version 4.5.0.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
2015-01-08 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* authors.el (authors-aliases): Add an entry to ignore.
|
||||
|
||||
2015-01-04 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Less 'make' chatter for admin/grammars
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ files.")
|
|||
|
||||
(defconst authors-aliases
|
||||
'(
|
||||
(nil "A\\. N\\. Other") ; unknown author 2014-12-03, later removed
|
||||
("Aaron S. Hawley" "Aaron Hawley")
|
||||
("Alexandru Harsanyi" "Alex Harsanyi")
|
||||
("Andrew Csillag" "Drew Csillag")
|
||||
|
|
|
|||
|
|
@ -1013,9 +1013,11 @@ if test "${enableval}" != "no"; then
|
|||
fi
|
||||
fi)
|
||||
|
||||
dnl Prefer silent make output. For verbose output, use
|
||||
dnl 'configure --disable-silent-rules' or 'make V=1' .
|
||||
AM_SILENT_RULES([yes])
|
||||
dnl Port to Automake 1.11.
|
||||
dnl This section can be removed once we assume Automake 1.14 or later.
|
||||
: ${AM_DEFAULT_VERBOSITY=1}
|
||||
: ${AM_V=$AM_DEFAULT_VERBOSITY}
|
||||
: ${AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY}
|
||||
AC_SUBST([AM_V])
|
||||
|
|
|
|||
|
|
@ -87,10 +87,7 @@ waiting for input.
|
|||
@defun redisplay &optional force
|
||||
This function tries immediately to redisplay. The optional argument
|
||||
@var{force}, if non-@code{nil}, forces the redisplay to be performed,
|
||||
instead of being preempted, even if input is pending and the variable
|
||||
@code{redisplay-dont-pause} is @code{nil} (see below). If
|
||||
@code{redisplay-dont-pause} is non-@code{nil} (the default), this
|
||||
function redisplays in any case, i.e., @var{force} does nothing.
|
||||
instead of being preempted if input is pending.
|
||||
|
||||
The function returns @code{t} if it actually tried to redisplay, and
|
||||
@code{nil} otherwise. A value of @code{t} does not mean that
|
||||
|
|
@ -98,28 +95,6 @@ redisplay proceeded to completion; it could have been preempted by
|
|||
newly arriving input.
|
||||
@end defun
|
||||
|
||||
@defvar redisplay-dont-pause
|
||||
If this variable is @code{nil}, arriving input events preempt
|
||||
redisplay; Emacs avoids starting a redisplay, and stops any redisplay
|
||||
that is in progress, until the input has been processed. In
|
||||
particular, @code{(redisplay)} returns @code{nil} without actually
|
||||
redisplaying, if there is pending input.
|
||||
|
||||
The default value is @code{t}, which means that pending input does not
|
||||
preempt redisplay.
|
||||
@end defvar
|
||||
|
||||
@defvar redisplay-preemption-period
|
||||
If @code{redisplay-dont-pause} is @code{nil}, this variable specifies
|
||||
how many seconds Emacs waits between checks for new input during
|
||||
redisplay; if input arrives during this interval, redisplay stops and
|
||||
the input is processed. The default value is 0.1; if the value is
|
||||
@code{nil}, Emacs does not check for input during redisplay.
|
||||
|
||||
This variable has no effect when @code{redisplay-dont-pause} is
|
||||
non-@code{nil} (the default).
|
||||
@end defvar
|
||||
|
||||
@defvar pre-redisplay-function
|
||||
A function run just before redisplay. It is called with one argument,
|
||||
the set of windows to redisplay.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
2015-01-11 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Default to 'configure --enable-silent-rules'
|
||||
* NEWS: Document this.
|
||||
|
||||
2015-01-10 Daniel Colascione <dancol@dancol.org>
|
||||
|
||||
* NEWS: Fix typo
|
||||
|
||||
2015-01-04 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
batch write-region no longer says "Wrote FOO"
|
||||
|
|
|
|||
24
etc/NEWS
24
etc/NEWS
|
|
@ -40,8 +40,10 @@ or by sticking with Emacs 24.4.
|
|||
** The configure option `--with-pkg-config-prog' has been removed.
|
||||
Use './configure PKG_CONFIG=/full/name/of/pkg-config' if you need to.
|
||||
|
||||
** The configure option '--enable-silent-rules' and the command
|
||||
'make V=0' now do a better job of suppressing chatter.
|
||||
** The configure option '--enable-silent-rules' is now the default,
|
||||
and silent rules are now quieter. To get the old behavior where
|
||||
'make' chatters a lot, configure with '--disable-silent-rules' or
|
||||
build with 'make V=1'.
|
||||
|
||||
---
|
||||
** The `grep-changelog' script (and its manual page) are no longer included.
|
||||
|
|
@ -141,10 +143,6 @@ this has no effect.
|
|||
** A new text property `inhibit-read-only' can be used in read-only
|
||||
buffers to allow certain parts of the text to be writable.
|
||||
|
||||
** A new function `file-tree-walk' allows to apply a certain action
|
||||
to all the files and subdirectories of a directory, similarly to the C
|
||||
library function `ftw'.
|
||||
|
||||
** A new function `directory-files-recursively' returns all matching
|
||||
files (recursively) under a directory.
|
||||
|
||||
|
|
@ -166,6 +164,8 @@ characters, which can be used for geometry-related calculations.
|
|||
|
||||
* Editing Changes in Emacs 25.1
|
||||
|
||||
** Unicode names entered via C-x 8 RET now use substring completion by default.
|
||||
|
||||
** New minor mode global-eldoc-mode is enabled by default.
|
||||
|
||||
** Emacs now supports "bracketed paste mode" when running on a terminal
|
||||
|
|
@ -191,10 +191,16 @@ Unicode standards.
|
|||
|
||||
When you invoke `shell' interactively, the *shell* buffer will now
|
||||
display in a new window. However, you can customize this behavior via
|
||||
the new `shell-display-buffer-actions' variable. For example, to get
|
||||
the `display-buffer-alist' variable. For example, to get
|
||||
the old behavior -- *shell* buffer displays in current window -- use
|
||||
(setq shell-display-buffer-actions '(display-buffer-same-window)).
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("^\\*shell\\*$" . (display-buffer-same-window))).
|
||||
|
||||
|
||||
** EIEIO
|
||||
*** The <class>-list-p and <class>-child-p functions are declared obsolete.
|
||||
*** The <class> variables are declared obsolete.
|
||||
*** The <initarg> variables are declared obsolete.
|
||||
** ido
|
||||
*** New command `ido-bury-buffer-at-head' bound to C-S-b
|
||||
Bury the buffer at the head of `ido-matches', analogous to how C-k
|
||||
|
|
@ -607,7 +613,7 @@ Horizontal scroll bars are turned off by default.
|
|||
`scroll-bar-height'.
|
||||
|
||||
+++
|
||||
** The height of a frame's menu and tool bar are no more counted in the
|
||||
** The height of a frame's menu and tool bar are no longer counted in the
|
||||
frame's text height. This means that the text height stands only for
|
||||
the height of the frame's root window plus that of the echo area (if
|
||||
present). This was already the behavior for frames with external tool
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ otherwise leave it unmarked.
|
|||
---
|
||||
** The default value of `history-length' has increased to 100.
|
||||
|
||||
+++
|
||||
** `redisplay-dont-pause' is declared as obsolete.
|
||||
|
||||
|
||||
* Changes in Specialized Modes and Packages in Emacs 24.5
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,41 @@
|
|||
2015-01-10 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Port to 32-bit --with-wide-int
|
||||
* make-docfile.c (write_globals): Define and use symbols like
|
||||
iQnil (a small integer, like 0) rather than aQnil (an address
|
||||
constant).
|
||||
|
||||
Port to 32-bit Sun C 5.12 sparc
|
||||
* make-docfile.c (close_emacs_globals): Align lispsym to GCALIGNMENT.
|
||||
The alignment is required on all platforms; it just happens to have
|
||||
been properly aligned on the previous platforms we tested.
|
||||
|
||||
2015-01-05 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Use 0 for Qnil
|
||||
* make-docfile.c (compare_globals): Consider 'nil' to be the least.
|
||||
|
||||
Compute C decls for DEFSYMs automatically
|
||||
Fixes Bug#15880.
|
||||
* make-docfile.c: Revamp to generate table of symbols, too.
|
||||
Include <stdbool.h>.
|
||||
(xstrdup): New function.
|
||||
(main): Don't process the same file twice.
|
||||
(SYMBOL): New constant in enum global_type.
|
||||
(struct symbol): Turn 'value' member into a union, either v.value
|
||||
for int or v.svalue for string. All uses changed.
|
||||
(add_global): New arg svalue, which overrides value, so that globals
|
||||
can have a string value.
|
||||
(close_emacs_global): New arg num_symbols; all uses changed.
|
||||
Output lispsym decl.
|
||||
(write_globals): Output symbol globals too. Output more
|
||||
ATTRIBUTE_CONST, now that Qnil etc. are C constants.
|
||||
Output defsym_name table.
|
||||
(scan_c_file): Move most of guts into ...
|
||||
(scan_c_stream): ... new function. Scan for DEFSYMs and
|
||||
record symbols found. Don't read past EOF if file doesn't
|
||||
end in newline.
|
||||
|
||||
2015-01-04 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
'temacs -nw' should not call missing functions
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* config.h unconditionally includes this anyway */
|
||||
|
||||
|
|
@ -63,6 +64,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
static int scan_file (char *filename);
|
||||
static int scan_lisp_file (const char *filename, const char *mode);
|
||||
static int scan_c_file (char *filename, const char *mode);
|
||||
static int scan_c_stream (FILE *infile);
|
||||
static void start_globals (void);
|
||||
static void write_globals (void);
|
||||
|
||||
|
|
@ -106,6 +108,17 @@ xmalloc (unsigned int size)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Like strdup, but get fatal error if memory is exhausted. */
|
||||
|
||||
static char *
|
||||
xstrdup (char *s)
|
||||
{
|
||||
char *result = strdup (s);
|
||||
if (! result)
|
||||
fatal ("virtual memory exhausted", 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Like realloc but get fatal error if memory is exhausted. */
|
||||
|
||||
static void *
|
||||
|
|
@ -123,7 +136,6 @@ main (int argc, char **argv)
|
|||
{
|
||||
int i;
|
||||
int err_count = 0;
|
||||
int first_infile;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
|
|
@ -167,16 +179,21 @@ main (int argc, char **argv)
|
|||
if (generate_globals)
|
||||
start_globals ();
|
||||
|
||||
first_infile = i;
|
||||
for (; i < argc; i++)
|
||||
if (argc <= i)
|
||||
scan_c_stream (stdin);
|
||||
else
|
||||
{
|
||||
int j;
|
||||
/* Don't process one file twice. */
|
||||
for (j = first_infile; j < i; j++)
|
||||
if (! strcmp (argv[i], argv[j]))
|
||||
break;
|
||||
if (j == i)
|
||||
err_count += scan_file (argv[i]);
|
||||
int first_infile = i;
|
||||
for (; i < argc; i++)
|
||||
{
|
||||
int j;
|
||||
/* Don't process one file twice. */
|
||||
for (j = first_infile; j < i; j++)
|
||||
if (strcmp (argv[i], argv[j]) == 0)
|
||||
break;
|
||||
if (j == i)
|
||||
err_count += scan_file (argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (err_count == 0 && generate_globals)
|
||||
|
|
@ -528,13 +545,15 @@ write_c_args (char *func, char *buf, int minargs, int maxargs)
|
|||
}
|
||||
|
||||
/* The types of globals. These are sorted roughly in decreasing alignment
|
||||
order to avoid allocation gaps, except that functions are last. */
|
||||
order to avoid allocation gaps, except that symbols and functions
|
||||
are last. */
|
||||
enum global_type
|
||||
{
|
||||
INVALID,
|
||||
LISP_OBJECT,
|
||||
EMACS_INTEGER,
|
||||
BOOLEAN,
|
||||
SYMBOL,
|
||||
FUNCTION
|
||||
};
|
||||
|
||||
|
|
@ -543,7 +562,11 @@ struct global
|
|||
{
|
||||
enum global_type type;
|
||||
char *name;
|
||||
int value;
|
||||
union
|
||||
{
|
||||
int value;
|
||||
char const *svalue;
|
||||
} v;
|
||||
};
|
||||
|
||||
/* All the variable names we saw while scanning C sources in `-g'
|
||||
|
|
@ -553,7 +576,7 @@ int num_globals_allocated;
|
|||
struct global *globals;
|
||||
|
||||
static void
|
||||
add_global (enum global_type type, char *name, int value)
|
||||
add_global (enum global_type type, char *name, int value, char const *svalue)
|
||||
{
|
||||
/* Ignore the one non-symbol that can occur. */
|
||||
if (strcmp (name, "..."))
|
||||
|
|
@ -574,7 +597,10 @@ add_global (enum global_type type, char *name, int value)
|
|||
|
||||
globals[num_globals - 1].type = type;
|
||||
globals[num_globals - 1].name = name;
|
||||
globals[num_globals - 1].value = value;
|
||||
if (svalue)
|
||||
globals[num_globals - 1].v.svalue = svalue;
|
||||
else
|
||||
globals[num_globals - 1].v.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -587,21 +613,58 @@ compare_globals (const void *a, const void *b)
|
|||
if (ga->type != gb->type)
|
||||
return ga->type - gb->type;
|
||||
|
||||
/* Consider "nil" to be the least, so that iQnil is zero. That
|
||||
way, Qnil's internal representation is zero, which is a bit faster. */
|
||||
if (ga->type == SYMBOL)
|
||||
{
|
||||
bool a_nil = strcmp (ga->name, "Qnil") == 0;
|
||||
bool b_nil = strcmp (gb->name, "Qnil") == 0;
|
||||
if (a_nil | b_nil)
|
||||
return b_nil - a_nil;
|
||||
}
|
||||
|
||||
return strcmp (ga->name, gb->name);
|
||||
}
|
||||
|
||||
static void
|
||||
close_emacs_globals (void)
|
||||
close_emacs_globals (int num_symbols)
|
||||
{
|
||||
puts ("};");
|
||||
puts ("extern struct emacs_globals globals;");
|
||||
printf (("};\n"
|
||||
"extern struct emacs_globals globals;\n"
|
||||
"\n"
|
||||
"#ifndef DEFINE_SYMBOLS\n"
|
||||
"extern\n"
|
||||
"#endif\n"
|
||||
"struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[%d];\n"),
|
||||
num_symbols);
|
||||
}
|
||||
|
||||
static void
|
||||
write_globals (void)
|
||||
{
|
||||
int i, seen_defun = 0;
|
||||
int i, j;
|
||||
bool seen_defun = false;
|
||||
int symnum = 0;
|
||||
int num_symbols = 0;
|
||||
qsort (globals, num_globals, sizeof (struct global), compare_globals);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < num_globals; i++)
|
||||
{
|
||||
while (i + 1 < num_globals
|
||||
&& strcmp (globals[i].name, globals[i + 1].name) == 0)
|
||||
{
|
||||
if (globals[i].type == FUNCTION
|
||||
&& globals[i].v.value != globals[i + 1].v.value)
|
||||
error ("function '%s' defined twice with differing signatures",
|
||||
globals[i].name);
|
||||
i++;
|
||||
}
|
||||
num_symbols += globals[i].type == SYMBOL;
|
||||
globals[j++] = globals[i];
|
||||
}
|
||||
num_globals = j;
|
||||
|
||||
for (i = 0; i < num_globals; ++i)
|
||||
{
|
||||
char const *type = 0;
|
||||
|
|
@ -617,12 +680,13 @@ write_globals (void)
|
|||
case LISP_OBJECT:
|
||||
type = "Lisp_Object";
|
||||
break;
|
||||
case SYMBOL:
|
||||
case FUNCTION:
|
||||
if (!seen_defun)
|
||||
{
|
||||
close_emacs_globals ();
|
||||
close_emacs_globals (num_symbols);
|
||||
putchar ('\n');
|
||||
seen_defun = 1;
|
||||
seen_defun = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -635,6 +699,13 @@ write_globals (void)
|
|||
printf ("#define %s globals.f_%s\n",
|
||||
globals[i].name, globals[i].name);
|
||||
}
|
||||
else if (globals[i].type == SYMBOL)
|
||||
printf (("DEFINE_LISP_SYMBOL_BEGIN (%s)\n"
|
||||
"#define i%s %d\n"
|
||||
"#define %s builtin_lisp_symbol (i%s)\n"
|
||||
"DEFINE_LISP_SYMBOL_END (%s)\n\n"),
|
||||
globals[i].name, globals[i].name, symnum++,
|
||||
globals[i].name, globals[i].name, globals[i].name);
|
||||
else
|
||||
{
|
||||
/* It would be nice to have a cleaner way to deal with these
|
||||
|
|
@ -647,39 +718,65 @@ write_globals (void)
|
|||
fputs ("_Noreturn ", stdout);
|
||||
|
||||
printf ("EXFUN (%s, ", globals[i].name);
|
||||
if (globals[i].value == -1)
|
||||
if (globals[i].v.value == -1)
|
||||
fputs ("MANY", stdout);
|
||||
else if (globals[i].value == -2)
|
||||
else if (globals[i].v.value == -2)
|
||||
fputs ("UNEVALLED", stdout);
|
||||
else
|
||||
printf ("%d", globals[i].value);
|
||||
printf ("%d", globals[i].v.value);
|
||||
putchar (')');
|
||||
|
||||
/* It would be nice to have a cleaner way to deal with these
|
||||
special hacks, too. */
|
||||
if (strcmp (globals[i].name, "Fbyteorder") == 0
|
||||
if (strcmp (globals[i].name, "Fatom") == 0
|
||||
|| strcmp (globals[i].name, "Fbyteorder") == 0
|
||||
|| strcmp (globals[i].name, "Fcharacterp") == 0
|
||||
|| strcmp (globals[i].name, "Fchar_or_string_p") == 0
|
||||
|| strcmp (globals[i].name, "Fconsp") == 0
|
||||
|| strcmp (globals[i].name, "Feq") == 0
|
||||
|| strcmp (globals[i].name, "Fface_attribute_relative_p") == 0
|
||||
|| strcmp (globals[i].name, "Fframe_windows_min_size") == 0
|
||||
|| strcmp (globals[i].name, "Fgnutls_errorp") == 0
|
||||
|| strcmp (globals[i].name, "Fidentity") == 0
|
||||
|| strcmp (globals[i].name, "Fintegerp") == 0
|
||||
|| strcmp (globals[i].name, "Finteractive") == 0
|
||||
|| strcmp (globals[i].name, "Ffloatp") == 0
|
||||
|| strcmp (globals[i].name, "Flistp") == 0
|
||||
|| strcmp (globals[i].name, "Fmax_char") == 0
|
||||
|| strcmp (globals[i].name, "Ftool_bar_height") == 0)
|
||||
|| strcmp (globals[i].name, "Fnatnump") == 0
|
||||
|| strcmp (globals[i].name, "Fnlistp") == 0
|
||||
|| strcmp (globals[i].name, "Fnull") == 0
|
||||
|| strcmp (globals[i].name, "Fnumberp") == 0
|
||||
|| strcmp (globals[i].name, "Fstringp") == 0
|
||||
|| strcmp (globals[i].name, "Fsymbolp") == 0
|
||||
|| strcmp (globals[i].name, "Ftool_bar_height") == 0
|
||||
|| strcmp (globals[i].name, "Fwindow__sanitize_window_sizes") == 0
|
||||
#ifndef WINDOWSNT
|
||||
|| strcmp (globals[i].name, "Fgnutls_available_p") == 0
|
||||
|| strcmp (globals[i].name, "Fzlib_available_p") == 0
|
||||
#endif
|
||||
|| 0)
|
||||
fputs (" ATTRIBUTE_CONST", stdout);
|
||||
|
||||
puts (";");
|
||||
}
|
||||
|
||||
while (i + 1 < num_globals
|
||||
&& !strcmp (globals[i].name, globals[i + 1].name))
|
||||
{
|
||||
if (globals[i].type == FUNCTION
|
||||
&& globals[i].value != globals[i + 1].value)
|
||||
error ("function '%s' defined twice with differing signatures",
|
||||
globals[i].name);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!seen_defun)
|
||||
close_emacs_globals ();
|
||||
close_emacs_globals (num_symbols);
|
||||
|
||||
puts ("#ifdef DEFINE_SYMBOLS");
|
||||
puts ("static char const *const defsym_name[] = {");
|
||||
for (int i = 0; i < num_globals; i++)
|
||||
{
|
||||
if (globals[i].type == SYMBOL)
|
||||
printf ("\t\"%s\",\n", globals[i].v.svalue);
|
||||
while (i + 1 < num_globals
|
||||
&& strcmp (globals[i].name, globals[i + 1].name) == 0)
|
||||
i++;
|
||||
}
|
||||
puts ("};");
|
||||
puts ("#endif");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -692,9 +789,6 @@ static int
|
|||
scan_c_file (char *filename, const char *mode)
|
||||
{
|
||||
FILE *infile;
|
||||
register int c;
|
||||
register int commas;
|
||||
int minargs, maxargs;
|
||||
int extension = filename[strlen (filename) - 1];
|
||||
|
||||
if (extension == 'o')
|
||||
|
|
@ -720,8 +814,15 @@ scan_c_file (char *filename, const char *mode)
|
|||
|
||||
/* Reset extension to be able to detect duplicate files. */
|
||||
filename[strlen (filename) - 1] = extension;
|
||||
return scan_c_stream (infile);
|
||||
}
|
||||
|
||||
static int
|
||||
scan_c_stream (FILE *infile)
|
||||
{
|
||||
int commas, minargs, maxargs;
|
||||
int c = '\n';
|
||||
|
||||
c = '\n';
|
||||
while (!feof (infile))
|
||||
{
|
||||
int doc_keyword = 0;
|
||||
|
|
@ -750,37 +851,53 @@ scan_c_file (char *filename, const char *mode)
|
|||
if (c != 'F')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != 'V')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != 'A')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != 'R')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != '_')
|
||||
continue;
|
||||
|
||||
defvarflag = 1;
|
||||
|
||||
c = getc (infile);
|
||||
defvarperbufferflag = (c == 'P');
|
||||
if (generate_globals)
|
||||
if (c == 'S')
|
||||
{
|
||||
if (c == 'I')
|
||||
type = EMACS_INTEGER;
|
||||
else if (c == 'L')
|
||||
type = LISP_OBJECT;
|
||||
else if (c == 'B')
|
||||
type = BOOLEAN;
|
||||
c = getc (infile);
|
||||
if (c != 'Y')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != 'M')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != ' ' && c != '\t' && c != '(')
|
||||
continue;
|
||||
type = SYMBOL;
|
||||
}
|
||||
else if (c == 'V')
|
||||
{
|
||||
c = getc (infile);
|
||||
if (c != 'A')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != 'R')
|
||||
continue;
|
||||
c = getc (infile);
|
||||
if (c != '_')
|
||||
continue;
|
||||
|
||||
c = getc (infile);
|
||||
/* We need to distinguish between DEFVAR_BOOL and
|
||||
DEFVAR_BUFFER_DEFAULTS. */
|
||||
if (generate_globals && type == BOOLEAN && c != 'O')
|
||||
type = INVALID;
|
||||
defvarflag = 1;
|
||||
|
||||
c = getc (infile);
|
||||
defvarperbufferflag = (c == 'P');
|
||||
if (generate_globals)
|
||||
{
|
||||
if (c == 'I')
|
||||
type = EMACS_INTEGER;
|
||||
else if (c == 'L')
|
||||
type = LISP_OBJECT;
|
||||
else if (c == 'B')
|
||||
type = BOOLEAN;
|
||||
}
|
||||
|
||||
c = getc (infile);
|
||||
/* We need to distinguish between DEFVAR_BOOL and
|
||||
DEFVAR_BUFFER_DEFAULTS. */
|
||||
if (generate_globals && type == BOOLEAN && c != 'O')
|
||||
type = INVALID;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else if (c == 'D')
|
||||
{
|
||||
|
|
@ -797,7 +914,7 @@ scan_c_file (char *filename, const char *mode)
|
|||
|
||||
if (generate_globals
|
||||
&& (!defvarflag || defvarperbufferflag || type == INVALID)
|
||||
&& !defunflag)
|
||||
&& !defunflag && type != SYMBOL)
|
||||
continue;
|
||||
|
||||
while (c != '(')
|
||||
|
|
@ -807,15 +924,19 @@ scan_c_file (char *filename, const char *mode)
|
|||
c = getc (infile);
|
||||
}
|
||||
|
||||
/* Lisp variable or function name. */
|
||||
c = getc (infile);
|
||||
if (c != '"')
|
||||
continue;
|
||||
c = read_c_string_or_comment (infile, -1, 0, 0);
|
||||
if (type != SYMBOL)
|
||||
{
|
||||
/* Lisp variable or function name. */
|
||||
c = getc (infile);
|
||||
if (c != '"')
|
||||
continue;
|
||||
c = read_c_string_or_comment (infile, -1, 0, 0);
|
||||
}
|
||||
|
||||
if (generate_globals)
|
||||
{
|
||||
int i = 0;
|
||||
char const *svalue = 0;
|
||||
|
||||
/* Skip "," and whitespace. */
|
||||
do
|
||||
|
|
@ -827,6 +948,8 @@ scan_c_file (char *filename, const char *mode)
|
|||
/* Read in the identifier. */
|
||||
do
|
||||
{
|
||||
if (c < 0)
|
||||
goto eof;
|
||||
input_buffer[i++] = c;
|
||||
c = getc (infile);
|
||||
}
|
||||
|
|
@ -837,13 +960,27 @@ scan_c_file (char *filename, const char *mode)
|
|||
name = xmalloc (i + 1);
|
||||
memcpy (name, input_buffer, i + 1);
|
||||
|
||||
if (type == SYMBOL)
|
||||
{
|
||||
do
|
||||
c = getc (infile);
|
||||
while (c == ' ' || c == '\t' || c == '\n' || c == '\r');
|
||||
if (c != '"')
|
||||
continue;
|
||||
c = read_c_string_or_comment (infile, -1, 0, 0);
|
||||
svalue = xstrdup (input_buffer);
|
||||
}
|
||||
|
||||
if (!defunflag)
|
||||
{
|
||||
add_global (type, name, 0);
|
||||
add_global (type, name, 0, svalue);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == SYMBOL)
|
||||
continue;
|
||||
|
||||
/* DEFVAR_LISP ("name", addr, "doc")
|
||||
DEFVAR_LISP ("name", addr /\* doc *\/)
|
||||
DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
|
||||
|
|
@ -896,7 +1033,7 @@ scan_c_file (char *filename, const char *mode)
|
|||
|
||||
if (generate_globals)
|
||||
{
|
||||
add_global (FUNCTION, name, maxargs);
|
||||
add_global (FUNCTION, name, maxargs, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,8 +84,13 @@
|
|||
except that it indicates to GCC that the supported format string directives
|
||||
are the ones of the system printf(), rather than the ones standardized by
|
||||
ISO C99 and POSIX. */
|
||||
#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \
|
||||
#if GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU
|
||||
# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \
|
||||
_GL_ATTRIBUTE_FORMAT_PRINTF (formatstring_parameter, first_argument)
|
||||
#else
|
||||
# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \
|
||||
_GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument))
|
||||
#endif
|
||||
|
||||
/* _GL_ATTRIBUTE_FORMAT_SCANF
|
||||
indicates to GCC that the function takes a format string and arguments,
|
||||
|
|
|
|||
355
lisp/ChangeLog
355
lisp/ChangeLog
|
|
@ -1,7 +1,319 @@
|
|||
2015-01-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||
|
||||
* net/shr.el (shr-urlify): Don't bother the user about
|
||||
invalidly-encoded display strings.
|
||||
|
||||
2015-01-10 Ivan Shmakov <ivan@siamics.net>
|
||||
|
||||
* net/shr.el (shr-urlify): Decode URLs before using them as titles
|
||||
(bug#19555).
|
||||
|
||||
2015-01-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||
|
||||
* net/eww.el (eww): Always interpret URLs that start with https?:
|
||||
as plain URLs, even if they have spaces in them (bug#19556).
|
||||
(eww): Also interpret things like "en.wikipedia.org/wiki/Free
|
||||
software" as an URL.
|
||||
(eww): Don't interpret "org/foo" as an URL.
|
||||
(eww): Clear the title when loading so that we don't display
|
||||
misleading information.
|
||||
|
||||
2015-01-10 Daniel Colascione <dancol@dancol.org>
|
||||
|
||||
* vc/vc-hooks.el (vc-prefix-map): Bind vc-delete-file to C-x v x,
|
||||
by analogy with dired.
|
||||
|
||||
2015-01-09 Daniel Colascione <dancol@dancol.org>
|
||||
|
||||
* progmodes/js.el (js--function-heading-1-re)
|
||||
(js--function-prologue-beginning): Parse ES6 generator function
|
||||
declarations. (That is, "function* name()").
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/eieio.el (defclass): Move from eieio-defclass all the code
|
||||
that creates functions, and most of the sanity checks.
|
||||
Mark as obsolete the <class>-child-p function.
|
||||
* emacs-lisp/eieio-core.el (eieio--define-field-accessors): Remove.
|
||||
(eieio--class, eieio--object): Use cl-defstruct.
|
||||
(eieio--object-num-slots): Define manually.
|
||||
(eieio-defclass-autoload): Use eieio--class-make.
|
||||
(eieio-defclass-internal): Rename from eieio-defclass. Move all the
|
||||
`(lambda...) definitions and most of the sanity checks to `defclass'.
|
||||
Mark as obsolete the <class>-list-p function, the <class> variable and
|
||||
the <initarg> variables. Use pcase-dolist.
|
||||
(eieio-defclass): New compatibility function.
|
||||
* emacs-lisp/eieio-opt.el (eieio-build-class-alist)
|
||||
(eieio-class-speedbar): Don't use eieio-default-superclass var.
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/eieio-generic.el: New file.
|
||||
* emacs-lisp/eieio-core.el: Move all generic function code to
|
||||
eieio-generic.el.
|
||||
(eieio--defmethod): Declare.
|
||||
|
||||
* emacs-lisp/eieio.el: Require eieio-generic. Move all generic
|
||||
function code to eieio-generic.el.
|
||||
* emacs-lisp/eieio-opt.el (eieio-help-generic): Move to
|
||||
eieio-generic.el.
|
||||
* emacs-lisp/eieio-datadebug.el (eieio-debug-methodinvoke): Update call
|
||||
to eieio--generic-call.
|
||||
* emacs-lisp/eieio-base.el (eieio-instance-inheritor): Don't use
|
||||
<class>-child type.
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/chart.el (chart-add-sequence, chart-bar-quickie):
|
||||
Don't use <class> as a variable.
|
||||
|
||||
* emacs-lisp/eieio.el (same-class-p): Accept class object as well.
|
||||
(call-next-method): Simplify.
|
||||
(clone): Obey eieio-backward-compatibility.
|
||||
|
||||
* emacs-lisp/eieio-opt.el (eieio-read-generic-p): Remove.
|
||||
(eieio-read-generic): Use `generic-p' instead.
|
||||
|
||||
* emacs-lisp/eieio-core.el (eieio-backward-compatibility): New var.
|
||||
(eieio-defclass-autoload): Obey it.
|
||||
(eieio--class-object): Improve error behavior.
|
||||
(eieio-class-children-fast, same-class-fast-p): Remove. Inline at
|
||||
every use site.
|
||||
(eieio--defgeneric-form-primary-only): Rename from
|
||||
eieio-defgeneric-form-primary-only; update all callers.
|
||||
(eieio--defgeneric-form-primary-only-one): Rename from
|
||||
eieio-defgeneric-form-primary-only-one; update all callers.
|
||||
(eieio-defgeneric-reset-generic-form)
|
||||
(eieio-defgeneric-reset-generic-form-primary-only)
|
||||
(eieio-defgeneric-reset-generic-form-primary-only-one): Remove.
|
||||
(eieio--method-optimize-primary): New function to replace them.
|
||||
(eieio--defmethod, eieio-defmethod): Use it.
|
||||
(eieio--perform-slot-validation): Rename from
|
||||
eieio-perform-slot-validation; update all callers.
|
||||
(eieio--validate-slot-value): Rename from eieio-validate-slot-value.
|
||||
Change `class' to be a class object. Update all callers.
|
||||
(eieio--validate-class-slot-value): Rename from
|
||||
eieio-validate-class-slot-value. Change `class' to be a class object.
|
||||
Update all callers.
|
||||
(eieio-oset-default): Accept class object as well.
|
||||
(eieio--generic-call-primary-only): Rename from
|
||||
eieio-generic-call-primary-only. Update all callers.
|
||||
|
||||
* emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value):
|
||||
Improve error messages.
|
||||
(eieio-persistent-slot-type-is-class-p): Handle `list-of' types, as
|
||||
well as user-defined types. Emit errors for legacy types like
|
||||
<class>-child and <class>-list, if not eieio-backward-compatibility.
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/eieio.el (eieio-class-parents): Accept class objects.
|
||||
(eieio--class-slot-initarg): Rename from class-slot-initarg.
|
||||
Change `class' arg to be a class object. Update all callers.
|
||||
(call-next-method): Adjust to new return value of `eieio-generic-form'.
|
||||
(eieio-default-superclass): Set var to the class object.
|
||||
(eieio-edebug-prin1-to-string): Fix recursive call for lists.
|
||||
Change print behavior to affect class objects rather than
|
||||
class symbols.
|
||||
|
||||
* emacs-lisp/eieio-core.el (eieio-class-object): New function.
|
||||
(eieio-class-parents-fast): Remove macro.
|
||||
(eieio--class-option-assoc): Rename from class-option-assoc.
|
||||
Update all callers.
|
||||
(eieio--class-option): Rename from class-option. Change `class' arg to
|
||||
be a class object. Update all callers.
|
||||
(eieio--class-method-invocation-order): Rename from
|
||||
class-method-invocation-order. Change `class' arg to be a class
|
||||
object. Update all callers.
|
||||
(eieio-defclass-autoload, eieio-defclass): Set the `parent' field to
|
||||
a list of class objects rather than names.
|
||||
(eieio-defclass): Remove redundant quotes. Use `eieio-oref-default'
|
||||
for accessors to class allocated slots.
|
||||
(eieio--perform-slot-validation-for-default): Rename from
|
||||
eieio-perform-slot-validation-for-default. Update all callers.
|
||||
(eieio--add-new-slot): Rename from eieio-add-new-slot.
|
||||
Update all callers. Use push.
|
||||
(eieio-copy-parents-into-subclass): Adjust to new content of
|
||||
`parent' field. Use dolist.
|
||||
(eieio-oref): Remove support for providing a class rather than
|
||||
an object.
|
||||
(eieio-oref-default): Prefer class objects over class names.
|
||||
(eieio--slot-originating-class-p): Rename from
|
||||
eieio-slot-originating-class-p. Update all callers. Use `or'.
|
||||
(eieio--slot-name-index): Turn check into assertion.
|
||||
(eieio--class-slot-name-index): Rename from
|
||||
eieio-class-slot-name-index. Change `class' arg to be a class object.
|
||||
Update all callers.
|
||||
(eieio-attribute-to-initarg): Move to eieio-test-persist.el.
|
||||
(eieio--c3-candidate): Rename from eieio-c3-candidate.
|
||||
Update all callers.
|
||||
(eieio--c3-merge-lists): Rename from eieio-c3-merge-lists.
|
||||
Update all callers.
|
||||
(eieio--class-precedence-c3): Rename from eieio-class-precedence-c3.
|
||||
Update all callers.
|
||||
(eieio--class-precedence-dfs): Rename from eieio-class-precedence-dfs.
|
||||
Update all callers.
|
||||
(eieio--class-precedence-bfs): Rename from eieio-class-precedence-bfs.
|
||||
Update all callers. Adjust to new `parent' content.
|
||||
(eieio--class-precedence-list): Rename from -class-precedence-list.
|
||||
Update all callers.
|
||||
(eieio-generic-call): Use autoloadp and autoload-do-load.
|
||||
Slight simplification.
|
||||
(eieio-generic-call, eieio-generic-call-primary-only): Adjust to new
|
||||
return value of `eieio-generic-form'.
|
||||
(eieiomt-add): Index the hashtable with class objects rather than
|
||||
class names.
|
||||
(eieio-generic-form): Accept class objects as well.
|
||||
|
||||
* emacs-lisp/eieio-base.el (eieio-persistent-convert-list-to-object):
|
||||
Adjust to new convention for eieio-persistent-validate/fix-slot-value.
|
||||
(eieio-persistent-validate/fix-slot-value):
|
||||
Change `class' arg to be a class object. Update all callers.
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/eieio.el (child-of-class-p): Make it accept class objects
|
||||
additionally to class names.
|
||||
|
||||
* emacs-lisp/eieio-core.el (eieio--with-scoped-class): Use let-binding.
|
||||
(object): Remove first (constant) slot; rename second to `class-tag'.
|
||||
(eieio--object-class-object, eieio--object-class-name): New funs
|
||||
to replace eieio--object-class.
|
||||
(eieio--class-object, eieio--class-p): New functions.
|
||||
(same-class-fast-p): Make it a defsubst, change its implementation
|
||||
to check the class objects rather than their names.
|
||||
(eieio-object-p): Rewrite.
|
||||
(eieio-defclass): Adjust the object initialization according to the new
|
||||
object layout.
|
||||
(eieio--scoped-class): Declare it returns a class object (not a class
|
||||
name any more). Adjust calls accordingly (along with calls to
|
||||
eieio--with-scoped-class).
|
||||
(eieio--slot-name-index): Rename from eieio-slot-name-index and change
|
||||
its class arg to be a class object. Adjust callers accordingly.
|
||||
(eieio-slot-originating-class-p): Make its start-class arg a class
|
||||
object. Adjust all callers.
|
||||
(eieio--initarg-to-attribute): Rename from eieio-initarg-to-attribute.
|
||||
Make its `class' arg a class object. Adjust all callers.
|
||||
|
||||
* emacs-lisp/eieio-base.el (eieio-persistent-validate/fix-slot-value):
|
||||
Use eieio--slot-name-index rather than eieio-slot-name-index.
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/eieio.el (make-instance): Simplify by not adding an object
|
||||
name argument.
|
||||
(eieio-object-name): Use eieio-object-name-string.
|
||||
(eieio--object-names): New const.
|
||||
(eieio-object-name-string, eieio-object-set-name-string): Re-implement
|
||||
using a hashtable rather than a built-in slot.
|
||||
(eieio-constructor): Rename from `constructor'. Remove `newname' arg.
|
||||
(clone): Don't mess with the object's "name".
|
||||
|
||||
* emacs-lisp/eieio-custom.el (eieio-widget-test): Remove dummy arg.
|
||||
(eieio-object-value-get): Use eieio-object-set-name-string.
|
||||
|
||||
* emacs-lisp/eieio-core.el (eieio--defalias): Follow aliases.
|
||||
(eieio--object): Remove `name' field.
|
||||
(eieio-defclass): Adjust to new convention where constructors don't
|
||||
take an "object name" any more.
|
||||
(eieio--defgeneric-init-form, eieio--defmethod): Follow aliases.
|
||||
(eieio-validate-slot-value, eieio-oset-default)
|
||||
(eieio-slot-name-index): Don't hardcode eieio--object-num-slots.
|
||||
(eieio-generic-call-primary-only): Simplify.
|
||||
|
||||
* emacs-lisp/eieio-base.el (clone) <eieio-instance-inheritor>:
|
||||
Use call-next-method.
|
||||
(eieio-constructor): Rename from `constructor'.
|
||||
(eieio-persistent-convert-list-to-object): Drop objname.
|
||||
(eieio-persistent-validate/fix-slot-value): Don't hardcode
|
||||
eieio--object-num-slots.
|
||||
(eieio-named): Use a normal slot.
|
||||
(slot-missing) <eieio-named>: Remove.
|
||||
(eieio-object-name-string, eieio-object-set-name-string, clone)
|
||||
<eieio-named>: New methods.
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/eieio-core.el (eieio--class-v): Rename from class-v.
|
||||
(method-*): Add a "eieio--" prefix to those constants.
|
||||
|
||||
* emacs-lisp/eieio.el: Move edebug specs to the corresponding macro.
|
||||
|
||||
* emacs-lisp/eieio-speedbar.el: Use lexical-binding.
|
||||
|
||||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/eieio.el (child-of-class-p): Fix case where `class' is
|
||||
`eieio-default-superclass'.
|
||||
|
||||
* emacs-lisp/eieio-datadebug.el: Use lexical-binding.
|
||||
|
||||
* emacs-lisp/eieio-custom.el: Use lexical-binding.
|
||||
(eieio-object-value-to-abstract): Simplify.
|
||||
|
||||
* emacs-lisp/eieio-opt.el (eieio-build-class-list): Use cl-mapcan.
|
||||
(eieio-build-class-alist): Use dolist.
|
||||
(eieio-all-generic-functions): Adjust to use of hashtables.
|
||||
|
||||
* emacs-lisp/eieio-core.el (class): Rename field symbol-obarray to
|
||||
symbol-hashtable. It contains a hashtable instead of an obarray.
|
||||
(generic-p): Use symbol property `eieio-method-hashtable' instead of
|
||||
`eieio-method-obarray'.
|
||||
(generic-primary-only-p, generic-primary-only-one-p):
|
||||
Slight optimization.
|
||||
(eieio-defclass-autoload-map): Use a hashtable instead of an obarray.
|
||||
(eieio-defclass-autoload, eieio-defclass): Adjust/simplify accordingly.
|
||||
(eieio-class-un-autoload): Use autoload-do-load.
|
||||
(eieio-defclass): Use dolist, cl-pushnew, cl-callf.
|
||||
Use new cl-deftype-satisfies. Adjust to use of hashtables.
|
||||
Don't hardcode the value of eieio--object-num-slots.
|
||||
(eieio-defgeneric-form-primary-only-one): Remove `doc-string' arg.
|
||||
Use a closure rather than a backquoted lambda.
|
||||
(eieio--defmethod): Adjust call accordingly. Set doc-string via the
|
||||
function-documentation property.
|
||||
(eieio-slot-originating-class-p, eieio-slot-name-index)
|
||||
(eieiomt--optimizing-hashtable, eieiomt-install, eieiomt-add)
|
||||
(eieio-generic-form): Adjust to use of hashtables.
|
||||
(eieiomt--sym-optimize): Rename from eieiomt-sym-optimize; take
|
||||
additional class argument.
|
||||
(eieio-generic-call-methodname): Remove, unused.
|
||||
|
||||
* emacs-lisp/eieio-base.el (eieio-persistent-slot-type-is-class-p):
|
||||
Prefer \' to $.
|
||||
|
||||
2015-01-08 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* simple.el (line-move-visual): When converting X pixel coordinate
|
||||
to temporary-goal-column, adjust the value for right-to-left
|
||||
screen lines. This fixes vertical-motion, next/prev-line, etc.
|
||||
|
||||
2015-01-08 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* files.el (file-tree-walk): Remove; of unknown authorship. (Bug#19325)
|
||||
|
||||
2015-01-07 K. Handa <handa@gnu.org>
|
||||
|
||||
* international/ccl.el (define-ccl-program): Improve the docstring.
|
||||
|
||||
2015-01-06 Sam Steingold <sds@gnu.org>
|
||||
|
||||
* shell.el (shell-display-buffer-actions): Remove,
|
||||
use `display-buffer-alist' instead.
|
||||
|
||||
2015-01-05 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
* progmodes/xref.el (xref--insert-xrefs): Add `help-echo' property
|
||||
to the references.
|
||||
|
||||
2015-01-05 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* minibuffer.el (completion-category-defaults): New var.
|
||||
Set unicode-name to use substring completion.
|
||||
(completion-category-defaults): Set it to nil.
|
||||
|
||||
2015-01-04 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Add mouse interaction to xref.
|
||||
|
||||
* progmodes/xref.el (xref--button-map): New variable.
|
||||
(xref--mouse-2): New command.
|
||||
(xref--insert-xrefs): Add `mouse-face' and `keymap' properties to
|
||||
|
|
@ -30,7 +342,6 @@
|
|||
2015-01-04 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Unbreak `mouse-action' property in text buttons.
|
||||
|
||||
* button.el (push-button): Fix regression from 2012-12-06.
|
||||
|
||||
2015-01-03 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
|
@ -144,11 +455,9 @@
|
|||
2014-12-29 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
Unbreak jumping to an alias's definition.
|
||||
|
||||
* emacs-lisp/find-func.el (find-function-library): Return a pair
|
||||
(ORIG-FUNCTION . LIBRARY) instead of just its second element.
|
||||
(find-function-noselect): Use it.
|
||||
|
||||
* progmodes/elisp-mode.el (elisp--xref-identifier-file): Rename to
|
||||
`elisp--xref-identifier-location', incorporate logic from
|
||||
`elisp--xref-find-definitions', use the changed
|
||||
|
|
@ -217,7 +526,6 @@
|
|||
2014-12-27 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
python.el: Native readline completion.
|
||||
|
||||
* progmodes/python.el (python-shell-completion-native-disabled-interpreters)
|
||||
(python-shell-completion-native-enable)
|
||||
(python-shell-completion-native-output-timeout): New defcustoms.
|
||||
|
|
@ -236,9 +544,8 @@
|
|||
|
||||
python.el: Enhance shell user interaction and deprecate
|
||||
python-shell-get-or-create-process.
|
||||
|
||||
* progmodes/python.el
|
||||
(python-shell-get-process-or-error): New function.
|
||||
* progmodes/python.el (python-shell-get-process-or-error):
|
||||
New function.
|
||||
(python-shell-with-shell-buffer): Use it.
|
||||
(python-shell-send-string, python-shell-send-region)
|
||||
(python-shell-send-buffer, python-shell-send-defun)
|
||||
|
|
@ -266,22 +573,15 @@
|
|||
2014-12-27 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
python.el: Fix message when sending region.
|
||||
|
||||
* progmodes/python.el (python-shell-send-region): Rename argument
|
||||
send-main from nomain. Fix message.
|
||||
(python-shell-send-buffer): Rename argument send-main from arg.
|
||||
|
||||
2014-12-27 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
python.el: Cleanup temp files even with eval errors.
|
||||
|
||||
* progmodes/python.el (python-shell-send-file): Make file-name
|
||||
mandatory. Fix temp file removal in the majority of cases.
|
||||
|
||||
2014-12-27 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
python.el: Handle file encoding for shell.
|
||||
|
||||
* progmodes/python.el (python-rx-constituents): Add coding-cookie.
|
||||
(python-shell--save-temp-file): Write file with proper encoding.
|
||||
(python-shell-buffer-substring): Add coding cookie for detected
|
||||
|
|
@ -343,7 +643,7 @@
|
|||
|
||||
2014-12-27 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* lisp/subr.el (redisplay-dont-pause): Mark as obsolete.
|
||||
* subr.el (redisplay-dont-pause): Mark as obsolete.
|
||||
|
||||
2014-12-27 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
|
|
@ -416,7 +716,6 @@
|
|||
2014-12-26 Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||
|
||||
python.el: Generate clearer shell buffer names.
|
||||
|
||||
* progmodes/python.el (python-shell-get-process-name)
|
||||
(python-shell-internal-get-process-name): Use `buffer-name`.
|
||||
(python-shell-internal-get-or-create-process): Simplify.
|
||||
|
|
@ -539,7 +838,7 @@
|
|||
2014-12-19 Alan Mackenzie <acm@muc.de>
|
||||
|
||||
Make C++11 uniform init syntax work.
|
||||
New keywords "final" and "override"
|
||||
New keywords "final" and "override".
|
||||
* progmodes/cc-engine.el (c-back-over-member-initializer-braces):
|
||||
New function.
|
||||
(c-guess-basic-syntax): Set `containing-sex' and `lim' using the
|
||||
|
|
@ -575,8 +874,7 @@
|
|||
|
||||
2014-12-18 Artur Malabarba <bruce.connor.am@gmail.com>
|
||||
|
||||
* let-alist.el (let-alist): Evaluate the `alist' argument only
|
||||
once.
|
||||
* let-alist.el (let-alist): Evaluate the `alist' argument only once.
|
||||
|
||||
2014-12-18 Sam Steingold <sds@gnu.org>
|
||||
|
||||
|
|
@ -590,13 +888,12 @@
|
|||
Add code for "preserving" window sizes.
|
||||
* dired.el (dired-pop-to-buffer): Call fit-window-to-buffer with
|
||||
`preserve-size' t.
|
||||
(dired-mark-pop-up): Preserve size of window showing marked
|
||||
files.
|
||||
(dired-mark-pop-up): Preserve size of window showing marked files.
|
||||
* electric.el (Electric-pop-up-window):
|
||||
* help.el (resize-temp-buffer-window): Call fit-window-to-buffer
|
||||
with `preserve-size' t.
|
||||
* minibuffer.el (minibuffer-completion-help): Use
|
||||
`resize-temp-buffer-window' instead of `fit-window-to-buffer'
|
||||
* minibuffer.el (minibuffer-completion-help):
|
||||
Use `resize-temp-buffer-window' instead of `fit-window-to-buffer'
|
||||
(Bug#19355). Preserve size of completions window.
|
||||
* register.el (register-preview): Preserve size of register
|
||||
preview window.
|
||||
|
|
@ -606,8 +903,7 @@
|
|||
`window-preserve-size'.
|
||||
(window-min-pixel-size, window--preservable-size)
|
||||
(window-preserve-size, window-preserved-size)
|
||||
(window--preserve-size, window--min-size-ignore-p): New
|
||||
functions.
|
||||
(window--preserve-size, window--min-size-ignore-p): New functions.
|
||||
(window-min-size, window-min-delta, window--resizable)
|
||||
(window--resize-this-window, split-window-below)
|
||||
(split-window-right): Amend doc-string.
|
||||
|
|
@ -622,8 +918,7 @@
|
|||
window above or below.
|
||||
(window--state-put-2): Handle horizontal scroll bars.
|
||||
(window--display-buffer): Call `preserve-size' if asked for.
|
||||
(display-buffer): Mention `preserve-size' alist member in
|
||||
doc-string.
|
||||
(display-buffer): Mention `preserve-size' alist member in doc-string.
|
||||
(fit-window-to-buffer): New argument PRESERVE-SIZE.
|
||||
* textmodes/ispell.el (ispell-command-loop): Suppress horizontal
|
||||
scroll bar on ispell's windows. Don't count window lines and
|
||||
|
|
@ -711,7 +1006,7 @@
|
|||
|
||||
2014-12-14 Alan Mackenzie <acm@muc.de>
|
||||
|
||||
* lisp/cus-start.el (all): Add fast-but-imprecise-scrolling.
|
||||
* cus-start.el (all): Add fast-but-imprecise-scrolling.
|
||||
|
||||
2014-12-14 Artur Malabarba <bruce.connor.am@gmail.com>
|
||||
|
||||
|
|
@ -1857,7 +2152,7 @@
|
|||
|
||||
2014-11-19 Artur Malabarba <bruce.connor.am@gmail.com>
|
||||
|
||||
* lisp/ido.el (ido-bury-buffer-at-head): New command.
|
||||
* ido.el (ido-bury-buffer-at-head): New command.
|
||||
(ido-buffer-completion-map): Bind it to C-S-b.
|
||||
|
||||
2014-11-18 Juri Linkov <juri@linkov.net>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,52 @@
|
|||
2015-01-07 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
Don't use <class> as a variable and don't assume that <class>-list-p is
|
||||
automatically defined.
|
||||
|
||||
* ede/speedbar.el (ede-speedbar-compile-line)
|
||||
(ede-speedbar-get-top-project-for-line):
|
||||
* ede.el (ede-buffer-belongs-to-target-p)
|
||||
(ede-buffer-belongs-to-project-p, ede-build-forms-menu)
|
||||
(ede-add-project-to-global-list):
|
||||
* semantic/db-typecache.el (semanticdb-get-typecache):
|
||||
* semantic/db-file.el (semanticdb-load-database):
|
||||
* semantic/db-el.el (semanticdb-elisp-sym->tag):
|
||||
* semantic/db-ebrowse.el (semanticdb-ebrowse-load-helper):
|
||||
* ede/project-am.el (project-am-preferred-target-type):
|
||||
* ede/proj.el (ede-proj-load):
|
||||
* ede/custom.el (ede-customize-current-target, ede-customize-target):
|
||||
* semantic/ede-grammar.el ("semantic grammar"):
|
||||
* semantic/scope.el (semantic-scope-reset-cache)
|
||||
(semantic-calculate-scope):
|
||||
* srecode/map.el (srecode-map-update-map):
|
||||
* srecode/insert.el (srecode-insert-show-error-report)
|
||||
(srecode-insert-method, srecode-insert-include-lookup)
|
||||
(srecode-insert-method):
|
||||
* srecode/fields.el (srecode-active-template-region):
|
||||
* srecode/compile.el (srecode-flush-active-templates)
|
||||
(srecode-compile-inserter): Don't use <class> as a variable.
|
||||
Use `oref-default' for class slots.
|
||||
|
||||
* semantic/grammar.el (semantic-grammar-eldoc-last-data): New var.
|
||||
(semantic-grammar-eldoc-get-macro-docstring): Use it instead of
|
||||
eldoc-last-data.
|
||||
* semantic/fw.el (semantic-exit-on-input): Use `declare'.
|
||||
(semantic-throw-on-input): Use `with-current-buffer'.
|
||||
* semantic/db.el (semanticdb-abstract-table-list): Define if not
|
||||
pre-defined.
|
||||
* semantic/db-find.el (semanticdb-find-tags-collector):
|
||||
Use save-current-buffer.
|
||||
(semanticdb-find-tags-collector): Don't use <class> as a variable.
|
||||
* semantic/complete.el (semantic-complete-active-default)
|
||||
(semantic-complete-current-matched-tag): Declare.
|
||||
(semantic-complete-inline-custom-type): Don't use <class> as a variable.
|
||||
* semantic/bovine/make.el (semantic-analyze-possible-completions):
|
||||
Use with-current-buffer.
|
||||
* semantic.el (semantic-parser-warnings): Declare.
|
||||
* ede/base.el (ede-target-list): Define if not pre-defined.
|
||||
(ede-with-projectfile): Prefer find-file-noselect over
|
||||
save-window-excursion.
|
||||
|
||||
2014-12-22 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* srecode/srt-mode.el (srecode-macro-help): Use eieio-class-children.
|
||||
|
|
|
|||
|
|
@ -248,12 +248,12 @@ Argument LIST-O-O is the list of objects to choose from."
|
|||
(let ((obj ede-object))
|
||||
(if (consp obj)
|
||||
(setq obj (car obj)))
|
||||
(and obj (obj-of-class-p obj ede-target))))
|
||||
(and obj (obj-of-class-p obj 'ede-target))))
|
||||
|
||||
(defun ede-buffer-belongs-to-project-p ()
|
||||
"Return non-nil if this buffer belongs to at least one project."
|
||||
(if (or (null ede-object) (consp ede-object)) nil
|
||||
(obj-of-class-p ede-object-project ede-project)))
|
||||
(obj-of-class-p ede-object-project 'ede-project)))
|
||||
|
||||
(defun ede-menu-obj-of-class-p (class)
|
||||
"Return non-nil if some member of `ede-object' is a child of CLASS."
|
||||
|
|
@ -281,7 +281,7 @@ Argument MENU-DEF is the menu definition to use."
|
|||
;; First, collect the build items from the project
|
||||
(setq newmenu (append newmenu (ede-menu-items-build obj t)))
|
||||
;; Second, declare the current target menu items
|
||||
(if (and ede-obj (ede-menu-obj-of-class-p ede-target))
|
||||
(if (and ede-obj (ede-menu-obj-of-class-p 'ede-target))
|
||||
(while ede-obj
|
||||
(setq newmenu (append newmenu
|
||||
(ede-menu-items-build (car ede-obj) t))
|
||||
|
|
@ -1078,7 +1078,7 @@ On success, return the added project."
|
|||
(error "No project created to add to master list"))
|
||||
(when (not (eieio-object-p proj))
|
||||
(error "Attempt to add non-object to master project list"))
|
||||
(when (not (obj-of-class-p proj ede-project-placeholder))
|
||||
(when (not (obj-of-class-p proj 'ede-project-placeholder))
|
||||
(error "Attempt to add a non-project to the ede projects list"))
|
||||
(add-to-list 'ede-projects proj)
|
||||
proj)
|
||||
|
|
@ -1099,6 +1099,8 @@ Flush the dead projects from the project cache."
|
|||
(ede-delete-project-from-global-list D))
|
||||
))
|
||||
|
||||
(defvar ede--disable-inode) ;Defined in ede/files.el.
|
||||
|
||||
(defun ede-global-list-sanity-check ()
|
||||
"Perform a sanity check to make sure there are no duplicate projects."
|
||||
(interactive)
|
||||
|
|
|
|||
|
|
@ -159,6 +159,9 @@ and querying them will cause the actual project to get loaded.")
|
|||
;; Projects can also affect how EDE works, by changing what appears in
|
||||
;; the EDE menu, or how some keys are bound.
|
||||
;;
|
||||
(unless (fboundp 'ede-target-list-p)
|
||||
(cl-deftype ede-target-list () '(list-of ede-target)))
|
||||
|
||||
(defclass ede-project (ede-project-placeholder)
|
||||
((subproj :initform nil
|
||||
:type list
|
||||
|
|
@ -287,16 +290,18 @@ All specific project types must derive from this project."
|
|||
;;
|
||||
(defmacro ede-with-projectfile (obj &rest forms)
|
||||
"For the project in which OBJ resides, execute FORMS."
|
||||
`(save-window-excursion
|
||||
(let* ((pf (if (obj-of-class-p ,obj ede-target)
|
||||
(ede-target-parent ,obj)
|
||||
,obj))
|
||||
(dbka (get-file-buffer (oref pf file))))
|
||||
(if (not dbka) (find-file (oref pf file))
|
||||
(switch-to-buffer dbka))
|
||||
(declare (indent 1))
|
||||
(unless (symbolp obj)
|
||||
(message "Beware! ede-with-projectfile's first arg is copied: %S" obj))
|
||||
`(let* ((pf (if (obj-of-class-p ,obj 'ede-target)
|
||||
(ede-target-parent ,obj)
|
||||
,obj))
|
||||
(dbka (get-file-buffer (oref pf file))))
|
||||
(with-current-buffer
|
||||
(if (not dbka) (find-file-noselect (oref pf file))
|
||||
dbka)
|
||||
,@forms
|
||||
(if (not dbka) (kill-buffer (current-buffer))))))
|
||||
(put 'ede-with-projectfile 'lisp-indent-function 1)
|
||||
|
||||
;;; The EDE persistent cache.
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
"Edit fields of the current target through EIEIO & Custom."
|
||||
(interactive)
|
||||
(require 'eieio-custom)
|
||||
(if (not (obj-of-class-p ede-object ede-target))
|
||||
(if (not (obj-of-class-p ede-object 'ede-target))
|
||||
(error "Current file is not part of a target"))
|
||||
(ede-customize-target ede-object))
|
||||
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
"Edit fields of the current target through EIEIO & Custom.
|
||||
OBJ is the target object to customize."
|
||||
(require 'eieio-custom)
|
||||
(if (and obj (not (obj-of-class-p obj ede-target)))
|
||||
(if (and obj (not (obj-of-class-p obj 'ede-target)))
|
||||
(error "No logical target to customize"))
|
||||
(ede-customize obj))
|
||||
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ for the tree being read in. If ROOTPROJ is nil, then assume that
|
|||
the PROJECT being read in is the root project."
|
||||
(save-excursion
|
||||
(let ((ret (eieio-persistent-read (concat project "Project.ede")
|
||||
ede-proj-project))
|
||||
'ede-proj-project))
|
||||
(subdirs (directory-files project nil "[^.].*" nil)))
|
||||
(if (not (object-of-class-p ret 'ede-proj-project))
|
||||
(error "Corrupt project file"))
|
||||
|
|
|
|||
|
|
@ -853,13 +853,13 @@ Argument FILE is the file to extract the end directory name from."
|
|||
(defun project-am-preferred-target-type (file)
|
||||
"For FILE, return the preferred type for that file."
|
||||
(cond ((string-match "\\.texi?\\(nfo\\)$" file)
|
||||
project-am-texinfo)
|
||||
'project-am-texinfo)
|
||||
((string-match "\\.[0-9]$" file)
|
||||
project-am-man)
|
||||
'project-am-man)
|
||||
((string-match "\\.el$" file)
|
||||
project-am-lisp)
|
||||
'project-am-lisp)
|
||||
(t
|
||||
project-am-program)))
|
||||
'project-am-program)))
|
||||
|
||||
(defmethod ede-buffer-header-file((this project-am-objectcode) buffer)
|
||||
"There are no default header files."
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ Argument DIR is the directory from which to derive the list of objects."
|
|||
(let ((obj (eieio-speedbar-find-nearest-object)))
|
||||
(if (not (eieio-object-p obj))
|
||||
nil
|
||||
(cond ((obj-of-class-p obj ede-project)
|
||||
(cond ((obj-of-class-p obj 'ede-project)
|
||||
(project-compile-project obj))
|
||||
((obj-of-class-p obj ede-target)
|
||||
((obj-of-class-p obj 'ede-target)
|
||||
(project-compile-target obj))
|
||||
(t (error "Error in speedbar structure"))))))
|
||||
|
||||
|
|
@ -133,9 +133,9 @@ Argument DIR is the directory from which to derive the list of objects."
|
|||
(let ((obj (eieio-speedbar-find-nearest-object)))
|
||||
(if (not (eieio-object-p obj))
|
||||
(error "Error in speedbar or ede structure")
|
||||
(if (obj-of-class-p obj ede-target)
|
||||
(if (obj-of-class-p obj 'ede-target)
|
||||
(setq obj (ede-target-parent obj)))
|
||||
(if (obj-of-class-p obj ede-project)
|
||||
(if (obj-of-class-p obj 'ede-project)
|
||||
obj
|
||||
(error "Error in speedbar or ede structure")))))
|
||||
|
||||
|
|
|
|||
|
|
@ -573,6 +573,7 @@ string."
|
|||
;; The best way to call the parser from programs is via
|
||||
;; `semantic-fetch-tags'. This, in turn, uses other internal
|
||||
;; API functions which plug-in parsers can take advantage of.
|
||||
(defvar semantic-parser-warnings)
|
||||
|
||||
(defun semantic-fetch-tags ()
|
||||
"Fetch semantic tags from the current buffer.
|
||||
|
|
@ -602,49 +603,49 @@ was marked unparseable, then do nothing, and return the cache."
|
|||
(garbage-collect)
|
||||
(cond
|
||||
|
||||
;;;; Try the incremental parser to do a fast update.
|
||||
((semantic-parse-tree-needs-update-p)
|
||||
(setq res (semantic-parse-changes))
|
||||
(if (semantic-parse-tree-needs-rebuild-p)
|
||||
;; If the partial reparse fails, jump to a full reparse.
|
||||
(semantic-fetch-tags)
|
||||
;; Clear the cache of unmatched syntax tokens
|
||||
;;
|
||||
;; NOTE TO SELF:
|
||||
;;
|
||||
;; Move this into the incremental parser. This is a bug.
|
||||
;;
|
||||
(semantic-clear-unmatched-syntax-cache)
|
||||
(run-hook-with-args ;; Let hooks know the updated tags
|
||||
'semantic-after-partial-cache-change-hook res))
|
||||
(setq semantic--completion-cache nil))
|
||||
;; Try the incremental parser to do a fast update.
|
||||
((semantic-parse-tree-needs-update-p)
|
||||
(setq res (semantic-parse-changes))
|
||||
(if (semantic-parse-tree-needs-rebuild-p)
|
||||
;; If the partial reparse fails, jump to a full reparse.
|
||||
(semantic-fetch-tags)
|
||||
;; Clear the cache of unmatched syntax tokens
|
||||
;;
|
||||
;; NOTE TO SELF:
|
||||
;;
|
||||
;; Move this into the incremental parser. This is a bug.
|
||||
;;
|
||||
(semantic-clear-unmatched-syntax-cache)
|
||||
(run-hook-with-args ;; Let hooks know the updated tags
|
||||
'semantic-after-partial-cache-change-hook res))
|
||||
(setq semantic--completion-cache nil))
|
||||
|
||||
;;;; Parse the whole system.
|
||||
((semantic-parse-tree-needs-rebuild-p)
|
||||
;; Use Emacs's built-in progress-reporter (only interactive).
|
||||
(if noninteractive
|
||||
(setq res (semantic-parse-region (point-min) (point-max)))
|
||||
(let ((semantic--progress-reporter
|
||||
(and (>= (point-max) semantic-minimum-working-buffer-size)
|
||||
(eq semantic-working-type 'percent)
|
||||
(make-progress-reporter
|
||||
(semantic-parser-working-message (buffer-name))
|
||||
0 100))))
|
||||
(setq res (semantic-parse-region (point-min) (point-max)))
|
||||
(if semantic--progress-reporter
|
||||
(progress-reporter-done semantic--progress-reporter))))
|
||||
;; Parse the whole system.
|
||||
((semantic-parse-tree-needs-rebuild-p)
|
||||
;; Use Emacs's built-in progress-reporter (only interactive).
|
||||
(if noninteractive
|
||||
(setq res (semantic-parse-region (point-min) (point-max)))
|
||||
(let ((semantic--progress-reporter
|
||||
(and (>= (point-max) semantic-minimum-working-buffer-size)
|
||||
(eq semantic-working-type 'percent)
|
||||
(make-progress-reporter
|
||||
(semantic-parser-working-message (buffer-name))
|
||||
0 100))))
|
||||
(setq res (semantic-parse-region (point-min) (point-max)))
|
||||
(if semantic--progress-reporter
|
||||
(progress-reporter-done semantic--progress-reporter))))
|
||||
|
||||
;; Clear the caches when we see there were no errors.
|
||||
;; But preserve the unmatched syntax cache and warnings!
|
||||
(let (semantic-unmatched-syntax-cache
|
||||
semantic-unmatched-syntax-cache-check
|
||||
semantic-parser-warnings)
|
||||
(semantic-clear-toplevel-cache))
|
||||
;; Set up the new overlays
|
||||
(semantic--tag-link-list-to-buffer res)
|
||||
;; Set up the cache with the new results
|
||||
(semantic--set-buffer-cache res)
|
||||
))))
|
||||
;; Clear the caches when we see there were no errors.
|
||||
;; But preserve the unmatched syntax cache and warnings!
|
||||
(let (semantic-unmatched-syntax-cache
|
||||
semantic-unmatched-syntax-cache-check
|
||||
semantic-parser-warnings)
|
||||
(semantic-clear-toplevel-cache))
|
||||
;; Set up the new overlays
|
||||
(semantic--tag-link-list-to-buffer res)
|
||||
;; Set up the cache with the new results
|
||||
(semantic--set-buffer-cache res)
|
||||
))))
|
||||
|
||||
;; Always return the current parse tree.
|
||||
semantic--buffer-cache)
|
||||
|
|
|
|||
|
|
@ -178,9 +178,8 @@ This is the same as a regular prototype."
|
|||
makefile-mode (context)
|
||||
"Return a list of possible completions in a Makefile.
|
||||
Uses default implementation, and also gets a list of filenames."
|
||||
(save-excursion
|
||||
(require 'semantic/analyze/complete)
|
||||
(set-buffer (oref context buffer))
|
||||
(require 'semantic/analyze/complete)
|
||||
(with-current-buffer (oref context buffer)
|
||||
(let* ((normal (semantic-analyze-possible-completions-default context))
|
||||
(classes (oref context :prefixclass))
|
||||
(filetags nil))
|
||||
|
|
|
|||
|
|
@ -188,6 +188,8 @@ Value should be a ... what?")
|
|||
"Default history variable for any unhistoried prompt.
|
||||
Keeps STRINGS only in the history.")
|
||||
|
||||
(defvar semantic-complete-active-default)
|
||||
(defvar semantic-complete-current-matched-tag)
|
||||
|
||||
(defun semantic-complete-read-tag-engine (collector displayor prompt
|
||||
default-tag initial-input
|
||||
|
|
@ -1871,7 +1873,7 @@ completion text in ghost text."
|
|||
(list 'const
|
||||
:tag doc1
|
||||
C)))
|
||||
(eieio-build-class-alist semantic-displayor-abstract t))
|
||||
(eieio-build-class-alist 'semantic-displayor-abstract t))
|
||||
)
|
||||
"Possible options for inline completion displayors.
|
||||
Use this to enable custom editing.")
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ is specified by `semanticdb-default-save-directory'."
|
|||
If DIRECTORY is found to be defunct, it won't load the DB, and will
|
||||
warn instead."
|
||||
(if (file-directory-p directory)
|
||||
(semanticdb-create-database semanticdb-project-database-ebrowse
|
||||
(semanticdb-create-database 'semanticdb-project-database-ebrowse
|
||||
directory)
|
||||
(let* ((BF (semanticdb-ebrowse-file-for-directory directory))
|
||||
(BFL (concat BF "-load.el"))
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ TOKTYPE is a hint to the type of tag desired."
|
|||
(semantic-elisp-desymbolify
|
||||
;; FIXME: This only gives the instance slots and ignores the
|
||||
;; class-allocated slots.
|
||||
(eieio--class-public-a (find-class semanticdb-project-database))) ;; slots ;FIXME: eieio--
|
||||
(eieio--class-public-a (find-class 'semanticdb-project-database))) ;; slots ;FIXME: eieio--
|
||||
(semantic-elisp-desymbolify (eieio-class-parents sym)) ;; parents
|
||||
))
|
||||
((not toktype)
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ If DIRECTORY doesn't exist, create a new one."
|
|||
(defun semanticdb-load-database (filename)
|
||||
"Load the database FILENAME."
|
||||
(condition-case foo
|
||||
(let* ((r (eieio-persistent-read filename semanticdb-project-database-file))
|
||||
(let* ((r (eieio-persistent-read filename
|
||||
'semanticdb-project-database-file))
|
||||
(c (semanticdb-get-database-tables r))
|
||||
(tv (oref r semantic-tag-version))
|
||||
(fv (oref r semanticdb-version))
|
||||
|
|
|
|||
|
|
@ -1114,7 +1114,7 @@ for backward compatibility.
|
|||
If optional argument BRUTISH is non-nil, then ignore include statements,
|
||||
and search all tables in this project tree."
|
||||
(let (found match)
|
||||
(save-excursion
|
||||
(save-current-buffer
|
||||
;; If path is a buffer, set ourselves up in that buffer
|
||||
;; so that the override methods work correctly.
|
||||
(when (bufferp path) (set-buffer path))
|
||||
|
|
@ -1127,7 +1127,7 @@ and search all tables in this project tree."
|
|||
;; databases and not associated with a file.
|
||||
(unless (and find-file-match
|
||||
(obj-of-class-p
|
||||
(car tableandtags) semanticdb-search-results-table))
|
||||
(car tableandtags) 'semanticdb-search-results-table))
|
||||
(when (setq match (funcall function
|
||||
(car tableandtags) (cdr tableandtags)))
|
||||
(when find-file-match
|
||||
|
|
@ -1144,7 +1144,7 @@ and search all tables in this project tree."
|
|||
;; `semanticdb-search-results-table', since those are system
|
||||
;; databases and not associated with a file.
|
||||
(unless (and find-file-match
|
||||
(obj-of-class-p table semanticdb-search-results-table))
|
||||
(obj-of-class-p table 'semanticdb-search-results-table))
|
||||
(when (and table (setq match (funcall function table nil)))
|
||||
(semanticdb-find-log-activity table match)
|
||||
(when find-file-match
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ If there is no table, create one, and fill it in."
|
|||
(defmethod semanticdb-get-typecache ((db semanticdb-project-database))
|
||||
"Retrieve the typecache from the semantic database DB.
|
||||
If there is no table, create one, and fill it in."
|
||||
(semanticdb-cache-get db semanticdb-database-typecache)
|
||||
(semanticdb-cache-get db 'semanticdb-database-typecache)
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -330,6 +330,10 @@ Adds the number of tags in this file to the object print name."
|
|||
|
||||
;;; DATABASE BASE CLASS
|
||||
;;
|
||||
(unless (fboundp 'semanticdb-abstract-table-list-p)
|
||||
(cl-deftype semanticdb-abstract-table-list ()
|
||||
'(list-of semanticdb-abstract-table)))
|
||||
|
||||
(defclass semanticdb-project-database (eieio-instance-tracker)
|
||||
((tracking-symbol :initform semanticdb-database-list)
|
||||
(reference-directory :type string
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ Argument THIS is the target that should insert stuff."
|
|||
;; "Target class for Emacs/Semantic grammar files." nil nil)
|
||||
|
||||
(ede-proj-register-target "semantic grammar"
|
||||
semantic-ede-proj-target-grammar)
|
||||
'semantic-ede-proj-target-grammar)
|
||||
|
||||
(provide 'semantic/ede-grammar)
|
||||
|
||||
|
|
|
|||
|
|
@ -378,11 +378,11 @@ If FORMS includes a call to `semantic-throw-on-input', then
|
|||
if a user presses any key during execution, this form macro
|
||||
will exit with the value passed to `semantic-throw-on-input'.
|
||||
If FORMS completes, then the return value is the same as `progn'."
|
||||
(declare (indent 1))
|
||||
`(let ((semantic-current-input-throw-symbol ,symbol)
|
||||
(semantic--on-input-start-marker (point-marker)))
|
||||
(catch ,symbol
|
||||
,@forms)))
|
||||
(put 'semantic-exit-on-input 'lisp-indent-function 1)
|
||||
|
||||
(defmacro semantic-throw-on-input (from)
|
||||
"Exit with `throw' when in `semantic-exit-on-input' on user input.
|
||||
|
|
@ -391,15 +391,14 @@ to pass to `throw'. It is recommended to use the name of the function
|
|||
calling this one."
|
||||
`(when (and semantic-current-input-throw-symbol
|
||||
(or (input-pending-p)
|
||||
(save-excursion
|
||||
;; Timers might run during accept-process-output.
|
||||
;; If they redisplay, point must be where the user
|
||||
;; expects. (Bug#15045)
|
||||
(set-buffer (marker-buffer
|
||||
semantic--on-input-start-marker))
|
||||
(goto-char (marker-position
|
||||
semantic--on-input-start-marker))
|
||||
(accept-process-output))))
|
||||
(with-current-buffer
|
||||
;; Timers might run during accept-process-output.
|
||||
;; If they redisplay, point must be where the user
|
||||
;; expects. (Bug#15045)
|
||||
(marker-buffer semantic--on-input-start-marker)
|
||||
(save-excursion
|
||||
(goto-char semantic--on-input-start-marker)
|
||||
(accept-process-output)))))
|
||||
(throw semantic-current-input-throw-symbol ,from)))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1665,13 +1665,14 @@ Select the buffer containing the tag's definition, and move point there."
|
|||
(declare-function eldoc-get-fnsym-args-string "eldoc")
|
||||
(declare-function eldoc-get-var-docstring "eldoc")
|
||||
|
||||
(defvar semantic-grammar-eldoc-last-data (cons nil nil))
|
||||
|
||||
(defun semantic-grammar-eldoc-get-macro-docstring (macro expander)
|
||||
"Return a one-line docstring for the given grammar MACRO.
|
||||
EXPANDER is the name of the function that expands MACRO."
|
||||
(require 'eldoc)
|
||||
(if (and (eq expander (aref eldoc-last-data 0))
|
||||
(eq 'function (aref eldoc-last-data 2)))
|
||||
(aref eldoc-last-data 1)
|
||||
(if (eq expander (car semantic-grammar-eldoc-last-data))
|
||||
(cdr semantic-grammar-eldoc-last-data)
|
||||
(let ((doc (help-split-fundoc (documentation expander t) expander)))
|
||||
(cond
|
||||
(doc
|
||||
|
|
@ -1684,7 +1685,7 @@ EXPANDER is the name of the function that expands MACRO."
|
|||
(setq doc
|
||||
(eldoc-docstring-format-sym-doc
|
||||
macro (format "==> %s %s" expander doc) 'default))
|
||||
(eldoc-last-data-store expander doc 'function))
|
||||
(setq semantic-grammar-eldoc-last-data (cons expander doc)))
|
||||
doc)))
|
||||
|
||||
(define-mode-local-override semantic-idle-summary-current-symbol-info
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ Saves scoping information between runs of the analyzer.")
|
|||
"Get the current cached scope, and reset it."
|
||||
(when semanticdb-current-table
|
||||
(let ((co (semanticdb-cache-get semanticdb-current-table
|
||||
semantic-scope-cache)))
|
||||
'semantic-scope-cache)))
|
||||
(semantic-reset co))))
|
||||
|
||||
(defmethod semantic-scope-set-typecache ((cache semantic-scope-cache)
|
||||
|
|
@ -706,7 +706,7 @@ The class returned from the scope calculation is variable
|
|||
(let* ((TAG (semantic-current-tag))
|
||||
(scopecache
|
||||
(semanticdb-cache-get semanticdb-current-table
|
||||
semantic-scope-cache))
|
||||
'semantic-scope-cache))
|
||||
)
|
||||
(when (not (semantic-equivalent-tag-p TAG (oref scopecache tag)))
|
||||
(semantic-reset scopecache))
|
||||
|
|
|
|||
|
|
@ -87,10 +87,10 @@ for push, pop, and peek for the active template.")
|
|||
Useful if something goes wrong in SRecode, and the active template
|
||||
stack is broken."
|
||||
(interactive)
|
||||
(if (oref srecode-template active)
|
||||
(if (oref-default 'srecode-template active)
|
||||
(when (y-or-n-p (format "%d active templates. Flush? "
|
||||
(length (oref srecode-template active))))
|
||||
(oset-default srecode-template active nil))
|
||||
(length (oref-default 'srecode-template active))))
|
||||
(oset-default 'srecode-template active nil))
|
||||
(message "No active templates to flush."))
|
||||
)
|
||||
|
||||
|
|
@ -514,7 +514,7 @@ to the inserter constructor."
|
|||
;;(message "Compile: %s %S" name props)
|
||||
(if (not key)
|
||||
(apply 'srecode-template-inserter-variable name props)
|
||||
(let ((classes (eieio-class-children srecode-template-inserter))
|
||||
(let ((classes (eieio-class-children 'srecode-template-inserter))
|
||||
(new nil))
|
||||
;; Loop over the various subclasses and
|
||||
;; create the correct inserter.
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ If SET-TO is a string, then replace the text of OLAID wit SET-TO."
|
|||
|
||||
(defsubst srecode-active-template-region ()
|
||||
"Return the active region for template fields."
|
||||
(oref srecode-template-inserted-region active-region))
|
||||
(oref-default 'srecode-template-inserted-region active-region))
|
||||
|
||||
(defun srecode-field-post-command ()
|
||||
"Srecode field handler in the post command hook."
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ insertions."
|
|||
(propertize " (most recent at bottom)" 'face '(:slant italic))
|
||||
":\n")
|
||||
(data-debug-insert-stuff-list
|
||||
(reverse (oref srecode-template active)) "> ")
|
||||
(reverse (oref-default 'srecode-template active)) "> ")
|
||||
;; Show the current dictionary.
|
||||
(insert (propertize "Dictionary" 'face '(:weight bold)) "\n")
|
||||
(data-debug-insert-thing dictionary "" "> ")
|
||||
|
|
@ -396,7 +396,7 @@ Specify the :blank argument to enable this inserter.")
|
|||
(pm (point-marker)))
|
||||
(when (and inbuff
|
||||
;; Don't do this if we are not the active template.
|
||||
(= (length (oref srecode-template active)) 1))
|
||||
(= (length (oref-default 'srecode-template active)) 1))
|
||||
|
||||
(when (and (eq i t) inbuff (not (eq (oref sti where) 'begin)))
|
||||
(indent-according-to-mode)
|
||||
|
|
@ -773,7 +773,7 @@ generalized marker will do something else. See
|
|||
;; valid. Compare this to the actual template nesting depth and
|
||||
;; maybe use the override function which is stored in the cdr.
|
||||
(if (and srecode-template-inserter-point-override
|
||||
(<= (length (oref srecode-template active))
|
||||
(<= (length (oref-default 'srecode-template active))
|
||||
(car srecode-template-inserter-point-override)))
|
||||
;; Disable the old override while we do this.
|
||||
(let ((over (cdr srecode-template-inserter-point-override))
|
||||
|
|
@ -943,7 +943,7 @@ this template instance."
|
|||
;; Calculate and store the discovered template
|
||||
(let ((tmpl (srecode-template-get-table (srecode-table)
|
||||
templatenamepart))
|
||||
(active (oref srecode-template active))
|
||||
(active (oref-default 'srecode-template active))
|
||||
ctxt)
|
||||
(when (not tmpl)
|
||||
;; If it isn't just available, scan back through
|
||||
|
|
@ -1053,7 +1053,7 @@ template where a ^ inserter occurs."
|
|||
(lexical-let ((inserter1 sti))
|
||||
(cons
|
||||
;; DEPTH
|
||||
(+ (length (oref srecode-template active)) 1)
|
||||
(+ (length (oref-default 'srecode-template active)) 1)
|
||||
;; FUNCTION
|
||||
(lambda (dict)
|
||||
(let ((srecode-template-inserter-point-override nil))
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ if that file is NEW, otherwise assume the mode has not changed."
|
|||
(when (not srecode-current-map)
|
||||
(condition-case nil
|
||||
(setq srecode-current-map
|
||||
(eieio-persistent-read srecode-map-save-file srecode-map))
|
||||
(eieio-persistent-read srecode-map-save-file 'srecode-map))
|
||||
(error
|
||||
;; There was an error loading the old map. Create a new one.
|
||||
(setq srecode-current-map
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ or is created with the bounds of SEQ."
|
|||
(if (stringp (car (oref seq data)))
|
||||
(let ((labels (oref seq data)))
|
||||
(if (not axis)
|
||||
(setq axis (make-instance chart-axis-names
|
||||
(setq axis (make-instance 'chart-axis-names
|
||||
:name (oref seq name)
|
||||
:items labels
|
||||
:chart c))
|
||||
|
|
@ -430,7 +430,7 @@ or is created with the bounds of SEQ."
|
|||
(let ((range (cons 0 1))
|
||||
(l (oref seq data)))
|
||||
(if (not axis)
|
||||
(setq axis (make-instance chart-axis-range
|
||||
(setq axis (make-instance 'chart-axis-range
|
||||
:name (oref seq name)
|
||||
:chart c)))
|
||||
(while l
|
||||
|
|
@ -577,19 +577,19 @@ labeled NUMTITLE.
|
|||
Optional arguments:
|
||||
Set the chart's max element display to MAX, and sort lists with
|
||||
SORT-PRED if desired."
|
||||
(let ((nc (make-instance chart-bar
|
||||
(let ((nc (make-instance 'chart-bar
|
||||
:title title
|
||||
:key-label "8-m" ; This is a text key pic
|
||||
:direction dir
|
||||
))
|
||||
(iv (eq dir 'vertical)))
|
||||
(chart-add-sequence nc
|
||||
(make-instance chart-sequece
|
||||
(make-instance 'chart-sequece
|
||||
:data namelst
|
||||
:name nametitle)
|
||||
(if iv 'x-axis 'y-axis))
|
||||
(chart-add-sequence nc
|
||||
(make-instance chart-sequece
|
||||
(make-instance 'chart-sequece
|
||||
:data numlst
|
||||
:name numtitle)
|
||||
(if iv 'y-axis 'x-axis))
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
;; error if a slot is unbound.
|
||||
(defclass eieio-instance-inheritor ()
|
||||
((parent-instance :initarg :parent-instance
|
||||
:type eieio-instance-inheritor-child
|
||||
:type eieio-instance-inheritor
|
||||
:documentation
|
||||
"The parent of this instance.
|
||||
If a slot of this class is referenced, and is unbound, then the parent
|
||||
|
|
@ -63,25 +63,10 @@ SLOT-NAME is the offending slot. FN is the function signaling the error."
|
|||
;; Throw the regular signal.
|
||||
(call-next-method)))
|
||||
|
||||
(defmethod clone ((obj eieio-instance-inheritor) &rest params)
|
||||
(defmethod clone ((obj eieio-instance-inheritor) &rest _params)
|
||||
"Clone OBJ, initializing `:parent' to OBJ.
|
||||
All slots are unbound, except those initialized with PARAMS."
|
||||
(let ((nobj (make-vector (length obj) eieio-unbound))
|
||||
(nm (eieio--object-name obj))
|
||||
(passname (and params (stringp (car params))))
|
||||
(num 1))
|
||||
(aset nobj 0 'object)
|
||||
(setf (eieio--object-class nobj) (eieio--object-class obj))
|
||||
;; The following was copied from the default clone.
|
||||
(if (not passname)
|
||||
(save-match-data
|
||||
(if (string-match "-\\([0-9]+\\)" nm)
|
||||
(setq num (1+ (string-to-number (match-string 1 nm)))
|
||||
nm (substring nm 0 (match-beginning 0))))
|
||||
(setf (eieio--object-name nobj) (concat nm "-" (int-to-string num))))
|
||||
(setf (eieio--object-name nobj) (car params)))
|
||||
;; Now initialize from params.
|
||||
(if params (shared-initialize nobj (if passname (cdr params) params)))
|
||||
(let ((nobj (call-next-method)))
|
||||
(oset nobj parent-instance obj)
|
||||
nobj))
|
||||
|
||||
|
|
@ -155,7 +140,7 @@ Multiple calls to `make-instance' will return this object."))
|
|||
A singleton is a class which will only ever have one instance."
|
||||
:abstract t)
|
||||
|
||||
(defmethod constructor :STATIC ((class eieio-singleton) _name &rest _slots)
|
||||
(defmethod eieio-constructor :STATIC ((class eieio-singleton) &rest _slots)
|
||||
"Constructor for singleton CLASS.
|
||||
NAME and SLOTS initialize the new object.
|
||||
This constructor guarantees that no matter how many you request,
|
||||
|
|
@ -270,7 +255,7 @@ malicious code.
|
|||
Note: This function recurses when a slot of :type of some object is
|
||||
identified, and needing more object creation."
|
||||
(let ((objclass (nth 0 inputlist))
|
||||
(objname (nth 1 inputlist))
|
||||
;; (objname (nth 1 inputlist))
|
||||
(slots (nthcdr 2 inputlist))
|
||||
(createslots nil))
|
||||
|
||||
|
|
@ -285,7 +270,7 @@ identified, and needing more object creation."
|
|||
;; In addition, strip out quotes, list functions, and update
|
||||
;; object constructors as needed.
|
||||
(setq value (eieio-persistent-validate/fix-slot-value
|
||||
objclass name value))
|
||||
(eieio--class-v objclass) name value))
|
||||
|
||||
(push name createslots)
|
||||
(push value createslots)
|
||||
|
|
@ -293,7 +278,7 @@ identified, and needing more object creation."
|
|||
|
||||
(setq slots (cdr (cdr slots))))
|
||||
|
||||
(apply 'make-instance objclass objname (nreverse createslots))
|
||||
(apply #'make-instance objclass (nreverse createslots))
|
||||
|
||||
;;(eval inputlist)
|
||||
))
|
||||
|
|
@ -305,11 +290,13 @@ constructor functions are considered valid.
|
|||
Second, any text properties will be stripped from strings."
|
||||
(cond ((consp proposed-value)
|
||||
;; Lists with something in them need special treatment.
|
||||
(let ((slot-idx (eieio-slot-name-index class nil slot))
|
||||
(let ((slot-idx (eieio--slot-name-index class
|
||||
nil slot))
|
||||
(type nil)
|
||||
(classtype nil))
|
||||
(setq slot-idx (- slot-idx 3))
|
||||
(setq type (aref (eieio--class-public-type (class-v class))
|
||||
(setq slot-idx (- slot-idx
|
||||
(eval-when-compile eieio--object-num-slots)))
|
||||
(setq type (aref (eieio--class-public-type class)
|
||||
slot-idx))
|
||||
|
||||
(setq classtype (eieio-persistent-slot-type-is-class-p
|
||||
|
|
@ -346,8 +333,8 @@ Second, any text properties will be stripped from strings."
|
|||
(unless (and
|
||||
;; Do we have a type?
|
||||
(consp classtype) (class-p (car classtype)))
|
||||
(error "In save file, list of object constructors found, but no :type specified for slot %S"
|
||||
slot))
|
||||
(error "In save file, list of object constructors found, but no :type specified for slot %S of type %S"
|
||||
slot classtype))
|
||||
|
||||
;; We have a predicate, but it doesn't satisfy the predicate?
|
||||
(dolist (PV (cdr proposed-value))
|
||||
|
|
@ -375,31 +362,49 @@ Second, any text properties will be stripped from strings."
|
|||
)
|
||||
|
||||
(defun eieio-persistent-slot-type-is-class-p (type)
|
||||
"Return the class refered to in TYPE.
|
||||
"Return the class referred to in TYPE.
|
||||
If no class is referenced there, then return nil."
|
||||
(cond ((class-p type)
|
||||
;; If the type is a class, then return it.
|
||||
type)
|
||||
((and (eq 'list-of (car-safe type)) (class-p (cadr type)))
|
||||
;; If it is the type of a list of a class, then return that class and
|
||||
;; the type.
|
||||
(cons (cadr type) type))
|
||||
|
||||
((and (symbolp type) (string-match "-child$" (symbol-name type))
|
||||
((and (symbolp type) (get type 'cl-deftype-handler))
|
||||
;; Macro-expand the type according to cl-deftype definitions.
|
||||
(eieio-persistent-slot-type-is-class-p
|
||||
(funcall (get type 'cl-deftype-handler))))
|
||||
|
||||
;; FIXME: foo-child should not be a valid type!
|
||||
((and (symbolp type) (string-match "-child\\'" (symbol-name type))
|
||||
(class-p (intern-soft (substring (symbol-name type) 0
|
||||
(match-beginning 0)))))
|
||||
(unless eieio-backward-compatibility
|
||||
(error "Use of bogus %S type instead of %S"
|
||||
type (intern-soft (substring (symbol-name type) 0
|
||||
(match-beginning 0)))))
|
||||
;; If it is the predicate ending with -child, then return
|
||||
;; that class. Unfortunately, in EIEIO, typep of just the
|
||||
;; class is the same as if we used -child, so no further work needed.
|
||||
(intern-soft (substring (symbol-name type) 0
|
||||
(match-beginning 0))))
|
||||
|
||||
((and (symbolp type) (string-match "-list$" (symbol-name type))
|
||||
;; FIXME: foo-list should not be a valid type!
|
||||
((and (symbolp type) (string-match "-list\\'" (symbol-name type))
|
||||
(class-p (intern-soft (substring (symbol-name type) 0
|
||||
(match-beginning 0)))))
|
||||
(unless eieio-backward-compatibility
|
||||
(error "Use of bogus %S type instead of (list-of %S)"
|
||||
type (intern-soft (substring (symbol-name type) 0
|
||||
(match-beginning 0)))))
|
||||
;; If it is the predicate ending with -list, then return
|
||||
;; that class and the predicate to use.
|
||||
(cons (intern-soft (substring (symbol-name type) 0
|
||||
(match-beginning 0)))
|
||||
type))
|
||||
|
||||
((and (consp type) (eq (car type) 'or))
|
||||
((eq (car-safe type) 'or)
|
||||
;; If type is a list, and is an or, it is possibly something
|
||||
;; like (or null myclass), so check for that.
|
||||
(let ((ans nil))
|
||||
|
|
@ -463,34 +468,38 @@ instance."
|
|||
|
||||
|
||||
;;; Named object
|
||||
;;
|
||||
;; Named objects use the objects `name' as a slot, and that slot
|
||||
;; is accessed with the `object-name' symbol.
|
||||
|
||||
(defclass eieio-named ()
|
||||
()
|
||||
"Object with a name.
|
||||
Name storage already occurs in an object. This object provides get/set
|
||||
access to it."
|
||||
((object-name :initarg :object-name :initform nil))
|
||||
"Object with a name."
|
||||
:abstract t)
|
||||
|
||||
(defmethod slot-missing ((obj eieio-named)
|
||||
slot-name operation &optional new-value)
|
||||
"Called when a non-existent slot is accessed.
|
||||
For variable `eieio-named', provide an imaginary `object-name' slot.
|
||||
Argument OBJ is the named object.
|
||||
Argument SLOT-NAME is the slot that was attempted to be accessed.
|
||||
OPERATION is the type of access, such as `oref' or `oset'.
|
||||
NEW-VALUE is the value that was being set into SLOT if OPERATION were
|
||||
a set type."
|
||||
(if (memq slot-name '(object-name :object-name))
|
||||
(cond ((eq operation 'oset)
|
||||
(if (not (stringp new-value))
|
||||
(signal 'invalid-slot-type
|
||||
(list obj slot-name 'string new-value)))
|
||||
(eieio-object-set-name-string obj new-value))
|
||||
(t (eieio-object-name-string obj)))
|
||||
(call-next-method)))
|
||||
(defmethod eieio-object-name-string ((obj eieio-named))
|
||||
"Return a string which is OBJ's name."
|
||||
(or (slot-value obj 'object-name)
|
||||
(symbol-name (eieio-object-class obj))))
|
||||
|
||||
(defmethod eieio-object-set-name-string ((obj eieio-named) name)
|
||||
"Set the string which is OBJ's NAME."
|
||||
(eieio--check-type stringp name)
|
||||
(eieio-oset obj 'object-name name))
|
||||
|
||||
(defmethod clone ((obj eieio-named) &rest params)
|
||||
"Clone OBJ, initializing `:parent' to OBJ.
|
||||
All slots are unbound, except those initialized with PARAMS."
|
||||
(let* ((newname (and (stringp (car params)) (pop params)))
|
||||
(nobj (apply #'call-next-method obj params))
|
||||
(nm (slot-value obj 'object-name)))
|
||||
(eieio-oset obj 'object-name
|
||||
(or newname
|
||||
(save-match-data
|
||||
(if (and nm (string-match "-\\([0-9]+\\)" nm))
|
||||
(let ((num (1+ (string-to-number
|
||||
(match-string 1 nm)))))
|
||||
(concat (substring nm 0 (match-beginning 0))
|
||||
"-" (int-to-string num)))
|
||||
(concat nm "-1")))))
|
||||
nobj))
|
||||
|
||||
(provide 'eieio-base)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
|||
;;; eieio-custom.el -- eieio object customization
|
||||
;;; eieio-custom.el -- eieio object customization -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 1999-2001, 2005, 2007-2015 Free Software Foundation,
|
||||
;; Inc.
|
||||
|
|
@ -70,7 +70,7 @@ of these.")
|
|||
:documentation "A number of thingies."))
|
||||
"A class for testing the widget on.")
|
||||
|
||||
(defcustom eieio-widget-test (eieio-widget-test-class "Foo")
|
||||
(defcustom eieio-widget-test (eieio-widget-test-class)
|
||||
"Test variable for editing an object."
|
||||
:type 'object
|
||||
:group 'eieio)
|
||||
|
|
@ -136,7 +136,7 @@ Updates occur regardless of the current customization group.")
|
|||
))
|
||||
(widget-value-set vc (widget-value vc))))
|
||||
|
||||
(defun eieio-custom-toggle-parent (widget &rest ignore)
|
||||
(defun eieio-custom-toggle-parent (widget &rest _)
|
||||
"Toggle visibility of parent of WIDGET.
|
||||
Optional argument IGNORE is an extraneous parameter."
|
||||
(eieio-custom-toggle-hide (widget-get widget :parent)))
|
||||
|
|
@ -154,7 +154,7 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
:clone-object-children nil
|
||||
)
|
||||
|
||||
(defun eieio-object-match (widget value)
|
||||
(defun eieio-object-match (_widget _value)
|
||||
"Match info for WIDGET against VALUE."
|
||||
;; Write me
|
||||
t)
|
||||
|
|
@ -193,7 +193,7 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
(let* ((chil nil)
|
||||
(obj (widget-get widget :value))
|
||||
(master-group (widget-get widget :eieio-group))
|
||||
(cv (class-v (eieio--object-class obj)))
|
||||
(cv (eieio--object-class-object obj))
|
||||
(slots (eieio--class-public-a cv))
|
||||
(flabel (eieio--class-public-custom-label cv))
|
||||
(fgroup (eieio--class-public-custom-group cv))
|
||||
|
|
@ -208,7 +208,8 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
chil)))
|
||||
;; Display information about the group being shown
|
||||
(when master-group
|
||||
(let ((groups (class-option (eieio--object-class obj) :custom-groups)))
|
||||
(let ((groups (eieio--class-option (eieio--object-class-object obj)
|
||||
:custom-groups)))
|
||||
(widget-insert "Groups:")
|
||||
(while groups
|
||||
(widget-insert " ")
|
||||
|
|
@ -216,7 +217,7 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
(widget-insert "*" (capitalize (symbol-name master-group)) "*")
|
||||
(widget-create 'push-button
|
||||
:thing (cons obj (car groups))
|
||||
:notify (lambda (widget &rest stuff)
|
||||
:notify (lambda (widget &rest _)
|
||||
(eieio-customize-object
|
||||
(car (widget-get widget :thing))
|
||||
(cdr (widget-get widget :thing))))
|
||||
|
|
@ -260,8 +261,8 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
(car flabel)
|
||||
(let ((s (symbol-name
|
||||
(or
|
||||
(class-slot-initarg
|
||||
(eieio--object-class obj)
|
||||
(eieio--class-slot-initarg
|
||||
(eieio--object-class-object obj)
|
||||
(car slots))
|
||||
(car slots)))))
|
||||
(capitalize
|
||||
|
|
@ -288,7 +289,7 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
"Get the value of WIDGET."
|
||||
(let* ((obj (widget-get widget :value))
|
||||
(master-group eieio-cog)
|
||||
(cv (class-v (eieio--object-class obj)))
|
||||
(cv (eieio--object-class-object obj))
|
||||
(fgroup (eieio--class-public-custom-group cv))
|
||||
(wids (widget-get widget :children))
|
||||
(name (if (widget-get widget :eieio-show-name)
|
||||
|
|
@ -296,7 +297,7 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
nil))
|
||||
(chil (if (widget-get widget :eieio-show-name)
|
||||
(nthcdr 1 wids) wids))
|
||||
(cv (class-v (eieio--object-class obj)))
|
||||
(cv (eieio--object-class-object obj))
|
||||
(slots (eieio--class-public-a cv))
|
||||
(fcust (eieio--class-public-custom cv)))
|
||||
;; If there are any prefix widgets, clear them.
|
||||
|
|
@ -317,11 +318,11 @@ Optional argument IGNORE is an extraneous parameter."
|
|||
fgroup (cdr fgroup)
|
||||
fcust (cdr fcust)))
|
||||
;; Set any name updates on it.
|
||||
(if name (setf (eieio--object-name obj) name))
|
||||
(if name (eieio-object-set-name-string obj name))
|
||||
;; This is the same object we had before.
|
||||
obj))
|
||||
|
||||
(defmethod eieio-done-customizing ((obj eieio-default-superclass))
|
||||
(defmethod eieio-done-customizing ((_obj eieio-default-superclass))
|
||||
"When applying change to a widget, call this method.
|
||||
This method is called by the default widget-edit commands.
|
||||
User made commands should also call this method when applying changes.
|
||||
|
|
@ -385,18 +386,18 @@ These groups are specified with the `:group' slot flag."
|
|||
(make-local-variable 'eieio-cog)
|
||||
(setq eieio-cog g)))
|
||||
|
||||
(defmethod eieio-custom-object-apply-reset ((obj eieio-default-superclass))
|
||||
(defmethod eieio-custom-object-apply-reset ((_obj eieio-default-superclass))
|
||||
"Insert an Apply and Reset button into the object editor.
|
||||
Argument OBJ is the object being customized."
|
||||
(widget-create 'push-button
|
||||
:notify (lambda (&rest ignore)
|
||||
:notify (lambda (&rest _)
|
||||
(widget-apply eieio-wo :value-get)
|
||||
(eieio-done-customizing eieio-co)
|
||||
(bury-buffer))
|
||||
"Accept")
|
||||
(widget-insert " ")
|
||||
(widget-create 'push-button
|
||||
:notify (lambda (&rest ignore)
|
||||
:notify (lambda (&rest _)
|
||||
;; I think the act of getting it sets
|
||||
;; its value through the get function.
|
||||
(message "Applying Changes...")
|
||||
|
|
@ -406,13 +407,13 @@ Argument OBJ is the object being customized."
|
|||
"Apply")
|
||||
(widget-insert " ")
|
||||
(widget-create 'push-button
|
||||
:notify (lambda (&rest ignore)
|
||||
:notify (lambda (&rest _)
|
||||
(message "Resetting")
|
||||
(eieio-customize-object eieio-co eieio-cog))
|
||||
"Reset")
|
||||
(widget-insert " ")
|
||||
(widget-create 'push-button
|
||||
:notify (lambda (&rest ignore)
|
||||
:notify (lambda (&rest _)
|
||||
(bury-buffer))
|
||||
"Cancel"))
|
||||
|
||||
|
|
@ -431,13 +432,11 @@ Must return the created widget."
|
|||
:clone-object-children t
|
||||
)
|
||||
|
||||
(defun eieio-object-value-to-abstract (widget value)
|
||||
(defun eieio-object-value-to-abstract (_widget value)
|
||||
"For WIDGET, convert VALUE to an abstract /safe/ representation."
|
||||
(if (eieio-object-p value) value
|
||||
(if (null value) value
|
||||
nil)))
|
||||
(if (eieio-object-p value) value))
|
||||
|
||||
(defun eieio-object-abstract-to-value (widget value)
|
||||
(defun eieio-object-abstract-to-value (_widget value)
|
||||
"For WIDGET, convert VALUE from an abstract /safe/ representation."
|
||||
value)
|
||||
|
||||
|
|
@ -453,7 +452,7 @@ Must return the created widget."
|
|||
(vector (concat "Group " (symbol-name group))
|
||||
(list 'customize-object obj (list 'quote group))
|
||||
t))
|
||||
(class-option (eieio--object-class obj) :custom-groups)))
|
||||
(eieio--class-option (eieio--object-class-object obj) :custom-groups)))
|
||||
|
||||
(defvar eieio-read-custom-group-history nil
|
||||
"History for the custom group reader.")
|
||||
|
|
@ -461,7 +460,8 @@ Must return the created widget."
|
|||
(defmethod eieio-read-customization-group ((obj eieio-default-superclass))
|
||||
"Do a completing read on the name of a customization group in OBJ.
|
||||
Return the symbol for the group, or nil"
|
||||
(let ((g (class-option (eieio--object-class obj) :custom-groups)))
|
||||
(let ((g (eieio--class-option (eieio--object-class-object obj)
|
||||
:custom-groups)))
|
||||
(if (= (length g) 1)
|
||||
(car g)
|
||||
;; Make the association list
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;;; eieio-datadebug.el --- EIEIO extensions to the data debugger.
|
||||
;;; eieio-datadebug.el --- EIEIO extensions to the data debugger. -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ PREBUTTONTEXT is some text between PREFIX and the object button."
|
|||
prefix
|
||||
"Name: ")
|
||||
(let* ((cl (eieio-object-class obj))
|
||||
(cv (class-v cl)))
|
||||
(cv (eieio--class-v cl)))
|
||||
(data-debug-insert-thing (class-constructor cl)
|
||||
prefix
|
||||
"Class: ")
|
||||
|
|
@ -96,7 +96,8 @@ PREBUTTONTEXT is some text between PREFIX and the object button."
|
|||
)
|
||||
(while publa
|
||||
(if (slot-boundp obj (car publa))
|
||||
(let* ((i (class-slot-initarg cl (car publa)))
|
||||
(let* ((i (eieio--class-slot-initarg (eieio--class-v cl)
|
||||
(car publa)))
|
||||
(v (eieio-oref obj (car publa))))
|
||||
(data-debug-insert-thing
|
||||
v prefix (concat
|
||||
|
|
@ -104,7 +105,8 @@ PREBUTTONTEXT is some text between PREFIX and the object button."
|
|||
(symbol-name (car publa)))
|
||||
" ")))
|
||||
;; Unbound case
|
||||
(let ((i (class-slot-initarg cl (car publa))))
|
||||
(let ((i (eieio--class-slot-initarg (eieio--class-v cl)
|
||||
(car publa))))
|
||||
(data-debug-insert-custom
|
||||
"#unbound" prefix
|
||||
(concat (if i (symbol-name i)
|
||||
|
|
@ -135,9 +137,9 @@ PREBUTTONTEXT is some text between PREFIX and the object button."
|
|||
(let* ((eieio-pre-method-execution-functions
|
||||
(lambda (l) (throw 'moose l) ))
|
||||
(data
|
||||
(catch 'moose (eieio-generic-call
|
||||
(catch 'moose (eieio--generic-call
|
||||
method (list class))))
|
||||
(buf (data-debug-new-buffer "*Method Invocation*"))
|
||||
(_buf (data-debug-new-buffer "*Method Invocation*"))
|
||||
(data2 (mapcar (lambda (sym)
|
||||
(symbol-function (car sym)))
|
||||
data)))
|
||||
|
|
|
|||
904
lisp/emacs-lisp/eieio-generic.el
Normal file
904
lisp/emacs-lisp/eieio-generic.el
Normal file
|
|
@ -0,0 +1,904 @@
|
|||
;;; eieio-generic.el --- CLOS-style generics for EIEIO -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 1995-1996, 1998-2015 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
||||
;; Keywords: OO, lisp
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
;;
|
||||
;; The "core" part of EIEIO is the implementation for the object
|
||||
;; system (such as eieio-defclass, or eieio-defmethod) but not the
|
||||
;; base classes for the object system, which are defined in EIEIO.
|
||||
;;
|
||||
;; See the commentary for eieio.el for more about EIEIO itself.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'eieio-core)
|
||||
(declare-function child-of-class-p "eieio")
|
||||
|
||||
(defconst eieio--method-static 0 "Index into :static tag on a method.")
|
||||
(defconst eieio--method-before 1 "Index into :before tag on a method.")
|
||||
(defconst eieio--method-primary 2 "Index into :primary tag on a method.")
|
||||
(defconst eieio--method-after 3 "Index into :after tag on a method.")
|
||||
(defconst eieio--method-num-lists 4 "Number of indexes into methods vector in which groups of functions are kept.")
|
||||
(defconst eieio--method-generic-before 4 "Index into generic :before tag on a method.")
|
||||
(defconst eieio--method-generic-primary 5 "Index into generic :primary tag on a method.")
|
||||
(defconst eieio--method-generic-after 6 "Index into generic :after tag on a method.")
|
||||
(defconst eieio--method-num-slots 7 "Number of indexes into a method's vector.")
|
||||
|
||||
(defsubst eieio--specialized-key-to-generic-key (key)
|
||||
"Convert a specialized KEY into a generic method key."
|
||||
(cond ((eq key eieio--method-static) 0) ;; don't convert
|
||||
((< key eieio--method-num-lists) (+ key 3)) ;; The conversion
|
||||
(t key) ;; already generic.. maybe.
|
||||
))
|
||||
|
||||
|
||||
(defsubst generic-p (method)
|
||||
"Return non-nil if symbol METHOD is a generic function.
|
||||
Only methods have the symbol `eieio-method-hashtable' as a property
|
||||
\(which contains a list of all bindings to that method type.)"
|
||||
(and (fboundp method) (get method 'eieio-method-hashtable)))
|
||||
|
||||
(defun eieio--generic-primary-only-p (method)
|
||||
"Return t if symbol METHOD is a generic function with only primary methods.
|
||||
Only methods have the symbol `eieio-method-hashtable' as a property (which
|
||||
contains a list of all bindings to that method type.)
|
||||
Methods with only primary implementations are executed in an optimized way."
|
||||
(and (generic-p method)
|
||||
(let ((M (get method 'eieio-method-tree)))
|
||||
(not (or (>= 0 (length (aref M eieio--method-primary)))
|
||||
(aref M eieio--method-static)
|
||||
(aref M eieio--method-before)
|
||||
(aref M eieio--method-after)
|
||||
(aref M eieio--method-generic-before)
|
||||
(aref M eieio--method-generic-primary)
|
||||
(aref M eieio--method-generic-after)))
|
||||
)))
|
||||
|
||||
(defun eieio--generic-primary-only-one-p (method)
|
||||
"Return t if symbol METHOD is a generic function with only primary methods.
|
||||
Only methods have the symbol `eieio-method-hashtable' as a property (which
|
||||
contains a list of all bindings to that method type.)
|
||||
Methods with only primary implementations are executed in an optimized way."
|
||||
(and (generic-p method)
|
||||
(let ((M (get method 'eieio-method-tree)))
|
||||
(not (or (/= 1 (length (aref M eieio--method-primary)))
|
||||
(aref M eieio--method-static)
|
||||
(aref M eieio--method-before)
|
||||
(aref M eieio--method-after)
|
||||
(aref M eieio--method-generic-before)
|
||||
(aref M eieio--method-generic-primary)
|
||||
(aref M eieio--method-generic-after)))
|
||||
)))
|
||||
|
||||
(defun eieio--defgeneric-init-form (method doc-string)
|
||||
"Form to use for the initial definition of a generic."
|
||||
(while (and (fboundp method) (symbolp (symbol-function method)))
|
||||
;; Follow aliases, so methods applied to obsolete aliases still work.
|
||||
(setq method (symbol-function method)))
|
||||
|
||||
(cond
|
||||
((or (not (fboundp method))
|
||||
(eq 'autoload (car-safe (symbol-function method))))
|
||||
;; Make sure the method tables are installed.
|
||||
(eieio--mt-install method)
|
||||
;; Construct the actual body of this function.
|
||||
(put method 'function-documentation doc-string)
|
||||
(eieio--defgeneric-form method))
|
||||
((generic-p method) (symbol-function method)) ;Leave it as-is.
|
||||
(t (error "You cannot create a generic/method over an existing symbol: %s"
|
||||
method))))
|
||||
|
||||
(defun eieio--defgeneric-form (method)
|
||||
"The lambda form that would be used as the function defined on METHOD.
|
||||
All methods should call the same EIEIO function for dispatch.
|
||||
DOC-STRING is the documentation attached to METHOD."
|
||||
(lambda (&rest local-args)
|
||||
(eieio--generic-call method local-args)))
|
||||
|
||||
(defun eieio--defgeneric-form-primary-only (method)
|
||||
"The lambda form that would be used as the function defined on METHOD.
|
||||
All methods should call the same EIEIO function for dispatch.
|
||||
DOC-STRING is the documentation attached to METHOD."
|
||||
(lambda (&rest local-args)
|
||||
(eieio--generic-call-primary-only method local-args)))
|
||||
|
||||
(defvar eieio--generic-call-arglst nil
|
||||
"When using `call-next-method', provides a context for parameters.")
|
||||
(defvar eieio--generic-call-key nil
|
||||
"When using `call-next-method', provides a context for the current key.
|
||||
Keys are a number representing :before, :primary, and :after methods.")
|
||||
(defvar eieio--generic-call-next-method-list nil
|
||||
"When executing a PRIMARY or STATIC method, track the 'next-method'.
|
||||
During executions, the list is first generated, then as each next method
|
||||
is called, the next method is popped off the stack.")
|
||||
|
||||
(defun eieio--defgeneric-form-primary-only-one (method class impl)
|
||||
"The lambda form that would be used as the function defined on METHOD.
|
||||
All methods should call the same EIEIO function for dispatch.
|
||||
CLASS is the class symbol needed for private method access.
|
||||
IMPL is the symbol holding the method implementation."
|
||||
(lambda (&rest local-args)
|
||||
;; This is a cool cheat. Usually we need to look up in the
|
||||
;; method table to find out if there is a method or not. We can
|
||||
;; instead make that determination at load time when there is
|
||||
;; only one method. If the first arg is not a child of the class
|
||||
;; of that one implementation, then clearly, there is no method def.
|
||||
(if (not (eieio-object-p (car local-args)))
|
||||
;; Not an object. Just signal.
|
||||
(signal 'no-method-definition
|
||||
(list method local-args))
|
||||
|
||||
;; We do have an object. Make sure it is the right type.
|
||||
(if (not (child-of-class-p (eieio--object-class-object (car local-args))
|
||||
class))
|
||||
|
||||
;; If not the right kind of object, call no applicable
|
||||
(apply #'no-applicable-method (car local-args)
|
||||
method local-args)
|
||||
|
||||
;; It is ok, do the call.
|
||||
;; Fill in inter-call variables then evaluate the method.
|
||||
(let ((eieio--generic-call-next-method-list nil)
|
||||
(eieio--generic-call-key eieio--method-primary)
|
||||
(eieio--generic-call-arglst local-args)
|
||||
)
|
||||
(eieio--with-scoped-class (eieio--class-v class)
|
||||
(apply impl local-args)))))))
|
||||
|
||||
(defun eieio-unbind-method-implementations (method)
|
||||
"Make the generic method METHOD have no implementations.
|
||||
It will leave the original generic function in place,
|
||||
but remove reference to all implementations of METHOD."
|
||||
(put method 'eieio-method-tree nil)
|
||||
(put method 'eieio-method-hashtable nil))
|
||||
|
||||
(defun eieio--method-optimize-primary (method)
|
||||
(when eieio-optimize-primary-methods-flag
|
||||
;; Optimizing step:
|
||||
;;
|
||||
;; If this method, after this setup, only has primary methods, then
|
||||
;; we can setup the generic that way.
|
||||
(let ((doc-string (documentation method 'raw)))
|
||||
(put method 'function-documentation doc-string)
|
||||
;; Use `defalias' so as to interact properly with nadvice.el.
|
||||
(defalias method
|
||||
(if (eieio--generic-primary-only-p method)
|
||||
;; If there is only one primary method, then we can go one more
|
||||
;; optimization step.
|
||||
(if (eieio--generic-primary-only-one-p method)
|
||||
(let* ((M (get method 'eieio-method-tree))
|
||||
(entry (car (aref M eieio--method-primary))))
|
||||
(eieio--defgeneric-form-primary-only-one
|
||||
method (car entry) (cdr entry)))
|
||||
(eieio--defgeneric-form-primary-only method))
|
||||
(eieio--defgeneric-form method))))))
|
||||
|
||||
(defun eieio--defmethod (method kind argclass code)
|
||||
"Work part of the `defmethod' macro defining METHOD with ARGS."
|
||||
(let ((key
|
||||
;; Find optional keys.
|
||||
(cond ((memq kind '(:BEFORE :before)) eieio--method-before)
|
||||
((memq kind '(:AFTER :after)) eieio--method-after)
|
||||
((memq kind '(:STATIC :static)) eieio--method-static)
|
||||
((memq kind '(:PRIMARY :primary nil)) eieio--method-primary)
|
||||
;; Primary key.
|
||||
;; (t eieio--method-primary)
|
||||
(t (error "Unknown method kind %S" kind)))))
|
||||
|
||||
(while (and (fboundp method) (symbolp (symbol-function method)))
|
||||
;; Follow aliases, so methods applied to obsolete aliases still work.
|
||||
(setq method (symbol-function method)))
|
||||
|
||||
;; Make sure there is a generic (when called from defclass).
|
||||
(eieio--defalias
|
||||
method (eieio--defgeneric-init-form
|
||||
method (or (documentation code)
|
||||
(format "Generically created method `%s'." method))))
|
||||
;; Create symbol for property to bind to. If the first arg is of
|
||||
;; the form (varname vartype) and `vartype' is a class, then
|
||||
;; that class will be the type symbol. If not, then it will fall
|
||||
;; under the type `primary' which is a non-specific calling of the
|
||||
;; function.
|
||||
(if argclass
|
||||
(if (not (class-p argclass)) ;FIXME: Accept cl-defstructs!
|
||||
(error "Unknown class type %s in method parameters"
|
||||
argclass))
|
||||
;; Generics are higher.
|
||||
(setq key (eieio--specialized-key-to-generic-key key)))
|
||||
;; Put this lambda into the symbol so we can find it.
|
||||
(eieio--mt-add method code key argclass)
|
||||
)
|
||||
|
||||
(eieio--method-optimize-primary method)
|
||||
|
||||
method)
|
||||
|
||||
(define-obsolete-variable-alias 'eieio-pre-method-execution-hooks
|
||||
'eieio-pre-method-execution-functions "24.3")
|
||||
(defvar eieio-pre-method-execution-functions nil
|
||||
"Abnormal hook run just before an EIEIO method is executed.
|
||||
The hook function must accept one argument, the list of forms
|
||||
about to be executed.")
|
||||
|
||||
(defun eieio--generic-call (method args)
|
||||
"Call METHOD with ARGS.
|
||||
ARGS provides the context on which implementation to use.
|
||||
This should only be called from a generic function."
|
||||
;; We must expand our arguments first as they are always
|
||||
;; passed in as quoted symbols
|
||||
(let ((newargs nil) (mclass nil) (lambdas nil) (tlambdas nil) (keys nil)
|
||||
(eieio--generic-call-arglst args)
|
||||
(firstarg nil)
|
||||
(primarymethodlist nil))
|
||||
;; get a copy
|
||||
(setq newargs args
|
||||
firstarg (car newargs))
|
||||
;; Is the class passed in autoloaded?
|
||||
;; Since class names are also constructors, they can be autoloaded
|
||||
;; via the autoload command. Check for this, and load them in.
|
||||
;; It is ok if it doesn't turn out to be a class. Probably want that
|
||||
;; function loaded anyway.
|
||||
(if (and (symbolp firstarg)
|
||||
(fboundp firstarg)
|
||||
(autoloadp (symbol-function firstarg)))
|
||||
(autoload-do-load (symbol-function firstarg)))
|
||||
;; Determine the class to use.
|
||||
(cond ((eieio-object-p firstarg)
|
||||
(setq mclass (eieio--object-class-name firstarg)))
|
||||
((class-p firstarg)
|
||||
(setq mclass firstarg))
|
||||
)
|
||||
;; Make sure the class is a valid class
|
||||
;; mclass can be nil (meaning a generic for should be used.
|
||||
;; mclass cannot have a value that is not a class, however.
|
||||
(unless (or (null mclass) (class-p mclass))
|
||||
(error "Cannot dispatch method %S on class %S"
|
||||
method mclass)
|
||||
)
|
||||
;; Now create a list in reverse order of all the calls we have
|
||||
;; make in order to successfully do this right. Rules:
|
||||
;; 1) Only call generics if scoped-class is not defined
|
||||
;; This prevents multiple calls in the case of recursion
|
||||
;; 2) Only call static if this is a static method.
|
||||
;; 3) Only call specifics if the definition allows for them.
|
||||
;; 4) Call in order based on :before, :primary, and :after
|
||||
(when (eieio-object-p firstarg)
|
||||
;; Non-static calls do all this stuff.
|
||||
|
||||
;; :after methods
|
||||
(setq tlambdas
|
||||
(if mclass
|
||||
(eieio--mt-method-list method eieio--method-after mclass)
|
||||
(list (eieio--generic-form method eieio--method-after nil)))
|
||||
;;(or (and mclass (eieio--generic-form method eieio--method-after mclass))
|
||||
;; (eieio--generic-form method eieio--method-after nil))
|
||||
)
|
||||
(setq lambdas (append tlambdas lambdas)
|
||||
keys (append (make-list (length tlambdas) eieio--method-after) keys))
|
||||
|
||||
;; :primary methods
|
||||
(setq tlambdas
|
||||
(or (and mclass (eieio--generic-form method eieio--method-primary mclass))
|
||||
(eieio--generic-form method eieio--method-primary nil)))
|
||||
(when tlambdas
|
||||
(setq lambdas (cons tlambdas lambdas)
|
||||
keys (cons eieio--method-primary keys)
|
||||
primarymethodlist
|
||||
(eieio--mt-method-list method eieio--method-primary mclass)))
|
||||
|
||||
;; :before methods
|
||||
(setq tlambdas
|
||||
(if mclass
|
||||
(eieio--mt-method-list method eieio--method-before mclass)
|
||||
(list (eieio--generic-form method eieio--method-before nil)))
|
||||
;;(or (and mclass (eieio--generic-form method eieio--method-before mclass))
|
||||
;; (eieio--generic-form method eieio--method-before nil))
|
||||
)
|
||||
(setq lambdas (append tlambdas lambdas)
|
||||
keys (append (make-list (length tlambdas) eieio--method-before) keys))
|
||||
)
|
||||
|
||||
(if mclass
|
||||
;; For the case of a class,
|
||||
;; if there were no methods found, then there could be :static methods.
|
||||
(when (not lambdas)
|
||||
(setq tlambdas
|
||||
(eieio--generic-form method eieio--method-static mclass))
|
||||
(setq lambdas (cons tlambdas lambdas)
|
||||
keys (cons eieio--method-static keys)
|
||||
primarymethodlist ;; Re-use even with bad name here
|
||||
(eieio--mt-method-list method eieio--method-static mclass)))
|
||||
;; For the case of no class (ie - mclass == nil) then there may
|
||||
;; be a primary method.
|
||||
(setq tlambdas
|
||||
(eieio--generic-form method eieio--method-primary nil))
|
||||
(when tlambdas
|
||||
(setq lambdas (cons tlambdas lambdas)
|
||||
keys (cons eieio--method-primary keys)
|
||||
primarymethodlist
|
||||
(eieio--mt-method-list method eieio--method-primary nil)))
|
||||
)
|
||||
|
||||
(run-hook-with-args 'eieio-pre-method-execution-functions
|
||||
primarymethodlist)
|
||||
|
||||
;; Now loop through all occurrences forms which we must execute
|
||||
;; (which are happily sorted now) and execute them all!
|
||||
(let ((rval nil) (lastval nil) (found nil))
|
||||
(while lambdas
|
||||
(if (car lambdas)
|
||||
(eieio--with-scoped-class (cdr (car lambdas))
|
||||
(let* ((eieio--generic-call-key (car keys))
|
||||
(has-return-val
|
||||
(or (= eieio--generic-call-key eieio--method-primary)
|
||||
(= eieio--generic-call-key eieio--method-static)))
|
||||
(eieio--generic-call-next-method-list
|
||||
;; Use the cdr, as the first element is the fcn
|
||||
;; we are calling right now.
|
||||
(when has-return-val (cdr primarymethodlist)))
|
||||
)
|
||||
(setq found t)
|
||||
;;(setq rval (apply (car (car lambdas)) newargs))
|
||||
(setq lastval (apply (car (car lambdas)) newargs))
|
||||
(when has-return-val
|
||||
(setq rval lastval))
|
||||
)))
|
||||
(setq lambdas (cdr lambdas)
|
||||
keys (cdr keys)))
|
||||
(if (not found)
|
||||
(if (eieio-object-p (car args))
|
||||
(setq rval (apply #'no-applicable-method (car args) method args))
|
||||
(signal
|
||||
'no-method-definition
|
||||
(list method args))))
|
||||
rval)))
|
||||
|
||||
(defun eieio--generic-call-primary-only (method args)
|
||||
"Call METHOD with ARGS for methods with only :PRIMARY implementations.
|
||||
ARGS provides the context on which implementation to use.
|
||||
This should only be called from a generic function.
|
||||
|
||||
This method is like `eieio--generic-call', but only
|
||||
implementations in the :PRIMARY slot are queried. After many
|
||||
years of use, it appears that over 90% of methods in use
|
||||
have :PRIMARY implementations only. We can therefore optimize
|
||||
for this common case to improve performance."
|
||||
;; We must expand our arguments first as they are always
|
||||
;; passed in as quoted symbols
|
||||
(let ((newargs nil) (mclass nil) (lambdas nil)
|
||||
(eieio--generic-call-arglst args)
|
||||
(firstarg nil)
|
||||
(primarymethodlist nil)
|
||||
)
|
||||
;; get a copy
|
||||
(setq newargs args
|
||||
firstarg (car newargs))
|
||||
|
||||
;; Determine the class to use.
|
||||
(cond ((eieio-object-p firstarg)
|
||||
(setq mclass (eieio--object-class-name firstarg)))
|
||||
((not firstarg)
|
||||
(error "Method %s called on nil" method))
|
||||
(t
|
||||
(error "Primary-only method %s called on something not an object" method)))
|
||||
;; Make sure the class is a valid class
|
||||
;; mclass can be nil (meaning a generic for should be used.
|
||||
;; mclass cannot have a value that is not a class, however.
|
||||
(when (null mclass)
|
||||
(error "Cannot dispatch method %S on class %S" method mclass)
|
||||
)
|
||||
|
||||
;; :primary methods
|
||||
(setq lambdas (eieio--generic-form method eieio--method-primary mclass))
|
||||
(setq primarymethodlist ;; Re-use even with bad name here
|
||||
(eieio--mt-method-list method eieio--method-primary mclass))
|
||||
|
||||
;; Now loop through all occurrences forms which we must execute
|
||||
;; (which are happily sorted now) and execute them all!
|
||||
(eieio--with-scoped-class (cdr lambdas)
|
||||
(let* ((rval nil) (lastval nil)
|
||||
(eieio--generic-call-key eieio--method-primary)
|
||||
;; Use the cdr, as the first element is the fcn
|
||||
;; we are calling right now.
|
||||
(eieio--generic-call-next-method-list (cdr primarymethodlist))
|
||||
)
|
||||
|
||||
(if (or (not lambdas) (not (car lambdas)))
|
||||
|
||||
;; No methods found for this impl...
|
||||
(if (eieio-object-p (car args))
|
||||
(setq rval (apply #'no-applicable-method
|
||||
(car args) method args))
|
||||
(signal
|
||||
'no-method-definition
|
||||
(list method args)))
|
||||
|
||||
;; Do the regular implementation here.
|
||||
|
||||
(run-hook-with-args 'eieio-pre-method-execution-functions
|
||||
lambdas)
|
||||
|
||||
(setq lastval (apply (car lambdas) newargs))
|
||||
(setq rval lastval))
|
||||
|
||||
rval))))
|
||||
|
||||
(defun eieio--mt-method-list (method key class)
|
||||
"Return an alist list of methods lambdas.
|
||||
METHOD is the method name.
|
||||
KEY represents either :before, or :after methods.
|
||||
CLASS is the starting class to search from in the method tree.
|
||||
If CLASS is nil, then an empty list of methods should be returned."
|
||||
;; Note: eieiomt - the MT means MethodTree. See more comments below
|
||||
;; for the rest of the eieiomt methods.
|
||||
|
||||
;; Collect lambda expressions stored for the class and its parent
|
||||
;; classes.
|
||||
(let (lambdas)
|
||||
(dolist (ancestor (eieio--class-precedence-list (eieio--class-v class)))
|
||||
;; Lookup the form to use for the PRIMARY object for the next level
|
||||
(let ((tmpl (eieio--generic-form method key ancestor)))
|
||||
(when (and tmpl
|
||||
(or (not lambdas)
|
||||
;; This prevents duplicates coming out of the
|
||||
;; class method optimizer. Perhaps we should
|
||||
;; just not optimize before/afters?
|
||||
(not (member tmpl lambdas))))
|
||||
(push tmpl lambdas))))
|
||||
|
||||
;; Return collected lambda. For :after methods, return in current
|
||||
;; order (most general class last); Otherwise, reverse order.
|
||||
(if (eq key eieio--method-after)
|
||||
lambdas
|
||||
(nreverse lambdas))))
|
||||
|
||||
|
||||
;;;
|
||||
;; eieio-method-tree : eieio--mt-
|
||||
;;
|
||||
;; Stored as eieio-method-tree in property list of a generic method
|
||||
;;
|
||||
;; (eieio-method-tree . [BEFORE PRIMARY AFTER
|
||||
;; genericBEFORE genericPRIMARY genericAFTER])
|
||||
;; and
|
||||
;; (eieio-method-hashtable . [BEFORE PRIMARY AFTER
|
||||
;; genericBEFORE genericPRIMARY genericAFTER])
|
||||
;; where the association is a vector.
|
||||
;; (aref 0 -- all static methods.
|
||||
;; (aref 1 -- all methods classified as :before
|
||||
;; (aref 2 -- all methods classified as :primary
|
||||
;; (aref 3 -- all methods classified as :after
|
||||
;; (aref 4 -- a generic classified as :before
|
||||
;; (aref 5 -- a generic classified as :primary
|
||||
;; (aref 6 -- a generic classified as :after
|
||||
;;
|
||||
(defvar eieio--mt--optimizing-hashtable nil
|
||||
"While mapping atoms, this contain the hashtable being optimized.")
|
||||
|
||||
(defun eieio--mt-install (method-name)
|
||||
"Install the method tree, and hashtable onto METHOD-NAME.
|
||||
Do not do the work if they already exist."
|
||||
(unless (and (get method-name 'eieio-method-tree)
|
||||
(get method-name 'eieio-method-hashtable))
|
||||
(put method-name 'eieio-method-tree
|
||||
(make-vector eieio--method-num-slots nil))
|
||||
(let ((emto (put method-name 'eieio-method-hashtable
|
||||
(make-vector eieio--method-num-slots nil))))
|
||||
(aset emto 0 (make-hash-table :test 'eq))
|
||||
(aset emto 1 (make-hash-table :test 'eq))
|
||||
(aset emto 2 (make-hash-table :test 'eq))
|
||||
(aset emto 3 (make-hash-table :test 'eq)))))
|
||||
|
||||
(defun eieio--mt-add (method-name method key class)
|
||||
"Add to METHOD-NAME the forms METHOD in a call position KEY for CLASS.
|
||||
METHOD-NAME is the name created by a call to `defgeneric'.
|
||||
METHOD are the forms for a given implementation.
|
||||
KEY is an integer (see comment in eieio.el near this function) which
|
||||
is associated with the :static :before :primary and :after tags.
|
||||
It also indicates if CLASS is defined or not.
|
||||
CLASS is the class this method is associated with."
|
||||
(if (or (> key eieio--method-num-slots) (< key 0))
|
||||
(error "eieio--mt-add: method key error!"))
|
||||
(let ((emtv (get method-name 'eieio-method-tree))
|
||||
(emto (get method-name 'eieio-method-hashtable)))
|
||||
;; Make sure the method tables are available.
|
||||
(unless (and emtv emto)
|
||||
(error "Programmer error: eieio--mt-add"))
|
||||
;; only add new cells on if it doesn't already exist!
|
||||
(if (assq class (aref emtv key))
|
||||
(setcdr (assq class (aref emtv key)) method)
|
||||
(aset emtv key (cons (cons class method) (aref emtv key))))
|
||||
;; Add function definition into newly created symbol, and store
|
||||
;; said symbol in the correct hashtable, otherwise use the
|
||||
;; other array to keep this stuff.
|
||||
(if (< key eieio--method-num-lists)
|
||||
(puthash (eieio--class-v class) (list method) (aref emto key)))
|
||||
;; Save the defmethod file location in a symbol property.
|
||||
(let ((fname (if load-in-progress
|
||||
load-file-name
|
||||
buffer-file-name)))
|
||||
(when fname
|
||||
(when (string-match "\\.elc\\'" fname)
|
||||
(setq fname (substring fname 0 (1- (length fname)))))
|
||||
(cl-pushnew (list class fname) (get method-name 'method-locations)
|
||||
:test 'equal)))
|
||||
;; Now optimize the entire hashtable.
|
||||
(if (< key eieio--method-num-lists)
|
||||
(let ((eieio--mt--optimizing-hashtable (aref emto key)))
|
||||
;; @todo - Is this overkill? Should we just clear the symbol?
|
||||
(maphash #'eieio--mt--sym-optimize eieio--mt--optimizing-hashtable)))
|
||||
))
|
||||
|
||||
(defun eieio--mt-next (class)
|
||||
"Return the next parent class for CLASS.
|
||||
If CLASS is a superclass, return variable `eieio-default-superclass'.
|
||||
If CLASS is variable `eieio-default-superclass' then return nil.
|
||||
This is different from function `class-parent' as class parent returns
|
||||
nil for superclasses. This function performs no type checking!"
|
||||
;; No type-checking because all calls are made from functions which
|
||||
;; are safe and do checking for us.
|
||||
(or (eieio--class-parent (eieio--class-v class))
|
||||
(if (eq class 'eieio-default-superclass)
|
||||
nil
|
||||
'(eieio-default-superclass))))
|
||||
|
||||
(defun eieio--mt--sym-optimize (class s)
|
||||
"Find the next class above S which has a function body for the optimizer."
|
||||
;; Set the value to nil in case there is no nearest cell.
|
||||
(setcdr s nil)
|
||||
;; Find the nearest cell that has a function body. If we find one,
|
||||
;; we replace the nil from above.
|
||||
(catch 'done
|
||||
(dolist (ancestor
|
||||
(cl-rest (eieio--class-precedence-list class)))
|
||||
(let ((ov (gethash ancestor eieio--mt--optimizing-hashtable)))
|
||||
(when (car ov)
|
||||
(setcdr s ancestor) ;; store ov as our next symbol
|
||||
(throw 'done ancestor))))))
|
||||
|
||||
(defun eieio--generic-form (method key class)
|
||||
"Return the lambda form belonging to METHOD using KEY based upon CLASS.
|
||||
If CLASS is not a class then use `generic' instead. If class has
|
||||
no form, but has a parent class, then trace to that parent class.
|
||||
The first time a form is requested from a symbol, an optimized path
|
||||
is memorized for faster future use."
|
||||
(if (symbolp class) (setq class (eieio--class-v class)))
|
||||
(let ((emto (aref (get method 'eieio-method-hashtable)
|
||||
(if class key (eieio--specialized-key-to-generic-key key)))))
|
||||
(if (eieio--class-p class)
|
||||
;; 1) find our symbol
|
||||
(let ((cs (gethash class emto)))
|
||||
(unless cs
|
||||
;; 2) If there isn't one, then make one.
|
||||
;; This can be slow since it only occurs once
|
||||
(puthash class (setq cs (list nil)) emto)
|
||||
;; 2.1) Cache its nearest neighbor with a quick optimize
|
||||
;; which should only occur once for this call ever
|
||||
(let ((eieio--mt--optimizing-hashtable emto))
|
||||
(eieio--mt--sym-optimize class cs)))
|
||||
;; 3) If it's bound return this one.
|
||||
(if (car cs)
|
||||
(cons (car cs) class)
|
||||
;; 4) If it's not bound then this variable knows something
|
||||
(if (cdr cs)
|
||||
(progn
|
||||
;; 4.1) This symbol holds the next class in its value
|
||||
(setq class (cdr cs)
|
||||
cs (gethash class emto))
|
||||
;; 4.2) The optimizer should always have chosen a
|
||||
;; function-symbol
|
||||
;;(if (car cs)
|
||||
(cons (car cs) class)
|
||||
;;(error "EIEIO optimizer: erratic data loss!"))
|
||||
)
|
||||
;; There never will be a funcall...
|
||||
nil)))
|
||||
;; for a generic call, what is a list, is the function body we want.
|
||||
(let ((emtl (aref (get method 'eieio-method-tree)
|
||||
(if class key (eieio--specialized-key-to-generic-key key)))))
|
||||
(if emtl
|
||||
;; The car of EMTL is supposed to be a class, which in this
|
||||
;; case is nil, so skip it.
|
||||
(cons (cdr (car emtl)) nil)
|
||||
nil)))))
|
||||
|
||||
|
||||
(define-error 'no-method-definition "No method definition")
|
||||
(define-error 'no-next-method "No next method")
|
||||
|
||||
;;; CLOS methods and generics
|
||||
;;
|
||||
(defmacro defgeneric (method _args &optional doc-string)
|
||||
"Create a generic function METHOD.
|
||||
DOC-STRING is the base documentation for this class. A generic
|
||||
function has no body, as its purpose is to decide which method body
|
||||
is appropriate to use. Uses `defmethod' to create methods, and calls
|
||||
`defgeneric' for you. With this implementation the ARGS are
|
||||
currently ignored. You can use `defgeneric' to apply specialized
|
||||
top level documentation to a method."
|
||||
(declare (doc-string 3))
|
||||
`(eieio--defalias ',method
|
||||
(eieio--defgeneric-init-form ',method ,doc-string)))
|
||||
|
||||
(defmacro defmethod (method &rest args)
|
||||
"Create a new METHOD through `defgeneric' with ARGS.
|
||||
|
||||
The optional second argument KEY is a specifier that
|
||||
modifies how the method is called, including:
|
||||
:before - Method will be called before the :primary
|
||||
:primary - The default if not specified
|
||||
:after - Method will be called after the :primary
|
||||
:static - First arg could be an object or class
|
||||
The next argument is the ARGLIST. The ARGLIST specifies the arguments
|
||||
to the method as with `defun'. The first argument can have a type
|
||||
specifier, such as:
|
||||
((VARNAME CLASS) ARG2 ...)
|
||||
where VARNAME is the name of the local variable for the method being
|
||||
created. The CLASS is a class symbol for a class made with `defclass'.
|
||||
A DOCSTRING comes after the ARGLIST, and is optional.
|
||||
All the rest of the args are the BODY of the method. A method will
|
||||
return the value of the last form in the BODY.
|
||||
|
||||
Summary:
|
||||
|
||||
(defmethod mymethod [:before | :primary | :after | :static]
|
||||
((typearg class-name) arg2 &optional opt &rest rest)
|
||||
\"doc-string\"
|
||||
body)"
|
||||
(declare (doc-string 3)
|
||||
(debug
|
||||
(&define ; this means we are defining something
|
||||
[&or name ("setf" :name setf name)]
|
||||
;; ^^ This is the methods symbol
|
||||
[ &optional symbolp ] ; this is key :before etc
|
||||
list ; arguments
|
||||
[ &optional stringp ] ; documentation string
|
||||
def-body ; part to be debugged
|
||||
)))
|
||||
(let* ((key (if (keywordp (car args)) (pop args)))
|
||||
(params (car args))
|
||||
(arg1 (car params))
|
||||
(fargs (if (consp arg1)
|
||||
(cons (car arg1) (cdr params))
|
||||
params))
|
||||
(class (if (consp arg1) (nth 1 arg1)))
|
||||
(code `(lambda ,fargs ,@(cdr args))))
|
||||
`(progn
|
||||
;; Make sure there is a generic and the byte-compiler sees it.
|
||||
(defgeneric ,method ,args
|
||||
,(or (documentation code)
|
||||
(format "Generically created method `%s'." method)))
|
||||
(eieio--defmethod ',method ',key ',class #',code))))
|
||||
|
||||
|
||||
|
||||
;;;
|
||||
;; Method Calling Functions
|
||||
|
||||
(defun next-method-p ()
|
||||
"Return non-nil if there is a next method.
|
||||
Returns a list of lambda expressions which is the `next-method'
|
||||
order."
|
||||
eieio--generic-call-next-method-list)
|
||||
|
||||
(defun call-next-method (&rest replacement-args)
|
||||
"Call the superclass method from a subclass method.
|
||||
The superclass method is specified in the current method list,
|
||||
and is called the next method.
|
||||
|
||||
If REPLACEMENT-ARGS is non-nil, then use them instead of
|
||||
`eieio--generic-call-arglst'. The generic arg list are the
|
||||
arguments passed in at the top level.
|
||||
|
||||
Use `next-method-p' to find out if there is a next method to call."
|
||||
(if (not (eieio--scoped-class))
|
||||
(error "`call-next-method' not called within a class specific method"))
|
||||
(if (and (/= eieio--generic-call-key eieio--method-primary)
|
||||
(/= eieio--generic-call-key eieio--method-static))
|
||||
(error "Cannot `call-next-method' except in :primary or :static methods")
|
||||
)
|
||||
(let ((newargs (or replacement-args eieio--generic-call-arglst))
|
||||
(next (car eieio--generic-call-next-method-list))
|
||||
)
|
||||
(if (not (and next (car next)))
|
||||
(apply #'no-next-method newargs)
|
||||
(let* ((eieio--generic-call-next-method-list
|
||||
(cdr eieio--generic-call-next-method-list))
|
||||
(eieio--generic-call-arglst newargs)
|
||||
(fcn (car next))
|
||||
)
|
||||
(eieio--with-scoped-class (cdr next)
|
||||
(apply fcn newargs)) ))))
|
||||
|
||||
(defgeneric no-applicable-method (object method &rest args)
|
||||
"Called if there are no implementations for OBJECT in METHOD.")
|
||||
|
||||
(defmethod no-applicable-method (object method &rest _args)
|
||||
"Called if there are no implementations for OBJECT in METHOD.
|
||||
OBJECT is the object which has no method implementation.
|
||||
ARGS are the arguments that were passed to METHOD.
|
||||
|
||||
Implement this for a class to block this signal. The return
|
||||
value becomes the return value of the original method call."
|
||||
(signal 'no-method-definition (list method object)))
|
||||
|
||||
(defgeneric no-next-method (object &rest args)
|
||||
"Called from `call-next-method' when no additional methods are available.")
|
||||
|
||||
(defmethod no-next-method (object &rest args)
|
||||
"Called from `call-next-method' when no additional methods are available.
|
||||
OBJECT is othe object being called on `call-next-method'.
|
||||
ARGS are the arguments it is called by.
|
||||
This method signals `no-next-method' by default. Override this
|
||||
method to not throw an error, and its return value becomes the
|
||||
return value of `call-next-method'."
|
||||
(signal 'no-next-method (list object args)))
|
||||
|
||||
(add-hook 'help-fns-describe-function-functions 'eieio--help-generic)
|
||||
(defun eieio--help-generic (generic)
|
||||
"Describe GENERIC if it is a generic function."
|
||||
(when (and (symbolp generic) (generic-p generic))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward " in `.+'.$" nil t)
|
||||
(replace-match ".")))
|
||||
(save-excursion
|
||||
(insert "\n\nThis is a generic function"
|
||||
(cond
|
||||
((and (eieio--generic-primary-only-p generic)
|
||||
(eieio--generic-primary-only-one-p generic))
|
||||
" with only one primary method")
|
||||
((eieio--generic-primary-only-p generic)
|
||||
" with only primary methods")
|
||||
(t ""))
|
||||
".\n\n")
|
||||
(insert (propertize "Implementations:\n\n" 'face 'bold))
|
||||
(let ((i 4)
|
||||
(prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] ))
|
||||
;; Loop over fanciful generics
|
||||
(while (< i 7)
|
||||
(let ((gm (aref (get generic 'eieio-method-tree) i)))
|
||||
(when gm
|
||||
(insert "Generic "
|
||||
(aref prefix (- i 3))
|
||||
"\n"
|
||||
(or (nth 2 gm) "Undocumented")
|
||||
"\n\n")))
|
||||
(setq i (1+ i)))
|
||||
(setq i 0)
|
||||
;; Loop over defined class-specific methods
|
||||
(while (< i 4)
|
||||
(let* ((gm (reverse (aref (get generic 'eieio-method-tree) i)))
|
||||
cname location)
|
||||
(while gm
|
||||
(setq cname (caar gm))
|
||||
(insert "`")
|
||||
(help-insert-xref-button (symbol-name cname)
|
||||
'help-variable cname)
|
||||
(insert "' " (aref prefix i) " ")
|
||||
;; argument list
|
||||
(let* ((func (cdr (car gm)))
|
||||
(arglst (help-function-arglist func)))
|
||||
(prin1 arglst (current-buffer)))
|
||||
(insert "\n"
|
||||
(or (documentation (cdr (car gm)))
|
||||
"Undocumented"))
|
||||
;; Print file location if available
|
||||
(when (and (setq location (get generic 'method-locations))
|
||||
(setq location (assoc cname location)))
|
||||
(setq location (cadr location))
|
||||
(insert "\n\nDefined in `")
|
||||
(help-insert-xref-button
|
||||
(file-name-nondirectory location)
|
||||
'eieio-method-def cname generic location)
|
||||
(insert "'\n"))
|
||||
(setq gm (cdr gm))
|
||||
(insert "\n")))
|
||||
(setq i (1+ i)))))))
|
||||
|
||||
;;; Obsolete backward compatibility functions.
|
||||
;; Needed to run byte-code compiled with the EIEIO of Emacs-23.
|
||||
|
||||
(defun eieio-defmethod (method args)
|
||||
"Obsolete work part of an old version of the `defmethod' macro."
|
||||
(let ((key nil) (body nil) (firstarg nil) (argfix nil) (argclass nil) loopa)
|
||||
;; find optional keys
|
||||
(setq key
|
||||
(cond ((memq (car args) '(:BEFORE :before))
|
||||
(setq args (cdr args))
|
||||
eieio--method-before)
|
||||
((memq (car args) '(:AFTER :after))
|
||||
(setq args (cdr args))
|
||||
eieio--method-after)
|
||||
((memq (car args) '(:STATIC :static))
|
||||
(setq args (cdr args))
|
||||
eieio--method-static)
|
||||
((memq (car args) '(:PRIMARY :primary))
|
||||
(setq args (cdr args))
|
||||
eieio--method-primary)
|
||||
;; Primary key.
|
||||
(t eieio--method-primary)))
|
||||
;; Get body, and fix contents of args to be the arguments of the fn.
|
||||
(setq body (cdr args)
|
||||
args (car args))
|
||||
(setq loopa args)
|
||||
;; Create a fixed version of the arguments.
|
||||
(while loopa
|
||||
(setq argfix (cons (if (listp (car loopa)) (car (car loopa)) (car loopa))
|
||||
argfix))
|
||||
(setq loopa (cdr loopa)))
|
||||
;; Make sure there is a generic.
|
||||
(eieio-defgeneric
|
||||
method
|
||||
(if (stringp (car body))
|
||||
(car body) (format "Generically created method `%s'." method)))
|
||||
;; create symbol for property to bind to. If the first arg is of
|
||||
;; the form (varname vartype) and `vartype' is a class, then
|
||||
;; that class will be the type symbol. If not, then it will fall
|
||||
;; under the type `primary' which is a non-specific calling of the
|
||||
;; function.
|
||||
(setq firstarg (car args))
|
||||
(if (listp firstarg)
|
||||
(progn
|
||||
(setq argclass (nth 1 firstarg))
|
||||
(if (not (class-p argclass))
|
||||
(error "Unknown class type %s in method parameters"
|
||||
(nth 1 firstarg))))
|
||||
;; Generics are higher.
|
||||
(setq key (eieio--specialized-key-to-generic-key key)))
|
||||
;; Put this lambda into the symbol so we can find it.
|
||||
(if (byte-code-function-p (car-safe body))
|
||||
(eieio--mt-add method (car-safe body) key argclass)
|
||||
(eieio--mt-add method (append (list 'lambda (reverse argfix)) body)
|
||||
key argclass))
|
||||
)
|
||||
|
||||
(eieio--method-optimize-primary method)
|
||||
|
||||
method)
|
||||
(make-obsolete 'eieio-defmethod 'eieio--defmethod "24.1")
|
||||
|
||||
(defun eieio-defgeneric (method doc-string)
|
||||
"Obsolete work part of an old version of the `defgeneric' macro."
|
||||
(if (and (fboundp method) (not (generic-p method))
|
||||
(or (byte-code-function-p (symbol-function method))
|
||||
(not (eq 'autoload (car (symbol-function method)))))
|
||||
)
|
||||
(error "You cannot create a generic/method over an existing symbol: %s"
|
||||
method))
|
||||
;; Don't do this over and over.
|
||||
(unless (fboundp 'method)
|
||||
;; This defun tells emacs where the first definition of this
|
||||
;; method is defined.
|
||||
`(defun ,method nil)
|
||||
;; Make sure the method tables are installed.
|
||||
(eieio--mt-install method)
|
||||
;; Apply the actual body of this function.
|
||||
(put method 'function-documentation doc-string)
|
||||
(fset method (eieio--defgeneric-form method))
|
||||
;; Return the method
|
||||
'method))
|
||||
(make-obsolete 'eieio-defgeneric nil "24.1")
|
||||
|
||||
(provide 'eieio-generic)
|
||||
|
||||
;;; eieio-generic.el ends here
|
||||
|
|
@ -60,7 +60,7 @@ Argument PREFIX is the character prefix to use.
|
|||
Argument CH-PREFIX is another character prefix to display."
|
||||
(eieio--check-type class-p this-root)
|
||||
(let ((myname (symbol-name this-root))
|
||||
(chl (eieio--class-children (class-v this-root)))
|
||||
(chl (eieio--class-children (eieio--class-v this-root)))
|
||||
(fprefix (concat ch-prefix " +--"))
|
||||
(mprefix (concat ch-prefix " | "))
|
||||
(lprefix (concat ch-prefix " ")))
|
||||
|
|
@ -81,7 +81,7 @@ If CLASS is actually an object, then also display current values of that object.
|
|||
;; Header line
|
||||
(prin1 class)
|
||||
(insert " is a"
|
||||
(if (class-option class :abstract)
|
||||
(if (eieio--class-option (eieio--class-v class) :abstract)
|
||||
"n abstract"
|
||||
"")
|
||||
" class")
|
||||
|
|
@ -149,7 +149,7 @@ If CLASS is actually an object, then also display current values of that object.
|
|||
(defun eieio-help-class-slots (class)
|
||||
"Print help description for the slots in CLASS.
|
||||
Outputs to the current buffer."
|
||||
(let* ((cv (class-v class))
|
||||
(let* ((cv (eieio--class-v class))
|
||||
(docs (eieio--class-public-doc cv))
|
||||
(names (eieio--class-public-a cv))
|
||||
(deflt (eieio--class-public-d cv))
|
||||
|
|
@ -218,11 +218,10 @@ Outputs to the current buffer."
|
|||
(defun eieio-build-class-list (class)
|
||||
"Return a list of all classes that inherit from CLASS."
|
||||
(if (class-p class)
|
||||
(apply #'append
|
||||
(mapcar
|
||||
(lambda (c)
|
||||
(append (list c) (eieio-build-class-list c)))
|
||||
(eieio-class-children-fast class)))
|
||||
(cl-mapcan
|
||||
(lambda (c)
|
||||
(append (list c) (eieio-build-class-list c)))
|
||||
(eieio--class-children (eieio--class-v class)))
|
||||
(list class)))
|
||||
|
||||
(defun eieio-build-class-alist (&optional class instantiable-only buildlist)
|
||||
|
|
@ -231,15 +230,16 @@ Optional argument CLASS is the class to start with.
|
|||
If INSTANTIABLE-ONLY is non nil, only allow names of classes which
|
||||
are not abstract, otherwise allow all classes.
|
||||
Optional argument BUILDLIST is more list to attach and is used internally."
|
||||
(let* ((cc (or class eieio-default-superclass))
|
||||
(sublst (eieio--class-children (class-v cc))))
|
||||
(let* ((cc (or class 'eieio-default-superclass))
|
||||
(sublst (eieio--class-children (eieio--class-v cc))))
|
||||
(unless (assoc (symbol-name cc) buildlist)
|
||||
(when (or (not instantiable-only) (not (class-abstract-p cc)))
|
||||
;; FIXME: Completion tables don't need alists, and ede/generic.el needs
|
||||
;; the symbols rather than their names.
|
||||
(setq buildlist (cons (cons (symbol-name cc) 1) buildlist))))
|
||||
(while sublst
|
||||
(dolist (elem sublst)
|
||||
(setq buildlist (eieio-build-class-alist
|
||||
(car sublst) instantiable-only buildlist))
|
||||
(setq sublst (cdr sublst)))
|
||||
elem instantiable-only buildlist)))
|
||||
buildlist))
|
||||
|
||||
(defvar eieio-read-class nil
|
||||
|
|
@ -311,132 +311,59 @@ are not abstract."
|
|||
(eieio-help-class ctr))
|
||||
))))
|
||||
|
||||
|
||||
;;;###autoload
|
||||
(defun eieio-help-generic (generic)
|
||||
"Describe GENERIC if it is a generic function."
|
||||
(when (and (symbolp generic) (generic-p generic))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward " in `.+'.$" nil t)
|
||||
(replace-match ".")))
|
||||
(save-excursion
|
||||
(insert "\n\nThis is a generic function"
|
||||
(cond
|
||||
((and (generic-primary-only-p generic)
|
||||
(generic-primary-only-one-p generic))
|
||||
" with only one primary method")
|
||||
((generic-primary-only-p generic)
|
||||
" with only primary methods")
|
||||
(t ""))
|
||||
".\n\n")
|
||||
(insert (propertize "Implementations:\n\n" 'face 'bold))
|
||||
(let ((i 4)
|
||||
(prefix [ ":STATIC" ":BEFORE" ":PRIMARY" ":AFTER" ] ))
|
||||
;; Loop over fanciful generics
|
||||
(while (< i 7)
|
||||
(let ((gm (aref (get generic 'eieio-method-tree) i)))
|
||||
(when gm
|
||||
(insert "Generic "
|
||||
(aref prefix (- i 3))
|
||||
"\n"
|
||||
(or (nth 2 gm) "Undocumented")
|
||||
"\n\n")))
|
||||
(setq i (1+ i)))
|
||||
(setq i 0)
|
||||
;; Loop over defined class-specific methods
|
||||
(while (< i 4)
|
||||
(let* ((gm (reverse (aref (get generic 'eieio-method-tree) i)))
|
||||
cname location)
|
||||
(while gm
|
||||
(setq cname (caar gm))
|
||||
(insert "`")
|
||||
(help-insert-xref-button (symbol-name cname)
|
||||
'help-variable cname)
|
||||
(insert "' " (aref prefix i) " ")
|
||||
;; argument list
|
||||
(let* ((func (cdr (car gm)))
|
||||
(arglst (help-function-arglist func)))
|
||||
(prin1 arglst (current-buffer)))
|
||||
(insert "\n"
|
||||
(or (documentation (cdr (car gm)))
|
||||
"Undocumented"))
|
||||
;; Print file location if available
|
||||
(when (and (setq location (get generic 'method-locations))
|
||||
(setq location (assoc cname location)))
|
||||
(setq location (cadr location))
|
||||
(insert "\n\nDefined in `")
|
||||
(help-insert-xref-button
|
||||
(file-name-nondirectory location)
|
||||
'eieio-method-def cname generic location)
|
||||
(insert "'\n"))
|
||||
(setq gm (cdr gm))
|
||||
(insert "\n")))
|
||||
(setq i (1+ i)))))))
|
||||
|
||||
(defun eieio-all-generic-functions (&optional class)
|
||||
"Return a list of all generic functions.
|
||||
Optional CLASS argument returns only those functions that contain
|
||||
methods for CLASS."
|
||||
(let ((l nil) tree (cn (if class (symbol-name class) nil)))
|
||||
(let ((l nil))
|
||||
(mapatoms
|
||||
(lambda (symbol)
|
||||
(setq tree (get symbol 'eieio-method-obarray))
|
||||
(if tree
|
||||
(progn
|
||||
;; A symbol might be interned for that class in one of
|
||||
;; these three slots in the method-obarray.
|
||||
(if (or (not class)
|
||||
(fboundp (intern-soft cn (aref tree 0)))
|
||||
(fboundp (intern-soft cn (aref tree 1)))
|
||||
(fboundp (intern-soft cn (aref tree 2))))
|
||||
(setq l (cons symbol l)))))))
|
||||
(let ((tree (get symbol 'eieio-method-hashtable)))
|
||||
(when tree
|
||||
;; A symbol might be interned for that class in one of
|
||||
;; these three slots in the method-obarray.
|
||||
(if (or (not class)
|
||||
(car (gethash class (aref tree 0)))
|
||||
(car (gethash class (aref tree 1)))
|
||||
(car (gethash class (aref tree 2))))
|
||||
(setq l (cons symbol l)))))))
|
||||
l))
|
||||
|
||||
(defun eieio-method-documentation (generic class)
|
||||
"Return a list of the specific documentation of GENERIC for CLASS.
|
||||
If there is not an explicit method for CLASS in GENERIC, or if that
|
||||
function has no documentation, then return nil."
|
||||
(let ((tree (get generic 'eieio-method-obarray))
|
||||
(cn (symbol-name class))
|
||||
before primary after)
|
||||
(if (not tree)
|
||||
nil
|
||||
(let ((tree (get generic 'eieio-method-hashtable)))
|
||||
(when tree
|
||||
;; A symbol might be interned for that class in one of
|
||||
;; these three slots in the method-obarray.
|
||||
(setq before (intern-soft cn (aref tree 0))
|
||||
primary (intern-soft cn (aref tree 1))
|
||||
after (intern-soft cn (aref tree 2)))
|
||||
(if (not (or (fboundp before)
|
||||
(fboundp primary)
|
||||
(fboundp after)))
|
||||
nil
|
||||
(list (if (fboundp before)
|
||||
(cons (help-function-arglist before)
|
||||
(documentation before))
|
||||
nil)
|
||||
(if (fboundp primary)
|
||||
(cons (help-function-arglist primary)
|
||||
(documentation primary))
|
||||
nil)
|
||||
(if (fboundp after)
|
||||
(cons (help-function-arglist after)
|
||||
(documentation after))
|
||||
nil))))))
|
||||
;; these three slots in the method-hashtable.
|
||||
;; FIXME: Where do these 0/1/2 come from? Isn't 0 for :static,
|
||||
;; 1 for before, and 2 for primary (and 3 for after)?
|
||||
(let ((before (car (gethash class (aref tree 0))))
|
||||
(primary (car (gethash class (aref tree 1))))
|
||||
(after (car (gethash class (aref tree 2)))))
|
||||
(if (not (or before primary after))
|
||||
nil
|
||||
(list (if before
|
||||
(cons (help-function-arglist before)
|
||||
(documentation before))
|
||||
nil)
|
||||
(if primary
|
||||
(cons (help-function-arglist primary)
|
||||
(documentation primary))
|
||||
nil)
|
||||
(if after
|
||||
(cons (help-function-arglist after)
|
||||
(documentation after))
|
||||
nil)))))))
|
||||
|
||||
(defvar eieio-read-generic nil
|
||||
"History of the `eieio-read-generic' prompt.")
|
||||
|
||||
(defun eieio-read-generic-p (fn)
|
||||
"Function used in function `eieio-read-generic'.
|
||||
This is because `generic-p' is a macro.
|
||||
Argument FN is the function to test."
|
||||
(generic-p fn))
|
||||
|
||||
(defun eieio-read-generic (prompt &optional historyvar)
|
||||
"Read a generic function from the minibuffer with PROMPT.
|
||||
Optional argument HISTORYVAR is the variable to use as history."
|
||||
(intern (completing-read prompt obarray 'eieio-read-generic-p
|
||||
(intern (completing-read prompt obarray #'generic-p
|
||||
t nil (or historyvar 'eieio-read-generic))))
|
||||
|
||||
;;; METHOD STATS
|
||||
|
|
@ -627,21 +554,21 @@ Optional argument HISTORYVAR is the variable to use as history."
|
|||
()
|
||||
"Menu part in easymenu format used in speedbar while in `eieio' mode.")
|
||||
|
||||
(defun eieio-class-speedbar (dir-or-object depth)
|
||||
(defun eieio-class-speedbar (_dir-or-object _depth)
|
||||
"Create buttons in speedbar that represents the current project.
|
||||
DIR-OR-OBJECT is the object to expand, or nil, and DEPTH is the
|
||||
current expansion depth."
|
||||
(when (eq (point-min) (point-max))
|
||||
;; This function is only called once, to start the whole deal.
|
||||
;; Create and expand the default object.
|
||||
(eieio-class-button eieio-default-superclass 0)
|
||||
(eieio-class-button 'eieio-default-superclass 0)
|
||||
(forward-line -1)
|
||||
(speedbar-expand-line)))
|
||||
|
||||
(defun eieio-class-button (class depth)
|
||||
"Draw a speedbar button at the current point for CLASS at DEPTH."
|
||||
(eieio--check-type class-p class)
|
||||
(let ((subclasses (eieio--class-children (class-v class))))
|
||||
(let ((subclasses (eieio--class-children (eieio--class-v class))))
|
||||
(if subclasses
|
||||
(speedbar-make-tag-line 'angle ?+
|
||||
'eieio-sb-expand
|
||||
|
|
@ -666,7 +593,7 @@ Argument INDENT is the depth of indentation."
|
|||
(speedbar-with-writable
|
||||
(save-excursion
|
||||
(end-of-line) (forward-char 1)
|
||||
(let ((subclasses (eieio--class-children (class-v class))))
|
||||
(let ((subclasses (eieio--class-children (eieio--class-v class))))
|
||||
(while subclasses
|
||||
(eieio-class-button (car subclasses) (1+ indent))
|
||||
(setq subclasses (cdr subclasses)))))))
|
||||
|
|
@ -676,7 +603,7 @@ Argument INDENT is the depth of indentation."
|
|||
(t (error "Ooops... not sure what to do")))
|
||||
(speedbar-center-buffer-smartly))
|
||||
|
||||
(defun eieio-describe-class-sb (text token indent)
|
||||
(defun eieio-describe-class-sb (_text token _indent)
|
||||
"Describe the class TEXT in TOKEN.
|
||||
INDENT is the current indentation level."
|
||||
(dframe-with-attached-buffer
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;;; eieio-speedbar.el -- Classes for managing speedbar displays.
|
||||
;;; eieio-speedbar.el -- Classes for managing speedbar displays. -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 1999-2002, 2005, 2007-2015 Free Software Foundation,
|
||||
;; Inc.
|
||||
|
|
@ -200,7 +200,7 @@ that path."
|
|||
"Return a string describing OBJECT."
|
||||
(eieio-object-name-string object))
|
||||
|
||||
(defmethod eieio-speedbar-derive-line-path (object)
|
||||
(defmethod eieio-speedbar-derive-line-path (_object)
|
||||
"Return the path which OBJECT has something to do with."
|
||||
nil)
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ Argument DEPTH is the depth at which the tag line is inserted."
|
|||
(if exp
|
||||
(eieio-speedbar-expand object (1+ depth))))))
|
||||
|
||||
(defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) depth)
|
||||
(defmethod eieio-speedbar-child-make-tag-lines ((object eieio-speedbar) _depth)
|
||||
"Base method for creating tag lines for non-object children."
|
||||
(error "You must implement `eieio-speedbar-child-make-tag-lines' for %s"
|
||||
(eieio-object-name object)))
|
||||
|
|
@ -340,7 +340,7 @@ OBJECT."
|
|||
|
||||
;;; Speedbar specific function callbacks.
|
||||
;;
|
||||
(defun eieio-speedbar-object-click (text token indent)
|
||||
(defun eieio-speedbar-object-click (_text token _indent)
|
||||
"Handle a user click on TEXT representing object TOKEN.
|
||||
The object is at indentation level INDENT."
|
||||
(eieio-speedbar-handle-click token))
|
||||
|
|
@ -412,7 +412,7 @@ Optional DEPTH is the depth we start at."
|
|||
|
||||
;;; Methods to the eieio-speedbar-* classes which need to be overridden.
|
||||
;;
|
||||
(defmethod eieio-speedbar-object-children ((object eieio-speedbar))
|
||||
(defmethod eieio-speedbar-object-children ((_object eieio-speedbar))
|
||||
"Return a list of children to be displayed in speedbar.
|
||||
If the return value is a list of OBJECTs, then those objects are
|
||||
queried for details. If the return list is made of strings,
|
||||
|
|
|
|||
|
|
@ -53,17 +53,16 @@
|
|||
(message eieio-version))
|
||||
|
||||
(require 'eieio-core)
|
||||
(require 'eieio-generic)
|
||||
|
||||
|
||||
;;; Defining a new class
|
||||
;;
|
||||
(defmacro defclass (name superclass slots &rest options-and-doc)
|
||||
(defmacro defclass (name superclasses slots &rest options-and-doc)
|
||||
"Define NAME as a new class derived from SUPERCLASS with SLOTS.
|
||||
OPTIONS-AND-DOC is used as the class' options and base documentation.
|
||||
SUPERCLASS is a list of superclasses to inherit from, with SLOTS
|
||||
being the slots residing in that class definition. NOTE: Currently
|
||||
only one slot may exist in SUPERCLASS as multiple inheritance is not
|
||||
yet supported. Supported tags are:
|
||||
SUPERCLASSES is a list of superclasses to inherit from, with SLOTS
|
||||
being the slots residing in that class definition. Supported tags are:
|
||||
|
||||
:initform - Initializing form.
|
||||
:initarg - Tag used during initialization.
|
||||
|
|
@ -114,12 +113,178 @@ Options in CLOS not supported in EIEIO:
|
|||
Due to the way class options are set up, you can add any tags you wish,
|
||||
and reference them using the function `class-option'."
|
||||
(declare (doc-string 4))
|
||||
;; This is eval-and-compile only to silence spurious compiler warnings
|
||||
;; about functions and variables not known to be defined.
|
||||
;; When eieio-defclass code is merged here and this becomes
|
||||
;; transparent to the compiler, the eval-and-compile can be removed.
|
||||
`(eval-and-compile
|
||||
(eieio-defclass ',name ',superclass ',slots ',options-and-doc)))
|
||||
(eieio--check-type listp superclasses)
|
||||
|
||||
(cond ((and (stringp (car options-and-doc))
|
||||
(/= 1 (% (length options-and-doc) 2)))
|
||||
(error "Too many arguments to `defclass'"))
|
||||
((and (symbolp (car options-and-doc))
|
||||
(/= 0 (% (length options-and-doc) 2)))
|
||||
(error "Too many arguments to `defclass'")))
|
||||
|
||||
(if (stringp (car options-and-doc))
|
||||
(setq options-and-doc
|
||||
(cons :documentation options-and-doc)))
|
||||
|
||||
;; Make sure the method invocation order is a valid value.
|
||||
(let ((io (eieio--class-option-assoc options-and-doc
|
||||
:method-invocation-order)))
|
||||
(when (and io (not (member io '(:depth-first :breadth-first :c3))))
|
||||
(error "Method invocation order %s is not allowed" io)))
|
||||
|
||||
(let ((testsym1 (intern (concat (symbol-name name) "-p")))
|
||||
(testsym2 (intern (format "eieio--childp--%s" name)))
|
||||
(accessors ()))
|
||||
|
||||
;; Collect the accessors we need to define.
|
||||
(pcase-dolist (`(,sname . ,soptions) slots)
|
||||
(let* ((acces (plist-get soptions :accessor))
|
||||
(initarg (plist-get soptions :initarg))
|
||||
(reader (plist-get soptions :reader))
|
||||
(writer (plist-get soptions :writer))
|
||||
(alloc (plist-get soptions :allocation))
|
||||
(label (plist-get soptions :label)))
|
||||
|
||||
(if eieio-error-unsupported-class-tags
|
||||
(let ((tmp soptions))
|
||||
(while tmp
|
||||
(if (not (member (car tmp) '(:accessor
|
||||
:initform
|
||||
:initarg
|
||||
:documentation
|
||||
:protection
|
||||
:reader
|
||||
:writer
|
||||
:allocation
|
||||
:type
|
||||
:custom
|
||||
:label
|
||||
:group
|
||||
:printer
|
||||
:allow-nil-initform
|
||||
:custom-groups)))
|
||||
(signal 'invalid-slot-type (list (car tmp))))
|
||||
(setq tmp (cdr (cdr tmp))))))
|
||||
|
||||
;; Make sure the :allocation parameter has a valid value.
|
||||
(if (not (memq alloc '(nil :class :instance)))
|
||||
(signal 'invalid-slot-type (list :allocation alloc)))
|
||||
|
||||
;; Label is nil, or a string
|
||||
(if (not (or (null label) (stringp label)))
|
||||
(signal 'invalid-slot-type (list :label label)))
|
||||
|
||||
;; Is there an initarg, but allocation of class?
|
||||
(if (and initarg (eq alloc :class))
|
||||
(message "Class allocated slots do not need :initarg"))
|
||||
|
||||
;; Anyone can have an accessor function. This creates a function
|
||||
;; of the specified name, and also performs a `defsetf' if applicable
|
||||
;; so that users can `setf' the space returned by this function.
|
||||
(when acces
|
||||
;; FIXME: The defmethod below only defines a part of the generic
|
||||
;; function (good), but the define-setter below affects the whole
|
||||
;; generic function (bad)!
|
||||
(push `(gv-define-setter ,acces (store object)
|
||||
;; Apparently, eieio-oset-default doesn't work like
|
||||
;; oref-default and only accept class arguments!
|
||||
(list ',(if nil ;; (eq alloc :class)
|
||||
'eieio-oset-default
|
||||
'eieio-oset)
|
||||
object '',sname store))
|
||||
accessors)
|
||||
(push `(defmethod ,acces ,(if (eq alloc :class) :static :primary)
|
||||
((this ,name))
|
||||
,(format
|
||||
"Retrieve the slot `%S' from an object of class `%S'."
|
||||
sname name)
|
||||
(if (slot-boundp this ',sname)
|
||||
;; Use oref-default for :class allocated slots, since
|
||||
;; these also accept the use of a class argument instead
|
||||
;; of an object argument.
|
||||
(,(if (eq alloc :class) 'eieio-oref-default 'eieio-oref)
|
||||
this ',sname)
|
||||
;; Else - Some error? nil?
|
||||
nil))
|
||||
accessors))
|
||||
|
||||
;; If a writer is defined, then create a generic method of that
|
||||
;; name whose purpose is to set the value of the slot.
|
||||
(if writer
|
||||
(push `(defmethod ,writer ((this ,name) value)
|
||||
,(format "Set the slot `%S' of an object of class `%S'."
|
||||
sname name)
|
||||
(setf (slot-value this ',sname) value))
|
||||
accessors))
|
||||
;; If a reader is defined, then create a generic method
|
||||
;; of that name whose purpose is to access this slot value.
|
||||
(if reader
|
||||
(push `(defmethod ,reader ((this ,name))
|
||||
,(format "Access the slot `%S' from object of class `%S'."
|
||||
sname name)
|
||||
(slot-value this ',sname))
|
||||
accessors))
|
||||
))
|
||||
|
||||
`(progn
|
||||
;; This test must be created right away so we can have self-
|
||||
;; referencing classes. ei, a class whose slot can contain only
|
||||
;; pointers to itself.
|
||||
|
||||
;; Create the test function.
|
||||
(defun ,testsym1 (obj)
|
||||
,(format "Test OBJ to see if it an object of type %S." name)
|
||||
(and (eieio-object-p obj)
|
||||
(same-class-p obj ',name)))
|
||||
|
||||
(defun ,testsym2 (obj)
|
||||
,(format
|
||||
"Test OBJ to see if it an object is a child of type %S."
|
||||
name)
|
||||
(and (eieio-object-p obj)
|
||||
(object-of-class-p obj ',name)))
|
||||
|
||||
,@(when eieio-backward-compatibility
|
||||
(let ((f (intern (format "%s-child-p" name))))
|
||||
`((defalias ',f ',testsym2)
|
||||
(make-obsolete
|
||||
',f ,(format "use (cl-typep ... '%s) instead" name) "25.1"))))
|
||||
|
||||
;; When using typep, (typep OBJ 'myclass) returns t for objects which
|
||||
;; are subclasses of myclass. For our predicates, however, it is
|
||||
;; important for EIEIO to be backwards compatible, where
|
||||
;; myobject-p, and myobject-child-p are different.
|
||||
;; "cl" uses this technique to specify symbols with specific typep
|
||||
;; test, so we can let typep have the CLOS documented behavior
|
||||
;; while keeping our above predicate clean.
|
||||
|
||||
(put ',name 'cl-deftype-satisfies #',testsym2)
|
||||
|
||||
(eieio-defclass-internal ',name ',superclasses ',slots ',options-and-doc)
|
||||
|
||||
,@accessors
|
||||
|
||||
;; Create the constructor function
|
||||
,(if (eieio--class-option-assoc options-and-doc :abstract)
|
||||
;; Abstract classes cannot be instantiated. Say so.
|
||||
(let ((abs (eieio--class-option-assoc options-and-doc :abstract)))
|
||||
(if (not (stringp abs))
|
||||
(setq abs (format "Class %s is abstract" name)))
|
||||
`(defun ,name (&rest _)
|
||||
,(format "You cannot create a new object of type %S." name)
|
||||
(error ,abs)))
|
||||
|
||||
;; Non-abstract classes need a constructor.
|
||||
`(defun ,name (&rest slots)
|
||||
,(format "Create a new object with name NAME of class type %S."
|
||||
name)
|
||||
(if (and slots
|
||||
(let ((x (car slots)))
|
||||
(or (stringp x) (null x))))
|
||||
(funcall (if eieio-backward-compatibility #'ignore #'message)
|
||||
"Obsolete name %S passed to %S constructor"
|
||||
(pop slots) ',name))
|
||||
(apply #'eieio-constructor ',name slots))))))
|
||||
|
||||
|
||||
;;; CLOS style implementation of object creators.
|
||||
|
|
@ -144,75 +309,16 @@ In EIEIO, the class' constructor requires a name for use when printing.
|
|||
`make-instance' in CLOS doesn't use names the way Emacs does, so the
|
||||
class is used as the name slot instead when INITARGS doesn't start with
|
||||
a string."
|
||||
(if (and (car initargs) (stringp (car initargs)))
|
||||
(apply (class-constructor class) initargs)
|
||||
(apply (class-constructor class)
|
||||
(cond ((symbolp class) (symbol-name class))
|
||||
(t (format "%S" class)))
|
||||
initargs)))
|
||||
(apply (class-constructor class) initargs))
|
||||
|
||||
|
||||
;;; CLOS methods and generics
|
||||
;;
|
||||
(defmacro defgeneric (method _args &optional doc-string)
|
||||
"Create a generic function METHOD.
|
||||
DOC-STRING is the base documentation for this class. A generic
|
||||
function has no body, as its purpose is to decide which method body
|
||||
is appropriate to use. Uses `defmethod' to create methods, and calls
|
||||
`defgeneric' for you. With this implementation the ARGS are
|
||||
currently ignored. You can use `defgeneric' to apply specialized
|
||||
top level documentation to a method."
|
||||
(declare (doc-string 3))
|
||||
`(eieio--defalias ',method
|
||||
(eieio--defgeneric-init-form ',method ,doc-string)))
|
||||
|
||||
(defmacro defmethod (method &rest args)
|
||||
"Create a new METHOD through `defgeneric' with ARGS.
|
||||
|
||||
The optional second argument KEY is a specifier that
|
||||
modifies how the method is called, including:
|
||||
:before - Method will be called before the :primary
|
||||
:primary - The default if not specified
|
||||
:after - Method will be called after the :primary
|
||||
:static - First arg could be an object or class
|
||||
The next argument is the ARGLIST. The ARGLIST specifies the arguments
|
||||
to the method as with `defun'. The first argument can have a type
|
||||
specifier, such as:
|
||||
((VARNAME CLASS) ARG2 ...)
|
||||
where VARNAME is the name of the local variable for the method being
|
||||
created. The CLASS is a class symbol for a class made with `defclass'.
|
||||
A DOCSTRING comes after the ARGLIST, and is optional.
|
||||
All the rest of the args are the BODY of the method. A method will
|
||||
return the value of the last form in the BODY.
|
||||
|
||||
Summary:
|
||||
|
||||
(defmethod mymethod [:before | :primary | :after | :static]
|
||||
((typearg class-name) arg2 &optional opt &rest rest)
|
||||
\"doc-string\"
|
||||
body)"
|
||||
(declare (doc-string 3))
|
||||
(let* ((key (if (keywordp (car args)) (pop args)))
|
||||
(params (car args))
|
||||
(arg1 (car params))
|
||||
(fargs (if (consp arg1)
|
||||
(cons (car arg1) (cdr params))
|
||||
params))
|
||||
(class (if (consp arg1) (nth 1 arg1)))
|
||||
(code `(lambda ,fargs ,@(cdr args))))
|
||||
`(progn
|
||||
;; Make sure there is a generic and the byte-compiler sees it.
|
||||
(defgeneric ,method ,args
|
||||
,(or (documentation code)
|
||||
(format "Generically created method `%s'." method)))
|
||||
(eieio--defmethod ',method ',key ',class #',code))))
|
||||
|
||||
;;; Get/Set slots in an object.
|
||||
;;
|
||||
(defmacro oref (obj slot)
|
||||
"Retrieve the value stored in OBJ in the slot named by SLOT.
|
||||
Slot is the name of the slot when created by `defclass' or the label
|
||||
created by the :initarg tag."
|
||||
(declare (debug (form symbolp)))
|
||||
`(eieio-oref ,obj (quote ,slot)))
|
||||
|
||||
(defalias 'slot-value 'eieio-oref)
|
||||
|
|
@ -223,6 +329,7 @@ created by the :initarg tag."
|
|||
The default value is the value installed in a class with the :initform
|
||||
tag. SLOT can be the slot name, or the tag specified by the :initarg
|
||||
tag in the `defclass' call."
|
||||
(declare (debug (form symbolp)))
|
||||
`(eieio-oref-default ,obj (quote ,slot)))
|
||||
|
||||
;;; Handy CLOS macros
|
||||
|
|
@ -246,7 +353,7 @@ SPEC-LIST is of a form similar to `let'. For example:
|
|||
Where each VAR is the local variable given to the associated
|
||||
SLOT. A slot specified without a variable name is given a
|
||||
variable name of the same name as the slot."
|
||||
(declare (indent 2))
|
||||
(declare (indent 2) (debug (sexp sexp def-body)))
|
||||
(require 'cl-lib)
|
||||
;; Transform the spec-list into a cl-symbol-macrolet spec-list.
|
||||
(let ((mappings (mapcar (lambda (entry)
|
||||
|
|
@ -261,33 +368,43 @@ variable name of the same name as the slot."
|
|||
;; well embedded into an object.
|
||||
;;
|
||||
(define-obsolete-function-alias
|
||||
'object-class-fast #'eieio--object-class "24.4")
|
||||
'object-class-fast #'eieio--object-class-name "24.4")
|
||||
|
||||
(defun eieio-object-name (obj &optional extra)
|
||||
"Return a Lisp like symbol string for object OBJ.
|
||||
If EXTRA, include that in the string returned to represent the symbol."
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
(format "#<%s %s%s>" (symbol-name (eieio--object-class obj))
|
||||
(eieio--object-name obj) (or extra "")))
|
||||
(format "#<%s %s%s>" (eieio--object-class-name obj)
|
||||
(eieio-object-name-string obj) (or extra "")))
|
||||
(define-obsolete-function-alias 'object-name #'eieio-object-name "24.4")
|
||||
|
||||
(defun eieio-object-name-string (obj) "Return a string which is OBJ's name."
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
(eieio--object-name obj))
|
||||
(defconst eieio--object-names (make-hash-table :test #'eq :weakness 'key))
|
||||
|
||||
;; In the past, every EIEIO object had a `name' field, so we had the two method
|
||||
;; below "for free". Since this field is very rarely used, we got rid of it
|
||||
;; and instead we keep it in a weak hash-tables, for those very rare objects
|
||||
;; that use it.
|
||||
(defmethod eieio-object-name-string (obj)
|
||||
"Return a string which is OBJ's name."
|
||||
(declare (obsolete eieio-named "25.1"))
|
||||
(or (gethash obj eieio--object-names)
|
||||
(symbol-name (eieio-object-class obj))))
|
||||
(define-obsolete-function-alias
|
||||
'object-name-string #'eieio-object-name-string "24.4")
|
||||
|
||||
(defun eieio-object-set-name-string (obj name)
|
||||
(defmethod eieio-object-set-name-string (obj name)
|
||||
"Set the string which is OBJ's NAME."
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
(declare (obsolete eieio-named "25.1"))
|
||||
(eieio--check-type stringp name)
|
||||
(setf (eieio--object-name obj) name))
|
||||
(setf (gethash obj eieio--object-names) name))
|
||||
(define-obsolete-function-alias
|
||||
'object-set-name-string 'eieio-object-set-name-string "24.4")
|
||||
|
||||
(defun eieio-object-class (obj) "Return the class struct defining OBJ."
|
||||
(defun eieio-object-class (obj)
|
||||
"Return the class struct defining OBJ."
|
||||
;; FIXME: We say we return a "struct" but we return a symbol instead!
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
(eieio--object-class obj))
|
||||
(eieio--object-class-name obj))
|
||||
(define-obsolete-function-alias 'object-class #'eieio-object-class "24.4")
|
||||
;; CLOS name, maybe?
|
||||
(define-obsolete-function-alias 'class-of #'eieio-object-class "24.4")
|
||||
|
|
@ -295,7 +412,7 @@ If EXTRA, include that in the string returned to represent the symbol."
|
|||
(defun eieio-object-class-name (obj)
|
||||
"Return a Lisp like symbol name for OBJ's class."
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
(eieio-class-name (eieio--object-class obj)))
|
||||
(eieio-class-name (eieio--object-class-name obj)))
|
||||
(define-obsolete-function-alias
|
||||
'object-class-name 'eieio-object-class-name "24.4")
|
||||
|
||||
|
|
@ -303,15 +420,16 @@ If EXTRA, include that in the string returned to represent the symbol."
|
|||
"Return parent classes to CLASS. (overload of variable).
|
||||
|
||||
The CLOS function `class-direct-superclasses' is aliased to this function."
|
||||
(eieio--check-type class-p class)
|
||||
(eieio-class-parents-fast class))
|
||||
(let ((c (eieio-class-object class)))
|
||||
(eieio--class-parent c)))
|
||||
|
||||
(define-obsolete-function-alias 'class-parents #'eieio-class-parents "24.4")
|
||||
|
||||
(defun eieio-class-children (class)
|
||||
"Return child classes to CLASS.
|
||||
The CLOS function `class-direct-subclasses' is aliased to this function."
|
||||
(eieio--check-type class-p class)
|
||||
(eieio-class-children-fast class))
|
||||
(eieio--class-children (eieio--class-v class)))
|
||||
(define-obsolete-function-alias
|
||||
'class-children #'eieio-class-children "24.4")
|
||||
|
||||
|
|
@ -326,38 +444,44 @@ The CLOS function `class-direct-subclasses' is aliased to this function."
|
|||
`(car (eieio-class-parents ,class)))
|
||||
(define-obsolete-function-alias 'class-parent 'eieio-class-parent "24.4")
|
||||
|
||||
(defun same-class-p (obj class) "Return t if OBJ is of class-type CLASS."
|
||||
(eieio--check-type class-p class)
|
||||
(defun same-class-p (obj class)
|
||||
"Return t if OBJ is of class-type CLASS."
|
||||
(setq class (eieio--class-object class))
|
||||
(eieio--check-type eieio--class-p class)
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
(same-class-fast-p obj class))
|
||||
(eq (eieio--object-class-object obj) class))
|
||||
|
||||
(defun object-of-class-p (obj class)
|
||||
"Return non-nil if OBJ is an instance of CLASS or CLASS' subclasses."
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
;; class will be checked one layer down
|
||||
(child-of-class-p (eieio--object-class obj) class))
|
||||
(child-of-class-p (eieio--object-class-object obj) class))
|
||||
;; Backwards compatibility
|
||||
(defalias 'obj-of-class-p 'object-of-class-p)
|
||||
|
||||
(defun child-of-class-p (child class)
|
||||
"Return non-nil if CHILD class is a subclass of CLASS."
|
||||
(eieio--check-type class-p class)
|
||||
(eieio--check-type class-p child)
|
||||
(let ((p nil))
|
||||
(while (and child (not (eq child class)))
|
||||
(setq p (append p (eieio--class-parent (class-v child)))
|
||||
child (car p)
|
||||
p (cdr p)))
|
||||
(if child t)))
|
||||
(setq child (eieio--class-object child))
|
||||
(eieio--check-type eieio--class-p child)
|
||||
;; `eieio-default-superclass' is never mentioned in eieio--class-parent,
|
||||
;; so we have to special case it here.
|
||||
(or (eq class 'eieio-default-superclass)
|
||||
(let ((p nil))
|
||||
(setq class (eieio--class-object class))
|
||||
(eieio--check-type eieio--class-p class)
|
||||
(while (and child (not (eq child class)))
|
||||
(setq p (append p (eieio--class-parent child))
|
||||
child (pop p)))
|
||||
(if child t))))
|
||||
|
||||
(defun object-slots (obj)
|
||||
"Return list of slots available in OBJ."
|
||||
(eieio--check-type eieio-object-p obj)
|
||||
(eieio--class-public-a (class-v (eieio--object-class obj))))
|
||||
(eieio--class-public-a (eieio--object-class-object obj)))
|
||||
|
||||
(defun class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg."
|
||||
(eieio--check-type class-p class)
|
||||
(let ((ia (eieio--class-initarg-tuples (class-v class)))
|
||||
(defun eieio--class-slot-initarg (class slot) "Fetch from CLASS, SLOT's :initarg."
|
||||
(eieio--check-type eieio--class-p class)
|
||||
(let ((ia (eieio--class-initarg-tuples class))
|
||||
(f nil))
|
||||
(while (and ia (not f))
|
||||
(if (eq (cdr (car ia)) slot)
|
||||
|
|
@ -371,6 +495,7 @@ The CLOS function `class-direct-subclasses' is aliased to this function."
|
|||
"Set the value in OBJ for slot SLOT to VALUE.
|
||||
SLOT is the slot name as specified in `defclass' or the tag created
|
||||
with in the :initarg slot. VALUE can be any Lisp object."
|
||||
(declare (debug (form symbolp form)))
|
||||
`(eieio-oset ,obj (quote ,slot) ,value))
|
||||
|
||||
(defmacro oset-default (class slot value)
|
||||
|
|
@ -378,6 +503,7 @@ with in the :initarg slot. VALUE can be any Lisp object."
|
|||
The default value is usually set with the :initform tag during class
|
||||
creation. This allows users to change the default behavior of classes
|
||||
after they are created."
|
||||
(declare (debug (form symbolp form)))
|
||||
`(eieio-oset-default ,class (quote ,slot) ,value))
|
||||
|
||||
;;; CLOS queries into classes and slots
|
||||
|
|
@ -402,11 +528,9 @@ OBJECT can be an instance or a class."
|
|||
|
||||
(defun slot-exists-p (object-or-class slot)
|
||||
"Return non-nil if OBJECT-OR-CLASS has SLOT."
|
||||
(let ((cv (class-v (cond ((eieio-object-p object-or-class)
|
||||
(eieio-object-class object-or-class))
|
||||
((class-p object-or-class)
|
||||
object-or-class))
|
||||
)))
|
||||
(let ((cv (cond ((eieio-object-p object-or-class)
|
||||
(eieio--object-class-object object-or-class))
|
||||
(t (eieio-class-object object-or-class)))))
|
||||
(or (memq slot (eieio--class-public-a cv))
|
||||
(memq slot (eieio--class-class-allocation-a cv)))
|
||||
))
|
||||
|
|
@ -418,7 +542,7 @@ If ERRORP is non-nil, `wrong-argument-type' is signaled."
|
|||
(if (not (class-p symbol))
|
||||
(if errorp (signal 'wrong-type-argument (list 'class-p symbol))
|
||||
nil)
|
||||
(class-v symbol)))
|
||||
(eieio--class-v symbol)))
|
||||
|
||||
;;; Slightly more complex utility functions for objects
|
||||
;;
|
||||
|
|
@ -496,44 +620,6 @@ If SLOT is unbound, do nothing."
|
|||
nil
|
||||
(eieio-oset object slot (delete item (eieio-oref object slot)))))
|
||||
|
||||
;;;
|
||||
;; Method Calling Functions
|
||||
|
||||
(defun next-method-p ()
|
||||
"Return non-nil if there is a next method.
|
||||
Returns a list of lambda expressions which is the `next-method'
|
||||
order."
|
||||
eieio-generic-call-next-method-list)
|
||||
|
||||
(defun call-next-method (&rest replacement-args)
|
||||
"Call the superclass method from a subclass method.
|
||||
The superclass method is specified in the current method list,
|
||||
and is called the next method.
|
||||
|
||||
If REPLACEMENT-ARGS is non-nil, then use them instead of
|
||||
`eieio-generic-call-arglst'. The generic arg list are the
|
||||
arguments passed in at the top level.
|
||||
|
||||
Use `next-method-p' to find out if there is a next method to call."
|
||||
(if (not (eieio--scoped-class))
|
||||
(error "`call-next-method' not called within a class specific method"))
|
||||
(if (and (/= eieio-generic-call-key method-primary)
|
||||
(/= eieio-generic-call-key method-static))
|
||||
(error "Cannot `call-next-method' except in :primary or :static methods")
|
||||
)
|
||||
(let ((newargs (or replacement-args eieio-generic-call-arglst))
|
||||
(next (car eieio-generic-call-next-method-list))
|
||||
)
|
||||
(if (or (not next) (not (car next)))
|
||||
(apply #'no-next-method (car newargs) (cdr newargs))
|
||||
(let* ((eieio-generic-call-next-method-list
|
||||
(cdr eieio-generic-call-next-method-list))
|
||||
(eieio-generic-call-arglst newargs)
|
||||
(fcn (car next))
|
||||
)
|
||||
(eieio--with-scoped-class (cdr next)
|
||||
(apply fcn newargs)) ))))
|
||||
|
||||
;;; Here are some CLOS items that need the CL package
|
||||
;;
|
||||
|
||||
|
|
@ -556,22 +642,23 @@ Its slots are automatically adopted by classes with no specified parents.
|
|||
This class is not stored in the `parent' slot of a class vector."
|
||||
:abstract t)
|
||||
|
||||
(setq eieio-default-superclass (eieio--class-v 'eieio-default-superclass))
|
||||
|
||||
(defalias 'standard-class 'eieio-default-superclass)
|
||||
|
||||
(defgeneric constructor (class newname &rest slots)
|
||||
(defgeneric eieio-constructor (class &rest slots)
|
||||
"Default constructor for CLASS `eieio-default-superclass'.")
|
||||
|
||||
(defmethod constructor :static
|
||||
((class eieio-default-superclass) newname &rest slots)
|
||||
(define-obsolete-function-alias 'constructor #'eieio-constructor "25.1")
|
||||
|
||||
(defmethod eieio-constructor :static
|
||||
((class eieio-default-superclass) &rest slots)
|
||||
"Default constructor for CLASS `eieio-default-superclass'.
|
||||
NEWNAME is the name to be given to the constructed object.
|
||||
SLOTS are the initialization slots used by `shared-initialize'.
|
||||
This static method is called when an object is constructed.
|
||||
It allocates the vector used to represent an EIEIO object, and then
|
||||
calls `shared-initialize' on that object."
|
||||
(let* ((new-object (copy-sequence (eieio--class-default-object-cache (class-v class)))))
|
||||
;; Update the name for the newly created object.
|
||||
(setf (eieio--object-name new-object) newname)
|
||||
(let* ((new-object (copy-sequence (eieio--class-default-object-cache (eieio--class-v class)))))
|
||||
;; Call the initialize method on the new object with the slots
|
||||
;; that were passed down to us.
|
||||
(initialize-instance new-object slots)
|
||||
|
|
@ -585,10 +672,10 @@ Called from the constructor routine.")
|
|||
(defmethod shared-initialize ((obj eieio-default-superclass) slots)
|
||||
"Set slots of OBJ with SLOTS which is a list of name/value pairs.
|
||||
Called from the constructor routine."
|
||||
(eieio--with-scoped-class (eieio--object-class obj)
|
||||
(eieio--with-scoped-class (eieio--object-class-object obj)
|
||||
(while slots
|
||||
(let ((rn (eieio-initarg-to-attribute (eieio--object-class obj)
|
||||
(car slots))))
|
||||
(let ((rn (eieio--initarg-to-attribute (eieio--object-class-object obj)
|
||||
(car slots))))
|
||||
(if (not rn)
|
||||
(slot-missing obj (car slots) 'oset (car (cdr slots)))
|
||||
(eieio-oset obj rn (car (cdr slots)))))
|
||||
|
|
@ -609,7 +696,7 @@ not taken, then new objects of your class will not have their values
|
|||
dynamically set from SLOTS."
|
||||
;; First, see if any of our defaults are `lambda', and
|
||||
;; re-evaluate them and apply the value to our slots.
|
||||
(let* ((this-class (class-v (eieio--object-class this)))
|
||||
(let* ((this-class (eieio--object-class-object this))
|
||||
(slot (eieio--class-public-a this-class))
|
||||
(defaults (eieio--class-public-d this-class)))
|
||||
(while slot
|
||||
|
|
@ -662,34 +749,6 @@ EIEIO can only dispatch on the first argument, so the first two are swapped."
|
|||
(signal 'unbound-slot (list (eieio-class-name class) (eieio-object-name object)
|
||||
slot-name fn)))
|
||||
|
||||
(defgeneric no-applicable-method (object method &rest args)
|
||||
"Called if there are no implementations for OBJECT in METHOD.")
|
||||
|
||||
(defmethod no-applicable-method ((object eieio-default-superclass)
|
||||
method &rest _args)
|
||||
"Called if there are no implementations for OBJECT in METHOD.
|
||||
OBJECT is the object which has no method implementation.
|
||||
ARGS are the arguments that were passed to METHOD.
|
||||
|
||||
Implement this for a class to block this signal. The return
|
||||
value becomes the return value of the original method call."
|
||||
(signal 'no-method-definition (list method (eieio-object-name object)))
|
||||
)
|
||||
|
||||
(defgeneric no-next-method (object &rest args)
|
||||
"Called from `call-next-method' when no additional methods are available.")
|
||||
|
||||
(defmethod no-next-method ((object eieio-default-superclass)
|
||||
&rest args)
|
||||
"Called from `call-next-method' when no additional methods are available.
|
||||
OBJECT is othe object being called on `call-next-method'.
|
||||
ARGS are the arguments it is called by.
|
||||
This method signals `no-next-method' by default. Override this
|
||||
method to not throw an error, and its return value becomes the
|
||||
return value of `call-next-method'."
|
||||
(signal 'no-next-method (list (eieio-object-name object) args))
|
||||
)
|
||||
|
||||
(defgeneric clone (obj &rest params)
|
||||
"Make a copy of OBJ, and then supply PARAMS.
|
||||
PARAMS is a parameter list of the same form used by `initialize-instance'.
|
||||
|
|
@ -699,18 +758,11 @@ first and modify the returned object.")
|
|||
|
||||
(defmethod clone ((obj eieio-default-superclass) &rest params)
|
||||
"Make a copy of OBJ, and then apply PARAMS."
|
||||
(let ((nobj (copy-sequence obj))
|
||||
(nm (eieio--object-name obj))
|
||||
(passname (and params (stringp (car params))))
|
||||
(num 1))
|
||||
(if params (shared-initialize nobj (if passname (cdr params) params)))
|
||||
(if (not passname)
|
||||
(save-match-data
|
||||
(if (string-match "-\\([0-9]+\\)" nm)
|
||||
(setq num (1+ (string-to-number (match-string 1 nm)))
|
||||
nm (substring nm 0 (match-beginning 0))))
|
||||
(setf (eieio--object-name nobj) (concat nm "-" (int-to-string num))))
|
||||
(setf (eieio--object-name nobj) (car params)))
|
||||
(let ((nobj (copy-sequence obj)))
|
||||
(if (stringp (car params))
|
||||
(funcall (if eieio-backward-compatibility #'ignore #'message)
|
||||
"Obsolete name %S passed to clone" (pop params)))
|
||||
(if params (shared-initialize nobj params))
|
||||
nobj))
|
||||
|
||||
(defgeneric destructor (this &rest params)
|
||||
|
|
@ -764,7 +816,7 @@ this object."
|
|||
(princ comment)
|
||||
(princ "\n"))
|
||||
(let* ((cl (eieio-object-class this))
|
||||
(cv (class-v cl)))
|
||||
(cv (eieio--class-v cl)))
|
||||
;; Now output readable lisp to recreate this object
|
||||
;; It should look like this:
|
||||
;; (<constructor> <name> <slot> <slot> ... )
|
||||
|
|
@ -782,7 +834,7 @@ this object."
|
|||
(eieio-print-depth (1+ eieio-print-depth)))
|
||||
(while publa
|
||||
(when (slot-boundp this (car publa))
|
||||
(let ((i (class-slot-initarg cl (car publa)))
|
||||
(let ((i (eieio--class-slot-initarg cv (car publa)))
|
||||
(v (eieio-oref this (car publa)))
|
||||
)
|
||||
(unless (or (not i) (equal v (car publd)))
|
||||
|
|
@ -848,7 +900,6 @@ of `eq'."
|
|||
(error "EIEIO: `change-class' is unimplemented"))
|
||||
|
||||
;; Hook ourselves into help system for describing classes and methods.
|
||||
(add-hook 'help-fns-describe-function-functions 'eieio-help-generic)
|
||||
(add-hook 'help-fns-describe-function-functions 'eieio-help-constructor)
|
||||
|
||||
;;; Interfacing with edebug
|
||||
|
|
@ -859,43 +910,23 @@ of `eq'."
|
|||
Used as advice around `edebug-prin1-to-string', held in the
|
||||
variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to
|
||||
`prin1-to-string' when appropriate."
|
||||
(cond ((class-p object) (eieio-class-name object))
|
||||
(cond ((eieio--class-p object) (eieio-class-name object))
|
||||
((eieio-object-p object) (object-print object))
|
||||
((and (listp object) (or (class-p (car object))
|
||||
((and (listp object) (or (eieio--class-p (car object))
|
||||
(eieio-object-p (car object))))
|
||||
(concat "(" (mapconcat #'eieio-edebug-prin1-to-string object " ")
|
||||
(concat "(" (mapconcat
|
||||
(lambda (x) (eieio-edebug-prin1-to-string print-function x))
|
||||
object " ")
|
||||
")"))
|
||||
(t (funcall print-function object noescape))))
|
||||
|
||||
(add-hook 'edebug-setup-hook
|
||||
(lambda ()
|
||||
(def-edebug-spec defmethod
|
||||
(&define ; this means we are defining something
|
||||
[&or name ("setf" :name setf name)]
|
||||
;; ^^ This is the methods symbol
|
||||
[ &optional symbolp ] ; this is key :before etc
|
||||
list ; arguments
|
||||
[ &optional stringp ] ; documentation string
|
||||
def-body ; part to be debugged
|
||||
))
|
||||
;; The rest of the macros
|
||||
(def-edebug-spec oref (form quote))
|
||||
(def-edebug-spec oref-default (form quote))
|
||||
(def-edebug-spec oset (form quote form))
|
||||
(def-edebug-spec oset-default (form quote form))
|
||||
(def-edebug-spec class-v form)
|
||||
(def-edebug-spec class-p form)
|
||||
(def-edebug-spec eieio-object-p form)
|
||||
(def-edebug-spec class-constructor form)
|
||||
(def-edebug-spec generic-p form)
|
||||
(def-edebug-spec with-slots (list list def-body))
|
||||
(advice-add 'edebug-prin1-to-string
|
||||
:around #'eieio-edebug-prin1-to-string)))
|
||||
(advice-add 'edebug-prin1-to-string
|
||||
:around #'eieio-edebug-prin1-to-string)
|
||||
|
||||
|
||||
;;; Start of automatically extracted autoloads.
|
||||
|
||||
;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "62709d76ae43f4fe70ed922391f9c64d")
|
||||
;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "9a908efef1720439feb6323c1dd01770")
|
||||
;;; Generated autoloads from eieio-custom.el
|
||||
|
||||
(autoload 'customize-object "eieio-custom" "\
|
||||
|
|
@ -906,7 +937,7 @@ Optional argument GROUP is the sub-group of slots to display.
|
|||
|
||||
;;;***
|
||||
|
||||
;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "76058d02377b677eed3d15c28fc7ab21")
|
||||
;;;### (autoloads nil "eieio-opt" "eieio-opt.el" "e922bf7ebc7dcb272480c4ba148da1ac")
|
||||
;;; Generated autoloads from eieio-opt.el
|
||||
|
||||
(autoload 'eieio-browse "eieio-opt" "\
|
||||
|
|
@ -927,11 +958,6 @@ Describe CTR if it is a class constructor.
|
|||
|
||||
\(fn CTR)" nil nil)
|
||||
|
||||
(autoload 'eieio-help-generic "eieio-opt" "\
|
||||
Describe GENERIC if it is a generic function.
|
||||
|
||||
\(fn GENERIC)" nil nil)
|
||||
|
||||
;;;***
|
||||
|
||||
;;; End of automatically extracted autoloads.
|
||||
|
|
|
|||
|
|
@ -729,38 +729,6 @@ The path separator is colon in GNU and GNU-like systems."
|
|||
(lambda (f) (and (file-directory-p f) 'dir-ok)))
|
||||
(error "No such directory found via CDPATH environment variable"))))
|
||||
|
||||
(defun file-tree-walk (dir action &rest args)
|
||||
"Walk DIR executing ACTION on each file, with ARGS as additional arguments.
|
||||
For each file, the function calls ACTION as follows:
|
||||
|
||||
\(ACTION DIRECTORY BASENAME ARGS\)
|
||||
|
||||
Where DIRECTORY is the leading directory of the file,
|
||||
BASENAME is the basename of the file,
|
||||
and ARGS are as specified in the call to this function, or nil if omitted.
|
||||
|
||||
The ACTION is applied to each subdirectory before descending into
|
||||
it, and if nil is returned at that point, the descent will be
|
||||
prevented. Directory entries are sorted with string-lessp."
|
||||
(cond ((file-directory-p dir)
|
||||
(setq dir (file-name-as-directory dir))
|
||||
(let ((lst (directory-files dir nil nil t))
|
||||
fullname file)
|
||||
(while lst
|
||||
(setq file (car lst))
|
||||
(setq lst (cdr lst))
|
||||
(cond ((member file '("." "..")))
|
||||
(t
|
||||
(and (apply action dir file args)
|
||||
(setq fullname (concat dir file))
|
||||
(file-directory-p fullname)
|
||||
(apply 'file-tree-walk fullname action args)))))))
|
||||
(t
|
||||
(apply action
|
||||
(file-name-directory dir)
|
||||
(file-name-nondirectory dir)
|
||||
args))))
|
||||
|
||||
(defsubst directory-name-p (name)
|
||||
"Return non-nil if NAME ends with a slash character."
|
||||
(and (> (length name) 0)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
2015-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* registry.el: Don't use <class> as a variable.
|
||||
|
||||
2014-12-29 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* message.el (message-make-fqdn):
|
||||
|
|
@ -10,6 +14,12 @@
|
|||
* mm-decode.el (mm-shr): Bind `shr-width' to `fill-column' so that
|
||||
lines don't get overlong when responding.
|
||||
|
||||
2014-12-19 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* gnus-group.el (gnus-read-ephemeral-bug-group):
|
||||
Bind coding-system-for-read and coding-system-for-write only around
|
||||
with-temp-file, and make buffer unibyte. Don't write temp file twice.
|
||||
|
||||
2014-12-18 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* registry.el (registry-db): Set default slot later.
|
||||
|
|
@ -67,9 +77,9 @@
|
|||
|
||||
2014-12-09 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||
|
||||
* gnus-art.el (gnus-article-mime-handles): Refactored out into own
|
||||
* gnus-art.el (gnus-article-mime-handles): Refactor out into own
|
||||
function for reuse.
|
||||
(gnus-mime-buttonize-attachments-in-header): Adjusted.
|
||||
(gnus-mime-buttonize-attachments-in-header): Adjust.
|
||||
|
||||
2014-12-07 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||
|
||||
|
|
|
|||
|
|
@ -2455,27 +2455,27 @@ the bug number, and browsing the URL must return mbox output."
|
|||
(setq ids (string-to-number ids)))
|
||||
(unless (listp ids)
|
||||
(setq ids (list ids)))
|
||||
(let ((tmpfile (mm-make-temp-file "gnus-temp-group-"))
|
||||
(coding-system-for-write 'binary)
|
||||
(coding-system-for-read 'binary))
|
||||
(with-temp-file tmpfile
|
||||
(dolist (id ids)
|
||||
(url-insert-file-contents (format mbox-url id)))
|
||||
(goto-char (point-min))
|
||||
;; Add the debbugs address so that we can respond to reports easily.
|
||||
(while (re-search-forward "^To: " nil t)
|
||||
(end-of-line)
|
||||
(insert (format ", %s@%s" (car ids)
|
||||
(gnus-replace-in-string
|
||||
(gnus-replace-in-string mbox-url "^http://" "")
|
||||
"/.*$" ""))))
|
||||
(write-region (point-min) (point-max) tmpfile)
|
||||
(gnus-group-read-ephemeral-group
|
||||
(format "nndoc+ephemeral:bug#%s"
|
||||
(mapconcat 'number-to-string ids ","))
|
||||
`(nndoc ,tmpfile
|
||||
(nndoc-article-type mbox))
|
||||
nil window-conf))
|
||||
(let ((tmpfile (mm-make-temp-file "gnus-temp-group-")))
|
||||
(let ((coding-system-for-write 'binary)
|
||||
(coding-system-for-read 'binary))
|
||||
(with-temp-file tmpfile
|
||||
(mm-disable-multibyte)
|
||||
(dolist (id ids)
|
||||
(url-insert-file-contents (format mbox-url id)))
|
||||
(goto-char (point-min))
|
||||
;; Add the debbugs address so that we can respond to reports easily.
|
||||
(while (re-search-forward "^To: " nil t)
|
||||
(end-of-line)
|
||||
(insert (format ", %s@%s" (car ids)
|
||||
(gnus-replace-in-string
|
||||
(gnus-replace-in-string mbox-url "^http://" "")
|
||||
"/.*$" ""))))))
|
||||
(gnus-group-read-ephemeral-group
|
||||
(format "nndoc+ephemeral:bug#%s"
|
||||
(mapconcat 'number-to-string ids ","))
|
||||
`(nndoc ,tmpfile
|
||||
(nndoc-article-type mbox))
|
||||
nil window-conf)
|
||||
(delete-file tmpfile)))
|
||||
|
||||
(defun gnus-read-ephemeral-debian-bug-group (number)
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@
|
|||
:type hash-table
|
||||
:documentation "The data hashtable.")))
|
||||
;; Do this separately, since defclass doesn't allow expressions in :initform.
|
||||
(oset-default registry-db max-size most-positive-fixnum)
|
||||
(oset-default 'registry-db max-size most-positive-fixnum)
|
||||
|
||||
(defmethod initialize-instance :BEFORE ((this registry-db) slots)
|
||||
"Check whether a registry object needs to be upgraded."
|
||||
|
|
|
|||
|
|
@ -1355,6 +1355,14 @@ IF := (if EXPRESSION CCL_BLOCK_0 CCL_BLOCK_1)
|
|||
BRANCH := (branch EXPRESSION CCL_BLOCK_0 [CCL_BLOCK_1 ...])
|
||||
|
||||
;; Execute STATEMENTs until (break) or (end) is executed.
|
||||
|
||||
;; Create a block of STATEMENTs for repeating. The STATEMENTs
|
||||
;; are executed sequentially until REPEAT or BREAK is executed.
|
||||
;; If REPEAT statement is executed, STATEMENTs are executed from the
|
||||
;; start again. If BREAK statements is executed, the execution
|
||||
;; exits from the block. If neither REPEAT nor BREAK is
|
||||
;; executed, the execution exits from the block after executing the
|
||||
;; last STATEMENT.
|
||||
LOOP := (loop STATEMENT [STATEMENT ...])
|
||||
|
||||
;; Terminate the most inner loop.
|
||||
|
|
@ -1501,17 +1509,42 @@ ARRAY := `[' integer ... `]'
|
|||
|
||||
|
||||
TRANSLATE :=
|
||||
(translate-character REG(table) REG(charset) REG(codepoint))
|
||||
| (translate-character SYMBOL REG(charset) REG(codepoint))
|
||||
;; SYMBOL must refer to a table defined by `define-translation-table'.
|
||||
;; Decode character SRC, translate it by translate table
|
||||
;; TABLE, and encode it back to DST. TABLE is specified
|
||||
;; by its id number in REG_0, SRC is specified by its
|
||||
;; charset id number and codepoint in REG_1 and REG_2
|
||||
;; respectively.
|
||||
;; On encoding, the charset of highest priority is selected.
|
||||
;; After the execution, DST is specified by its charset
|
||||
;; id number and codepoint in REG_1 and REG_2 respectively.
|
||||
(translate-character REG_0 REG_1 REG_2)
|
||||
|
||||
;; Same as above except for SYMBOL specifying the name of
|
||||
;; the translate table defined by `define-translation-table'.
|
||||
| (translate-character SYMBOL REG_1 REG_2)
|
||||
|
||||
LOOKUP :=
|
||||
(lookup-character SYMBOL REG(charset) REG(codepoint))
|
||||
;; Look up character SRC in hash table TABLE. TABLE is
|
||||
;; specified by its name in SYMBOL, and SRC is specified by
|
||||
;; its charset id number and codepoint in REG_1 and REG_2
|
||||
;; respectively.
|
||||
;; If its associated value is an integer, set REG_1 to that
|
||||
;; value, and set r7 to 1. Otherwise, set r7 to 0.
|
||||
(lookup-character SYMBOL REG_1 REG_2)
|
||||
|
||||
;; Look up integer value N in hash table TABLE. TABLE is
|
||||
;; specified by its name in SYMBOL and N is specified in
|
||||
;; REG.
|
||||
;; If its associated value is a character, set REG to that
|
||||
;; value, and set r7 to 1. Otherwise, set r7 to 0.
|
||||
| (lookup-integer SYMBOL REG(integer))
|
||||
;; SYMBOL refers to a table defined by `define-translation-hash-table'.
|
||||
|
||||
MAP :=
|
||||
(iterate-multiple-map REG REG MAP-IDs)
|
||||
| (map-multiple REG REG (MAP-SET))
|
||||
| (map-single REG REG MAP-ID)
|
||||
;; The following statements are for internal use only.
|
||||
(iterate-multiple-map REG REG MAP-IDs)
|
||||
| (map-multiple REG REG (MAP-SET))
|
||||
| (map-single REG REG MAP-ID)
|
||||
|
||||
MAP-IDs := MAP-ID ...
|
||||
MAP-SET := MAP-IDs | (MAP-IDs) MAP-SET
|
||||
MAP-ID := integer
|
||||
|
|
|
|||
|
|
@ -826,16 +826,27 @@ styles for specific categories, such as files, buffers, etc."
|
|||
:type completion--styles-type
|
||||
:version "23.1")
|
||||
|
||||
(defcustom completion-category-overrides
|
||||
'((buffer (styles . (basic substring))))
|
||||
"List of `completion-styles' overrides for specific categories.
|
||||
(defvar completion-category-defaults
|
||||
'((buffer (styles . (basic substring)))
|
||||
(unicode-name (styles . (basic substring))))
|
||||
"Default settings for specific completion categories.
|
||||
Each entry has the shape (CATEGORY . ALIST) where ALIST is
|
||||
an association list that can specify properties such as:
|
||||
- `styles': the list of `completion-styles' to use for that category.
|
||||
- `cycle': the `completion-cycle-threshold' to use for that category.
|
||||
Categories are symbols such as `buffer' and `file', used when
|
||||
completing buffer and file names, respectively.")
|
||||
|
||||
(defcustom completion-category-overrides nil
|
||||
"List of category-specific user overrides for completion styles.
|
||||
Each override has the shape (CATEGORY . ALIST) where ALIST is
|
||||
an association list that can specify properties such as:
|
||||
- `styles': the list of `completion-styles' to use for that category.
|
||||
- `cycle': the `completion-cycle-threshold' to use for that category.
|
||||
Categories are symbols such as `buffer' and `file', used when
|
||||
completing buffer and file names, respectively."
|
||||
:version "24.1"
|
||||
completing buffer and file names, respectively.
|
||||
This overrides the defaults specified in `completion-category-defaults'."
|
||||
:version "25.1"
|
||||
:type `(alist :key-type (choice :tag "Category"
|
||||
(const buffer)
|
||||
(const file)
|
||||
|
|
@ -851,9 +862,13 @@ completing buffer and file names, respectively."
|
|||
(const :tag "Select one value from the menu." cycle)
|
||||
,completion--cycling-threshold-type))))
|
||||
|
||||
(defun completion--category-override (category tag)
|
||||
(or (assq tag (cdr (assq category completion-category-overrides)))
|
||||
(assq tag (cdr (assq category completion-category-defaults)))))
|
||||
|
||||
(defun completion--styles (metadata)
|
||||
(let* ((cat (completion-metadata-get metadata 'category))
|
||||
(over (assq 'styles (cdr (assq cat completion-category-overrides)))))
|
||||
(over (completion--category-override cat 'styles)))
|
||||
(if over
|
||||
(delete-dups (append (cdr over) (copy-sequence completion-styles)))
|
||||
completion-styles)))
|
||||
|
|
@ -967,7 +982,7 @@ completion candidates than this number."
|
|||
|
||||
(defun completion--cycle-threshold (metadata)
|
||||
(let* ((cat (completion-metadata-get metadata 'category))
|
||||
(over (assq 'cycle (cdr (assq cat completion-category-overrides)))))
|
||||
(over (completion--category-override cat 'cycle)))
|
||||
(if over (cdr over) completion-cycle-threshold)))
|
||||
|
||||
(defvar-local completion-all-sorted-completions nil)
|
||||
|
|
|
|||
|
|
@ -255,14 +255,18 @@ word(s) will be searched for via `eww-search-prefix'."
|
|||
((string-match-p "\\`ftp://" url)
|
||||
(user-error "FTP is not supported."))
|
||||
(t
|
||||
(if (and (= (length (split-string url)) 1)
|
||||
(or (and (not (string-match-p "\\`[\"\'].*[\"\']\\'" url))
|
||||
(> (length (split-string url "[.:]")) 1))
|
||||
(string-match eww-local-regex url)))
|
||||
(if (or (string-match "\\`https?:" url)
|
||||
;; Also try to match "naked" URLs like
|
||||
;; en.wikipedia.org/wiki/Free software
|
||||
(string-match "\\`[A-Za-z_]+\\.[A-Za-z._]+/" url)
|
||||
(and (= (length (split-string url)) 1)
|
||||
(or (and (not (string-match-p "\\`[\"\'].*[\"\']\\'" url))
|
||||
(> (length (split-string url "[.:]")) 1))
|
||||
(string-match eww-local-regex url))))
|
||||
(progn
|
||||
(unless (string-match-p "\\`[a-zA-Z][-a-zA-Z0-9+.]*://" url)
|
||||
(setq url (concat "http://" url)))
|
||||
;; some site don't redirect final /
|
||||
;; Some sites do not redirect final /
|
||||
(when (string= (url-filename (url-generic-parse-url url)) "")
|
||||
(setq url (concat url "/"))))
|
||||
(setq url (concat eww-search-prefix
|
||||
|
|
@ -273,6 +277,7 @@ word(s) will be searched for via `eww-search-prefix'."
|
|||
(eww-save-history))
|
||||
(eww-setup-buffer)
|
||||
(plist-put eww-data :url url)
|
||||
(plist-put eww-data :title "")
|
||||
(eww-update-header-line-format)
|
||||
(let ((inhibit-read-only t))
|
||||
(insert (format "Loading %s..." url))
|
||||
|
|
|
|||
|
|
@ -894,7 +894,12 @@ START, and END. Note that START and END should be markers."
|
|||
(add-text-properties
|
||||
start (point)
|
||||
(list 'shr-url url
|
||||
'help-echo (if title (shr-fold-text (format "%s (%s)" url title)) url)
|
||||
'help-echo (let ((iri (or (ignore-errors
|
||||
(decode-coding-string
|
||||
(url-unhex-string url)
|
||||
'utf-8 t))
|
||||
url)))
|
||||
(if title (format "%s (%s)" iri title) iri))
|
||||
'follow-link t
|
||||
'mouse-face 'highlight
|
||||
'keymap shr-map)))
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ name as matched contains
|
|||
|
||||
(defconst js--function-heading-1-re
|
||||
(concat
|
||||
"^\\s-*function\\s-+\\(" js--name-re "\\)")
|
||||
"^\\s-*function\\(?:\\s-\\|\\*\\)+\\(" js--name-re "\\)")
|
||||
"Regexp matching the start of a JavaScript function header.
|
||||
Match group 1 is the name of the function.")
|
||||
|
||||
|
|
@ -796,6 +796,9 @@ determined. Otherwise, return nil."
|
|||
(let ((name t))
|
||||
(forward-word)
|
||||
(forward-comment most-positive-fixnum)
|
||||
(when (eq (char-after) ?*)
|
||||
(forward-char)
|
||||
(forward-comment most-positive-fixnum))
|
||||
(when (looking-at js--name-re)
|
||||
(setq name (match-string-no-properties 0))
|
||||
(goto-char (match-end 0)))
|
||||
|
|
|
|||
|
|
@ -434,7 +434,8 @@ GROUP is a string for decoration purposes and XREF is an
|
|||
(list 'xref-location location
|
||||
'face 'font-lock-keyword-face
|
||||
'mouse-face 'highlight
|
||||
'keymap xref--button-map)
|
||||
'keymap xref--button-map
|
||||
'help-echo "mouse-2: display, RET or mouse-1: navigate")
|
||||
description))
|
||||
(when (or more1 more2)
|
||||
(insert "\n")))))
|
||||
|
|
|
|||
|
|
@ -309,13 +309,6 @@ for Shell mode only."
|
|||
(const :tag "on" t))
|
||||
:group 'shell)
|
||||
|
||||
(defcustom shell-display-buffer-actions display-buffer-base-action
|
||||
"The `display-buffer' actions for the `*shell*' buffer."
|
||||
:type display-buffer--action-custom-type
|
||||
:risky t
|
||||
:version "25.1"
|
||||
:group 'shell)
|
||||
|
||||
(defvar shell-dirstack nil
|
||||
"List of directories saved by pushd in this buffer's shell.
|
||||
Thus, this does not include the shell's current directory.")
|
||||
|
|
@ -726,7 +719,7 @@ Otherwise, one argument `-i' is passed to the shell.
|
|||
|
||||
;; The buffer's window must be correctly set when we call comint (so
|
||||
;; that comint sets the COLUMNS env var properly).
|
||||
(pop-to-buffer buffer shell-display-buffer-actions)
|
||||
(pop-to-buffer buffer)
|
||||
(unless (comint-check-proc buffer)
|
||||
(let* ((prog (or explicit-shell-file-name
|
||||
(getenv "ESHELL") shell-file-name))
|
||||
|
|
|
|||
|
|
@ -5604,14 +5604,22 @@ If NOERROR, don't signal an error if we can't move that many lines."
|
|||
(> (cdr temporary-goal-column) 0))
|
||||
(setq target-hscroll (cdr temporary-goal-column)))
|
||||
;; Otherwise, we should reset `temporary-goal-column'.
|
||||
(let ((posn (posn-at-point)))
|
||||
(let ((posn (posn-at-point))
|
||||
x-pos)
|
||||
(cond
|
||||
;; Handle the `overflow-newline-into-fringe' case:
|
||||
((eq (nth 1 posn) 'right-fringe)
|
||||
(setq temporary-goal-column (cons (- (window-width) 1) hscroll)))
|
||||
((car (posn-x-y posn))
|
||||
(setq x-pos (car (posn-x-y posn)))
|
||||
;; In R2L lines, the X pixel coordinate is measured from the
|
||||
;; left edge of the window, but columns are still counted
|
||||
;; from the logical-order beginning of the line, i.e. from
|
||||
;; the right edge in this case. We need to adjust for that.
|
||||
(if (eq (current-bidi-paragraph-direction) 'right-to-left)
|
||||
(setq x-pos (- (window-body-width nil t) 1 x-pos)))
|
||||
(setq temporary-goal-column
|
||||
(cons (/ (float (car (posn-x-y posn)))
|
||||
(cons (/ (float x-pos)
|
||||
(frame-char-width))
|
||||
hscroll))))))
|
||||
(if target-hscroll
|
||||
|
|
|
|||
|
|
@ -1312,6 +1312,7 @@ is converted into a string by expressing it in decimal."
|
|||
(make-obsolete-variable 'redisplay-end-trigger-functions 'jit-lock-register "23.1")
|
||||
(make-obsolete-variable 'deferred-action-list 'post-command-hook "24.1")
|
||||
(make-obsolete-variable 'deferred-action-function 'post-command-hook "24.1")
|
||||
(make-obsolete-variable 'redisplay-dont-pause nil "24.5")
|
||||
(make-obsolete 'window-redisplay-end-trigger nil "23.1")
|
||||
(make-obsolete 'set-window-redisplay-end-trigger nil "23.1")
|
||||
|
||||
|
|
|
|||
|
|
@ -886,7 +886,7 @@ current, and kill the buffer that visits the link."
|
|||
(define-key map "=" 'vc-diff)
|
||||
(define-key map "D" 'vc-root-diff)
|
||||
(define-key map "~" 'vc-revision-other-window)
|
||||
(define-key map "[delete]" 'vc-delete-file)
|
||||
(define-key map "x" 'vc-delete-file)
|
||||
map))
|
||||
(fset 'vc-prefix-map vc-prefix-map)
|
||||
(define-key ctl-x-map "v" 'vc-prefix-map)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# stdio_h.m4 serial 43
|
||||
# stdio_h.m4 serial 44
|
||||
dnl Copyright (C) 2007-2015 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
|
|
@ -12,6 +12,24 @@ AC_DEFUN([gl_STDIO_H],
|
|||
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
|
||||
gl_NEXT_HEADERS([stdio.h])
|
||||
|
||||
dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and
|
||||
dnl inttypes.h behave like gnu instead of system; we must give our
|
||||
dnl printf wrapper the right attribute to match.
|
||||
AC_CACHE_CHECK([whether inttypes macros match system or gnu printf],
|
||||
[gl_cv_func_printf_attribute_flavor],
|
||||
[AC_EGREP_CPP([findme .(ll|j)d. findme],
|
||||
[#define __STDC_FORMAT_MACROS 1
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
findme PRIdMAX findme
|
||||
], [gl_cv_func_printf_attribute_flavor=gnu],
|
||||
[gl_cv_func_printf_attribute_flavor=system])])
|
||||
if test "$gl_cv_func_printf_attribute_flavor" = gnu; then
|
||||
AC_DEFINE([GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU], [1],
|
||||
[Define to 1 if printf and friends should be labeled with
|
||||
attribute "__gnu_printf__" instead of "__printf__"])
|
||||
fi
|
||||
|
||||
dnl No need to create extra modules for these functions. Everyone who uses
|
||||
dnl <stdio.h> likely needs them.
|
||||
GNULIB_FSCANF=1
|
||||
|
|
|
|||
18
src/.gdbinit
18
src/.gdbinit
|
|
@ -70,6 +70,16 @@ define xgettype
|
|||
set $type = (enum Lisp_Type) (USE_LSB_TAG ? $bugfix & (1 << GCTYPEBITS) - 1 : (EMACS_UINT) $bugfix >> VALBITS)
|
||||
end
|
||||
|
||||
# Access the name of a symbol
|
||||
define xsymname
|
||||
if (CHECK_LISP_OBJECT_TYPE)
|
||||
set $bugfix = $arg0.i
|
||||
else
|
||||
set $bugfix = $arg0
|
||||
end
|
||||
set $symname = ((struct Lisp_Symbol *) ((char *)lispsym + $bugfix))->name
|
||||
end
|
||||
|
||||
# Set up something to print out s-expressions.
|
||||
# We save and restore print_output_debug_flag to prevent the w32 port
|
||||
# from calling OutputDebugString, which causes GDB to display each
|
||||
|
|
@ -1073,8 +1083,8 @@ end
|
|||
|
||||
define xprintsym
|
||||
xgetptr $arg0
|
||||
set $sym = (struct Lisp_Symbol *) $ptr
|
||||
xgetptr $sym->name
|
||||
xsymname $ptr
|
||||
xgetptr $symname
|
||||
set $sym_name = (struct Lisp_String *) $ptr
|
||||
xprintstr $sym_name
|
||||
end
|
||||
|
|
@ -1258,8 +1268,8 @@ tbreak init_sys_modes
|
|||
commands
|
||||
silent
|
||||
xgetptr globals.f_Vinitial_window_system
|
||||
set $tem = (struct Lisp_Symbol *) $ptr
|
||||
xgetptr $tem->name
|
||||
xsymname $ptr
|
||||
xgetptr $symname
|
||||
set $tem = (struct Lisp_String *) $ptr
|
||||
set $tem = (char *) $tem->data
|
||||
# If we are running in synchronous mode, we want a chance to look
|
||||
|
|
|
|||
247
src/ChangeLog
247
src/ChangeLog
|
|
@ -1,3 +1,246 @@
|
|||
2015-01-11 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Port to MSB hosts without optimization
|
||||
E.g., when configuring --with-wide-int CFLAGS='-O0' on x86,
|
||||
the inline function XTYPE needs to be declared before being used.
|
||||
* lisp.h (XTYPE): New forward declaration.
|
||||
|
||||
2015-01-10 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Port to 32-bit --with-wide-int
|
||||
Prefer symbol indexes to struct Lisp_Symbol * casted and then
|
||||
widened, as the latter had trouble with GCC on Fedora 21 when
|
||||
configured --with-wide-int and when used in static initializers.
|
||||
* alloc.c (garbage_collect_1, which_symbols):
|
||||
* lread.c (init_obarray):
|
||||
Prefer builtin_lisp_symbol when it can be used.
|
||||
* dispextern.h (struct image_type.type):
|
||||
* font.c (font_property_table.key):
|
||||
* frame.c (struct frame_parm_table.sym):
|
||||
* keyboard.c (scroll_bar_parts, struct event_head):
|
||||
* xdisp.c (struct props.name):
|
||||
Use the index of a builtin symbol rather than its address.
|
||||
All uses changed.
|
||||
* lisp.h (TAG_SYMPTR, XSYMBOL_INIT): Remove, replacing with ...
|
||||
(TAG_SYMOFFSET, SYMBOL_INDEX): ... new macros that deal with
|
||||
symbol indexes rather than pointers, and which work better on MSB
|
||||
hosts because they shift right before tagging. All uses changed.
|
||||
(DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END):
|
||||
No longer noops on wide-int hosts, since they work now.
|
||||
(builtin_lisp_symbol): New function.
|
||||
|
||||
Port to HAVE_FREETYPE && !HAVE_XFT
|
||||
* dispextern.h (struct face.extra) [HAVE_FREETYPE && !HAVE_XFT]:
|
||||
* font.h (syms_of_xftfont) [HAVE_FREETYPE && !HAVE_XFT]:
|
||||
Declare in this case too.
|
||||
|
||||
2015-01-10 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32fns.c (Fw32_register_hot_key): Use XINT instead of XLI.
|
||||
|
||||
* w32notify.c (Fw32notify_add_watch, w32_get_watch_object): Use
|
||||
make_pointer_integer instead of XIL.
|
||||
(Fw32notify_rm_watch): Use XINTPTR instead of XLI.
|
||||
|
||||
* w32inevt.c (handle_file_notifications): Use make_pointer_integer
|
||||
instead of XIL. Put a list of the descriptor, action, and file
|
||||
name in event->arg, instead of spreading them between event->code
|
||||
and event->arg.
|
||||
|
||||
* w32term.c (queue_notifications): Use make_pointer_integer
|
||||
instead of XIL. Put a list of the descriptor, action, and file
|
||||
name in event->arg, instead of spreading them between event->code
|
||||
and event->arg.
|
||||
|
||||
* keyboard.c (kbd_buffer_get_event) [HAVE_W32NOTIFY]: Adjust Lisp
|
||||
event creation to changes in w32term.c and w32inevt.c above.
|
||||
|
||||
2015-01-09 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Port Qnil==0 changes to 32-bit --with-wide-int
|
||||
* lisp.h (lisp_h_XSYMBOL, XSYMBOL): Assume USE_LSB_TAG in the
|
||||
macro-implemented version. For the non-USE_LSB_TAG case, supply
|
||||
a new inline function that is the inverse of the new TAG_SYMPTR.
|
||||
(lisp_h_XUNTAGBASE, XUNTAGBASE): Remove. All uses removed.
|
||||
(TAG_SYMPTR) [!USE_LSB_TAG]: If the pointer subtraction yields a
|
||||
negative number, don't allow sign bits to bleed into the encoded
|
||||
value. Shift in zero bits instead.
|
||||
|
||||
Refactor pointer-to-integer conversion
|
||||
* gfilenotify.c (monitor_to_lisp, lisp_to_monitor):
|
||||
Rename and move to lisp.h. All uses changed.
|
||||
* lisp.h (XINTPTR, make_pointer_integer): New inline functions,
|
||||
which are renamed from gfilenotify.c's lisp_to_monitor and
|
||||
monitor_to_lisp, and with more-generic void * signatures.
|
||||
|
||||
2015-01-08 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* dispnew.c (buffer_posn_from_coords): Fix the value of the column
|
||||
returned for right-to-left screen lines. (Before the change on
|
||||
2014-12-30, the incorrectly-computed X pixel coordinate concealed
|
||||
this bug.)
|
||||
|
||||
* .gdbinit (xsymname): New subroutine.
|
||||
(xprintsym, initial-tbreak): Use it to access the name of a symbol
|
||||
in a way that doesn't cause GDB to barf when it tries to
|
||||
dereference a NULL pointer.
|
||||
|
||||
* xdisp.c (next_element_from_c_string): Use Lisp integer zero as
|
||||
the object.
|
||||
(set_cursor_from_row, try_cursor_movement, dump_glyph)
|
||||
(insert_left_trunc_glyphs, append_space_for_newline)
|
||||
(extend_face_to_end_of_line, highlight_trailing_whitespace)
|
||||
(find_row_edges, ROW_GLYPH_NEWLINE_P, Fmove_point_visually)
|
||||
(Fbidi_resolved_levels, produce_special_glyphs)
|
||||
(rows_from_pos_range, mouse_face_from_buffer_pos)
|
||||
(note_mouse_highlight): Use nil as the object for glyphs inserted
|
||||
by the display engine, and test with NILP instead of INTEGERP.
|
||||
(Bug#19535)
|
||||
|
||||
* w32fns.c (Fx_show_tip): Use NILP to test for glyphs inserted by
|
||||
the display engine.
|
||||
|
||||
* xfns.c (Fx_show_tip): Use NILP to test for glyphs inserted by
|
||||
the display engine.
|
||||
|
||||
* dispextern.h (struct glyph, struct it): Update comments for the
|
||||
OBJECT members.
|
||||
|
||||
2015-01-08 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Port new Lisp symbol init to x86 --with-wide-int
|
||||
* lisp.h (DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END):
|
||||
Define to empty on platforms where EMACS_INT_MAX != INTPTR_MAX, as
|
||||
GCC (at least) does not allow a constant initializer to widen an
|
||||
address constant.
|
||||
|
||||
* lisp.h (TAG_SYMPTR): Don't do arithmetic on NULL.
|
||||
This is a followup to the "Port Qnil==0 XUNTAG to clang" patch.
|
||||
Although clang doesn't need it, some other compiler might, and
|
||||
it's easy enough to be safe.
|
||||
|
||||
* conf_post.h (ATTRIBUTE_ALLOC_SIZE): Port to clang 3.5.0.
|
||||
Apparently clang removed support for the alloc_size attribute.
|
||||
|
||||
Port Qnil==0 XUNTAG to clang
|
||||
clang has undefined behavior if the program subtracts an integer
|
||||
from (char *) 0. Problem reported by YAMAMOTO Mitsuharu in:
|
||||
http://lists.gnu.org/archive/html/emacs-devel/2015-01/msg00132.html
|
||||
* lisp.h (lisp_h_XUNTAG) [USE_LSB_TAG]:
|
||||
(XUNTAG) [!USE_LSB_TAG]: Port to clang 3.5.0.
|
||||
|
||||
Port GFileMonitor * hack to Qnil==0 platforms
|
||||
Reported by Glenn Morris in: http://bugs.gnu.org/15880#112
|
||||
* gfilenotify.c (monitor_to_lisp, lisp_to_monitor): New functions.
|
||||
(dir_monitor_callback, Fgfile_add_watch, Fgfile_rm_watch): Use them.
|
||||
|
||||
2015-01-06 Jan Djärv <jan.h.d@swipnet.se>
|
||||
|
||||
* nsterm.m (x_set_window_size): Call updateFrameSize to get real
|
||||
size instead of using widht/height. The frame may be constrained.
|
||||
|
||||
2015-01-05 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* lisp.h (XSYMBOL): Parenthesize id in forward decl.
|
||||
Needed when neither optimizing nor inlining.
|
||||
Also, sort decls alphabetically.
|
||||
|
||||
2015-01-05 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32proc.c, w32.h, w32fns.c, w32font.c, w32menu.c, w32notify.c:
|
||||
* w32proc.c, w32select.c, w32term.c, w32uniscribe.c: Remove
|
||||
declarations of Q* variables that represent symbols.
|
||||
|
||||
2015-01-05 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Use 0 for Qnil
|
||||
Fixes Bug#15880.
|
||||
If USE_LSB_TAG, arrange for the representation of Qnil to be zero so
|
||||
that NILP (x) is equivalent to testing whether x is 0 at the
|
||||
machine level. The overall effects of this and the previous patch
|
||||
shrink the size of the text segment by 2.3% and speeds up
|
||||
compilation of all the .elc files by about 0.5% on my platform,
|
||||
which is Fedora 20 x86-64.
|
||||
* lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG)
|
||||
(make_lisp_symbol) [USE_LSB_TAG]:
|
||||
Symbols now tag the difference from lispsym, not the pointer.
|
||||
(lisp_h_XUNTAGBASE, TAG_SYMPTR): New macros.
|
||||
(Lisp_Int0, Lisp_Int1, Lisp_Symbol, Lisp_Misc, Lisp_String, Lisp_Cons):
|
||||
Renumber so that Lisp_Symbol is 0, so that Qnil is zero.
|
||||
(XSYMBOL): New forward decl.
|
||||
(XUNTAGBASE): New function.
|
||||
(XUNTAG): Use it.
|
||||
|
||||
Compute C decls for DEFSYMs automatically
|
||||
Fixes Bug#15880.
|
||||
This patch also makes Q constants (e.g., Qnil) constant addresses
|
||||
from the C point of view.
|
||||
* alloc.c, bidi.c, buffer.c, bytecode.c, callint.c, casefiddle.c:
|
||||
* casetab.c, category.c, ccl.c, charset.c, chartab.c, cmds.c, coding.c:
|
||||
* composite.c, data.c, dbusbind.c, decompress.c, dired.c, dispnew.c:
|
||||
* doc.c, editfns.c, emacs.c, eval.c, fileio.c, fns.c, font.c, fontset.c:
|
||||
* frame.c, fringe.c, ftfont.c, ftxfont.c, gfilenotify.c, gnutls.c:
|
||||
* image.c, inotify.c, insdel.c, keyboard.c, keymap.c, lread.c:
|
||||
* macfont.m, macros.c, minibuf.c, nsfns.m, nsfont.m, nsimage.m:
|
||||
* nsmenu.m, nsselect.m, nsterm.m, print.c, process.c, profiler.c:
|
||||
* search.c, sound.c, syntax.c, term.c, terminal.c, textprop.c, undo.c:
|
||||
* window.c, xdisp.c, xfaces.c, xfns.c, xftfont.c, xmenu.c, xml.c:
|
||||
* xselect.c, xsettings.c, xterm.c:
|
||||
Remove Q vars that represent symbols (e.g., Qnil, Qt, Qemacs).
|
||||
These names are now defined automatically by make-docfile.
|
||||
* alloc.c (init_symbol): New function.
|
||||
(Fmake_symbol): Use it.
|
||||
(c_symbol_p): New function.
|
||||
(valid_lisp_object_p, purecopy): Use it.
|
||||
* alloc.c (marked_pinned_symbols):
|
||||
Use make_lisp_symbol instead of make_lisp_ptr.
|
||||
(garbage_collect_1): Mark lispsym symbols.
|
||||
(CHECK_ALLOCATED_AND_LIVE_SYMBOL): New macro.
|
||||
(mark_object): Use it.
|
||||
(sweep_symbols): Sweep lispsym symbols.
|
||||
(symbol_uses_obj): New function.
|
||||
(which_symbols): Use it. Work for lispsym symbols, too.
|
||||
(init_alloc_once): Initialize Vpurify_flag here; no need to wait,
|
||||
since Qt's address is already known now.
|
||||
(syms_of_alloc): Add lispsym count to symbols_consed.
|
||||
* buffer.c (init_buffer_once): Compare to Qnil, not to make_number (0),
|
||||
when testing whether storage is all bits zero.
|
||||
* dispextern.h (struct image_type):
|
||||
* font.c (font_property_table):
|
||||
* frame.c (struct frame_parm_table, frame_parms):
|
||||
* keyboard.c (scroll_bar_parts, struct event_head):
|
||||
* xdisp.c (struct props):
|
||||
Use XSYMBOL_INIT (Qfoo) and struct Lisp_Symbol * rather than &Qfoo and
|
||||
Lisp_Object *, since Qfoo is no longer an object whose address can be
|
||||
taken. All uses changed.
|
||||
* eval.c (run_hook): New function. Most uses of Frun_hooks changed to
|
||||
use it, so that they no longer need to take the address of a Lisp sym.
|
||||
(syms_of_eval): Don't use DEFSYM on Vrun_hooks, as it's a variable.
|
||||
* frame.c (syms_of_frame): Add defsyms for the frame_parms table.
|
||||
* keyboard.c (syms_of_keyboard): Don't DEFSYM Qmenu_bar here.
|
||||
DEFSYM Qdeactivate_mark before the corresponding var.
|
||||
* keymap.c (syms_of_keymap): Use DEFSYM for Qmenu_bar and Qmode_line
|
||||
instead of interning their symbols; this avoids duplicates.
|
||||
(LISP_INITIALLY, TAG_PTR)
|
||||
(DEFINE_LISP_SYMBOL_BEGIN, DEFINE_LISP_SYMBOL_END, XSYMBOL_INIT):
|
||||
New macros.
|
||||
(LISP_INITIALLY_ZERO): Use it.
|
||||
(enum symbol_interned, enum symbol_redirect, struct Lisp_Symbol)
|
||||
(EXFUN, DEFUN_ARGS_MANY, DEFUN_ARGS_UNEVALLED, DEFUN_ARGS_*):
|
||||
Move decls up, to avoid forward uses. Include globals.h earlier, too.
|
||||
(make_lisp_symbol): New function.
|
||||
(XSETSYMBOL): Use it.
|
||||
(DEFSYM): Now just a placeholder for make-docfile.
|
||||
* lread.c (DEFINE_SYMBOLS): Define, for globals.h.
|
||||
(intern_sym): New function, with body taken from old intern_driver.
|
||||
(intern_driver): Use it. Last arg is now Lisp integer, not ptrdiff_t.
|
||||
All uses changed.
|
||||
(define_symbol): New function.
|
||||
(init_obarray): Define the C symbols taken from lispsym.
|
||||
Use plain DEFSYM for Qt and Qnil.
|
||||
* syntax.c (init_syntax_once): No need to worry about
|
||||
Qchar_table_extra_slots.
|
||||
|
||||
2015-01-04 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
'temacs -nw' should not call missing functions
|
||||
|
|
@ -146,6 +389,10 @@
|
|||
* xterm.c (do_ewmh_fullscreen): Don't remove maximized_horz/vert
|
||||
when going to fullscreen (Bug#0x180004f).
|
||||
|
||||
2014-12-27 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* window.c (Fwindow_body_width): Doc fix. (Bug#19395)
|
||||
|
||||
2014-12-27 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* buffer.c (syms_of_buffer) <Vafter_change_functions>: fix docstring.
|
||||
|
|
|
|||
147
src/alloc.c
147
src/alloc.c
|
|
@ -263,23 +263,6 @@ no_sanitize_memcpy (void *dest, void const *src, size_t size)
|
|||
|
||||
#endif /* MAX_SAVE_STACK > 0 */
|
||||
|
||||
static Lisp_Object Qconses;
|
||||
static Lisp_Object Qsymbols;
|
||||
static Lisp_Object Qmiscs;
|
||||
static Lisp_Object Qstrings;
|
||||
static Lisp_Object Qvectors;
|
||||
static Lisp_Object Qfloats;
|
||||
static Lisp_Object Qintervals;
|
||||
static Lisp_Object Qbuffers;
|
||||
static Lisp_Object Qstring_bytes, Qvector_slots, Qheap;
|
||||
static Lisp_Object Qgc_cons_threshold;
|
||||
Lisp_Object Qautomatic_gc;
|
||||
Lisp_Object Qchar_table_extra_slots;
|
||||
|
||||
/* Hook run after GC has finished. */
|
||||
|
||||
static Lisp_Object Qpost_gc_hook;
|
||||
|
||||
static void mark_terminals (void);
|
||||
static void gc_sweep (void);
|
||||
static Lisp_Object make_pure_vector (ptrdiff_t);
|
||||
|
|
@ -3410,13 +3393,29 @@ set_symbol_name (Lisp_Object sym, Lisp_Object name)
|
|||
XSYMBOL (sym)->name = name;
|
||||
}
|
||||
|
||||
void
|
||||
init_symbol (Lisp_Object val, Lisp_Object name)
|
||||
{
|
||||
struct Lisp_Symbol *p = XSYMBOL (val);
|
||||
set_symbol_name (val, name);
|
||||
set_symbol_plist (val, Qnil);
|
||||
p->redirect = SYMBOL_PLAINVAL;
|
||||
SET_SYMBOL_VAL (p, Qunbound);
|
||||
set_symbol_function (val, Qnil);
|
||||
set_symbol_next (val, NULL);
|
||||
p->gcmarkbit = false;
|
||||
p->interned = SYMBOL_UNINTERNED;
|
||||
p->constant = 0;
|
||||
p->declared_special = false;
|
||||
p->pinned = false;
|
||||
}
|
||||
|
||||
DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
|
||||
doc: /* Return a newly allocated uninterned symbol whose name is NAME.
|
||||
Its value is void, and its function definition and property list are nil. */)
|
||||
(Lisp_Object name)
|
||||
{
|
||||
register Lisp_Object val;
|
||||
register struct Lisp_Symbol *p;
|
||||
Lisp_Object val;
|
||||
|
||||
CHECK_STRING (name);
|
||||
|
||||
|
|
@ -3444,18 +3443,7 @@ Its value is void, and its function definition and property list are nil. */)
|
|||
|
||||
MALLOC_UNBLOCK_INPUT;
|
||||
|
||||
p = XSYMBOL (val);
|
||||
set_symbol_name (val, name);
|
||||
set_symbol_plist (val, Qnil);
|
||||
p->redirect = SYMBOL_PLAINVAL;
|
||||
SET_SYMBOL_VAL (p, Qunbound);
|
||||
set_symbol_function (val, Qnil);
|
||||
set_symbol_next (val, NULL);
|
||||
p->gcmarkbit = false;
|
||||
p->interned = SYMBOL_UNINTERNED;
|
||||
p->constant = 0;
|
||||
p->declared_special = false;
|
||||
p->pinned = false;
|
||||
init_symbol (val, name);
|
||||
consing_since_gc += sizeof (struct Lisp_Symbol);
|
||||
symbols_consed++;
|
||||
total_free_symbols--;
|
||||
|
|
@ -4925,6 +4913,14 @@ mark_stack (void *end)
|
|||
|
||||
#endif /* GC_MARK_STACK != 0 */
|
||||
|
||||
static bool
|
||||
c_symbol_p (struct Lisp_Symbol *sym)
|
||||
{
|
||||
char *lispsym_ptr = (char *) lispsym;
|
||||
char *sym_ptr = (char *) sym;
|
||||
ptrdiff_t lispsym_offset = sym_ptr - lispsym_ptr;
|
||||
return 0 <= lispsym_offset && lispsym_offset < sizeof lispsym;
|
||||
}
|
||||
|
||||
/* Determine whether it is safe to access memory at address P. */
|
||||
static int
|
||||
|
|
@ -4978,6 +4974,9 @@ valid_lisp_object_p (Lisp_Object obj)
|
|||
if (PURE_POINTER_P (p))
|
||||
return 1;
|
||||
|
||||
if (SYMBOLP (obj) && c_symbol_p (p))
|
||||
return ((char *) p - (char *) lispsym) % sizeof lispsym[0] == 0;
|
||||
|
||||
if (p == &buffer_defaults || p == &buffer_local_symbols)
|
||||
return 2;
|
||||
|
||||
|
|
@ -5343,7 +5342,7 @@ purecopy (Lisp_Object obj)
|
|||
}
|
||||
else if (SYMBOLP (obj))
|
||||
{
|
||||
if (!XSYMBOL (obj)->pinned)
|
||||
if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj)))
|
||||
{ /* We can't purify them, but they appear in many pure objects.
|
||||
Mark them as `pinned' so we know to mark them at every GC cycle. */
|
||||
XSYMBOL (obj)->pinned = true;
|
||||
|
|
@ -5532,7 +5531,7 @@ mark_pinned_symbols (void)
|
|||
union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim;
|
||||
for (; sym < end; ++sym)
|
||||
if (sym->s.pinned)
|
||||
mark_object (make_lisp_ptr (&sym->s, Lisp_Symbol));
|
||||
mark_object (make_lisp_symbol (&sym->s));
|
||||
|
||||
lim = SYMBOL_BLOCK_SIZE;
|
||||
}
|
||||
|
|
@ -5566,7 +5565,7 @@ garbage_collect_1 (void *end)
|
|||
return Qnil;
|
||||
|
||||
/* Record this function, so it appears on the profiler's backtraces. */
|
||||
record_in_backtrace (Qautomatic_gc, &Qnil, 0);
|
||||
record_in_backtrace (Qautomatic_gc, 0, 0);
|
||||
|
||||
check_cons_list ();
|
||||
|
||||
|
|
@ -5630,6 +5629,9 @@ garbage_collect_1 (void *end)
|
|||
mark_buffer (&buffer_defaults);
|
||||
mark_buffer (&buffer_local_symbols);
|
||||
|
||||
for (i = 0; i < ARRAYELTS (lispsym); i++)
|
||||
mark_object (builtin_lisp_symbol (i));
|
||||
|
||||
for (i = 0; i < staticidx; i++)
|
||||
mark_object (*staticvec[i]);
|
||||
|
||||
|
|
@ -6193,17 +6195,28 @@ mark_object (Lisp_Object arg)
|
|||
emacs_abort (); \
|
||||
} while (0)
|
||||
|
||||
/* Check both of the above conditions. */
|
||||
/* Check both of the above conditions, for non-symbols. */
|
||||
#define CHECK_ALLOCATED_AND_LIVE(LIVEP) \
|
||||
do { \
|
||||
CHECK_ALLOCATED (); \
|
||||
CHECK_LIVE (LIVEP); \
|
||||
} while (0) \
|
||||
|
||||
/* Check both of the above conditions, for symbols. */
|
||||
#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() \
|
||||
do { \
|
||||
if (!c_symbol_p (ptr)) \
|
||||
{ \
|
||||
CHECK_ALLOCATED (); \
|
||||
CHECK_LIVE (live_symbol_p); \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
#else /* not GC_CHECK_MARKED_OBJECTS */
|
||||
|
||||
#define CHECK_LIVE(LIVEP) ((void) 0)
|
||||
#define CHECK_ALLOCATED_AND_LIVE(LIVEP) ((void) 0)
|
||||
#define CHECK_LIVE(LIVEP) ((void) 0)
|
||||
#define CHECK_ALLOCATED_AND_LIVE(LIVEP) ((void) 0)
|
||||
#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() ((void) 0)
|
||||
|
||||
#endif /* not GC_CHECK_MARKED_OBJECTS */
|
||||
|
||||
|
|
@ -6363,7 +6376,7 @@ mark_object (Lisp_Object arg)
|
|||
nextsym:
|
||||
if (ptr->gcmarkbit)
|
||||
break;
|
||||
CHECK_ALLOCATED_AND_LIVE (live_symbol_p);
|
||||
CHECK_ALLOCATED_AND_LIVE_SYMBOL ();
|
||||
ptr->gcmarkbit = 1;
|
||||
/* Attempt to catch bogus objects. */
|
||||
eassert (valid_lisp_object_p (ptr->function));
|
||||
|
|
@ -6720,13 +6733,16 @@ NO_INLINE /* For better stack traces */
|
|||
static void
|
||||
sweep_symbols (void)
|
||||
{
|
||||
register struct symbol_block *sblk;
|
||||
struct symbol_block *sblk;
|
||||
struct symbol_block **sprev = &symbol_block;
|
||||
register int lim = symbol_block_index;
|
||||
EMACS_INT num_free = 0, num_used = 0;
|
||||
int lim = symbol_block_index;
|
||||
EMACS_INT num_free = 0, num_used = ARRAYELTS (lispsym);
|
||||
|
||||
symbol_free_list = NULL;
|
||||
|
||||
for (int i = 0; i < ARRAYELTS (lispsym); i++)
|
||||
lispsym[i].gcmarkbit = 0;
|
||||
|
||||
for (sblk = symbol_block; sblk; sblk = *sprev)
|
||||
{
|
||||
int this_free = 0;
|
||||
|
|
@ -6974,6 +6990,21 @@ Frames, windows, buffers, and subprocesses count as vectors
|
|||
bounded_number (strings_consed));
|
||||
}
|
||||
|
||||
static bool
|
||||
symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj)
|
||||
{
|
||||
struct Lisp_Symbol *sym = XSYMBOL (symbol);
|
||||
Lisp_Object val = find_symbol_value (symbol);
|
||||
return (EQ (val, obj)
|
||||
|| EQ (sym->function, obj)
|
||||
|| (!NILP (sym->function)
|
||||
&& COMPILEDP (sym->function)
|
||||
&& EQ (AREF (sym->function, COMPILED_BYTECODE), obj))
|
||||
|| (!NILP (val)
|
||||
&& COMPILEDP (val)
|
||||
&& EQ (AREF (val, COMPILED_BYTECODE), obj)));
|
||||
}
|
||||
|
||||
/* Find at most FIND_MAX symbols which have OBJ as their value or
|
||||
function. This is used in gdbinit's `xwhichsymbols' command. */
|
||||
|
||||
|
|
@ -6986,6 +7017,17 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
|
|||
|
||||
if (! DEADP (obj))
|
||||
{
|
||||
for (int i = 0; i < ARRAYELTS (lispsym); i++)
|
||||
{
|
||||
Lisp_Object sym = builtin_lisp_symbol (i);
|
||||
if (symbol_uses_obj (sym, obj))
|
||||
{
|
||||
found = Fcons (sym, found);
|
||||
if (--find_max == 0)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
for (sblk = symbol_block; sblk; sblk = sblk->next)
|
||||
{
|
||||
union aligned_Lisp_Symbol *aligned_sym = sblk->symbols;
|
||||
|
|
@ -6993,25 +7035,13 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max)
|
|||
|
||||
for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++)
|
||||
{
|
||||
struct Lisp_Symbol *sym = &aligned_sym->s;
|
||||
Lisp_Object val;
|
||||
Lisp_Object tem;
|
||||
|
||||
if (sblk == symbol_block && bn >= symbol_block_index)
|
||||
break;
|
||||
|
||||
XSETSYMBOL (tem, sym);
|
||||
val = find_symbol_value (tem);
|
||||
if (EQ (val, obj)
|
||||
|| EQ (sym->function, obj)
|
||||
|| (!NILP (sym->function)
|
||||
&& COMPILEDP (sym->function)
|
||||
&& EQ (AREF (sym->function, COMPILED_BYTECODE), obj))
|
||||
|| (!NILP (val)
|
||||
&& COMPILEDP (val)
|
||||
&& EQ (AREF (val, COMPILED_BYTECODE), obj)))
|
||||
Lisp_Object sym = make_lisp_symbol (&aligned_sym->s);
|
||||
if (symbol_uses_obj (sym, obj))
|
||||
{
|
||||
found = Fcons (tem, found);
|
||||
found = Fcons (sym, found);
|
||||
if (--find_max == 0)
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -7154,7 +7184,9 @@ verify_alloca (void)
|
|||
void
|
||||
init_alloc_once (void)
|
||||
{
|
||||
/* Used to do Vpurify_flag = Qt here, but Qt isn't set up yet! */
|
||||
/* Even though Qt's contents are not set up, its address is known. */
|
||||
Vpurify_flag = Qt;
|
||||
|
||||
purebeg = PUREBEG;
|
||||
pure_size = PURESIZE;
|
||||
|
||||
|
|
@ -7230,6 +7262,7 @@ If this portion is smaller than `gc-cons-threshold', this is ignored. */);
|
|||
|
||||
DEFVAR_INT ("symbols-consed", symbols_consed,
|
||||
doc: /* Number of symbols that have been consed so far. */);
|
||||
symbols_consed += ARRAYELTS (lispsym);
|
||||
|
||||
DEFVAR_INT ("string-chars-consed", string_chars_consed,
|
||||
doc: /* Number of string characters that have been consed so far. */);
|
||||
|
|
|
|||
|
|
@ -262,7 +262,6 @@ typedef enum {
|
|||
} bidi_category_t;
|
||||
|
||||
static Lisp_Object paragraph_start_re, paragraph_separate_re;
|
||||
static Lisp_Object Qparagraph_start, Qparagraph_separate;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
|||
41
src/buffer.c
41
src/buffer.c
|
|
@ -118,41 +118,8 @@ static void reset_buffer_local_variables (struct buffer *, bool);
|
|||
due to user rplac'ing this alist or its elements. */
|
||||
Lisp_Object Vbuffer_alist;
|
||||
|
||||
static Lisp_Object Qkill_buffer_query_functions;
|
||||
|
||||
/* Hook run before changing a major mode. */
|
||||
static Lisp_Object Qchange_major_mode_hook;
|
||||
|
||||
Lisp_Object Qfirst_change_hook;
|
||||
Lisp_Object Qbefore_change_functions;
|
||||
Lisp_Object Qafter_change_functions;
|
||||
|
||||
static Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
|
||||
static Lisp_Object Qpermanent_local_hook;
|
||||
|
||||
static Lisp_Object Qprotected_field;
|
||||
|
||||
static Lisp_Object QSFundamental; /* A string "Fundamental". */
|
||||
|
||||
static Lisp_Object Qkill_buffer_hook;
|
||||
static Lisp_Object Qbuffer_list_update_hook;
|
||||
|
||||
static Lisp_Object Qget_file_buffer;
|
||||
|
||||
static Lisp_Object Qoverlayp;
|
||||
|
||||
Lisp_Object Qpriority, Qbefore_string, Qafter_string;
|
||||
|
||||
static Lisp_Object Qevaporate;
|
||||
|
||||
Lisp_Object Qmodification_hooks;
|
||||
Lisp_Object Qinsert_in_front_hooks;
|
||||
Lisp_Object Qinsert_behind_hooks;
|
||||
|
||||
Lisp_Object Qchoice, Qrange, Qleft, Qright;
|
||||
Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar;
|
||||
static Lisp_Object Qoverwrite_mode, Qfraction;
|
||||
|
||||
static void alloc_buffer_text (struct buffer *, ptrdiff_t);
|
||||
static void free_buffer_text (struct buffer *b);
|
||||
static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
|
||||
|
|
@ -1719,7 +1686,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
|
|||
return unbind_to (count, Qt);
|
||||
|
||||
/* Then run the hooks. */
|
||||
Frun_hooks (1, &Qkill_buffer_hook);
|
||||
run_hook (Qkill_buffer_hook);
|
||||
unbind_to (count, Qnil);
|
||||
}
|
||||
|
||||
|
|
@ -2748,7 +2715,7 @@ The first thing this function does is run
|
|||
the normal hook `change-major-mode-hook'. */)
|
||||
(void)
|
||||
{
|
||||
Frun_hooks (1, &Qchange_major_mode_hook);
|
||||
run_hook (Qchange_major_mode_hook);
|
||||
|
||||
/* Make sure none of the bindings in local_var_alist
|
||||
remain swapped in, in their symbols. */
|
||||
|
|
@ -5071,9 +5038,9 @@ init_buffer_once (void)
|
|||
/* Make sure all markable slots in buffer_defaults
|
||||
are initialized reasonably, so mark_buffer won't choke. */
|
||||
reset_buffer (&buffer_defaults);
|
||||
eassert (EQ (BVAR (&buffer_defaults, name), make_number (0)));
|
||||
eassert (NILP (BVAR (&buffer_defaults, name)));
|
||||
reset_buffer_local_variables (&buffer_defaults, 1);
|
||||
eassert (EQ (BVAR (&buffer_local_symbols, name), make_number (0)));
|
||||
eassert (NILP (BVAR (&buffer_local_symbols, name)));
|
||||
reset_buffer (&buffer_local_symbols);
|
||||
reset_buffer_local_variables (&buffer_local_symbols, 1);
|
||||
/* Prevent GC from getting confused. */
|
||||
|
|
|
|||
|
|
@ -1141,12 +1141,6 @@ record_unwind_current_buffer (void)
|
|||
} while (false)
|
||||
|
||||
extern Lisp_Object Vbuffer_alist;
|
||||
extern Lisp_Object Qbefore_change_functions;
|
||||
extern Lisp_Object Qafter_change_functions;
|
||||
extern Lisp_Object Qfirst_change_hook;
|
||||
extern Lisp_Object Qpriority, Qbefore_string, Qafter_string;
|
||||
extern Lisp_Object Qchoice, Qrange, Qleft, Qright;
|
||||
extern Lisp_Object Qvertical_scroll_bar, Qhorizontal_scroll_bar;
|
||||
|
||||
/* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is
|
||||
a `for' loop which iterates over the buffers from Vbuffer_alist. */
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ by Hallvard:
|
|||
|
||||
#ifdef BYTE_CODE_METER
|
||||
|
||||
Lisp_Object Qbyte_code_meter;
|
||||
#define METER_2(code1, code2) AREF (AREF (Vbyte_code_meter, code1), code2)
|
||||
#define METER_1(code) METER_2 (0, code)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,18 +28,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "window.h"
|
||||
#include "keymap.h"
|
||||
|
||||
Lisp_Object Qminus, Qplus;
|
||||
static Lisp_Object Qfuncall_interactively;
|
||||
static Lisp_Object Qcommand_debug_status;
|
||||
static Lisp_Object Qenable_recursive_minibuffers;
|
||||
|
||||
static Lisp_Object Qhandle_shift_selection;
|
||||
static Lisp_Object Qread_number;
|
||||
|
||||
Lisp_Object Qmouse_leave_buffer_hook;
|
||||
|
||||
static Lisp_Object Qlist, Qlet, Qletx, Qsave_excursion, Qif;
|
||||
Lisp_Object Qwhen, Qprogn;
|
||||
static Lisp_Object preserved_fns;
|
||||
|
||||
/* Marker used within call-interactively to refer to point. */
|
||||
|
|
@ -477,7 +465,7 @@ invoke it. If KEYS is omitted or nil, the return value of
|
|||
error ("Attempt to select inactive minibuffer window");
|
||||
|
||||
/* If the current buffer wants to clean up, let it. */
|
||||
Frun_hooks (1, &Qmouse_leave_buffer_hook);
|
||||
run_hook (Qmouse_leave_buffer_hook);
|
||||
|
||||
Fselect_window (w, Qnil);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "keymap.h"
|
||||
|
||||
enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP};
|
||||
|
||||
Lisp_Object Qidentity;
|
||||
|
||||
static Lisp_Object
|
||||
casify_object (enum case_action flag, Lisp_Object obj)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "character.h"
|
||||
#include "buffer.h"
|
||||
|
||||
static Lisp_Object Qcase_table_p, Qcase_table;
|
||||
Lisp_Object Vascii_downcase_table;
|
||||
static Lisp_Object Vascii_upcase_table;
|
||||
Lisp_Object Vascii_canon_table;
|
||||
|
|
|
|||
|
|
@ -53,8 +53,6 @@ bset_category_table (struct buffer *b, Lisp_Object val)
|
|||
|
||||
For the moment, we are not using this feature. */
|
||||
static int category_table_version;
|
||||
|
||||
static Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, Qcategory_table_p;
|
||||
|
||||
/* Category set staff. */
|
||||
|
||||
|
|
|
|||
24
src/ccl.c
24
src/ccl.c
|
|
@ -34,21 +34,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "ccl.h"
|
||||
#include "coding.h"
|
||||
|
||||
Lisp_Object Qccl, Qcclp;
|
||||
|
||||
/* This symbol is a property which associates with ccl program vector.
|
||||
Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector. */
|
||||
static Lisp_Object Qccl_program;
|
||||
|
||||
/* These symbols are properties which associate with code conversion
|
||||
map and their ID respectively. */
|
||||
static Lisp_Object Qcode_conversion_map;
|
||||
static Lisp_Object Qcode_conversion_map_id;
|
||||
|
||||
/* Symbols of ccl program have this property, a value of the property
|
||||
is an index for Vccl_program_table. */
|
||||
static Lisp_Object Qccl_program_idx;
|
||||
|
||||
/* Table of registered CCL programs. Each element is a vector of
|
||||
NAME, CCL_PROG, RESOLVEDP, and UPDATEDP, where NAME (symbol) is the
|
||||
name of the program, CCL_PROG (vector) is the compiled code of the
|
||||
|
|
@ -2297,8 +2282,17 @@ syms_of_ccl (void)
|
|||
|
||||
DEFSYM (Qccl, "ccl");
|
||||
DEFSYM (Qcclp, "cclp");
|
||||
|
||||
/* This symbol is a property which associates with ccl program vector.
|
||||
Ex: (get 'ccl-big5-encoder 'ccl-program) returns ccl program vector. */
|
||||
DEFSYM (Qccl_program, "ccl-program");
|
||||
|
||||
/* Symbols of ccl program have this property, a value of the property
|
||||
is an index for Vccl_program_table. */
|
||||
DEFSYM (Qccl_program_idx, "ccl-program-idx");
|
||||
|
||||
/* These symbols are properties which associate with code conversion
|
||||
map and their ID respectively. */
|
||||
DEFSYM (Qcode_conversion_map, "code-conversion-map");
|
||||
DEFSYM (Qcode_conversion_map_id, "code-conversion-map-id");
|
||||
|
||||
|
|
|
|||
|
|
@ -81,8 +81,6 @@ extern bool setup_ccl_program (struct ccl_program *, Lisp_Object);
|
|||
extern void ccl_driver (struct ccl_program *, int *, int *, int, int,
|
||||
Lisp_Object);
|
||||
|
||||
extern Lisp_Object Qccl, Qcclp;
|
||||
|
||||
#define CHECK_CCL_PROGRAM(x) \
|
||||
do { \
|
||||
if (NILP (Fccl_program_p (x))) \
|
||||
|
|
|
|||
|
|
@ -48,16 +48,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
#endif /* emacs */
|
||||
|
||||
Lisp_Object Qcharacterp;
|
||||
|
||||
static Lisp_Object Qauto_fill_chars;
|
||||
|
||||
/* Char-table of information about which character to unify to which
|
||||
Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */
|
||||
Lisp_Object Vchar_unify_table;
|
||||
|
||||
static Lisp_Object Qchar_script_table;
|
||||
|
||||
|
||||
|
||||
/* If character code C has modifier masks, reflect them to the
|
||||
|
|
|
|||
|
|
@ -657,7 +657,6 @@ extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int,
|
|||
extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t,
|
||||
ptrdiff_t *, ptrdiff_t *);
|
||||
|
||||
extern Lisp_Object Qcharacterp;
|
||||
extern Lisp_Object Vchar_unify_table;
|
||||
extern Lisp_Object string_escape_byte8 (Lisp_Object);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,16 +66,7 @@ struct charset *charset_table;
|
|||
static ptrdiff_t charset_table_size;
|
||||
static int charset_table_used;
|
||||
|
||||
Lisp_Object Qcharsetp;
|
||||
|
||||
/* Special charset symbols. */
|
||||
Lisp_Object Qascii;
|
||||
static Lisp_Object Qeight_bit;
|
||||
static Lisp_Object Qiso_8859_1;
|
||||
static Lisp_Object Qunicode;
|
||||
static Lisp_Object Qemacs;
|
||||
|
||||
/* The corresponding charsets. */
|
||||
/* Special charsets corresponding to symbols. */
|
||||
int charset_ascii;
|
||||
int charset_eight_bit;
|
||||
static int charset_iso_8859_1;
|
||||
|
|
@ -88,9 +79,6 @@ int charset_jisx0208_1978;
|
|||
int charset_jisx0208;
|
||||
int charset_ksc5601;
|
||||
|
||||
/* Value of charset attribute `charset-iso-plane'. */
|
||||
static Lisp_Object Qgl, Qgr;
|
||||
|
||||
/* Charset of unibyte characters. */
|
||||
int charset_unibyte;
|
||||
|
||||
|
|
@ -2344,12 +2332,14 @@ syms_of_charset (void)
|
|||
{
|
||||
DEFSYM (Qcharsetp, "charsetp");
|
||||
|
||||
/* Special charset symbols. */
|
||||
DEFSYM (Qascii, "ascii");
|
||||
DEFSYM (Qunicode, "unicode");
|
||||
DEFSYM (Qemacs, "emacs");
|
||||
DEFSYM (Qeight_bit, "eight-bit");
|
||||
DEFSYM (Qiso_8859_1, "iso-8859-1");
|
||||
|
||||
/* Value of charset attribute `charset-iso-plane'. */
|
||||
DEFSYM (Qgl, "gl");
|
||||
DEFSYM (Qgr, "gr");
|
||||
|
||||
|
|
@ -2362,10 +2352,6 @@ syms_of_charset (void)
|
|||
staticpro (&Vemacs_mule_charset_list);
|
||||
Vemacs_mule_charset_list = Qnil;
|
||||
|
||||
/* Don't staticpro them here. It's done in syms_of_fns. */
|
||||
QCtest = intern_c_string (":test");
|
||||
Qeq = intern_c_string ("eq");
|
||||
|
||||
staticpro (&Vcharset_hash_table);
|
||||
{
|
||||
Lisp_Object args[2];
|
||||
|
|
|
|||
|
|
@ -519,9 +519,6 @@ extern int iso_charset_table[ISO_MAX_DIMENSION][ISO_MAX_CHARS][ISO_MAX_FINAL];
|
|||
|
||||
|
||||
|
||||
extern Lisp_Object Qcharsetp;
|
||||
|
||||
extern Lisp_Object Qascii;
|
||||
extern int charset_ascii, charset_eight_bit;
|
||||
extern int charset_unicode;
|
||||
extern int charset_jisx0201_roman;
|
||||
|
|
|
|||
|
|
@ -57,9 +57,6 @@ static const int chartab_bits[4] =
|
|||
/* Preamble for uniprop (Unicode character property) tables. See the
|
||||
comment of "Unicode character property tables". */
|
||||
|
||||
/* Purpose of uniprop tables. */
|
||||
static Lisp_Object Qchar_code_property_table;
|
||||
|
||||
/* Types of decoder and encoder functions for uniprop values. */
|
||||
typedef Lisp_Object (*uniprop_decoder_t) (Lisp_Object, Lisp_Object);
|
||||
typedef Lisp_Object (*uniprop_encoder_t) (Lisp_Object, Lisp_Object);
|
||||
|
|
@ -1378,6 +1375,7 @@ CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
|
|||
void
|
||||
syms_of_chartab (void)
|
||||
{
|
||||
/* Purpose of uniprop tables. */
|
||||
DEFSYM (Qchar_code_property_table, "char-code-property-table");
|
||||
|
||||
defsubr (&Smake_char_table);
|
||||
|
|
|
|||
13
src/cmds.c
13
src/cmds.c
|
|
@ -31,11 +31,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "dispextern.h"
|
||||
#include "frame.h"
|
||||
|
||||
static Lisp_Object Qkill_forward_chars, Qkill_backward_chars;
|
||||
|
||||
/* A possible value for a buffer's overwrite-mode variable. */
|
||||
static Lisp_Object Qoverwrite_mode_binary;
|
||||
|
||||
static int internal_self_insert (int, EMACS_INT);
|
||||
|
||||
DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0,
|
||||
|
|
@ -322,9 +317,6 @@ At the end, it runs `post-self-insert-hook'. */)
|
|||
return 0. A value of 1 indicates this *might* not have been simple.
|
||||
A value of 2 means this did things that call for an undo boundary. */
|
||||
|
||||
static Lisp_Object Qexpand_abbrev;
|
||||
static Lisp_Object Qpost_self_insert_hook;
|
||||
|
||||
static int
|
||||
internal_self_insert (int c, EMACS_INT n)
|
||||
{
|
||||
|
|
@ -507,7 +499,7 @@ internal_self_insert (int c, EMACS_INT n)
|
|||
}
|
||||
|
||||
/* Run hooks for electric keys. */
|
||||
Frun_hooks (1, &Qpost_self_insert_hook);
|
||||
run_hook (Qpost_self_insert_hook);
|
||||
|
||||
return hairy;
|
||||
}
|
||||
|
|
@ -519,7 +511,10 @@ syms_of_cmds (void)
|
|||
{
|
||||
DEFSYM (Qkill_backward_chars, "kill-backward-chars");
|
||||
DEFSYM (Qkill_forward_chars, "kill-forward-chars");
|
||||
|
||||
/* A possible value for a buffer's overwrite-mode variable. */
|
||||
DEFSYM (Qoverwrite_mode_binary, "overwrite-mode-binary");
|
||||
|
||||
DEFSYM (Qexpand_abbrev, "expand-abbrev");
|
||||
DEFSYM (Qpost_self_insert_hook, "post-self-insert-hook");
|
||||
|
||||
|
|
|
|||
51
src/coding.c
51
src/coding.c
|
|
@ -303,35 +303,6 @@ encode_coding_XXX (struct coding_system *coding)
|
|||
|
||||
Lisp_Object Vcoding_system_hash_table;
|
||||
|
||||
static Lisp_Object Qcoding_system, Qeol_type;
|
||||
static Lisp_Object Qcoding_aliases;
|
||||
Lisp_Object Qunix, Qdos;
|
||||
static Lisp_Object Qmac;
|
||||
Lisp_Object Qbuffer_file_coding_system;
|
||||
static Lisp_Object Qpost_read_conversion, Qpre_write_conversion;
|
||||
static Lisp_Object Qdefault_char;
|
||||
Lisp_Object Qno_conversion, Qundecided;
|
||||
Lisp_Object Qcharset, Qutf_8;
|
||||
static Lisp_Object Qiso_2022;
|
||||
static Lisp_Object Qutf_16, Qshift_jis, Qbig5;
|
||||
static Lisp_Object Qbig, Qlittle;
|
||||
static Lisp_Object Qcoding_system_history;
|
||||
static Lisp_Object Qvalid_codes;
|
||||
static Lisp_Object QCcategory, QCmnemonic, QCdefault_char;
|
||||
static Lisp_Object QCdecode_translation_table, QCencode_translation_table;
|
||||
static Lisp_Object QCpost_read_conversion, QCpre_write_conversion;
|
||||
static Lisp_Object QCascii_compatible_p;
|
||||
|
||||
Lisp_Object Qcall_process, Qcall_process_region;
|
||||
Lisp_Object Qstart_process, Qopen_network_stream;
|
||||
static Lisp_Object Qtarget_idx;
|
||||
|
||||
static Lisp_Object Qinsufficient_source, Qinvalid_source, Qinterrupted;
|
||||
|
||||
/* If a symbol has this property, evaluate the value to define the
|
||||
symbol as a coding system. */
|
||||
static Lisp_Object Qcoding_system_define_form;
|
||||
|
||||
/* Format of end-of-line decided by system. This is Qunix on
|
||||
Unix and Mac, Qdos on DOS/Windows.
|
||||
This has an effect only for external encoding (i.e. for output to
|
||||
|
|
@ -340,17 +311,6 @@ static Lisp_Object system_eol_type;
|
|||
|
||||
#ifdef emacs
|
||||
|
||||
Lisp_Object Qcoding_system_p, Qcoding_system_error;
|
||||
|
||||
/* Coding system emacs-mule and raw-text are for converting only
|
||||
end-of-line format. */
|
||||
Lisp_Object Qemacs_mule, Qraw_text;
|
||||
Lisp_Object Qutf_8_emacs;
|
||||
|
||||
#if defined (WINDOWSNT) || defined (CYGWIN)
|
||||
static Lisp_Object Qutf_16le;
|
||||
#endif
|
||||
|
||||
/* Coding-systems are handed between Emacs Lisp programs and C internal
|
||||
routines by the following three variables. */
|
||||
/* Coding system to be used to encode text for terminal display when
|
||||
|
|
@ -359,11 +319,6 @@ struct coding_system safe_terminal_coding;
|
|||
|
||||
#endif /* emacs */
|
||||
|
||||
Lisp_Object Qtranslation_table;
|
||||
Lisp_Object Qtranslation_table_id;
|
||||
static Lisp_Object Qtranslation_table_for_decode;
|
||||
static Lisp_Object Qtranslation_table_for_encode;
|
||||
|
||||
/* Two special coding systems. */
|
||||
static Lisp_Object Vsjis_coding_system;
|
||||
static Lisp_Object Vbig5_coding_system;
|
||||
|
|
@ -10903,6 +10858,7 @@ syms_of_coding (void)
|
|||
|
||||
DEFSYM (Qcoding_system_p, "coding-system-p");
|
||||
|
||||
/* Error signaled when there's a problem with detecting a coding system. */
|
||||
DEFSYM (Qcoding_system_error, "coding-system-error");
|
||||
Fput (Qcoding_system_error, Qerror_conditions,
|
||||
listn (CONSTYPE_PURE, 2, Qcoding_system_error, Qerror));
|
||||
|
|
@ -10917,6 +10873,8 @@ syms_of_coding (void)
|
|||
|
||||
DEFSYM (Qvalid_codes, "valid-codes");
|
||||
|
||||
/* Coding system emacs-mule and raw-text are for converting only
|
||||
end-of-line format. */
|
||||
DEFSYM (Qemacs_mule, "emacs-mule");
|
||||
|
||||
DEFSYM (QCcategory, ":category");
|
||||
|
|
@ -10979,6 +10937,9 @@ syms_of_coding (void)
|
|||
DEFSYM (Qinsufficient_source, "insufficient-source");
|
||||
DEFSYM (Qinvalid_source, "invalid-source");
|
||||
DEFSYM (Qinterrupted, "interrupted");
|
||||
|
||||
/* If a symbol has this property, evaluate the value to define the
|
||||
symbol as a coding system. */
|
||||
DEFSYM (Qcoding_system_define_form, "coding-system-define-form");
|
||||
|
||||
defsubr (&Scoding_system_p);
|
||||
|
|
|
|||
19
src/coding.h
19
src/coding.h
|
|
@ -763,23 +763,7 @@ extern Lisp_Object from_unicode_buffer (const wchar_t *wstr);
|
|||
extern Lisp_Object preferred_coding_system (void);
|
||||
|
||||
|
||||
extern Lisp_Object Qutf_8, Qutf_8_emacs;
|
||||
|
||||
extern Lisp_Object Qcoding_category_index;
|
||||
extern Lisp_Object Qcoding_system_p;
|
||||
extern Lisp_Object Qraw_text, Qemacs_mule, Qno_conversion, Qundecided;
|
||||
extern Lisp_Object Qbuffer_file_coding_system;
|
||||
|
||||
extern Lisp_Object Qunix, Qdos;
|
||||
|
||||
extern Lisp_Object Qtranslation_table;
|
||||
extern Lisp_Object Qtranslation_table_id;
|
||||
|
||||
#ifdef emacs
|
||||
extern Lisp_Object Qfile_coding_system;
|
||||
extern Lisp_Object Qcall_process, Qcall_process_region;
|
||||
extern Lisp_Object Qstart_process, Qopen_network_stream;
|
||||
extern Lisp_Object Qwrite_region;
|
||||
|
||||
extern char *emacs_strerror (int);
|
||||
|
||||
|
|
@ -789,9 +773,6 @@ extern struct coding_system safe_terminal_coding;
|
|||
|
||||
#endif
|
||||
|
||||
/* Error signaled when there's a problem with detecting coding system */
|
||||
extern Lisp_Object Qcoding_system_error;
|
||||
|
||||
extern char emacs_mule_bytes[256];
|
||||
|
||||
#endif /* EMACS_CODING_H */
|
||||
|
|
|
|||
|
|
@ -134,8 +134,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
*/
|
||||
|
||||
|
||||
Lisp_Object Qcomposition;
|
||||
|
||||
/* Table of pointers to the structure `composition' indexed by
|
||||
COMPOSITION-ID. This structure is for storing information about
|
||||
each composition except for COMPONENTS-VEC. */
|
||||
|
|
@ -152,8 +150,6 @@ ptrdiff_t n_compositions;
|
|||
COMPOSITION-ID. */
|
||||
Lisp_Object composition_hash_table;
|
||||
|
||||
static Lisp_Object Qauto_composed;
|
||||
static Lisp_Object Qauto_composition_function;
|
||||
/* Maximum number of characters to look back for
|
||||
auto-compositions. */
|
||||
#define MAX_AUTO_COMPOSITION_LOOKBACK 3
|
||||
|
|
|
|||
|
|
@ -190,7 +190,6 @@ extern ptrdiff_t n_compositions;
|
|||
#define CHECK_BORDER (CHECK_HEAD | CHECK_TAIL)
|
||||
#define CHECK_ALL (CHECK_BORDER | CHECK_INSIDE)
|
||||
|
||||
extern Lisp_Object Qcomposition;
|
||||
extern Lisp_Object composition_hash_table;
|
||||
extern ptrdiff_t get_composition_id (ptrdiff_t, ptrdiff_t, ptrdiff_t,
|
||||
Lisp_Object, Lisp_Object);
|
||||
|
|
|
|||
|
|
@ -245,7 +245,9 @@ extern void _DebPrint (const char *fmt, ...);
|
|||
# define ATTRIBUTE_MALLOC
|
||||
#endif
|
||||
|
||||
#if 4 < __GNUC__ + (3 <= __GNUC_MINOR__)
|
||||
#if (__clang__ \
|
||||
? __has_attribute (alloc_size) \
|
||||
: 4 < __GNUC__ + (3 <= __GNUC_MINOR__))
|
||||
# define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
|
||||
#else
|
||||
# define ATTRIBUTE_ALLOC_SIZE(args)
|
||||
|
|
|
|||
56
src/data.c
56
src/data.c
|
|
@ -37,58 +37,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "font.h"
|
||||
#include "keymap.h"
|
||||
|
||||
Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
|
||||
static Lisp_Object Qsubr;
|
||||
Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
|
||||
Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range;
|
||||
static Lisp_Object Qwrong_length_argument;
|
||||
static Lisp_Object Qwrong_type_argument;
|
||||
Lisp_Object Qvoid_variable, Qvoid_function;
|
||||
static Lisp_Object Qcyclic_function_indirection;
|
||||
static Lisp_Object Qcyclic_variable_indirection;
|
||||
Lisp_Object Qcircular_list;
|
||||
static Lisp_Object Qsetting_constant;
|
||||
Lisp_Object Qinvalid_read_syntax;
|
||||
Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
|
||||
Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
|
||||
Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
|
||||
Lisp_Object Qtext_read_only;
|
||||
|
||||
Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp;
|
||||
static Lisp_Object Qnatnump;
|
||||
Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
|
||||
Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
|
||||
Lisp_Object Qbool_vector_p;
|
||||
Lisp_Object Qbuffer_or_string_p;
|
||||
static Lisp_Object Qkeywordp, Qboundp;
|
||||
Lisp_Object Qfboundp;
|
||||
Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
|
||||
|
||||
Lisp_Object Qcdr;
|
||||
static Lisp_Object Qad_advice_info, Qad_activate_internal;
|
||||
|
||||
static Lisp_Object Qdomain_error, Qsingularity_error, Qunderflow_error;
|
||||
Lisp_Object Qrange_error, Qoverflow_error;
|
||||
|
||||
Lisp_Object Qfloatp;
|
||||
Lisp_Object Qnumberp, Qnumber_or_marker_p;
|
||||
|
||||
Lisp_Object Qinteger, Qsymbol;
|
||||
static Lisp_Object Qcons, Qfloat, Qmisc, Qstring, Qvector;
|
||||
Lisp_Object Qwindow;
|
||||
static Lisp_Object Qoverlay, Qwindow_configuration;
|
||||
static Lisp_Object Qprocess, Qmarker;
|
||||
static Lisp_Object Qcompiled_function, Qframe;
|
||||
Lisp_Object Qbuffer;
|
||||
static Lisp_Object Qchar_table, Qbool_vector, Qhash_table;
|
||||
static Lisp_Object Qsubrp;
|
||||
static Lisp_Object Qmany, Qunevalled;
|
||||
Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
|
||||
static Lisp_Object Qdefun;
|
||||
|
||||
Lisp_Object Qinteractive_form;
|
||||
static Lisp_Object Qdefalias_fset_function;
|
||||
|
||||
static void swap_in_symval_forwarding (struct Lisp_Symbol *,
|
||||
struct Lisp_Buffer_Local_Value *);
|
||||
|
||||
|
|
@ -3584,10 +3532,6 @@ syms_of_data (void)
|
|||
PUT_ERROR (Qunderflow_error, Fcons (Qdomain_error, arith_tail),
|
||||
"Arithmetic underflow error");
|
||||
|
||||
staticpro (&Qnil);
|
||||
staticpro (&Qt);
|
||||
staticpro (&Qunbound);
|
||||
|
||||
/* Types that type-of returns. */
|
||||
DEFSYM (Qinteger, "integer");
|
||||
DEFSYM (Qsymbol, "symbol");
|
||||
|
|
|
|||
|
|
@ -41,37 +41,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#endif
|
||||
|
||||
|
||||
/* Subroutines. */
|
||||
static Lisp_Object Qdbus__init_bus;
|
||||
static Lisp_Object Qdbus_get_unique_name;
|
||||
static Lisp_Object Qdbus_message_internal;
|
||||
|
||||
/* D-Bus error symbol. */
|
||||
static Lisp_Object Qdbus_error;
|
||||
|
||||
/* Lisp symbols of the system and session buses. */
|
||||
static Lisp_Object QCdbus_system_bus, QCdbus_session_bus;
|
||||
|
||||
/* Lisp symbol for method call timeout. */
|
||||
static Lisp_Object QCdbus_timeout;
|
||||
|
||||
/* Lisp symbols of D-Bus types. */
|
||||
static Lisp_Object QCdbus_type_byte, QCdbus_type_boolean;
|
||||
static Lisp_Object QCdbus_type_int16, QCdbus_type_uint16;
|
||||
static Lisp_Object QCdbus_type_int32, QCdbus_type_uint32;
|
||||
static Lisp_Object QCdbus_type_int64, QCdbus_type_uint64;
|
||||
static Lisp_Object QCdbus_type_double, QCdbus_type_string;
|
||||
static Lisp_Object QCdbus_type_object_path, QCdbus_type_signature;
|
||||
#ifdef DBUS_TYPE_UNIX_FD
|
||||
static Lisp_Object QCdbus_type_unix_fd;
|
||||
#endif
|
||||
static Lisp_Object QCdbus_type_array, QCdbus_type_variant;
|
||||
static Lisp_Object QCdbus_type_struct, QCdbus_type_dict_entry;
|
||||
|
||||
/* Lisp symbols of objects in `dbus-registered-objects-table'. */
|
||||
static Lisp_Object QCdbus_registered_serial, QCdbus_registered_method;
|
||||
static Lisp_Object QCdbus_registered_signal;
|
||||
|
||||
/* Alist of D-Bus buses we are polling for messages.
|
||||
The key is the symbol or string of the bus, and the value is the
|
||||
connection address. */
|
||||
|
|
@ -1755,15 +1724,21 @@ syms_of_dbusbind (void)
|
|||
DEFSYM (Qdbus_message_internal, "dbus-message-internal");
|
||||
defsubr (&Sdbus_message_internal);
|
||||
|
||||
/* D-Bus error symbol. */
|
||||
DEFSYM (Qdbus_error, "dbus-error");
|
||||
Fput (Qdbus_error, Qerror_conditions,
|
||||
list2 (Qdbus_error, Qerror));
|
||||
Fput (Qdbus_error, Qerror_message,
|
||||
build_pure_c_string ("D-Bus error"));
|
||||
|
||||
/* Lisp symbols of the system and session buses. */
|
||||
DEFSYM (QCdbus_system_bus, ":system");
|
||||
DEFSYM (QCdbus_session_bus, ":session");
|
||||
|
||||
/* Lisp symbol for method call timeout. */
|
||||
DEFSYM (QCdbus_timeout, ":timeout");
|
||||
|
||||
/* Lisp symbols of D-Bus types. */
|
||||
DEFSYM (QCdbus_type_byte, ":byte");
|
||||
DEFSYM (QCdbus_type_boolean, ":boolean");
|
||||
DEFSYM (QCdbus_type_int16, ":int16");
|
||||
|
|
@ -1783,6 +1758,8 @@ syms_of_dbusbind (void)
|
|||
DEFSYM (QCdbus_type_variant, ":variant");
|
||||
DEFSYM (QCdbus_type_struct, ":struct");
|
||||
DEFSYM (QCdbus_type_dict_entry, ":dict-entry");
|
||||
|
||||
/* Lisp symbols of objects in `dbus-registered-objects-table'. */
|
||||
DEFSYM (QCdbus_registered_serial, ":serial");
|
||||
DEFSYM (QCdbus_registered_method, ":method");
|
||||
DEFSYM (QCdbus_registered_signal, ":signal");
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <verify.h>
|
||||
|
||||
static Lisp_Object Qzlib_dll;
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
# include <windows.h>
|
||||
# include "w32.h"
|
||||
|
|
|
|||
|
|
@ -51,13 +51,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "msdos.h" /* for fstatat */
|
||||
#endif
|
||||
|
||||
static Lisp_Object Qdirectory_files;
|
||||
static Lisp_Object Qdirectory_files_and_attributes;
|
||||
static Lisp_Object Qfile_name_completion;
|
||||
static Lisp_Object Qfile_name_all_completions;
|
||||
static Lisp_Object Qfile_attributes;
|
||||
static Lisp_Object Qfile_attributes_lessp;
|
||||
|
||||
static ptrdiff_t scmp (const char *, const char *, ptrdiff_t);
|
||||
static Lisp_Object file_attributes (int, char const *, Lisp_Object);
|
||||
|
||||
|
|
@ -450,7 +443,6 @@ These are all file names in directory DIRECTORY which begin with FILE. */)
|
|||
}
|
||||
|
||||
static int file_name_completion_stat (int, struct dirent *, struct stat *);
|
||||
static Lisp_Object Qdefault_directory;
|
||||
|
||||
static Lisp_Object
|
||||
file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
|
||||
|
|
|
|||
|
|
@ -393,10 +393,9 @@ struct glyph
|
|||
|
||||
/* Lisp object source of this glyph. Currently either a buffer or a
|
||||
string, if the glyph was produced from characters which came from
|
||||
a buffer or a string; or Lisp integer zero (a.k.a. "null object")
|
||||
if the glyph was inserted by redisplay for its own purposes, such
|
||||
as padding or truncation/continuation glyphs, or the
|
||||
overlay-arrow glyphs on TTYs. */
|
||||
a buffer or a string; or nil if the glyph was inserted by
|
||||
redisplay for its own purposes, such as padding, truncation, or
|
||||
continuation glyphs, or the overlay-arrow glyphs on TTYs. */
|
||||
Lisp_Object object;
|
||||
|
||||
/* Width in pixels. */
|
||||
|
|
@ -1727,8 +1726,8 @@ struct face
|
|||
attributes except the font. */
|
||||
struct face *ascii_face;
|
||||
|
||||
#ifdef HAVE_XFT
|
||||
/* Extra member that a font-driver uses privately. */
|
||||
#if defined HAVE_XFT || defined HAVE_FREETYPE
|
||||
/* Extra member that a font-driver uses privately. */
|
||||
void *extra;
|
||||
#endif
|
||||
};
|
||||
|
|
@ -2552,11 +2551,11 @@ struct it
|
|||
Object is normally the buffer which is being rendered, but it can
|
||||
also be a Lisp string in case the current display element comes
|
||||
from an overlay string or from a display string (before- or
|
||||
after-string). It may also be nil when a C string is being
|
||||
rendered, e.g., during mode-line or header-line update. It can
|
||||
also be a cons cell of the form `(space ...)', when we produce a
|
||||
stretch glyph from a `display' specification. Finally, it can be
|
||||
a zero-valued Lisp integer, but only temporarily, when we are
|
||||
after-string). It may also be a zero-valued Lisp integer when a
|
||||
C string is being rendered, e.g., during mode-line or header-line
|
||||
update. It can also be a cons cell of the form `(space ...)',
|
||||
when we produce a stretch glyph from a `display' specification.
|
||||
Finally, it can be nil, but only temporarily, when we are
|
||||
producing special glyphs for display purposes, like truncation
|
||||
and continuation glyphs, or blanks that extend each line to the
|
||||
edge of the window on a TTY.
|
||||
|
|
@ -2934,8 +2933,8 @@ struct redisplay_interface
|
|||
|
||||
struct image_type
|
||||
{
|
||||
/* A symbol uniquely identifying the image type, .e.g `jpeg'. */
|
||||
Lisp_Object *type;
|
||||
/* Index of a symbol uniquely identifying the image type, e.g., 'jpeg'. */
|
||||
int type;
|
||||
|
||||
/* Check that SPEC is a valid image specification for the given
|
||||
image type. Value is true if SPEC is valid. */
|
||||
|
|
@ -3249,7 +3248,6 @@ void move_it_in_display_line (struct it *it,
|
|||
enum move_operation_enum op);
|
||||
bool in_display_vector_p (struct it *);
|
||||
int frame_mode_line_height (struct frame *);
|
||||
extern Lisp_Object Qtool_bar;
|
||||
extern bool redisplaying_p;
|
||||
extern bool help_echo_showing_p;
|
||||
extern Lisp_Object help_echo_string, help_echo_window;
|
||||
|
|
@ -3429,7 +3427,6 @@ int face_at_string_position (struct window *w, Lisp_Object string,
|
|||
int merge_faces (struct frame *, Lisp_Object, int, int);
|
||||
int compute_char_face (struct frame *, int, Lisp_Object);
|
||||
void free_all_realized_faces (Lisp_Object);
|
||||
extern Lisp_Object Qforeground_color, Qbackground_color;
|
||||
extern char unspecified_fg[], unspecified_bg[];
|
||||
|
||||
/* Defined in xfns.c. */
|
||||
|
|
@ -3519,7 +3516,6 @@ void do_pending_window_change (bool);
|
|||
void change_frame_size (struct frame *, int, int, bool, bool, bool, bool);
|
||||
void init_display (void);
|
||||
void syms_of_display (void);
|
||||
extern Lisp_Object Qredisplay_dont_pause;
|
||||
extern void spec_glyph_lookup_face (struct window *, GLYPH *);
|
||||
extern void fill_up_frame_row_with_spaces (struct glyph_row *, int);
|
||||
|
||||
|
|
|
|||
|
|
@ -106,8 +106,6 @@ static void set_window_update_flags (struct window *w, bool on_p);
|
|||
|
||||
bool display_completed;
|
||||
|
||||
Lisp_Object Qdisplay_table, Qredisplay_dont_pause;
|
||||
|
||||
/* True means SIGWINCH happened when not safe. */
|
||||
|
||||
static bool delayed_size_change;
|
||||
|
|
@ -5177,7 +5175,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
|
|||
|
||||
Fset_buffer (old_current_buffer);
|
||||
|
||||
*dx = x0 + it.first_visible_x - it.current_x;
|
||||
*dx = to_x - it.current_x;
|
||||
*dy = *y - it.current_y;
|
||||
|
||||
string = w->contents;
|
||||
|
|
@ -5252,9 +5250,9 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
|
|||
}
|
||||
|
||||
/* Add extra (default width) columns if clicked after EOL. */
|
||||
x1 = max (0, it.current_x + it.pixel_width - it.first_visible_x);
|
||||
if (x0 > x1)
|
||||
it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
|
||||
x1 = max (0, it.current_x + it.pixel_width);
|
||||
if (to_x > x1)
|
||||
it.hpos += (to_x - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
|
||||
|
||||
*x = it.hpos;
|
||||
*y = it.vpos;
|
||||
|
|
@ -6204,7 +6202,9 @@ syms_of_display (void)
|
|||
frame_and_buffer_state = Fmake_vector (make_number (20), Qlambda);
|
||||
staticpro (&frame_and_buffer_state);
|
||||
|
||||
/* This is the "purpose" slot of a display table. */
|
||||
DEFSYM (Qdisplay_table, "display-table");
|
||||
|
||||
DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
|
||||
|
||||
DEFVAR_INT ("baud-rate", baud_rate,
|
||||
|
|
|
|||
|
|
@ -48,9 +48,6 @@ extern struct Lisp_Char_Table *window_display_table (struct window *);
|
|||
/* Defined in indent.c. */
|
||||
extern struct Lisp_Char_Table *buffer_display_table (void);
|
||||
|
||||
/* This is the `purpose' slot of a display table. */
|
||||
extern Lisp_Object Qdisplay_table;
|
||||
|
||||
/* Return the current length of the GLYPH table,
|
||||
or 0 if the table isn't currently valid. */
|
||||
#define GLYPH_TABLE_LENGTH \
|
||||
|
|
|
|||
|
|
@ -35,8 +35,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "keyboard.h"
|
||||
#include "keymap.h"
|
||||
|
||||
Lisp_Object Qfunction_documentation;
|
||||
|
||||
/* Buffer used for reading from documentation file. */
|
||||
static char *get_doc_string_buffer;
|
||||
static ptrdiff_t get_doc_string_buffer_size;
|
||||
|
|
|
|||
|
|
@ -409,8 +409,6 @@ msdos_stdcolor_idx (const char *name)
|
|||
Lisp_Object
|
||||
msdos_stdcolor_name (int idx)
|
||||
{
|
||||
extern Lisp_Object Qunspecified;
|
||||
|
||||
if (idx == FACE_TTY_DEFAULT_FG_COLOR)
|
||||
return build_string (unspecified_fg);
|
||||
else if (idx == FACE_TTY_DEFAULT_BG_COLOR)
|
||||
|
|
|
|||
|
|
@ -76,16 +76,6 @@ static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
|
|||
# define HAVE_TM_GMTOFF false
|
||||
#endif
|
||||
|
||||
static Lisp_Object Qbuffer_access_fontify_functions;
|
||||
|
||||
/* Symbol for the text property used to mark fields. */
|
||||
|
||||
Lisp_Object Qfield;
|
||||
|
||||
/* A special value for Qfield properties. */
|
||||
|
||||
static Lisp_Object Qboundary;
|
||||
|
||||
/* The startup value of the TZ environment variable; null if unset. */
|
||||
static char const *initial_tz;
|
||||
|
||||
|
|
@ -915,17 +905,11 @@ save_excursion_restore (Lisp_Object info)
|
|||
if (! NILP (tem))
|
||||
{
|
||||
if (! EQ (omark, nmark))
|
||||
{
|
||||
tem = intern ("activate-mark-hook");
|
||||
Frun_hooks (1, &tem);
|
||||
}
|
||||
run_hook (intern ("activate-mark-hook"));
|
||||
}
|
||||
/* If mark has ceased to be active, run deactivate hook. */
|
||||
else if (! NILP (tem1))
|
||||
{
|
||||
tem = intern ("deactivate-mark-hook");
|
||||
Frun_hooks (1, &tem);
|
||||
}
|
||||
run_hook (intern ("deactivate-mark-hook"));
|
||||
|
||||
/* If buffer was visible in a window, and a different window was
|
||||
selected, and the old selected window is still showing this
|
||||
|
|
@ -5009,8 +4993,12 @@ functions if all the text being accessed has this property. */);
|
|||
defsubr (&Sregion_beginning);
|
||||
defsubr (&Sregion_end);
|
||||
|
||||
/* Symbol for the text property used to mark fields. */
|
||||
DEFSYM (Qfield, "field");
|
||||
|
||||
/* A special value for Qfield properties. */
|
||||
DEFSYM (Qboundary, "boundary");
|
||||
|
||||
defsubr (&Sfield_beginning);
|
||||
defsubr (&Sfield_end);
|
||||
defsubr (&Sfield_string);
|
||||
|
|
|
|||
|
|
@ -151,13 +151,6 @@ static bool malloc_using_checking;
|
|||
extern void malloc_enable_thread (void);
|
||||
#endif
|
||||
|
||||
Lisp_Object Qfile_name_handler_alist;
|
||||
|
||||
Lisp_Object Qrisky_local_variable;
|
||||
|
||||
Lisp_Object Qkill_emacs;
|
||||
static Lisp_Object Qkill_emacs_hook;
|
||||
|
||||
/* If true, Emacs should not attempt to use a window-specific code,
|
||||
but instead should use the virtual terminal under which it was started. */
|
||||
bool inhibit_window_system;
|
||||
|
|
@ -1919,7 +1912,7 @@ all of which are called before Emacs is actually killed. */)
|
|||
/* Fsignal calls emacs_abort () if it sees that waiting_for_input is
|
||||
set. */
|
||||
waiting_for_input = 0;
|
||||
Frun_hooks (1, &Qkill_emacs_hook);
|
||||
run_hook (Qkill_emacs_hook);
|
||||
UNGCPRO;
|
||||
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
|
|
|
|||
38
src/eval.c
38
src/eval.c
|
|
@ -38,22 +38,6 @@ struct handler *handlerlist;
|
|||
int gcpro_level;
|
||||
#endif
|
||||
|
||||
Lisp_Object Qautoload, Qmacro, Qexit, Qinteractive, Qcommandp;
|
||||
Lisp_Object Qinhibit_quit;
|
||||
Lisp_Object Qand_rest;
|
||||
static Lisp_Object Qand_optional;
|
||||
static Lisp_Object Qinhibit_debugger;
|
||||
static Lisp_Object Qdeclare;
|
||||
Lisp_Object Qinternal_interpreter_environment, Qclosure;
|
||||
|
||||
static Lisp_Object Qdebug;
|
||||
|
||||
/* This holds either the symbol `run-hooks' or nil.
|
||||
It is nil at an early stage of startup, and when Emacs
|
||||
is shutting down. */
|
||||
|
||||
Lisp_Object Vrun_hooks;
|
||||
|
||||
/* Non-nil means record all fset's and provide's, to be undone
|
||||
if the file being autoloaded is not fully loaded.
|
||||
They are recorded by being consed onto the front of Vautoload_queue:
|
||||
|
|
@ -61,6 +45,11 @@ Lisp_Object Vrun_hooks;
|
|||
|
||||
Lisp_Object Vautoload_queue;
|
||||
|
||||
/* This holds either the symbol `run-hooks' or nil.
|
||||
It is nil at an early stage of startup, and when Emacs
|
||||
is shutting down. */
|
||||
Lisp_Object Vrun_hooks;
|
||||
|
||||
/* Current number of specbindings allocated in specpdl, not counting
|
||||
the dummy entry specpdl[-1]. */
|
||||
|
||||
|
|
@ -2363,14 +2352,10 @@ Instead, use `add-hook' and specify t for the LOCAL argument.
|
|||
usage: (run-hooks &rest HOOKS) */)
|
||||
(ptrdiff_t nargs, Lisp_Object *args)
|
||||
{
|
||||
Lisp_Object hook[1];
|
||||
ptrdiff_t i;
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
hook[0] = args[i];
|
||||
run_hook_with_args (1, hook, funcall_nil);
|
||||
}
|
||||
run_hook (args[i]);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
|
@ -2536,6 +2521,14 @@ run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
|
|||
}
|
||||
}
|
||||
|
||||
/* Run the hook HOOK, giving each function no args. */
|
||||
|
||||
void
|
||||
run_hook (Lisp_Object hook)
|
||||
{
|
||||
Frun_hook_with_args (1, &hook);
|
||||
}
|
||||
|
||||
/* Run the hook HOOK, giving each function the two args ARG1 and ARG2. */
|
||||
|
||||
void
|
||||
|
|
@ -3762,7 +3755,8 @@ alist of active lexical bindings. */);
|
|||
(Just imagine if someone makes it buffer-local). */
|
||||
Funintern (Qinternal_interpreter_environment, Qnil);
|
||||
|
||||
DEFSYM (Vrun_hooks, "run-hooks");
|
||||
Vrun_hooks = intern_c_string ("run-hooks");
|
||||
staticpro (&Vrun_hooks);
|
||||
|
||||
staticpro (&Vautoload_queue);
|
||||
Vautoload_queue = Qnil;
|
||||
|
|
|
|||
99
src/fileio.c
99
src/fileio.c
|
|
@ -113,50 +113,10 @@ static bool auto_save_error_occurred;
|
|||
static bool valid_timestamp_file_system;
|
||||
static dev_t timestamp_file_system;
|
||||
|
||||
/* The symbol bound to coding-system-for-read when
|
||||
insert-file-contents is called for recovering a file. This is not
|
||||
an actual coding system name, but just an indicator to tell
|
||||
insert-file-contents to use `emacs-mule' with a special flag for
|
||||
auto saving and recovering a file. */
|
||||
static Lisp_Object Qauto_save_coding;
|
||||
|
||||
/* Property name of a file name handler,
|
||||
which gives a list of operations it handles.. */
|
||||
static Lisp_Object Qoperations;
|
||||
|
||||
/* Lisp functions for translating file formats. */
|
||||
static Lisp_Object Qformat_decode, Qformat_annotate_function;
|
||||
|
||||
/* Lisp function for setting buffer-file-coding-system and the
|
||||
multibyteness of the current buffer after inserting a file. */
|
||||
static Lisp_Object Qafter_insert_file_set_coding;
|
||||
|
||||
static Lisp_Object Qwrite_region_annotate_functions;
|
||||
/* Each time an annotation function changes the buffer, the new buffer
|
||||
is added here. */
|
||||
static Lisp_Object Vwrite_region_annotation_buffers;
|
||||
|
||||
static Lisp_Object Qdelete_by_moving_to_trash;
|
||||
|
||||
/* Lisp function for moving files to trash. */
|
||||
static Lisp_Object Qmove_file_to_trash;
|
||||
|
||||
/* Lisp function for recursively copying directories. */
|
||||
static Lisp_Object Qcopy_directory;
|
||||
|
||||
/* Lisp function for recursively deleting directories. */
|
||||
static Lisp_Object Qdelete_directory;
|
||||
|
||||
static Lisp_Object Qsubstitute_env_in_file_name;
|
||||
static Lisp_Object Qget_buffer_window_list;
|
||||
|
||||
Lisp_Object Qfile_error, Qfile_notify_error;
|
||||
static Lisp_Object Qfile_already_exists, Qfile_date_error;
|
||||
static Lisp_Object Qexcl;
|
||||
Lisp_Object Qfile_name_history;
|
||||
|
||||
static Lisp_Object Qcar_less_than_car;
|
||||
|
||||
static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
|
||||
Lisp_Object *, struct coding_system *);
|
||||
static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
|
||||
|
|
@ -291,43 +251,6 @@ restore_point_unwind (Lisp_Object location)
|
|||
}
|
||||
|
||||
|
||||
static Lisp_Object Qexpand_file_name;
|
||||
static Lisp_Object Qsubstitute_in_file_name;
|
||||
static Lisp_Object Qdirectory_file_name;
|
||||
static Lisp_Object Qfile_name_directory;
|
||||
static Lisp_Object Qfile_name_nondirectory;
|
||||
static Lisp_Object Qunhandled_file_name_directory;
|
||||
static Lisp_Object Qfile_name_as_directory;
|
||||
static Lisp_Object Qcopy_file;
|
||||
static Lisp_Object Qmake_directory_internal;
|
||||
static Lisp_Object Qmake_directory;
|
||||
static Lisp_Object Qdelete_directory_internal;
|
||||
Lisp_Object Qdelete_file;
|
||||
static Lisp_Object Qrename_file;
|
||||
static Lisp_Object Qadd_name_to_file;
|
||||
static Lisp_Object Qmake_symbolic_link;
|
||||
Lisp_Object Qfile_exists_p;
|
||||
static Lisp_Object Qfile_executable_p;
|
||||
static Lisp_Object Qfile_readable_p;
|
||||
static Lisp_Object Qfile_writable_p;
|
||||
static Lisp_Object Qfile_symlink_p;
|
||||
static Lisp_Object Qaccess_file;
|
||||
Lisp_Object Qfile_directory_p;
|
||||
static Lisp_Object Qfile_regular_p;
|
||||
static Lisp_Object Qfile_accessible_directory_p;
|
||||
static Lisp_Object Qfile_modes;
|
||||
static Lisp_Object Qset_file_modes;
|
||||
static Lisp_Object Qset_file_times;
|
||||
static Lisp_Object Qfile_selinux_context;
|
||||
static Lisp_Object Qset_file_selinux_context;
|
||||
static Lisp_Object Qfile_acl;
|
||||
static Lisp_Object Qset_file_acl;
|
||||
static Lisp_Object Qfile_newer_than_file_p;
|
||||
Lisp_Object Qinsert_file_contents;
|
||||
Lisp_Object Qwrite_region;
|
||||
static Lisp_Object Qverify_visited_file_modtime;
|
||||
static Lisp_Object Qset_visited_file_modtime;
|
||||
|
||||
DEFUN ("find-file-name-handler", Ffind_file_name_handler,
|
||||
Sfind_file_name_handler, 2, 2, 0,
|
||||
doc: /* Return FILENAME's handler function for OPERATION, if it has one.
|
||||
|
|
@ -5866,7 +5789,10 @@ init_fileio (void)
|
|||
void
|
||||
syms_of_fileio (void)
|
||||
{
|
||||
/* Property name of a file name handler,
|
||||
which gives a list of operations it handles. */
|
||||
DEFSYM (Qoperations, "operations");
|
||||
|
||||
DEFSYM (Qexpand_file_name, "expand-file-name");
|
||||
DEFSYM (Qsubstitute_in_file_name, "substitute-in-file-name");
|
||||
DEFSYM (Qdirectory_file_name, "directory-file-name");
|
||||
|
|
@ -5903,6 +5829,12 @@ syms_of_fileio (void)
|
|||
DEFSYM (Qwrite_region, "write-region");
|
||||
DEFSYM (Qverify_visited_file_modtime, "verify-visited-file-modtime");
|
||||
DEFSYM (Qset_visited_file_modtime, "set-visited-file-modtime");
|
||||
|
||||
/* The symbol bound to coding-system-for-read when
|
||||
insert-file-contents is called for recovering a file. This is not
|
||||
an actual coding system name, but just an indicator to tell
|
||||
insert-file-contents to use `emacs-mule' with a special flag for
|
||||
auto saving and recovering a file. */
|
||||
DEFSYM (Qauto_save_coding, "auto-save-coding");
|
||||
|
||||
DEFSYM (Qfile_name_history, "file-name-history");
|
||||
|
|
@ -5938,9 +5870,14 @@ On MS-Windows, the value of this variable is largely ignored if
|
|||
behaves as if file names were encoded in `utf-8'. */);
|
||||
Vdefault_file_name_coding_system = Qnil;
|
||||
|
||||
/* Lisp functions for translating file formats. */
|
||||
DEFSYM (Qformat_decode, "format-decode");
|
||||
DEFSYM (Qformat_annotate_function, "format-annotate-function");
|
||||
|
||||
/* Lisp function for setting buffer-file-coding-system and the
|
||||
multibyteness of the current buffer after inserting a file. */
|
||||
DEFSYM (Qafter_insert_file_set_coding, "after-insert-file-set-coding");
|
||||
|
||||
DEFSYM (Qcar_less_than_car, "car-less-than-car");
|
||||
|
||||
Fput (Qfile_error, Qerror_conditions,
|
||||
|
|
@ -6094,11 +6031,17 @@ When non-nil, certain file deletion commands use the function
|
|||
This includes interactive calls to `delete-file' and
|
||||
`delete-directory' and the Dired deletion commands. */);
|
||||
delete_by_moving_to_trash = 0;
|
||||
Qdelete_by_moving_to_trash = intern_c_string ("delete-by-moving-to-trash");
|
||||
DEFSYM (Qdelete_by_moving_to_trash, "delete-by-moving-to-trash");
|
||||
|
||||
/* Lisp function for moving files to trash. */
|
||||
DEFSYM (Qmove_file_to_trash, "move-file-to-trash");
|
||||
|
||||
/* Lisp function for recursively copying directories. */
|
||||
DEFSYM (Qcopy_directory, "copy-directory");
|
||||
|
||||
/* Lisp function for recursively deleting directories. */
|
||||
DEFSYM (Qdelete_directory, "delete-directory");
|
||||
|
||||
DEFSYM (Qsubstitute_env_in_file_name, "substitute-env-in-file-name");
|
||||
DEFSYM (Qget_buffer_window_list, "get-buffer-window-list");
|
||||
|
||||
|
|
|
|||
22
src/fns.c
22
src/fns.c
|
|
@ -41,16 +41,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "xterm.h"
|
||||
#endif
|
||||
|
||||
Lisp_Object Qstring_lessp;
|
||||
static Lisp_Object Qstring_collate_lessp, Qstring_collate_equalp;
|
||||
static Lisp_Object Qprovide, Qrequire;
|
||||
static Lisp_Object Qyes_or_no_p_history;
|
||||
Lisp_Object Qcursor_in_echo_area;
|
||||
static Lisp_Object Qwidget_type;
|
||||
static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
|
||||
|
||||
static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512;
|
||||
|
||||
static void sort_vector_copy (Lisp_Object, ptrdiff_t,
|
||||
Lisp_Object [restrict], Lisp_Object [restrict]);
|
||||
static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object);
|
||||
|
|
@ -2788,8 +2778,6 @@ advisable. */)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static Lisp_Object Qsubfeatures;
|
||||
|
||||
DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 2, 0,
|
||||
doc: /* Return t if FEATURE is present in this Emacs.
|
||||
|
||||
|
|
@ -2808,8 +2796,6 @@ SUBFEATURE can be used to check a specific subfeature of FEATURE. */)
|
|||
return (NILP (tem)) ? Qnil : Qt;
|
||||
}
|
||||
|
||||
static Lisp_Object Qfuncall;
|
||||
|
||||
DEFUN ("provide", Fprovide, Sprovide, 1, 2, 0,
|
||||
doc: /* Announce that FEATURE is a feature of the current Emacs.
|
||||
The optional argument SUBFEATURES should be a list of symbols listing
|
||||
|
|
@ -3596,14 +3582,6 @@ base64_decode_1 (const char *from, char *to, ptrdiff_t length,
|
|||
|
||||
static struct Lisp_Hash_Table *weak_hash_tables;
|
||||
|
||||
/* Various symbols. */
|
||||
|
||||
static Lisp_Object Qhash_table_p;
|
||||
static Lisp_Object Qkey, Qvalue, Qeql;
|
||||
Lisp_Object Qeq, Qequal;
|
||||
Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
|
||||
static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Utilities
|
||||
|
|
|
|||
70
src/font.c
70
src/font.c
|
|
@ -41,16 +41,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include TERM_HEADER
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
Lisp_Object Qopentype;
|
||||
|
||||
/* Important character set strings. */
|
||||
Lisp_Object Qascii_0, Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip;
|
||||
|
||||
#define DEFAULT_ENCODING Qiso8859_1
|
||||
|
||||
/* Unicode category `Cf'. */
|
||||
static Lisp_Object QCf;
|
||||
|
||||
/* Vector of Vfont_weight_table, Vfont_slant_table, and Vfont_width_table. */
|
||||
static Lisp_Object font_style_table;
|
||||
|
||||
|
|
@ -110,21 +102,6 @@ static const struct table_entry width_table[] =
|
|||
{ 200, { "ultra-expanded", "ultraexpanded", "wide" }}
|
||||
};
|
||||
|
||||
Lisp_Object QCfoundry;
|
||||
static Lisp_Object QCadstyle, QCregistry;
|
||||
/* Symbols representing keys of font extra info. */
|
||||
Lisp_Object QCspacing, QCdpi, QCscalable, QCotf, QClang, QCscript, QCavgwidth;
|
||||
Lisp_Object QCantialias, QCfont_entity;
|
||||
static Lisp_Object QCfc_unknown_spec;
|
||||
/* Symbols representing values of font spacing property. */
|
||||
static Lisp_Object Qc, Qm, Qd;
|
||||
Lisp_Object Qp;
|
||||
/* Special ADSTYLE properties to avoid fonts used for Latin
|
||||
characters; used in xfont.c and ftfont.c. */
|
||||
Lisp_Object Qja, Qko;
|
||||
|
||||
static Lisp_Object QCuser_spec;
|
||||
|
||||
/* Alist of font registry symbols and the corresponding charset
|
||||
information. The information is retrieved from
|
||||
Vfont_encoding_alist on demand.
|
||||
|
|
@ -309,7 +286,7 @@ font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol)
|
|||
return tem;
|
||||
name = make_specified_string (str, nchars, len,
|
||||
len != nchars && len == nbytes);
|
||||
return intern_driver (name, obarray, XINT (tem));
|
||||
return intern_driver (name, obarray, tem);
|
||||
}
|
||||
|
||||
/* Return a pixel size of font-spec SPEC on frame F. */
|
||||
|
|
@ -662,30 +639,30 @@ font_prop_validate_otf (Lisp_Object prop, Lisp_Object val)
|
|||
values. */
|
||||
static const struct
|
||||
{
|
||||
/* Pointer to the key symbol. */
|
||||
Lisp_Object *key;
|
||||
/* Index of the key symbol. */
|
||||
int key;
|
||||
/* Function to validate PROP's value VAL, or NULL if any value is
|
||||
ok. The value is VAL or its regularized value if VAL is valid,
|
||||
and Qerror if not. */
|
||||
Lisp_Object (*validator) (Lisp_Object prop, Lisp_Object val);
|
||||
} font_property_table[] =
|
||||
{ { &QCtype, font_prop_validate_symbol },
|
||||
{ &QCfoundry, font_prop_validate_symbol },
|
||||
{ &QCfamily, font_prop_validate_symbol },
|
||||
{ &QCadstyle, font_prop_validate_symbol },
|
||||
{ &QCregistry, font_prop_validate_symbol },
|
||||
{ &QCweight, font_prop_validate_style },
|
||||
{ &QCslant, font_prop_validate_style },
|
||||
{ &QCwidth, font_prop_validate_style },
|
||||
{ &QCsize, font_prop_validate_non_neg },
|
||||
{ &QCdpi, font_prop_validate_non_neg },
|
||||
{ &QCspacing, font_prop_validate_spacing },
|
||||
{ &QCavgwidth, font_prop_validate_non_neg },
|
||||
{ { SYMBOL_INDEX (QCtype), font_prop_validate_symbol },
|
||||
{ SYMBOL_INDEX (QCfoundry), font_prop_validate_symbol },
|
||||
{ SYMBOL_INDEX (QCfamily), font_prop_validate_symbol },
|
||||
{ SYMBOL_INDEX (QCadstyle), font_prop_validate_symbol },
|
||||
{ SYMBOL_INDEX (QCregistry), font_prop_validate_symbol },
|
||||
{ SYMBOL_INDEX (QCweight), font_prop_validate_style },
|
||||
{ SYMBOL_INDEX (QCslant), font_prop_validate_style },
|
||||
{ SYMBOL_INDEX (QCwidth), font_prop_validate_style },
|
||||
{ SYMBOL_INDEX (QCsize), font_prop_validate_non_neg },
|
||||
{ SYMBOL_INDEX (QCdpi), font_prop_validate_non_neg },
|
||||
{ SYMBOL_INDEX (QCspacing), font_prop_validate_spacing },
|
||||
{ SYMBOL_INDEX (QCavgwidth), font_prop_validate_non_neg },
|
||||
/* The order of the above entries must match with enum
|
||||
font_property_index. */
|
||||
{ &QClang, font_prop_validate_symbol },
|
||||
{ &QCscript, font_prop_validate_symbol },
|
||||
{ &QCotf, font_prop_validate_otf }
|
||||
{ SYMBOL_INDEX (QClang), font_prop_validate_symbol },
|
||||
{ SYMBOL_INDEX (QCscript), font_prop_validate_symbol },
|
||||
{ SYMBOL_INDEX (QCotf), font_prop_validate_otf }
|
||||
};
|
||||
|
||||
/* Return an index number of font property KEY or -1 if KEY is not an
|
||||
|
|
@ -697,7 +674,7 @@ get_font_prop_index (Lisp_Object key)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < ARRAYELTS (font_property_table); i++)
|
||||
if (EQ (key, *font_property_table[i].key))
|
||||
if (EQ (key, builtin_lisp_symbol (font_property_table[i].key)))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -714,7 +691,7 @@ font_prop_validate (int idx, Lisp_Object prop, Lisp_Object val)
|
|||
if (NILP (val))
|
||||
return val;
|
||||
if (NILP (prop))
|
||||
prop = *font_property_table[idx].key;
|
||||
prop = builtin_lisp_symbol (font_property_table[idx].key);
|
||||
else
|
||||
{
|
||||
idx = get_font_prop_index (prop);
|
||||
|
|
@ -5169,19 +5146,21 @@ syms_of_font (void)
|
|||
|
||||
DEFSYM (Qopentype, "opentype");
|
||||
|
||||
/* Important character set symbols. */
|
||||
DEFSYM (Qascii_0, "ascii-0");
|
||||
DEFSYM (Qiso8859_1, "iso8859-1");
|
||||
DEFSYM (Qiso10646_1, "iso10646-1");
|
||||
DEFSYM (Qunicode_bmp, "unicode-bmp");
|
||||
DEFSYM (Qunicode_sip, "unicode-sip");
|
||||
|
||||
/* Unicode category `Cf'. */
|
||||
DEFSYM (QCf, "Cf");
|
||||
|
||||
/* Symbols representing keys of font extra info. */
|
||||
DEFSYM (QCotf, ":otf");
|
||||
DEFSYM (QClang, ":lang");
|
||||
DEFSYM (QCscript, ":script");
|
||||
DEFSYM (QCantialias, ":antialias");
|
||||
|
||||
DEFSYM (QCfoundry, ":foundry");
|
||||
DEFSYM (QCadstyle, ":adstyle");
|
||||
DEFSYM (QCregistry, ":registry");
|
||||
|
|
@ -5192,11 +5171,14 @@ syms_of_font (void)
|
|||
DEFSYM (QCfont_entity, ":font-entity");
|
||||
DEFSYM (QCfc_unknown_spec, ":fc-unknown-spec");
|
||||
|
||||
/* Symbols representing values of font spacing property. */
|
||||
DEFSYM (Qc, "c");
|
||||
DEFSYM (Qm, "m");
|
||||
DEFSYM (Qp, "p");
|
||||
DEFSYM (Qd, "d");
|
||||
|
||||
/* Special ADSTYLE properties to avoid fonts used for Latin
|
||||
characters; used in xfont.c and ftfont.c. */
|
||||
DEFSYM (Qja, "ja");
|
||||
DEFSYM (Qko, "ko");
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue