diff options
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 87 |
1 files changed, 82 insertions, 5 deletions
diff --git a/src/data.c b/src/data.c index 38cde0ff8b2..ace859d2d0c 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -904,7 +904,17 @@ Value, if non-nil, is a list (interactive SPEC). */) | |||
| 904 | else if (COMPILEDP (fun)) | 904 | else if (COMPILEDP (fun)) |
| 905 | { | 905 | { |
| 906 | if (PVSIZE (fun) > COMPILED_INTERACTIVE) | 906 | if (PVSIZE (fun) > COMPILED_INTERACTIVE) |
| 907 | return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE)); | 907 | { |
| 908 | Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE); | ||
| 909 | if (VECTORP (form)) | ||
| 910 | /* The vector form is the new form, where the first | ||
| 911 | element is the interactive spec, and the second is the | ||
| 912 | command modes. */ | ||
| 913 | return list2 (Qinteractive, AREF (form, 0)); | ||
| 914 | else | ||
| 915 | /* Old form -- just the interactive spec. */ | ||
| 916 | return list2 (Qinteractive, form); | ||
| 917 | } | ||
| 908 | } | 918 | } |
| 909 | #ifdef HAVE_MODULES | 919 | #ifdef HAVE_MODULES |
| 910 | else if (MODULE_FUNCTIONP (fun)) | 920 | else if (MODULE_FUNCTIONP (fun)) |
| @@ -920,10 +930,75 @@ Value, if non-nil, is a list (interactive SPEC). */) | |||
| 920 | else if (CONSP (fun)) | 930 | else if (CONSP (fun)) |
| 921 | { | 931 | { |
| 922 | Lisp_Object funcar = XCAR (fun); | 932 | Lisp_Object funcar = XCAR (fun); |
| 923 | if (EQ (funcar, Qclosure)) | 933 | if (EQ (funcar, Qclosure) |
| 924 | return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); | 934 | || EQ (funcar, Qlambda)) |
| 925 | else if (EQ (funcar, Qlambda)) | 935 | { |
| 926 | return Fassq (Qinteractive, Fcdr (XCDR (fun))); | 936 | Lisp_Object form = Fcdr (XCDR (fun)); |
| 937 | if (EQ (funcar, Qclosure)) | ||
| 938 | form = Fcdr (form); | ||
| 939 | Lisp_Object spec = Fassq (Qinteractive, form); | ||
| 940 | if (NILP (Fcdr (Fcdr (spec)))) | ||
| 941 | return spec; | ||
| 942 | else | ||
| 943 | return list2 (Qinteractive, Fcar (Fcdr (spec))); | ||
| 944 | } | ||
| 945 | } | ||
| 946 | return Qnil; | ||
| 947 | } | ||
| 948 | |||
| 949 | DEFUN ("command-modes", Fcommand_modes, Scommand_modes, 1, 1, 0, | ||
| 950 | doc: /* Return the modes COMMAND is defined for. | ||
| 951 | If COMMAND is not a command, the return value is nil. | ||
| 952 | The value, if non-nil, is a list of mode name symbols. */) | ||
| 953 | (Lisp_Object command) | ||
| 954 | { | ||
| 955 | Lisp_Object fun = indirect_function (command); /* Check cycles. */ | ||
| 956 | |||
| 957 | if (NILP (fun)) | ||
| 958 | return Qnil; | ||
| 959 | |||
| 960 | fun = command; | ||
| 961 | while (SYMBOLP (fun)) | ||
| 962 | fun = Fsymbol_function (fun); | ||
| 963 | |||
| 964 | if (COMPILEDP (fun)) | ||
| 965 | { | ||
| 966 | Lisp_Object form = AREF (fun, COMPILED_INTERACTIVE); | ||
| 967 | if (VECTORP (form)) | ||
| 968 | /* New form -- the second element is the command modes. */ | ||
| 969 | return AREF (form, 1); | ||
| 970 | else | ||
| 971 | /* Old .elc file -- no command modes. */ | ||
| 972 | return Qnil; | ||
| 973 | } | ||
| 974 | #ifdef HAVE_MODULES | ||
| 975 | else if (MODULE_FUNCTIONP (fun)) | ||
| 976 | { | ||
| 977 | Lisp_Object form | ||
| 978 | = module_function_command_modes (XMODULE_FUNCTION (fun)); | ||
| 979 | if (! NILP (form)) | ||
| 980 | return form; | ||
| 981 | } | ||
| 982 | #endif | ||
| 983 | else if (AUTOLOADP (fun)) | ||
| 984 | { | ||
| 985 | Lisp_Object modes = Fnth (make_int (3), fun); | ||
| 986 | if (CONSP (modes)) | ||
| 987 | return modes; | ||
| 988 | else | ||
| 989 | return Qnil; | ||
| 990 | } | ||
| 991 | else if (CONSP (fun)) | ||
| 992 | { | ||
| 993 | Lisp_Object funcar = XCAR (fun); | ||
| 994 | if (EQ (funcar, Qclosure) | ||
| 995 | || EQ (funcar, Qlambda)) | ||
| 996 | { | ||
| 997 | Lisp_Object form = Fcdr (XCDR (fun)); | ||
| 998 | if (EQ (funcar, Qclosure)) | ||
| 999 | form = Fcdr (form); | ||
| 1000 | return Fcdr (Fcdr (Fassq (Qinteractive, form))); | ||
| 1001 | } | ||
| 927 | } | 1002 | } |
| 928 | return Qnil; | 1003 | return Qnil; |
| 929 | } | 1004 | } |
| @@ -3908,6 +3983,7 @@ syms_of_data (void) | |||
| 3908 | 3983 | ||
| 3909 | defsubr (&Sindirect_variable); | 3984 | defsubr (&Sindirect_variable); |
| 3910 | defsubr (&Sinteractive_form); | 3985 | defsubr (&Sinteractive_form); |
| 3986 | defsubr (&Scommand_modes); | ||
| 3911 | defsubr (&Seq); | 3987 | defsubr (&Seq); |
| 3912 | defsubr (&Snull); | 3988 | defsubr (&Snull); |
| 3913 | defsubr (&Stype_of); | 3989 | defsubr (&Stype_of); |
| @@ -4030,6 +4106,7 @@ This variable cannot be set; trying to do so will signal an error. */); | |||
| 4030 | DEFSYM (Qunlet, "unlet"); | 4106 | DEFSYM (Qunlet, "unlet"); |
| 4031 | DEFSYM (Qset, "set"); | 4107 | DEFSYM (Qset, "set"); |
| 4032 | DEFSYM (Qset_default, "set-default"); | 4108 | DEFSYM (Qset_default, "set-default"); |
| 4109 | DEFSYM (Qcommand_modes, "command-modes"); | ||
| 4033 | defsubr (&Sadd_variable_watcher); | 4110 | defsubr (&Sadd_variable_watcher); |
| 4034 | defsubr (&Sremove_variable_watcher); | 4111 | defsubr (&Sremove_variable_watcher); |
| 4035 | defsubr (&Sget_variable_watchers); | 4112 | defsubr (&Sget_variable_watchers); |