diff options
| author | Po Lu | 2022-12-31 18:05:12 +0800 |
|---|---|---|
| committer | Po Lu | 2022-12-31 18:05:12 +0800 |
| commit | fd074f3133a348dd1d3b7ee569f0fc046223efb9 (patch) | |
| tree | ac82e56578f398be747175f0f42ca2b3cb0ca0b8 /src | |
| parent | cfbc8a5dbcd362b69b37b4e6832ae4a31834364c (diff) | |
| parent | f59d012af7e607448fdb435fcb4becb6a6ebe665 (diff) | |
| download | emacs-fd074f3133a348dd1d3b7ee569f0fc046223efb9.tar.gz emacs-fd074f3133a348dd1d3b7ee569f0fc046223efb9.zip | |
Merge remote-tracking branch 'origin/master' into feature/android
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispnew.c | 2 | ||||
| -rw-r--r-- | src/emacs.c | 1 | ||||
| -rw-r--r-- | src/eval.c | 6 | ||||
| -rw-r--r-- | src/frame.h | 14 | ||||
| -rw-r--r-- | src/gnutls.c | 142 | ||||
| -rw-r--r-- | src/indent.c | 2 | ||||
| -rw-r--r-- | src/json.c | 79 | ||||
| -rw-r--r-- | src/keyboard.c | 5 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/process.c | 11 | ||||
| -rw-r--r-- | src/treesit.c | 289 | ||||
| -rw-r--r-- | src/w32menu.c | 13 | ||||
| -rw-r--r-- | src/w32term.c | 11 | ||||
| -rw-r--r-- | src/xdisp.c | 40 | ||||
| -rw-r--r-- | src/xfns.c | 1 | ||||
| -rw-r--r-- | src/xterm.c | 6 | ||||
| -rw-r--r-- | src/xterm.h | 10 |
17 files changed, 467 insertions, 166 deletions
diff --git a/src/dispnew.c b/src/dispnew.c index ed10accac7b..6fc91e60eb5 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -3194,7 +3194,7 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "", | |||
| 3194 | Lisp_Object tail, frame; | 3194 | Lisp_Object tail, frame; |
| 3195 | 3195 | ||
| 3196 | FOR_EACH_FRAME (tail, frame) | 3196 | FOR_EACH_FRAME (tail, frame) |
| 3197 | if (FRAME_VISIBLE_P (XFRAME (frame))) | 3197 | if (FRAME_REDISPLAY_P (XFRAME (frame))) |
| 3198 | redraw_frame (XFRAME (frame)); | 3198 | redraw_frame (XFRAME (frame)); |
| 3199 | 3199 | ||
| 3200 | return Qnil; | 3200 | return Qnil; |
diff --git a/src/emacs.c b/src/emacs.c index b6686f88096..9ef58ca412e 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -2938,6 +2938,7 @@ killed. */ | |||
| 2938 | 2938 | ||
| 2939 | if (!NILP (restart)) | 2939 | if (!NILP (restart)) |
| 2940 | { | 2940 | { |
| 2941 | turn_on_atimers (false); | ||
| 2941 | #ifdef WINDOWSNT | 2942 | #ifdef WINDOWSNT |
| 2942 | if (w32_reexec_emacs (initial_cmdline, initial_wd) < 0) | 2943 | if (w32_reexec_emacs (initial_cmdline, initial_wd) < 0) |
| 2943 | #else | 2944 | #else |
diff --git a/src/eval.c b/src/eval.c index 99f3650fc9b..cff4b924778 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1367,7 +1367,7 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, | |||
| 1367 | error ("Invalid condition handler: %s", | 1367 | error ("Invalid condition handler: %s", |
| 1368 | SDATA (Fprin1_to_string (tem, Qt, Qnil))); | 1368 | SDATA (Fprin1_to_string (tem, Qt, Qnil))); |
| 1369 | if (CONSP (tem) && EQ (XCAR (tem), QCsuccess)) | 1369 | if (CONSP (tem) && EQ (XCAR (tem), QCsuccess)) |
| 1370 | success_handler = XCDR (tem); | 1370 | success_handler = tem; |
| 1371 | else | 1371 | else |
| 1372 | clausenb++; | 1372 | clausenb++; |
| 1373 | } | 1373 | } |
| @@ -1430,7 +1430,7 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, | |||
| 1430 | if (!NILP (success_handler)) | 1430 | if (!NILP (success_handler)) |
| 1431 | { | 1431 | { |
| 1432 | if (NILP (var)) | 1432 | if (NILP (var)) |
| 1433 | return Fprogn (success_handler); | 1433 | return Fprogn (XCDR (success_handler)); |
| 1434 | 1434 | ||
| 1435 | Lisp_Object handler_var = var; | 1435 | Lisp_Object handler_var = var; |
| 1436 | if (!NILP (Vinternal_interpreter_environment)) | 1436 | if (!NILP (Vinternal_interpreter_environment)) |
| @@ -1442,7 +1442,7 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform, | |||
| 1442 | 1442 | ||
| 1443 | specpdl_ref count = SPECPDL_INDEX (); | 1443 | specpdl_ref count = SPECPDL_INDEX (); |
| 1444 | specbind (handler_var, result); | 1444 | specbind (handler_var, result); |
| 1445 | return unbind_to (count, Fprogn (success_handler)); | 1445 | return unbind_to (count, Fprogn (XCDR (success_handler))); |
| 1446 | } | 1446 | } |
| 1447 | return result; | 1447 | return result; |
| 1448 | } | 1448 | } |
diff --git a/src/frame.h b/src/frame.h index e0b47d26d69..e5693e0877d 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -1025,6 +1025,20 @@ default_pixels_per_inch_y (void) | |||
| 1025 | /* True if frame F is currently visible. */ | 1025 | /* True if frame F is currently visible. */ |
| 1026 | #define FRAME_VISIBLE_P(f) (f)->visible | 1026 | #define FRAME_VISIBLE_P(f) (f)->visible |
| 1027 | 1027 | ||
| 1028 | /* True if frame F should be redisplayed. This is normally the same | ||
| 1029 | as FRAME_VISIBLE_P (f). Under X, frames can continue to be | ||
| 1030 | displayed to the user by the compositing manager even if they are | ||
| 1031 | invisible, so this also checks whether or not the frame is reported | ||
| 1032 | visible by the X server. */ | ||
| 1033 | |||
| 1034 | #ifndef HAVE_X_WINDOWS | ||
| 1035 | #define FRAME_REDISPLAY_P(f) (FRAME_VISIBLE_P (f)) | ||
| 1036 | #else | ||
| 1037 | #define FRAME_REDISPLAY_P(f) (FRAME_VISIBLE_P (f) \ | ||
| 1038 | || (FRAME_X_P (f) \ | ||
| 1039 | && FRAME_X_VISIBLE (f))) | ||
| 1040 | #endif | ||
| 1041 | |||
| 1028 | /* True if frame F is currently visible but hidden. */ | 1042 | /* True if frame F is currently visible but hidden. */ |
| 1029 | #define FRAME_OBSCURED_P(f) ((f)->visible > 1) | 1043 | #define FRAME_OBSCURED_P(f) ((f)->visible > 1) |
| 1030 | 1044 | ||
diff --git a/src/gnutls.c b/src/gnutls.c index 4093865cae5..e58322934de 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -34,6 +34,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 34 | # endif | 34 | # endif |
| 35 | 35 | ||
| 36 | # if GNUTLS_VERSION_NUMBER >= 0x030200 | 36 | # if GNUTLS_VERSION_NUMBER >= 0x030200 |
| 37 | # define HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 | ||
| 37 | # define HAVE_GNUTLS_CIPHER_GET_IV_SIZE | 38 | # define HAVE_GNUTLS_CIPHER_GET_IV_SIZE |
| 38 | # endif | 39 | # endif |
| 39 | 40 | ||
| @@ -121,6 +122,11 @@ DEF_DLL_FN (int, gnutls_certificate_set_x509_crl_file, | |||
| 121 | DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file, | 122 | DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file, |
| 122 | (gnutls_certificate_credentials_t, const char *, const char *, | 123 | (gnutls_certificate_credentials_t, const char *, const char *, |
| 123 | gnutls_x509_crt_fmt_t)); | 124 | gnutls_x509_crt_fmt_t)); |
| 125 | # ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 | ||
| 126 | DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file2, | ||
| 127 | (gnutls_certificate_credentials_t, const char *, const char *, | ||
| 128 | gnutls_x509_crt_fmt_t, const char *, unsigned int)); | ||
| 129 | # endif | ||
| 124 | # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST | 130 | # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST |
| 125 | DEF_DLL_FN (int, gnutls_certificate_set_x509_system_trust, | 131 | DEF_DLL_FN (int, gnutls_certificate_set_x509_system_trust, |
| 126 | (gnutls_certificate_credentials_t)); | 132 | (gnutls_certificate_credentials_t)); |
| @@ -314,6 +320,9 @@ init_gnutls_functions (void) | |||
| 314 | LOAD_DLL_FN (library, gnutls_certificate_set_verify_flags); | 320 | LOAD_DLL_FN (library, gnutls_certificate_set_verify_flags); |
| 315 | LOAD_DLL_FN (library, gnutls_certificate_set_x509_crl_file); | 321 | LOAD_DLL_FN (library, gnutls_certificate_set_x509_crl_file); |
| 316 | LOAD_DLL_FN (library, gnutls_certificate_set_x509_key_file); | 322 | LOAD_DLL_FN (library, gnutls_certificate_set_x509_key_file); |
| 323 | # ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 | ||
| 324 | LOAD_DLL_FN (library, gnutls_certificate_set_x509_key_file2); | ||
| 325 | # endif | ||
| 317 | # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST | 326 | # ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST |
| 318 | LOAD_DLL_FN (library, gnutls_certificate_set_x509_system_trust); | 327 | LOAD_DLL_FN (library, gnutls_certificate_set_x509_system_trust); |
| 319 | # endif | 328 | # endif |
| @@ -455,6 +464,9 @@ init_gnutls_functions (void) | |||
| 455 | # define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags | 464 | # define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags |
| 456 | # define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file | 465 | # define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file |
| 457 | # define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file | 466 | # define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file |
| 467 | # ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 | ||
| 468 | # define gnutls_certificate_set_x509_key_file2 fn_gnutls_certificate_set_x509_key_file2 | ||
| 469 | # endif | ||
| 458 | # define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust | 470 | # define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust |
| 459 | # define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file | 471 | # define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file |
| 460 | # define gnutls_certificate_type_get fn_gnutls_certificate_type_get | 472 | # define gnutls_certificate_type_get fn_gnutls_certificate_type_get |
| @@ -1774,6 +1786,72 @@ gnutls_verify_boot (Lisp_Object proc, Lisp_Object proplist) | |||
| 1774 | return gnutls_make_error (ret); | 1786 | return gnutls_make_error (ret); |
| 1775 | } | 1787 | } |
| 1776 | 1788 | ||
| 1789 | #ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 | ||
| 1790 | |||
| 1791 | /* Helper function for gnutls-boot. | ||
| 1792 | |||
| 1793 | The key :flags receives a list of symbols, each of which | ||
| 1794 | corresponds to a GnuTLS C flag, the ORed result is to be passed to | ||
| 1795 | the function `gnutls_certificate_set_x509_key_file2' as its last | ||
| 1796 | argument. */ | ||
| 1797 | static unsigned int | ||
| 1798 | key_file2_aux (Lisp_Object flags) | ||
| 1799 | { | ||
| 1800 | unsigned int rv = 0; | ||
| 1801 | Lisp_Object tail = flags; | ||
| 1802 | FOR_EACH_TAIL_SAFE (tail) | ||
| 1803 | { | ||
| 1804 | Lisp_Object flag = XCAR (tail); | ||
| 1805 | if (EQ (flag, Qgnutls_pkcs_plain)) | ||
| 1806 | rv |= GNUTLS_PKCS_PLAIN; | ||
| 1807 | else if (EQ (flag, Qgnutls_pkcs_pkcs12_3des)) | ||
| 1808 | rv |= GNUTLS_PKCS_PKCS12_3DES; | ||
| 1809 | else if (EQ (flag, Qgnutls_pkcs_pkcs12_arcfour)) | ||
| 1810 | rv |= GNUTLS_PKCS_PKCS12_ARCFOUR; | ||
| 1811 | else if (EQ (flag, Qgnutls_pkcs_pkcs12_rc2_40)) | ||
| 1812 | rv |= GNUTLS_PKCS_PKCS12_RC2_40; | ||
| 1813 | else if (EQ (flag, Qgnutls_pkcs_pbes2_3des)) | ||
| 1814 | rv |= GNUTLS_PKCS_PBES2_3DES; | ||
| 1815 | else if (EQ (flag, Qgnutls_pkcs_pbes2_aes_128)) | ||
| 1816 | rv |= GNUTLS_PKCS_PBES2_AES_128; | ||
| 1817 | else if (EQ (flag, Qgnutls_pkcs_pbes2_aes_192)) | ||
| 1818 | rv |= GNUTLS_PKCS_PBES2_AES_192; | ||
| 1819 | else if (EQ (flag, Qgnutls_pkcs_pbes2_aes_256)) | ||
| 1820 | rv |= GNUTLS_PKCS_PBES2_AES_256; | ||
| 1821 | else if (EQ (flag, Qgnutls_pkcs_null_password)) | ||
| 1822 | rv |= GNUTLS_PKCS_NULL_PASSWORD; | ||
| 1823 | else if (EQ (flag, Qgnutls_pkcs_pbes2_des)) | ||
| 1824 | rv |= GNUTLS_PKCS_PBES2_DES; | ||
| 1825 | #ifdef GNUTLS_PKCS_PBES1_DES_MD5 | ||
| 1826 | else if (EQ (flag, Qgnutls_pkcs_pbes1_des_md5)) | ||
| 1827 | rv |= GNUTLS_PKCS_PBES1_DES_MD5; | ||
| 1828 | #endif | ||
| 1829 | #ifdef GNUTLS_PKCS_PBES2_GOST_TC26Z | ||
| 1830 | else if (EQ (flag, Qgnutls_pkcs_pbes2_gost_tc26z)) | ||
| 1831 | rv |= GNUTLS_PKCS_PBES2_GOST_TC26Z; | ||
| 1832 | #endif | ||
| 1833 | #ifdef GNUTLS_PKCS_PBES2_GOST_CPA | ||
| 1834 | else if (EQ (flag, Qgnutls_pkcs_pbes2_gost_cpa)) | ||
| 1835 | rv |= GNUTLS_PKCS_PBES2_GOST_CPA; | ||
| 1836 | #endif | ||
| 1837 | #ifdef GNUTLS_PKCS_PBES2_GOST_CPB | ||
| 1838 | else if (EQ (flag, Qgnutls_pkcs_pbes2_gost_cpb)) | ||
| 1839 | rv |= GNUTLS_PKCS_PBES2_GOST_CPB; | ||
| 1840 | #endif | ||
| 1841 | #ifdef GNUTLS_PKCS_PBES2_GOST_CPC | ||
| 1842 | else if (EQ (flag, Qgnutls_pkcs_pbes2_gost_cpc)) | ||
| 1843 | rv |= GNUTLS_PKCS_PBES2_GOST_CPC; | ||
| 1844 | #endif | ||
| 1845 | #ifdef GNUTLS_PKCS_PBES2_GOST_CPD | ||
| 1846 | else if (EQ (flag, Qgnutls_pkcs_pbes2_gost_cpd)) | ||
| 1847 | rv |= GNUTLS_PKCS_PBES2_GOST_CPD; | ||
| 1848 | #endif | ||
| 1849 | } | ||
| 1850 | return rv; | ||
| 1851 | } | ||
| 1852 | |||
| 1853 | #endif /* HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 */ | ||
| 1854 | |||
| 1777 | DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0, | 1855 | DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0, |
| 1778 | doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST. | 1856 | doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST. |
| 1779 | Currently only client mode is supported. Return a success/failure | 1857 | Currently only client mode is supported. Return a success/failure |
| @@ -1813,6 +1891,22 @@ accept in Diffie-Hellman key exchange. | |||
| 1813 | :complete-negotiation, if non-nil, will make negotiation complete | 1891 | :complete-negotiation, if non-nil, will make negotiation complete |
| 1814 | before returning even on non-blocking sockets. | 1892 | before returning even on non-blocking sockets. |
| 1815 | 1893 | ||
| 1894 | :pass, the password of the private key as per GnuTLS' | ||
| 1895 | gnutls_certificate_set_x509_key_file2. Specify as nil to have a NULL | ||
| 1896 | password. | ||
| 1897 | |||
| 1898 | :flags, a list of symbols relating to :pass, each specifying a flag: | ||
| 1899 | GNUTLS_PKCS_PLAIN, GNUTLS_PKCS_PKCS12_3DES, | ||
| 1900 | GNUTLS_PKCS_PKCS12_ARCFOUR, GNUTLS_PKCS_PKCS12_RC2_40, | ||
| 1901 | GNUTLS_PKCS_PBES2_3DES, GNUTLS_PKCS_PBES2_AES_128, | ||
| 1902 | GNUTLS_PKCS_PBES2_AES_192, GNUTLS_PKCS_PBES2_AES_256, | ||
| 1903 | GNUTLS_PKCS_NULL_PASSWORD, GNUTLS_PKCS_PBES2_DES, | ||
| 1904 | GNUTLS_PKCS_PBES2_DES_MD5, GNUTLS_PKCS_PBES2_GOST_TC26Z, | ||
| 1905 | GNUTLS_PKCS_PBES2_GOST_CPA, GNUTLS_PKCS_PBES2_GOST_CPB, | ||
| 1906 | GNUTLS_PKCS_PBES2_GOST_CPC, GNUTLS_PKCS_PBES2_GOST_CPD. If not | ||
| 1907 | specified, or if nil, the bitflag with value 0 is used. | ||
| 1908 | Note that some of these are only supported since GnuTLS 3.6.3. | ||
| 1909 | |||
| 1816 | The debug level will be set for this process AND globally for GnuTLS. | 1910 | The debug level will be set for this process AND globally for GnuTLS. |
| 1817 | So if you set it higher or lower at any point, it affects global | 1911 | So if you set it higher or lower at any point, it affects global |
| 1818 | debugging. | 1912 | debugging. |
| @@ -1825,6 +1919,9 @@ Processes must be initialized with this function before other GnuTLS | |||
| 1825 | functions are used. This function allocates resources which can only | 1919 | functions are used. This function allocates resources which can only |
| 1826 | be deallocated by calling `gnutls-deinit' or by calling it again. | 1920 | be deallocated by calling `gnutls-deinit' or by calling it again. |
| 1827 | 1921 | ||
| 1922 | The :pass and :flags keys are ignored with old versions of GnuTLS, and | ||
| 1923 | :flags is ignored if :pass is not specified. | ||
| 1924 | |||
| 1828 | The callbacks alist can have a `verify' key, associated with a | 1925 | The callbacks alist can have a `verify' key, associated with a |
| 1829 | verification function (UNUSED). | 1926 | verification function (UNUSED). |
| 1830 | 1927 | ||
| @@ -1842,16 +1939,22 @@ one trustfile (usually a CA bundle). */) | |||
| 1842 | Lisp_Object global_init; | 1939 | Lisp_Object global_init; |
| 1843 | char const *priority_string_ptr = "NORMAL"; /* default priority string. */ | 1940 | char const *priority_string_ptr = "NORMAL"; /* default priority string. */ |
| 1844 | char *c_hostname; | 1941 | char *c_hostname; |
| 1942 | const char *c_pass; | ||
| 1845 | 1943 | ||
| 1846 | /* Placeholders for the property list elements. */ | 1944 | /* Placeholders for the property list elements. */ |
| 1847 | Lisp_Object priority_string; | 1945 | Lisp_Object priority_string; |
| 1848 | Lisp_Object trustfiles; | 1946 | Lisp_Object trustfiles; |
| 1849 | Lisp_Object crlfiles; | 1947 | Lisp_Object crlfiles; |
| 1850 | Lisp_Object keylist; | 1948 | Lisp_Object keylist; |
| 1949 | Lisp_Object pass; | ||
| 1950 | Lisp_Object flags; | ||
| 1851 | /* Lisp_Object callbacks; */ | 1951 | /* Lisp_Object callbacks; */ |
| 1852 | Lisp_Object loglevel; | 1952 | Lisp_Object loglevel; |
| 1853 | Lisp_Object hostname; | 1953 | Lisp_Object hostname; |
| 1854 | Lisp_Object prime_bits; | 1954 | Lisp_Object prime_bits; |
| 1955 | #ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 | ||
| 1956 | unsigned int aux_key_file; | ||
| 1957 | #endif | ||
| 1855 | struct Lisp_Process *p = XPROCESS (proc); | 1958 | struct Lisp_Process *p = XPROCESS (proc); |
| 1856 | 1959 | ||
| 1857 | CHECK_PROCESS (proc); | 1960 | CHECK_PROCESS (proc); |
| @@ -1877,6 +1980,13 @@ one trustfile (usually a CA bundle). */) | |||
| 1877 | crlfiles = plist_get (proplist, QCcrlfiles); | 1980 | crlfiles = plist_get (proplist, QCcrlfiles); |
| 1878 | loglevel = plist_get (proplist, QCloglevel); | 1981 | loglevel = plist_get (proplist, QCloglevel); |
| 1879 | prime_bits = plist_get (proplist, QCmin_prime_bits); | 1982 | prime_bits = plist_get (proplist, QCmin_prime_bits); |
| 1983 | pass = plist_get (proplist, QCpass); | ||
| 1984 | flags = plist_get (proplist, QCflags); | ||
| 1985 | |||
| 1986 | if (STRINGP (pass)) | ||
| 1987 | c_pass = SSDATA (pass); | ||
| 1988 | else | ||
| 1989 | c_pass = NULL; | ||
| 1880 | 1990 | ||
| 1881 | if (!STRINGP (hostname)) | 1991 | if (!STRINGP (hostname)) |
| 1882 | { | 1992 | { |
| @@ -2038,6 +2148,20 @@ one trustfile (usually a CA bundle). */) | |||
| 2038 | keyfile = ansi_encode_filename (keyfile); | 2148 | keyfile = ansi_encode_filename (keyfile); |
| 2039 | certfile = ansi_encode_filename (certfile); | 2149 | certfile = ansi_encode_filename (certfile); |
| 2040 | # endif | 2150 | # endif |
| 2151 | # ifdef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 | ||
| 2152 | if (!NILP (plist_member (proplist, QCpass))) | ||
| 2153 | { | ||
| 2154 | aux_key_file = key_file2_aux (flags); | ||
| 2155 | ret | ||
| 2156 | = gnutls_certificate_set_x509_key_file2 (x509_cred, | ||
| 2157 | SSDATA (certfile), | ||
| 2158 | SSDATA (keyfile), | ||
| 2159 | file_format, | ||
| 2160 | c_pass, | ||
| 2161 | aux_key_file); | ||
| 2162 | } | ||
| 2163 | else | ||
| 2164 | # endif | ||
| 2041 | ret = gnutls_certificate_set_x509_key_file | 2165 | ret = gnutls_certificate_set_x509_key_file |
| 2042 | (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format); | 2166 | (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format); |
| 2043 | 2167 | ||
| @@ -2862,8 +2986,26 @@ level in the ones. For builds without libgnutls, the value is -1. */); | |||
| 2862 | DEFSYM (QCmin_prime_bits, ":min-prime-bits"); | 2986 | DEFSYM (QCmin_prime_bits, ":min-prime-bits"); |
| 2863 | DEFSYM (QCloglevel, ":loglevel"); | 2987 | DEFSYM (QCloglevel, ":loglevel"); |
| 2864 | DEFSYM (QCcomplete_negotiation, ":complete-negotiation"); | 2988 | DEFSYM (QCcomplete_negotiation, ":complete-negotiation"); |
| 2989 | DEFSYM (QCpass, ":pass"); | ||
| 2990 | DEFSYM (QCflags, ":flags"); | ||
| 2865 | DEFSYM (QCverify_flags, ":verify-flags"); | 2991 | DEFSYM (QCverify_flags, ":verify-flags"); |
| 2866 | DEFSYM (QCverify_error, ":verify-error"); | 2992 | DEFSYM (QCverify_error, ":verify-error"); |
| 2993 | DEFSYM (Qgnutls_pkcs_plain, "GNUTLS_PKCS_PLAIN"); | ||
| 2994 | DEFSYM (Qgnutls_pkcs_pkcs12_3des, "GNUTLS_PKCS_PKCS12_3DES"); | ||
| 2995 | DEFSYM (Qgnutls_pkcs_pkcs12_arcfour, "GNUTLS_PKCS_PKCS12_ARCFOUR"); | ||
| 2996 | DEFSYM (Qgnutls_pkcs_pkcs12_rc2_40, "GNUTLS_PKCS_PKCS12_RC2_40"); | ||
| 2997 | DEFSYM (Qgnutls_pkcs_pbes2_3des, "GNUTLS_PKCS_PBES2_3DES"); | ||
| 2998 | DEFSYM (Qgnutls_pkcs_pbes2_aes_128, "GNUTLS_PKCS_PBES2_AES_128"); | ||
| 2999 | DEFSYM (Qgnutls_pkcs_pbes2_aes_192, "GNUTLS_PKCS_PBES2_AES_192"); | ||
| 3000 | DEFSYM (Qgnutls_pkcs_pbes2_aes_256, "GNUTLS_PKCS_PBES2_AES_256"); | ||
| 3001 | DEFSYM (Qgnutls_pkcs_null_password, "GNUTLS_PKCS_NULL_PASSWORD"); | ||
| 3002 | DEFSYM (Qgnutls_pkcs_pbes2_des, "GNUTLS_PKCS_PBES2_DES"); | ||
| 3003 | DEFSYM (Qgnutls_pkcs_pbes1_des_md5, "GNUTLS_PKCS_PBES1_DES_MD5"); | ||
| 3004 | DEFSYM (Qgnutls_pkcs_pbes2_gost_tc26z, "GNUTLS_PKCS_PBES2_GOST_TC26Z"); | ||
| 3005 | DEFSYM (Qgnutls_pkcs_pbes2_gost_cpa, "GNUTLS_PKCS_PBES2_GOST_CPA"); | ||
| 3006 | DEFSYM (Qgnutls_pkcs_pbes2_gost_cpb, "GNUTLS_PKCS_PBES2_GOST_CPB"); | ||
| 3007 | DEFSYM (Qgnutls_pkcs_pbes2_gost_cpc, "GNUTLS_PKCS_PBES2_GOST_CPC"); | ||
| 3008 | DEFSYM (Qgnutls_pkcs_pbes2_gost_cpd, "GNUTLS_PKCS_PBES2_GOST_CPD"); | ||
| 2867 | 3009 | ||
| 2868 | DEFSYM (QCcipher_id, ":cipher-id"); | 3010 | DEFSYM (QCcipher_id, ":cipher-id"); |
| 2869 | DEFSYM (QCcipher_aead_capable, ":cipher-aead-capable"); | 3011 | DEFSYM (QCcipher_aead_capable, ":cipher-aead-capable"); |
diff --git a/src/indent.c b/src/indent.c index 4671ccccf90..66edaff67de 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -887,6 +887,8 @@ DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ", | |||
| 887 | Optional second argument MINIMUM says always do at least MINIMUM spaces | 887 | Optional second argument MINIMUM says always do at least MINIMUM spaces |
| 888 | even if that goes past COLUMN; by default, MINIMUM is zero. | 888 | even if that goes past COLUMN; by default, MINIMUM is zero. |
| 889 | 889 | ||
| 890 | Whether this uses tabs or spaces depends on `indent-tabs-mode'. | ||
| 891 | |||
| 890 | The return value is the column where the insertion ends. */) | 892 | The return value is the column where the insertion ends. */) |
| 891 | (Lisp_Object column, Lisp_Object minimum) | 893 | (Lisp_Object column, Lisp_Object minimum) |
| 892 | { | 894 | { |
diff --git a/src/json.c b/src/json.c index cdcc11358e6..621c7d7c15f 100644 --- a/src/json.c +++ b/src/json.c | |||
| @@ -555,6 +555,40 @@ json_parse_args (ptrdiff_t nargs, | |||
| 555 | } | 555 | } |
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | static bool | ||
| 559 | json_available_p (void) | ||
| 560 | { | ||
| 561 | #ifdef WINDOWSNT | ||
| 562 | if (!json_initialized) | ||
| 563 | { | ||
| 564 | Lisp_Object status; | ||
| 565 | json_initialized = init_json_functions (); | ||
| 566 | status = json_initialized ? Qt : Qnil; | ||
| 567 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | ||
| 568 | } | ||
| 569 | return json_initialized; | ||
| 570 | #else /* !WINDOWSNT */ | ||
| 571 | return true; | ||
| 572 | #endif | ||
| 573 | } | ||
| 574 | |||
| 575 | #ifdef WINDOWSNT | ||
| 576 | static void | ||
| 577 | ensure_json_available (void) | ||
| 578 | { | ||
| 579 | if (!json_available_p ()) | ||
| 580 | Fsignal (Qjson_unavailable, | ||
| 581 | list1 (build_unibyte_string ("jansson library not found"))); | ||
| 582 | } | ||
| 583 | #endif | ||
| 584 | |||
| 585 | DEFUN ("json--available-p", Fjson__available_p, Sjson__available_p, 0, 0, NULL, | ||
| 586 | doc: /* Return non-nil if libjansson is available (internal use only). */) | ||
| 587 | (void) | ||
| 588 | { | ||
| 589 | return json_available_p () ? Qt : Qnil; | ||
| 590 | } | ||
| 591 | |||
| 558 | DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, MANY, | 592 | DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, MANY, |
| 559 | NULL, | 593 | NULL, |
| 560 | doc: /* Return the JSON representation of OBJECT as a string. | 594 | doc: /* Return the JSON representation of OBJECT as a string. |
| @@ -587,16 +621,7 @@ usage: (json-serialize OBJECT &rest ARGS) */) | |||
| 587 | specpdl_ref count = SPECPDL_INDEX (); | 621 | specpdl_ref count = SPECPDL_INDEX (); |
| 588 | 622 | ||
| 589 | #ifdef WINDOWSNT | 623 | #ifdef WINDOWSNT |
| 590 | if (!json_initialized) | 624 | ensure_json_available (); |
| 591 | { | ||
| 592 | Lisp_Object status; | ||
| 593 | json_initialized = init_json_functions (); | ||
| 594 | status = json_initialized ? Qt : Qnil; | ||
| 595 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | ||
| 596 | } | ||
| 597 | if (!json_initialized) | ||
| 598 | Fsignal (Qjson_unavailable, | ||
| 599 | list1 (build_unibyte_string ("jansson library not found"))); | ||
| 600 | #endif | 625 | #endif |
| 601 | 626 | ||
| 602 | struct json_configuration conf = | 627 | struct json_configuration conf = |
| @@ -696,16 +721,7 @@ usage: (json-insert OBJECT &rest ARGS) */) | |||
| 696 | specpdl_ref count = SPECPDL_INDEX (); | 721 | specpdl_ref count = SPECPDL_INDEX (); |
| 697 | 722 | ||
| 698 | #ifdef WINDOWSNT | 723 | #ifdef WINDOWSNT |
| 699 | if (!json_initialized) | 724 | ensure_json_available (); |
| 700 | { | ||
| 701 | Lisp_Object status; | ||
| 702 | json_initialized = init_json_functions (); | ||
| 703 | status = json_initialized ? Qt : Qnil; | ||
| 704 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | ||
| 705 | } | ||
| 706 | if (!json_initialized) | ||
| 707 | Fsignal (Qjson_unavailable, | ||
| 708 | list1 (build_unibyte_string ("jansson library not found"))); | ||
| 709 | #endif | 725 | #endif |
| 710 | 726 | ||
| 711 | struct json_configuration conf = | 727 | struct json_configuration conf = |
| @@ -953,16 +969,7 @@ usage: (json-parse-string STRING &rest ARGS) */) | |||
| 953 | specpdl_ref count = SPECPDL_INDEX (); | 969 | specpdl_ref count = SPECPDL_INDEX (); |
| 954 | 970 | ||
| 955 | #ifdef WINDOWSNT | 971 | #ifdef WINDOWSNT |
| 956 | if (!json_initialized) | 972 | ensure_json_available (); |
| 957 | { | ||
| 958 | Lisp_Object status; | ||
| 959 | json_initialized = init_json_functions (); | ||
| 960 | status = json_initialized ? Qt : Qnil; | ||
| 961 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | ||
| 962 | } | ||
| 963 | if (!json_initialized) | ||
| 964 | Fsignal (Qjson_unavailable, | ||
| 965 | list1 (build_unibyte_string ("jansson library not found"))); | ||
| 966 | #endif | 973 | #endif |
| 967 | 974 | ||
| 968 | Lisp_Object string = args[0]; | 975 | Lisp_Object string = args[0]; |
| @@ -1050,16 +1057,7 @@ usage: (json-parse-buffer &rest args) */) | |||
| 1050 | specpdl_ref count = SPECPDL_INDEX (); | 1057 | specpdl_ref count = SPECPDL_INDEX (); |
| 1051 | 1058 | ||
| 1052 | #ifdef WINDOWSNT | 1059 | #ifdef WINDOWSNT |
| 1053 | if (!json_initialized) | 1060 | ensure_json_available (); |
| 1054 | { | ||
| 1055 | Lisp_Object status; | ||
| 1056 | json_initialized = init_json_functions (); | ||
| 1057 | status = json_initialized ? Qt : Qnil; | ||
| 1058 | Vlibrary_cache = Fcons (Fcons (Qjson, status), Vlibrary_cache); | ||
| 1059 | } | ||
| 1060 | if (!json_initialized) | ||
| 1061 | Fsignal (Qjson_unavailable, | ||
| 1062 | list1 (build_unibyte_string ("jansson library not found"))); | ||
| 1063 | #endif | 1061 | #endif |
| 1064 | 1062 | ||
| 1065 | struct json_configuration conf = | 1063 | struct json_configuration conf = |
| @@ -1137,6 +1135,7 @@ syms_of_json (void) | |||
| 1137 | DEFSYM (Qplist, "plist"); | 1135 | DEFSYM (Qplist, "plist"); |
| 1138 | DEFSYM (Qarray, "array"); | 1136 | DEFSYM (Qarray, "array"); |
| 1139 | 1137 | ||
| 1138 | defsubr (&Sjson__available_p); | ||
| 1140 | defsubr (&Sjson_serialize); | 1139 | defsubr (&Sjson_serialize); |
| 1141 | defsubr (&Sjson_insert); | 1140 | defsubr (&Sjson_insert); |
| 1142 | defsubr (&Sjson_parse_string); | 1141 | defsubr (&Sjson_parse_string); |
diff --git a/src/keyboard.c b/src/keyboard.c index d68b50428a9..7bf89ac7d4b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -503,11 +503,10 @@ echo_add_key (Lisp_Object c) | |||
| 503 | if ((NILP (echo_string) || SCHARS (echo_string) == 0) | 503 | if ((NILP (echo_string) || SCHARS (echo_string) == 0) |
| 504 | && help_char_p (c)) | 504 | && help_char_p (c)) |
| 505 | { | 505 | { |
| 506 | AUTO_STRING (str, " (Type ? for further options, q for quick help)"); | 506 | AUTO_STRING (str, " (Type ? for further options, C-q for quick help)"); |
| 507 | AUTO_LIST2 (props, Qface, Qhelp_key_binding); | 507 | AUTO_LIST2 (props, Qface, Qhelp_key_binding); |
| 508 | Fadd_text_properties (make_fixnum (7), make_fixnum (8), props, str); | 508 | Fadd_text_properties (make_fixnum (7), make_fixnum (8), props, str); |
| 509 | Fadd_text_properties (make_fixnum (30), make_fixnum (31), props, | 509 | Fadd_text_properties (make_fixnum (30), make_fixnum (33), props, str); |
| 510 | str); | ||
| 511 | new_string = concat2 (new_string, str); | 510 | new_string = concat2 (new_string, str); |
| 512 | } | 511 | } |
| 513 | 512 | ||
diff --git a/src/lisp.h b/src/lisp.h index 1f1d47f2a95..d6525ebdc52 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -22,7 +22,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 22 | 22 | ||
| 23 | #include <alloca.h> | 23 | #include <alloca.h> |
| 24 | #include <setjmp.h> | 24 | #include <setjmp.h> |
| 25 | #include <stdalign.h> | ||
| 26 | #include <stdarg.h> | 25 | #include <stdarg.h> |
| 27 | #include <stddef.h> | 26 | #include <stddef.h> |
| 28 | #include <string.h> | 27 | #include <string.h> |
diff --git a/src/process.c b/src/process.c index de1b07a81cc..a4be68f7418 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -6810,10 +6810,13 @@ emacs_get_tty_pgrp (struct Lisp_Process *p) | |||
| 6810 | 6810 | ||
| 6811 | DEFUN ("process-running-child-p", Fprocess_running_child_p, | 6811 | DEFUN ("process-running-child-p", Fprocess_running_child_p, |
| 6812 | Sprocess_running_child_p, 0, 1, 0, | 6812 | Sprocess_running_child_p, 0, 1, 0, |
| 6813 | doc: /* Return non-nil if PROCESS has given the terminal to a | 6813 | doc: /* Return non-nil if PROCESS has given control of its terminal to a child. |
| 6814 | child. If the operating system does not make it possible to find out, | 6814 | If the operating system does not make it possible to find out, return t. |
| 6815 | return t. If we can find out, return the numeric ID of the foreground | 6815 | If it's possible to find out, return the numeric ID of the foreground |
| 6816 | process group. */) | 6816 | process group if PROCESS did give control of its terminal to a |
| 6817 | child process, and return nil if it didn't. | ||
| 6818 | |||
| 6819 | PROCESS must be a real subprocess, not a connection. */) | ||
| 6817 | (Lisp_Object process) | 6820 | (Lisp_Object process) |
| 6818 | { | 6821 | { |
| 6819 | /* Initialize in case ioctl doesn't exist or gives an error, | 6822 | /* Initialize in case ioctl doesn't exist or gives an error, |
diff --git a/src/treesit.c b/src/treesit.c index c882d455137..974d2fc4517 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | Copyright (C) 2021-2022 Free Software Foundation, Inc. | 3 | Copyright (C) 2021-2022 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | Maintainer: Yuan Fu <casouri@gmail.com> | ||
| 6 | |||
| 5 | This file is part of GNU Emacs. | 7 | This file is part of GNU Emacs. |
| 6 | 8 | ||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | 9 | GNU Emacs is free software: you can redistribute it and/or modify |
| @@ -404,6 +406,10 @@ init_treesit_functions (void) | |||
| 404 | 406 | ||
| 405 | /*** Initialization */ | 407 | /*** Initialization */ |
| 406 | 408 | ||
| 409 | /* This is the limit on recursion levels for some tree-sitter | ||
| 410 | functions. Remember to update docstrings when changing this | ||
| 411 | value. */ | ||
| 412 | const ptrdiff_t treesit_recursion_limit = 1000; | ||
| 407 | bool treesit_initialized = false; | 413 | bool treesit_initialized = false; |
| 408 | 414 | ||
| 409 | static bool | 415 | static bool |
| @@ -656,9 +662,8 @@ If DETAIL is non-nil, return (t . nil) when LANGUAGE is available, | |||
| 656 | } | 662 | } |
| 657 | } | 663 | } |
| 658 | 664 | ||
| 659 | DEFUN ("treesit-language-version", | 665 | DEFUN ("treesit-library-abi-version", Ftreesit_library_abi_version, |
| 660 | Ftreesit_language_version, | 666 | Streesit_library_abi_version, |
| 661 | Streesit_language_version, | ||
| 662 | 0, 1, 0, | 667 | 0, 1, 0, |
| 663 | doc: /* Return the language ABI version of the tree-sitter library. | 668 | doc: /* Return the language ABI version of the tree-sitter library. |
| 664 | 669 | ||
| @@ -674,6 +679,29 @@ is non-nil, return the oldest compatible ABI version. */) | |||
| 674 | return make_fixnum (TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION); | 679 | return make_fixnum (TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION); |
| 675 | } | 680 | } |
| 676 | 681 | ||
| 682 | DEFUN ("treesit-language-version", Ftreesit_language_abi_version, | ||
| 683 | Streesit_language_abi_version, | ||
| 684 | 0, 1, 0, | ||
| 685 | doc: /* Return the language ABI version of the tree-sitter LANGUAGE. | ||
| 686 | Return nil if LANGUAGE is not available. */) | ||
| 687 | (Lisp_Object language) | ||
| 688 | { | ||
| 689 | if (NILP (Ftreesit_langauge_available_p (language, Qnil))) | ||
| 690 | return Qnil; | ||
| 691 | else | ||
| 692 | { | ||
| 693 | Lisp_Object signal_symbol = Qnil; | ||
| 694 | Lisp_Object signal_data = Qnil; | ||
| 695 | TSLanguage *ts_language = treesit_load_language (language, | ||
| 696 | &signal_symbol, | ||
| 697 | &signal_data); | ||
| 698 | if (ts_language == NULL) | ||
| 699 | return Qnil; | ||
| 700 | uint32_t version = ts_language_version (ts_language); | ||
| 701 | return make_fixnum((ptrdiff_t) version); | ||
| 702 | } | ||
| 703 | } | ||
| 704 | |||
| 677 | /*** Parsing functions */ | 705 | /*** Parsing functions */ |
| 678 | 706 | ||
| 679 | static void | 707 | static void |
| @@ -927,11 +955,24 @@ static void | |||
| 927 | treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree, | 955 | treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree, |
| 928 | Lisp_Object parser) | 956 | Lisp_Object parser) |
| 929 | { | 957 | { |
| 930 | uint32_t len; | 958 | /* If the old_tree is NULL, meaning this is the first parse, the |
| 931 | TSRange *ranges = ts_tree_get_changed_ranges (old_tree, new_tree, &len); | 959 | changed range is the whole buffer. */ |
| 960 | Lisp_Object lisp_ranges; | ||
| 932 | struct buffer *buf = XBUFFER (XTS_PARSER (parser)->buffer); | 961 | struct buffer *buf = XBUFFER (XTS_PARSER (parser)->buffer); |
| 933 | Lisp_Object lisp_ranges = treesit_make_ranges (ranges, len, buf); | 962 | if (old_tree) |
| 934 | xfree (ranges); | 963 | { |
| 964 | uint32_t len; | ||
| 965 | TSRange *ranges = ts_tree_get_changed_ranges (old_tree, new_tree, &len); | ||
| 966 | lisp_ranges = treesit_make_ranges (ranges, len, buf); | ||
| 967 | xfree (ranges); | ||
| 968 | } | ||
| 969 | else | ||
| 970 | { | ||
| 971 | struct buffer *oldbuf = current_buffer; | ||
| 972 | set_buffer_internal (buf); | ||
| 973 | lisp_ranges = Fcons (Fcons (Fpoint_min (), Fpoint_max ()), Qnil); | ||
| 974 | set_buffer_internal (oldbuf); | ||
| 975 | } | ||
| 935 | 976 | ||
| 936 | specpdl_ref count = SPECPDL_INDEX (); | 977 | specpdl_ref count = SPECPDL_INDEX (); |
| 937 | 978 | ||
| @@ -949,6 +990,11 @@ treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree, | |||
| 949 | static void | 990 | static void |
| 950 | treesit_ensure_parsed (Lisp_Object parser) | 991 | treesit_ensure_parsed (Lisp_Object parser) |
| 951 | { | 992 | { |
| 993 | /* Make sure this comes before everything else, see comment | ||
| 994 | (ref:notifier-inside-ensure-parsed) for more detail. */ | ||
| 995 | if (!XTS_PARSER (parser)->need_reparse) | ||
| 996 | return; | ||
| 997 | |||
| 952 | struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); | 998 | struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); |
| 953 | 999 | ||
| 954 | /* Before we parse, catch up with the narrowing situation. */ | 1000 | /* Before we parse, catch up with the narrowing situation. */ |
| @@ -957,8 +1003,6 @@ treesit_ensure_parsed (Lisp_Object parser) | |||
| 957 | because it might set the flag to true. */ | 1003 | because it might set the flag to true. */ |
| 958 | treesit_sync_visible_region (parser); | 1004 | treesit_sync_visible_region (parser); |
| 959 | 1005 | ||
| 960 | if (!XTS_PARSER (parser)->need_reparse) | ||
| 961 | return; | ||
| 962 | TSParser *treesit_parser = XTS_PARSER (parser)->parser; | 1006 | TSParser *treesit_parser = XTS_PARSER (parser)->parser; |
| 963 | TSTree *tree = XTS_PARSER (parser)->tree; | 1007 | TSTree *tree = XTS_PARSER (parser)->tree; |
| 964 | TSInput input = XTS_PARSER (parser)->input; | 1008 | TSInput input = XTS_PARSER (parser)->input; |
| @@ -978,14 +1022,17 @@ treesit_ensure_parsed (Lisp_Object parser) | |||
| 978 | xsignal1 (Qtreesit_parse_error, buf); | 1022 | xsignal1 (Qtreesit_parse_error, buf); |
| 979 | } | 1023 | } |
| 980 | 1024 | ||
| 981 | if (tree != NULL) | ||
| 982 | { | ||
| 983 | treesit_call_after_change_functions (tree, new_tree, parser); | ||
| 984 | ts_tree_delete (tree); | ||
| 985 | } | ||
| 986 | |||
| 987 | XTS_PARSER (parser)->tree = new_tree; | 1025 | XTS_PARSER (parser)->tree = new_tree; |
| 988 | XTS_PARSER (parser)->need_reparse = false; | 1026 | XTS_PARSER (parser)->need_reparse = false; |
| 1027 | |||
| 1028 | /* After-change functions should run at the very end, most crucially | ||
| 1029 | after need_reparse is set to false, this way if the function | ||
| 1030 | calls some tree-sitter function which invokes | ||
| 1031 | treesit_ensure_parsed again, it returns early and do not | ||
| 1032 | recursively call the after change functions again. | ||
| 1033 | (ref:notifier-inside-ensure-parsed) */ | ||
| 1034 | treesit_call_after_change_functions (tree, new_tree, parser); | ||
| 1035 | ts_tree_delete (tree); | ||
| 989 | } | 1036 | } |
| 990 | 1037 | ||
| 991 | /* This is the read function provided to tree-sitter to read from a | 1038 | /* This is the read function provided to tree-sitter to read from a |
| @@ -1147,10 +1194,12 @@ treesit_query_error_to_string (TSQueryError error) | |||
| 1147 | 1194 | ||
| 1148 | static Lisp_Object | 1195 | static Lisp_Object |
| 1149 | treesit_compose_query_signal_data (uint32_t error_offset, | 1196 | treesit_compose_query_signal_data (uint32_t error_offset, |
| 1150 | TSQueryError error_type) | 1197 | TSQueryError error_type, |
| 1198 | Lisp_Object query_source) | ||
| 1151 | { | 1199 | { |
| 1152 | return list3 (build_string (treesit_query_error_to_string (error_type)), | 1200 | return list4 (build_string (treesit_query_error_to_string (error_type)), |
| 1153 | make_fixnum (error_offset + 1), | 1201 | make_fixnum (error_offset + 1), |
| 1202 | query_source, | ||
| 1154 | build_pure_c_string ("Debug the query with `treesit-query-validate'")); | 1203 | build_pure_c_string ("Debug the query with `treesit-query-validate'")); |
| 1155 | } | 1204 | } |
| 1156 | 1205 | ||
| @@ -1192,7 +1241,8 @@ treesit_ensure_query_compiled (Lisp_Object query, Lisp_Object *signal_symbol, | |||
| 1192 | { | 1241 | { |
| 1193 | *signal_symbol = Qtreesit_query_error; | 1242 | *signal_symbol = Qtreesit_query_error; |
| 1194 | *signal_data = treesit_compose_query_signal_data (error_offset, | 1243 | *signal_data = treesit_compose_query_signal_data (error_offset, |
| 1195 | error_type); | 1244 | error_type, |
| 1245 | source); | ||
| 1196 | } | 1246 | } |
| 1197 | XTS_COMPILED_QUERY (query)->query = treesit_query; | 1247 | XTS_COMPILED_QUERY (query)->query = treesit_query; |
| 1198 | return treesit_query; | 1248 | return treesit_query; |
| @@ -1762,7 +1812,7 @@ If NODE is nil, return nil. */) | |||
| 1762 | return build_string (string); | 1812 | return build_string (string); |
| 1763 | } | 1813 | } |
| 1764 | 1814 | ||
| 1765 | static TSTreeCursor treesit_cursor_helper (TSNode, Lisp_Object); | 1815 | static bool treesit_cursor_helper (TSTreeCursor *, TSNode, Lisp_Object); |
| 1766 | 1816 | ||
| 1767 | DEFUN ("treesit-node-parent", | 1817 | DEFUN ("treesit-node-parent", |
| 1768 | Ftreesit_node_parent, Streesit_node_parent, 1, 1, 0, | 1818 | Ftreesit_node_parent, Streesit_node_parent, 1, 1, 0, |
| @@ -1778,7 +1828,10 @@ Return nil if NODE has no parent. If NODE is nil, return nil. */) | |||
| 1778 | 1828 | ||
| 1779 | TSNode treesit_node = XTS_NODE (node)->node; | 1829 | TSNode treesit_node = XTS_NODE (node)->node; |
| 1780 | Lisp_Object parser = XTS_NODE (node)->parser; | 1830 | Lisp_Object parser = XTS_NODE (node)->parser; |
| 1781 | TSTreeCursor cursor = treesit_cursor_helper (treesit_node, parser); | 1831 | TSTreeCursor cursor; |
| 1832 | if (!treesit_cursor_helper (&cursor, treesit_node, parser)) | ||
| 1833 | return return_value; | ||
| 1834 | |||
| 1782 | if (ts_tree_cursor_goto_parent (&cursor)) | 1835 | if (ts_tree_cursor_goto_parent (&cursor)) |
| 1783 | { | 1836 | { |
| 1784 | TSNode parent = ts_tree_cursor_current_node (&cursor); | 1837 | TSNode parent = ts_tree_cursor_current_node (&cursor); |
| @@ -2042,12 +2095,11 @@ Note that this function returns an immediate child, not the smallest | |||
| 2042 | 2095 | ||
| 2043 | struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); | 2096 | struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); |
| 2044 | ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; | 2097 | ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; |
| 2045 | ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos)); | ||
| 2046 | 2098 | ||
| 2047 | treesit_check_position (pos, buf); | 2099 | treesit_check_position (pos, buf); |
| 2048 | |||
| 2049 | treesit_initialize (); | 2100 | treesit_initialize (); |
| 2050 | 2101 | ||
| 2102 | ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos)); | ||
| 2051 | TSNode treesit_node = XTS_NODE (node)->node; | 2103 | TSNode treesit_node = XTS_NODE (node)->node; |
| 2052 | TSNode child; | 2104 | TSNode child; |
| 2053 | if (NILP (named)) | 2105 | if (NILP (named)) |
| @@ -2078,14 +2130,14 @@ If NODE is nil, return nil. */) | |||
| 2078 | 2130 | ||
| 2079 | struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); | 2131 | struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); |
| 2080 | ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; | 2132 | ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; |
| 2081 | ptrdiff_t byte_beg = buf_charpos_to_bytepos (buf, XFIXNUM (beg)); | ||
| 2082 | ptrdiff_t byte_end = buf_charpos_to_bytepos (buf, XFIXNUM (end)); | ||
| 2083 | 2133 | ||
| 2084 | treesit_check_position (beg, buf); | 2134 | treesit_check_position (beg, buf); |
| 2085 | treesit_check_position (end, buf); | 2135 | treesit_check_position (end, buf); |
| 2086 | 2136 | ||
| 2087 | treesit_initialize (); | 2137 | treesit_initialize (); |
| 2088 | 2138 | ||
| 2139 | ptrdiff_t byte_beg = buf_charpos_to_bytepos (buf, XFIXNUM (beg)); | ||
| 2140 | ptrdiff_t byte_end = buf_charpos_to_bytepos (buf, XFIXNUM (end)); | ||
| 2089 | TSNode treesit_node = XTS_NODE (node)->node; | 2141 | TSNode treesit_node = XTS_NODE (node)->node; |
| 2090 | TSNode child; | 2142 | TSNode child; |
| 2091 | if (NILP (named)) | 2143 | if (NILP (named)) |
| @@ -2161,6 +2213,8 @@ See Info node `(elisp)Pattern Matching' for detailed explanation. */) | |||
| 2161 | return build_pure_c_string ("#equal"); | 2213 | return build_pure_c_string ("#equal"); |
| 2162 | if (EQ (pattern, QCmatch)) | 2214 | if (EQ (pattern, QCmatch)) |
| 2163 | return build_pure_c_string ("#match"); | 2215 | return build_pure_c_string ("#match"); |
| 2216 | if (EQ (pattern, QCpred)) | ||
| 2217 | return build_pure_c_string ("#pred"); | ||
| 2164 | Lisp_Object opening_delimeter | 2218 | Lisp_Object opening_delimeter |
| 2165 | = build_pure_c_string (VECTORP (pattern) ? "[" : "("); | 2219 | = build_pure_c_string (VECTORP (pattern) ? "[" : "("); |
| 2166 | Lisp_Object closing_delimiter | 2220 | Lisp_Object closing_delimiter |
| @@ -2260,10 +2314,10 @@ treesit_predicates_for_pattern (TSQuery *query, uint32_t pattern_index) | |||
| 2260 | return Fnreverse (result); | 2314 | return Fnreverse (result); |
| 2261 | } | 2315 | } |
| 2262 | 2316 | ||
| 2263 | /* Translate a capture NAME (symbol) to the text of the captured node. | 2317 | /* Translate a capture NAME (symbol) to a node. |
| 2264 | Signals treesit-query-error if such node is not captured. */ | 2318 | Signals treesit-query-error if such node is not captured. */ |
| 2265 | static Lisp_Object | 2319 | static Lisp_Object |
| 2266 | treesit_predicate_capture_name_to_text (Lisp_Object name, | 2320 | treesit_predicate_capture_name_to_node (Lisp_Object name, |
| 2267 | struct capture_range captures) | 2321 | struct capture_range captures) |
| 2268 | { | 2322 | { |
| 2269 | Lisp_Object node = Qnil; | 2323 | Lisp_Object node = Qnil; |
| @@ -2283,6 +2337,16 @@ treesit_predicate_capture_name_to_text (Lisp_Object name, | |||
| 2283 | name, build_pure_c_string ("A predicate can only refer" | 2337 | name, build_pure_c_string ("A predicate can only refer" |
| 2284 | " to captured nodes in the " | 2338 | " to captured nodes in the " |
| 2285 | "same pattern")); | 2339 | "same pattern")); |
| 2340 | return node; | ||
| 2341 | } | ||
| 2342 | |||
| 2343 | /* Translate a capture NAME (symbol) to the text of the captured node. | ||
| 2344 | Signals treesit-query-error if such node is not captured. */ | ||
| 2345 | static Lisp_Object | ||
| 2346 | treesit_predicate_capture_name_to_text (Lisp_Object name, | ||
| 2347 | struct capture_range captures) | ||
| 2348 | { | ||
| 2349 | Lisp_Object node = treesit_predicate_capture_name_to_node (name, captures); | ||
| 2286 | 2350 | ||
| 2287 | struct buffer *old_buffer = current_buffer; | 2351 | struct buffer *old_buffer = current_buffer; |
| 2288 | set_buffer_internal (XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer)); | 2352 | set_buffer_internal (XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer)); |
| @@ -2356,13 +2420,30 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures) | |||
| 2356 | return false; | 2420 | return false; |
| 2357 | } | 2421 | } |
| 2358 | 2422 | ||
| 2359 | /* About predicates: I decide to hard-code predicates in C instead of | 2423 | /* Handles predicate (#pred FN ARG...). Return true if FN returns |
| 2360 | implementing an extensible system where predicates are translated | 2424 | non-nil; return false otherwise. The arity of FN must match the |
| 2361 | to Lisp functions, and new predicates can be added by extending a | 2425 | number of ARGs */ |
| 2362 | list of functions, because I really couldn't imagine any useful | 2426 | static bool |
| 2363 | predicates besides equal and match. If we later found out that | 2427 | treesit_predicate_pred (Lisp_Object args, struct capture_range captures) |
| 2364 | such system is indeed useful and necessary, it can be easily | 2428 | { |
| 2365 | added. */ | 2429 | if (XFIXNUM (Flength (args)) < 2) |
| 2430 | xsignal2 (Qtreesit_query_error, | ||
| 2431 | build_pure_c_string ("Predicate `pred' requires " | ||
| 2432 | "at least two arguments, " | ||
| 2433 | "but was only given"), | ||
| 2434 | Flength (args)); | ||
| 2435 | |||
| 2436 | Lisp_Object fn = Fintern (XCAR (args), Qnil); | ||
| 2437 | Lisp_Object nodes = Qnil; | ||
| 2438 | Lisp_Object tail = XCDR (args); | ||
| 2439 | FOR_EACH_TAIL (tail) | ||
| 2440 | nodes = Fcons (treesit_predicate_capture_name_to_node (XCAR (tail), | ||
| 2441 | captures), | ||
| 2442 | nodes); | ||
| 2443 | nodes = Fnreverse (nodes); | ||
| 2444 | |||
| 2445 | return !NILP (CALLN (Fapply, fn, nodes)); | ||
| 2446 | } | ||
| 2366 | 2447 | ||
| 2367 | /* If all predicates in PREDICATES passes, return true; otherwise | 2448 | /* If all predicates in PREDICATES passes, return true; otherwise |
| 2368 | return false. */ | 2449 | return false. */ |
| @@ -2378,14 +2459,17 @@ treesit_eval_predicates (struct capture_range captures, Lisp_Object predicates) | |||
| 2378 | Lisp_Object fn = XCAR (predicate); | 2459 | Lisp_Object fn = XCAR (predicate); |
| 2379 | Lisp_Object args = XCDR (predicate); | 2460 | Lisp_Object args = XCDR (predicate); |
| 2380 | if (!NILP (Fstring_equal (fn, build_pure_c_string ("equal")))) | 2461 | if (!NILP (Fstring_equal (fn, build_pure_c_string ("equal")))) |
| 2381 | pass = treesit_predicate_equal (args, captures); | 2462 | pass &= treesit_predicate_equal (args, captures); |
| 2382 | else if (!NILP (Fstring_equal (fn, build_pure_c_string ("match")))) | 2463 | else if (!NILP (Fstring_equal (fn, build_pure_c_string ("match")))) |
| 2383 | pass = treesit_predicate_match (args, captures); | 2464 | pass &= treesit_predicate_match (args, captures); |
| 2465 | else if (!NILP (Fstring_equal (fn, build_pure_c_string ("pred")))) | ||
| 2466 | pass &= treesit_predicate_pred (args, captures); | ||
| 2384 | else | 2467 | else |
| 2385 | xsignal3 (Qtreesit_query_error, | 2468 | xsignal3 (Qtreesit_query_error, |
| 2386 | build_pure_c_string ("Invalid predicate"), | 2469 | build_pure_c_string ("Invalid predicate"), |
| 2387 | fn, build_pure_c_string ("Currently Emacs only supports" | 2470 | fn, build_pure_c_string ("Currently Emacs only supports" |
| 2388 | " equal and match predicate")); | 2471 | " equal, match, and pred" |
| 2472 | " predicate")); | ||
| 2389 | } | 2473 | } |
| 2390 | /* If all predicates passed, add captures to result list. */ | 2474 | /* If all predicates passed, add captures to result list. */ |
| 2391 | return pass; | 2475 | return pass; |
| @@ -2546,7 +2630,7 @@ the query. */) | |||
| 2546 | if (treesit_query == NULL) | 2630 | if (treesit_query == NULL) |
| 2547 | xsignal (Qtreesit_query_error, | 2631 | xsignal (Qtreesit_query_error, |
| 2548 | treesit_compose_query_signal_data (error_offset, | 2632 | treesit_compose_query_signal_data (error_offset, |
| 2549 | error_type)); | 2633 | error_type, query)); |
| 2550 | cursor = ts_query_cursor_new (); | 2634 | cursor = ts_query_cursor_new (); |
| 2551 | needs_to_free_query_and_cursor = true; | 2635 | needs_to_free_query_and_cursor = true; |
| 2552 | } | 2636 | } |
| @@ -2637,8 +2721,59 @@ treesit_assume_true (bool val) | |||
| 2637 | eassert (val == true); | 2721 | eassert (val == true); |
| 2638 | } | 2722 | } |
| 2639 | 2723 | ||
| 2724 | /* Tries to move CURSOR to point to TARGET. END_POS is the end of | ||
| 2725 | TARGET. If success, return true, otherwise move CURSOR back to | ||
| 2726 | starting position and return false. LIMIT is the recursion | ||
| 2727 | limit. */ | ||
| 2728 | static bool | ||
| 2729 | treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target, | ||
| 2730 | uint32_t end_pos, ptrdiff_t limit) | ||
| 2731 | { | ||
| 2732 | if (limit <= 0) | ||
| 2733 | return false; | ||
| 2734 | |||
| 2735 | TSNode cursor_node = ts_tree_cursor_current_node (cursor); | ||
| 2736 | if (ts_node_eq (cursor_node, *target)) | ||
| 2737 | return true; | ||
| 2738 | |||
| 2739 | if (!ts_tree_cursor_goto_first_child (cursor)) | ||
| 2740 | return false; | ||
| 2741 | |||
| 2742 | /* Skip nodes that definitely don't contain TARGET. */ | ||
| 2743 | while (ts_node_end_byte (cursor_node) < end_pos) | ||
| 2744 | { | ||
| 2745 | if (!ts_tree_cursor_goto_next_sibling (cursor)) | ||
| 2746 | break; | ||
| 2747 | cursor_node = ts_tree_cursor_current_node (cursor); | ||
| 2748 | } | ||
| 2749 | |||
| 2750 | /* Go through each sibling that could contain TARGET. Because of | ||
| 2751 | missing nodes (their width is 0), there could be multiple | ||
| 2752 | siblings that could contain TARGET. */ | ||
| 2753 | while (ts_node_start_byte (cursor_node) <= end_pos) | ||
| 2754 | { | ||
| 2755 | if (treesit_cursor_helper_1 (cursor, target, end_pos, limit - 1)) | ||
| 2756 | return true; | ||
| 2757 | |||
| 2758 | if (!ts_tree_cursor_goto_next_sibling (cursor)) | ||
| 2759 | break; | ||
| 2760 | cursor_node = ts_tree_cursor_current_node (cursor); | ||
| 2761 | } | ||
| 2762 | |||
| 2763 | /* Couldn't find TARGET, must be not in this subtree, move cursor | ||
| 2764 | back and pray that other brothers and sisters can succeed. */ | ||
| 2765 | treesit_assume_true (ts_tree_cursor_goto_parent (cursor)); | ||
| 2766 | return false; | ||
| 2767 | } | ||
| 2768 | |||
| 2640 | /* Create a TSTreeCursor pointing at NODE. PARSER is the lisp parser | 2769 | /* Create a TSTreeCursor pointing at NODE. PARSER is the lisp parser |
| 2641 | that produced NODE. | 2770 | that produced NODE. If success, return true, otherwise return |
| 2771 | false. This function should almost always succeed, but if the parse | ||
| 2772 | tree is strangely too deep and exceeds the recursion limit, this | ||
| 2773 | function will fail and return false. | ||
| 2774 | |||
| 2775 | If this function returns true, caller needs to free CURSOR; if | ||
| 2776 | returns false, caller don't need to free CURSOR. | ||
| 2642 | 2777 | ||
| 2643 | The reason we need this instead of simply using ts_tree_cursor_new | 2778 | The reason we need this instead of simply using ts_tree_cursor_new |
| 2644 | is that we have to create the cursor on the root node and traverse | 2779 | is that we have to create the cursor on the root node and traverse |
| @@ -2646,56 +2781,17 @@ treesit_assume_true (bool val) | |||
| 2646 | Otherwise going to sibling or parent of NODE wouldn't work. | 2781 | Otherwise going to sibling or parent of NODE wouldn't work. |
| 2647 | 2782 | ||
| 2648 | (Wow perfect filling.) */ | 2783 | (Wow perfect filling.) */ |
| 2649 | static TSTreeCursor | 2784 | static bool |
| 2650 | treesit_cursor_helper (TSNode node, Lisp_Object parser) | 2785 | treesit_cursor_helper (TSTreeCursor *cursor, TSNode node, Lisp_Object parser) |
| 2651 | { | 2786 | { |
| 2652 | uint32_t end_pos = ts_node_end_byte (node); | 2787 | uint32_t end_pos = ts_node_end_byte (node); |
| 2653 | TSNode root = ts_tree_root_node (XTS_PARSER (parser)->tree); | 2788 | TSNode root = ts_tree_root_node (XTS_PARSER (parser)->tree); |
| 2654 | TSTreeCursor cursor = ts_tree_cursor_new (root); | 2789 | *cursor = ts_tree_cursor_new (root); |
| 2655 | TSNode cursor_node = ts_tree_cursor_current_node (&cursor); | 2790 | bool success = treesit_cursor_helper_1 (cursor, &node, end_pos, |
| 2656 | /* This is like treesit-node-at. We go down from the root node, | 2791 | treesit_recursion_limit); |
| 2657 | either to first child or next sibling, repeatedly, and finally | 2792 | if (!success) |
| 2658 | arrive at NODE. */ | 2793 | ts_tree_cursor_delete (cursor); |
| 2659 | while (!ts_node_eq (node, cursor_node)) | 2794 | return success; |
| 2660 | { | ||
| 2661 | treesit_assume_true (ts_tree_cursor_goto_first_child (&cursor)); | ||
| 2662 | cursor_node = ts_tree_cursor_current_node (&cursor); | ||
| 2663 | /* ts_tree_cursor_goto_first_child_for_byte is not reliable, so | ||
| 2664 | we just go through each sibling. */ | ||
| 2665 | while (ts_node_is_missing (cursor_node) | ||
| 2666 | || ts_node_end_byte (cursor_node) < end_pos) | ||
| 2667 | { | ||
| 2668 | /* A "missing" node has zero width, so it's possible that | ||
| 2669 | its end = NODE.end but it's not NODE, so we skip them. | ||
| 2670 | But we need to make sure this missing node is not the | ||
| 2671 | node we are looking for before skipping it. */ | ||
| 2672 | if (ts_node_is_missing (cursor_node) | ||
| 2673 | && ts_node_eq (node, cursor_node)) | ||
| 2674 | return cursor; | ||
| 2675 | treesit_assume_true (ts_tree_cursor_goto_next_sibling (&cursor)); | ||
| 2676 | cursor_node = ts_tree_cursor_current_node (&cursor); | ||
| 2677 | } | ||
| 2678 | /* Right now CURSOR.end >= NODE.end. But what if CURSOR.end = | ||
| 2679 | NODE.end, and there are missing nodes after CURSOR, and the | ||
| 2680 | missing node after CURSOR is the NODE we are looking for?? | ||
| 2681 | Well, create a probe and look ahead. (This is tested by | ||
| 2682 | treesit-cursor-helper-with-missing-node.) */ | ||
| 2683 | TSTreeCursor probe = ts_tree_cursor_copy (&cursor); | ||
| 2684 | TSNode probe_node; | ||
| 2685 | while (ts_tree_cursor_goto_next_sibling (&probe)) | ||
| 2686 | { | ||
| 2687 | probe_node = ts_tree_cursor_current_node (&probe); | ||
| 2688 | if (!ts_node_is_missing (probe_node)) | ||
| 2689 | break; | ||
| 2690 | if (ts_node_eq (probe_node, node)) | ||
| 2691 | { | ||
| 2692 | ts_tree_cursor_delete (&cursor); | ||
| 2693 | return probe; | ||
| 2694 | } | ||
| 2695 | } | ||
| 2696 | ts_tree_cursor_delete (&probe); | ||
| 2697 | } | ||
| 2698 | return cursor; | ||
| 2699 | } | 2795 | } |
| 2700 | 2796 | ||
| 2701 | /* Move CURSOR to the next/previous sibling. FORWARD controls the | 2797 | /* Move CURSOR to the next/previous sibling. FORWARD controls the |
| @@ -2957,7 +3053,7 @@ Return the first matched node, or nil if none matches. */) | |||
| 2957 | 3053 | ||
| 2958 | /* We use a default limit of 1000. See bug#59426 for the | 3054 | /* We use a default limit of 1000. See bug#59426 for the |
| 2959 | discussion. */ | 3055 | discussion. */ |
| 2960 | ptrdiff_t the_limit = 1000; | 3056 | ptrdiff_t the_limit = treesit_recursion_limit; |
| 2961 | if (!NILP (limit)) | 3057 | if (!NILP (limit)) |
| 2962 | { | 3058 | { |
| 2963 | CHECK_FIXNUM (limit); | 3059 | CHECK_FIXNUM (limit); |
| @@ -2968,7 +3064,10 @@ Return the first matched node, or nil if none matches. */) | |||
| 2968 | 3064 | ||
| 2969 | Lisp_Object parser = XTS_NODE (node)->parser; | 3065 | Lisp_Object parser = XTS_NODE (node)->parser; |
| 2970 | Lisp_Object return_value = Qnil; | 3066 | Lisp_Object return_value = Qnil; |
| 2971 | TSTreeCursor cursor = treesit_cursor_helper (XTS_NODE (node)->node, parser); | 3067 | TSTreeCursor cursor; |
| 3068 | if (!treesit_cursor_helper (&cursor, XTS_NODE (node)->node, parser)) | ||
| 3069 | return return_value; | ||
| 3070 | |||
| 2972 | if (treesit_search_dfs (&cursor, predicate, parser, NILP (backward), | 3071 | if (treesit_search_dfs (&cursor, predicate, parser, NILP (backward), |
| 2973 | NILP (all), the_limit, false)) | 3072 | NILP (all), the_limit, false)) |
| 2974 | { | 3073 | { |
| @@ -3022,7 +3121,10 @@ always traverse leaf nodes first, then upwards. */) | |||
| 3022 | 3121 | ||
| 3023 | Lisp_Object parser = XTS_NODE (start)->parser; | 3122 | Lisp_Object parser = XTS_NODE (start)->parser; |
| 3024 | Lisp_Object return_value = Qnil; | 3123 | Lisp_Object return_value = Qnil; |
| 3025 | TSTreeCursor cursor = treesit_cursor_helper (XTS_NODE (start)->node, parser); | 3124 | TSTreeCursor cursor; |
| 3125 | if (!treesit_cursor_helper (&cursor, XTS_NODE (start)->node, parser)) | ||
| 3126 | return return_value; | ||
| 3127 | |||
| 3026 | if (treesit_search_forward (&cursor, predicate, parser, | 3128 | if (treesit_search_forward (&cursor, predicate, parser, |
| 3027 | NILP (backward), NILP (all))) | 3129 | NILP (backward), NILP (all))) |
| 3028 | { | 3130 | { |
| @@ -3130,7 +3232,7 @@ a regexp. */) | |||
| 3130 | 3232 | ||
| 3131 | /* We use a default limit of 1000. See bug#59426 for the | 3233 | /* We use a default limit of 1000. See bug#59426 for the |
| 3132 | discussion. */ | 3234 | discussion. */ |
| 3133 | ptrdiff_t the_limit = 1000; | 3235 | ptrdiff_t the_limit = treesit_recursion_limit; |
| 3134 | if (!NILP (limit)) | 3236 | if (!NILP (limit)) |
| 3135 | { | 3237 | { |
| 3136 | CHECK_FIXNUM (limit); | 3238 | CHECK_FIXNUM (limit); |
| @@ -3141,7 +3243,10 @@ a regexp. */) | |||
| 3141 | 3243 | ||
| 3142 | Lisp_Object parser = XTS_NODE (root)->parser; | 3244 | Lisp_Object parser = XTS_NODE (root)->parser; |
| 3143 | Lisp_Object parent = Fcons (Qnil, Qnil); | 3245 | Lisp_Object parent = Fcons (Qnil, Qnil); |
| 3144 | TSTreeCursor cursor = treesit_cursor_helper (XTS_NODE (root)->node, parser); | 3246 | TSTreeCursor cursor; |
| 3247 | if (!treesit_cursor_helper (&cursor, XTS_NODE (root)->node, parser)) | ||
| 3248 | return Qnil; | ||
| 3249 | |||
| 3145 | treesit_build_sparse_tree (&cursor, parent, predicate, process_fn, | 3250 | treesit_build_sparse_tree (&cursor, parent, predicate, process_fn, |
| 3146 | the_limit, parser); | 3251 | the_limit, parser); |
| 3147 | ts_tree_cursor_delete (&cursor); | 3252 | ts_tree_cursor_delete (&cursor); |
| @@ -3187,6 +3292,7 @@ syms_of_treesit (void) | |||
| 3187 | DEFSYM (QCanchor, ":anchor"); | 3292 | DEFSYM (QCanchor, ":anchor"); |
| 3188 | DEFSYM (QCequal, ":equal"); | 3293 | DEFSYM (QCequal, ":equal"); |
| 3189 | DEFSYM (QCmatch, ":match"); | 3294 | DEFSYM (QCmatch, ":match"); |
| 3295 | DEFSYM (QCpred, ":pred"); | ||
| 3190 | 3296 | ||
| 3191 | DEFSYM (Qnot_found, "not-found"); | 3297 | DEFSYM (Qnot_found, "not-found"); |
| 3192 | DEFSYM (Qsymbol_error, "symbol-error"); | 3298 | DEFSYM (Qsymbol_error, "symbol-error"); |
| @@ -3264,7 +3370,8 @@ then in the system default locations for dynamic libraries, in that order. */); | |||
| 3264 | Vtreesit_extra_load_path = Qnil; | 3370 | Vtreesit_extra_load_path = Qnil; |
| 3265 | 3371 | ||
| 3266 | defsubr (&Streesit_language_available_p); | 3372 | defsubr (&Streesit_language_available_p); |
| 3267 | defsubr (&Streesit_language_version); | 3373 | defsubr (&Streesit_library_abi_version); |
| 3374 | defsubr (&Streesit_language_abi_version); | ||
| 3268 | 3375 | ||
| 3269 | defsubr (&Streesit_parser_p); | 3376 | defsubr (&Streesit_parser_p); |
| 3270 | defsubr (&Streesit_node_p); | 3377 | defsubr (&Streesit_node_p); |
diff --git a/src/w32menu.c b/src/w32menu.c index b10239d5cc6..5f06f4c4170 100644 --- a/src/w32menu.c +++ b/src/w32menu.c | |||
| @@ -1073,7 +1073,10 @@ is_simple_dialog (Lisp_Object contents) | |||
| 1073 | if (NILP (Fstring_equal (name, other))) | 1073 | if (NILP (Fstring_equal (name, other))) |
| 1074 | return false; | 1074 | return false; |
| 1075 | 1075 | ||
| 1076 | /* Check there are no more options. */ | 1076 | /* Check there are no more options. |
| 1077 | |||
| 1078 | (FIXME: Since we use MB_YESNOCANCEL, we could also consider | ||
| 1079 | dialogs with 3 options: Yes/No/Cancel as "simple". */ | ||
| 1077 | options = XCDR (options); | 1080 | options = XCDR (options); |
| 1078 | return !(CONSP (options)); | 1081 | return !(CONSP (options)); |
| 1079 | } | 1082 | } |
| @@ -1085,7 +1088,13 @@ simple_dialog_show (struct frame *f, Lisp_Object contents, Lisp_Object header) | |||
| 1085 | UINT type; | 1088 | UINT type; |
| 1086 | Lisp_Object lispy_answer = Qnil, temp = XCAR (contents); | 1089 | Lisp_Object lispy_answer = Qnil, temp = XCAR (contents); |
| 1087 | 1090 | ||
| 1088 | type = MB_YESNO; | 1091 | /* We use MB_YESNOCANCEL to allow the user the equivalent of C-g |
| 1092 | when the Yes/No question is asked vya y-or-n-p or | ||
| 1093 | yes-or-no-p. */ | ||
| 1094 | if (w32_yes_no_dialog_show_cancel) | ||
| 1095 | type = MB_YESNOCANCEL; | ||
| 1096 | else | ||
| 1097 | type = MB_YESNO; | ||
| 1089 | 1098 | ||
| 1090 | /* Since we only handle Yes/No dialogs, and we already checked | 1099 | /* Since we only handle Yes/No dialogs, and we already checked |
| 1091 | is_simple_dialog, we don't need to worry about checking contents | 1100 | is_simple_dialog, we don't need to worry about checking contents |
diff --git a/src/w32term.c b/src/w32term.c index dff21489e5b..e40e4588fde 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -7696,6 +7696,7 @@ static void | |||
| 7696 | w32_initialize (void) | 7696 | w32_initialize (void) |
| 7697 | { | 7697 | { |
| 7698 | HANDLE shell; | 7698 | HANDLE shell; |
| 7699 | BOOL caret; | ||
| 7699 | HRESULT (WINAPI * set_user_model) (const wchar_t * id); | 7700 | HRESULT (WINAPI * set_user_model) (const wchar_t * id); |
| 7700 | 7701 | ||
| 7701 | baud_rate = 19200; | 7702 | baud_rate = 19200; |
| @@ -7732,8 +7733,9 @@ w32_initialize (void) | |||
| 7732 | 7733 | ||
| 7733 | /* Initialize w32_use_visible_system_caret based on whether a screen | 7734 | /* Initialize w32_use_visible_system_caret based on whether a screen |
| 7734 | reader is in use. */ | 7735 | reader is in use. */ |
| 7735 | if (!SystemParametersInfo (SPI_GETSCREENREADER, 0, | 7736 | if (SystemParametersInfo (SPI_GETSCREENREADER, 0, &caret, 0)) |
| 7736 | &w32_use_visible_system_caret, 0)) | 7737 | w32_use_visible_system_caret = caret == TRUE; |
| 7738 | else | ||
| 7737 | w32_use_visible_system_caret = 0; | 7739 | w32_use_visible_system_caret = 0; |
| 7738 | 7740 | ||
| 7739 | any_help_event_p = 0; | 7741 | any_help_event_p = 0; |
| @@ -7923,6 +7925,11 @@ unconditionally set to nil on older systems. */); | |||
| 7923 | w32_use_native_image_api = 0; | 7925 | w32_use_native_image_api = 0; |
| 7924 | #endif | 7926 | #endif |
| 7925 | 7927 | ||
| 7928 | DEFVAR_BOOL ("w32-yes-no-dialog-show-cancel", | ||
| 7929 | w32_yes_no_dialog_show_cancel, | ||
| 7930 | doc: /* If non-nil, show Cancel button in MS-Windows GUI Yes/No dialogs. */); | ||
| 7931 | w32_yes_no_dialog_show_cancel = 1; | ||
| 7932 | |||
| 7926 | /* FIXME: The following variable will be (hopefully) removed | 7933 | /* FIXME: The following variable will be (hopefully) removed |
| 7927 | before Emacs 25.1 gets released. */ | 7934 | before Emacs 25.1 gets released. */ |
| 7928 | 7935 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index cc4c60f02da..7d1e7eeb0b9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -12938,7 +12938,7 @@ clear_garbaged_frames (void) | |||
| 12938 | { | 12938 | { |
| 12939 | struct frame *f = XFRAME (frame); | 12939 | struct frame *f = XFRAME (frame); |
| 12940 | 12940 | ||
| 12941 | if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f)) | 12941 | if (FRAME_REDISPLAY_P (f) && FRAME_GARBAGED_P (f)) |
| 12942 | { | 12942 | { |
| 12943 | if (f->resized_p | 12943 | if (f->resized_p |
| 12944 | /* It makes no sense to redraw a non-selected TTY | 12944 | /* It makes no sense to redraw a non-selected TTY |
| @@ -12987,7 +12987,7 @@ echo_area_display (bool update_frame_p) | |||
| 12987 | f = XFRAME (WINDOW_FRAME (w)); | 12987 | f = XFRAME (WINDOW_FRAME (w)); |
| 12988 | 12988 | ||
| 12989 | /* Don't display if frame is invisible or not yet initialized. */ | 12989 | /* Don't display if frame is invisible or not yet initialized. */ |
| 12990 | if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p) | 12990 | if (!FRAME_REDISPLAY_P (f) || !f->glyphs_initialized_p) |
| 12991 | return; | 12991 | return; |
| 12992 | 12992 | ||
| 12993 | #ifdef HAVE_WINDOW_SYSTEM | 12993 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -13543,7 +13543,7 @@ prepare_menu_bars (void) | |||
| 13543 | TTY frames to be completely redrawn, when there | 13543 | TTY frames to be completely redrawn, when there |
| 13544 | are more than one of them, even though nothing | 13544 | are more than one of them, even though nothing |
| 13545 | should be changed on display. */ | 13545 | should be changed on display. */ |
| 13546 | || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f)))) | 13546 | || (FRAME_REDISPLAY_P (f) && FRAME_WINDOW_P (f)))) |
| 13547 | gui_consider_frame_title (frame); | 13547 | gui_consider_frame_title (frame); |
| 13548 | } | 13548 | } |
| 13549 | } | 13549 | } |
| @@ -14271,12 +14271,14 @@ redisplay_tab_bar (struct frame *f) | |||
| 14271 | frame_default_tab_bar_height = new_height; | 14271 | frame_default_tab_bar_height = new_height; |
| 14272 | } | 14272 | } |
| 14273 | 14273 | ||
| 14274 | /* If new_height or new_nrows indicate that we need to enlarge the | 14274 | /* If new_height or new_nrows indicate that we need to enlarge or |
| 14275 | tab-bar window, we can return right away. */ | 14275 | shrink the tab-bar window, we can return right away. */ |
| 14276 | if (new_nrows > f->n_tab_bar_rows | 14276 | if (new_nrows > f->n_tab_bar_rows |
| 14277 | || (EQ (Vauto_resize_tab_bars, Qgrow_only) | 14277 | || (EQ (Vauto_resize_tab_bars, Qgrow_only) |
| 14278 | && !f->minimize_tab_bar_window_p | 14278 | && !f->minimize_tab_bar_window_p |
| 14279 | && new_height > WINDOW_PIXEL_HEIGHT (w))) | 14279 | && new_height > WINDOW_PIXEL_HEIGHT (w)) |
| 14280 | || (! EQ (Vauto_resize_tab_bars, Qgrow_only) | ||
| 14281 | && new_height < WINDOW_PIXEL_HEIGHT (w))) | ||
| 14280 | { | 14282 | { |
| 14281 | if (FRAME_TERMINAL (f)->change_tab_bar_height_hook) | 14283 | if (FRAME_TERMINAL (f)->change_tab_bar_height_hook) |
| 14282 | FRAME_TERMINAL (f)->change_tab_bar_height_hook (f, new_height); | 14284 | FRAME_TERMINAL (f)->change_tab_bar_height_hook (f, new_height); |
| @@ -16430,7 +16432,7 @@ redisplay_internal (void) | |||
| 16430 | { | 16432 | { |
| 16431 | struct frame *f = XFRAME (frame); | 16433 | struct frame *f = XFRAME (frame); |
| 16432 | 16434 | ||
| 16433 | if (FRAME_VISIBLE_P (f)) | 16435 | if (FRAME_REDISPLAY_P (f)) |
| 16434 | { | 16436 | { |
| 16435 | ++number_of_visible_frames; | 16437 | ++number_of_visible_frames; |
| 16436 | /* Adjust matrices for visible frames only. */ | 16438 | /* Adjust matrices for visible frames only. */ |
| @@ -16572,7 +16574,7 @@ redisplay_internal (void) | |||
| 16572 | && !w->update_mode_line | 16574 | && !w->update_mode_line |
| 16573 | && !current_buffer->clip_changed | 16575 | && !current_buffer->clip_changed |
| 16574 | && !current_buffer->prevent_redisplay_optimizations_p | 16576 | && !current_buffer->prevent_redisplay_optimizations_p |
| 16575 | && FRAME_VISIBLE_P (XFRAME (w->frame)) | 16577 | && FRAME_REDISPLAY_P (XFRAME (w->frame)) |
| 16576 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) | 16578 | && !FRAME_OBSCURED_P (XFRAME (w->frame)) |
| 16577 | && !XFRAME (w->frame)->cursor_type_changed | 16579 | && !XFRAME (w->frame)->cursor_type_changed |
| 16578 | && !XFRAME (w->frame)->face_change | 16580 | && !XFRAME (w->frame)->face_change |
| @@ -16838,14 +16840,20 @@ redisplay_internal (void) | |||
| 16838 | /* Only GC scrollbars when we redisplay the whole frame. */ | 16840 | /* Only GC scrollbars when we redisplay the whole frame. */ |
| 16839 | = f->redisplay || !REDISPLAY_SOME_P (); | 16841 | = f->redisplay || !REDISPLAY_SOME_P (); |
| 16840 | bool f_redisplay_flag = f->redisplay; | 16842 | bool f_redisplay_flag = f->redisplay; |
| 16843 | |||
| 16844 | /* The X error handler may have deleted that frame | ||
| 16845 | before we went back to retry_frame. This must come | ||
| 16846 | before any accesses to f->terminal. */ | ||
| 16847 | if (!FRAME_LIVE_P (f)) | ||
| 16848 | continue; | ||
| 16849 | |||
| 16841 | /* Mark all the scroll bars to be removed; we'll redeem | 16850 | /* Mark all the scroll bars to be removed; we'll redeem |
| 16842 | the ones we want when we redisplay their windows. */ | 16851 | the ones we want when we redisplay their windows. */ |
| 16843 | if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) | 16852 | if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) |
| 16844 | FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); | 16853 | FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); |
| 16845 | 16854 | ||
| 16846 | if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) | 16855 | if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) |
| 16847 | { | 16856 | { |
| 16848 | |||
| 16849 | /* Don't allow freeing images and faces for this | 16857 | /* Don't allow freeing images and faces for this |
| 16850 | frame as long as the frame's update wasn't | 16858 | frame as long as the frame's update wasn't |
| 16851 | completed. This prevents crashes when some Lisp | 16859 | completed. This prevents crashes when some Lisp |
| @@ -16870,7 +16878,7 @@ redisplay_internal (void) | |||
| 16870 | if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook) | 16878 | if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook) |
| 16871 | FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); | 16879 | FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); |
| 16872 | 16880 | ||
| 16873 | if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) | 16881 | if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) |
| 16874 | { | 16882 | { |
| 16875 | /* If fonts changed on visible frame, display again. */ | 16883 | /* If fonts changed on visible frame, display again. */ |
| 16876 | if (f->fonts_changed) | 16884 | if (f->fonts_changed) |
| @@ -16976,7 +16984,7 @@ redisplay_internal (void) | |||
| 16976 | } | 16984 | } |
| 16977 | } | 16985 | } |
| 16978 | } | 16986 | } |
| 16979 | else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf)) | 16987 | else if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) |
| 16980 | { | 16988 | { |
| 16981 | sf->inhibit_clear_image_cache = true; | 16989 | sf->inhibit_clear_image_cache = true; |
| 16982 | displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); | 16990 | displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); |
| @@ -17027,7 +17035,7 @@ redisplay_internal (void) | |||
| 17027 | unrequest_sigio (); | 17035 | unrequest_sigio (); |
| 17028 | STOP_POLLING; | 17036 | STOP_POLLING; |
| 17029 | 17037 | ||
| 17030 | if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf)) | 17038 | if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) |
| 17031 | { | 17039 | { |
| 17032 | if (hscroll_retries <= MAX_HSCROLL_RETRIES | 17040 | if (hscroll_retries <= MAX_HSCROLL_RETRIES |
| 17033 | && hscroll_windows (selected_window)) | 17041 | && hscroll_windows (selected_window)) |
| @@ -17126,7 +17134,7 @@ redisplay_internal (void) | |||
| 17126 | 17134 | ||
| 17127 | FOR_EACH_FRAME (tail, frame) | 17135 | FOR_EACH_FRAME (tail, frame) |
| 17128 | { | 17136 | { |
| 17129 | if (XFRAME (frame)->visible) | 17137 | if (FRAME_REDISPLAY_P (XFRAME (frame))) |
| 17130 | new_count++; | 17138 | new_count++; |
| 17131 | } | 17139 | } |
| 17132 | 17140 | ||
| @@ -33262,7 +33270,7 @@ display_and_set_cursor (struct window *w, bool on, | |||
| 33262 | windows and frames; in the latter case, the frame or window may | 33270 | windows and frames; in the latter case, the frame or window may |
| 33263 | be in the midst of changing its size, and x and y may be off the | 33271 | be in the midst of changing its size, and x and y may be off the |
| 33264 | window. */ | 33272 | window. */ |
| 33265 | if (! FRAME_VISIBLE_P (f) | 33273 | if (! FRAME_REDISPLAY_P (f) |
| 33266 | || vpos >= w->current_matrix->nrows | 33274 | || vpos >= w->current_matrix->nrows |
| 33267 | || hpos >= w->current_matrix->matrix_w) | 33275 | || hpos >= w->current_matrix->matrix_w) |
| 33268 | return; | 33276 | return; |
| @@ -33423,7 +33431,7 @@ gui_update_cursor (struct frame *f, bool on_p) | |||
| 33423 | void | 33431 | void |
| 33424 | gui_clear_cursor (struct window *w) | 33432 | gui_clear_cursor (struct window *w) |
| 33425 | { | 33433 | { |
| 33426 | if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p) | 33434 | if (FRAME_REDISPLAY_P (XFRAME (w->frame)) && w->phys_cursor_on_p) |
| 33427 | update_window_cursor (w, false); | 33435 | update_window_cursor (w, false); |
| 33428 | } | 33436 | } |
| 33429 | 33437 | ||
diff --git a/src/xfns.c b/src/xfns.c index 668f711bdb5..1cc5aec1eb4 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -4741,6 +4741,7 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 4741 | #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */ | 4741 | #endif /* USE_LUCID && USE_TOOLKIT_SCROLL_BARS */ |
| 4742 | f->output_data.x->white_relief.pixel = -1; | 4742 | f->output_data.x->white_relief.pixel = -1; |
| 4743 | f->output_data.x->black_relief.pixel = -1; | 4743 | f->output_data.x->black_relief.pixel = -1; |
| 4744 | f->output_data.x->visibility_state = VisibilityFullyObscured; | ||
| 4744 | 4745 | ||
| 4745 | fset_icon_name (f, gui_display_get_arg (dpyinfo, | 4746 | fset_icon_name (f, gui_display_get_arg (dpyinfo, |
| 4746 | parms, | 4747 | parms, |
diff --git a/src/xterm.c b/src/xterm.c index 8e0a97899fe..1eef8e7a724 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -21743,9 +21743,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21743 | 21743 | ||
| 21744 | case VisibilityNotify: | 21744 | case VisibilityNotify: |
| 21745 | f = x_top_window_to_frame (dpyinfo, event->xvisibility.window); | 21745 | f = x_top_window_to_frame (dpyinfo, event->xvisibility.window); |
| 21746 | if (f && (event->xvisibility.state == VisibilityUnobscured | 21746 | |
| 21747 | || event->xvisibility.state == VisibilityPartiallyObscured)) | 21747 | if (f) |
| 21748 | SET_FRAME_VISIBLE (f, 1); | 21748 | FRAME_X_OUTPUT (f)->visibility_state = event->xvisibility.state; |
| 21749 | 21749 | ||
| 21750 | goto OTHER; | 21750 | goto OTHER; |
| 21751 | 21751 | ||
diff --git a/src/xterm.h b/src/xterm.h index 832ffc172b9..f06e1ec5bc6 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -1290,6 +1290,11 @@ struct x_output | |||
| 1290 | strictly an optimization to avoid extraneous synchronizing in | 1290 | strictly an optimization to avoid extraneous synchronizing in |
| 1291 | some cases. */ | 1291 | some cases. */ |
| 1292 | int root_x, root_y; | 1292 | int root_x, root_y; |
| 1293 | |||
| 1294 | /* The frame visibility state. This starts out | ||
| 1295 | VisibilityFullyObscured, but is set to something else in | ||
| 1296 | handle_one_xevent. */ | ||
| 1297 | int visibility_state; | ||
| 1293 | }; | 1298 | }; |
| 1294 | 1299 | ||
| 1295 | enum | 1300 | enum |
| @@ -1408,6 +1413,11 @@ extern void x_mark_frame_dirty (struct frame *f); | |||
| 1408 | /* And its corresponding visual info. */ | 1413 | /* And its corresponding visual info. */ |
| 1409 | #define FRAME_X_VISUAL_INFO(f) (&FRAME_DISPLAY_INFO (f)->visual_info) | 1414 | #define FRAME_X_VISUAL_INFO(f) (&FRAME_DISPLAY_INFO (f)->visual_info) |
| 1410 | 1415 | ||
| 1416 | /* Whether or not the frame is visible. Do not test this alone. | ||
| 1417 | Instead, use FRAME_REDISPLAY_P. */ | ||
| 1418 | #define FRAME_X_VISIBLE(f) (FRAME_X_OUTPUT (f)->visibility_state \ | ||
| 1419 | != VisibilityFullyObscured) | ||
| 1420 | |||
| 1411 | #ifdef HAVE_XRENDER | 1421 | #ifdef HAVE_XRENDER |
| 1412 | #define FRAME_X_PICTURE_FORMAT(f) FRAME_DISPLAY_INFO (f)->pict_format | 1422 | #define FRAME_X_PICTURE_FORMAT(f) FRAME_DISPLAY_INFO (f)->pict_format |
| 1413 | #define FRAME_X_PICTURE(f) ((f)->output_data.x->picture) | 1423 | #define FRAME_X_PICTURE(f) ((f)->output_data.x->picture) |