1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203
|
;; -*- Syntax: Emacs-Lisp; Mode: emacs-lisp -*-
;;
;; Per mode and per buffer mouse tracking with highlighting
;;
;; Copyright (C) 1992, 1993 by Guido Bosch <Guido.Bosch@loria.fr>
;; This file is written in GNU Emacs Lisp, It is a part of XEmacs.
;; The software contained in this file 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 2, 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; see the file COPYING. If not, write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
;;
;;; Synched up with: Not in FSF.
;; Please send bugs and comments to Russell.Ritchie@gssec.bt.co.uk or
;; tlp00@spg.amdahl.com.
;;
;; <DISCLAIMER>
;; This program is still under development. Neither the author nor any
;; of the maintainers accepts responsibility to anyone for the consequences of
;; using it or for whether it serves any particular purpose or works
;; at all.
; Change History
; Revision 3.16 Fri Jun 28 13:01:12 1996 ritchier@msc.ie
; Stop multiple highlighting lossage with 19.14 release.
; Revision 3.15 Thu Feb 15 14:26:34 GMT 1996 Russell.Ritchie@gssec.bt.co.uk
; lisp-interaction-popup-menu => lisp-interaction-mode-popup-menu,
; emacs-lisp-popup-menu => emacs-lisp-mode-popup-menu.
; Revision 3.14 Tue Nov 14 11:14:38 GMT 1995 Russell.Ritchie@gssec.bt.co.uk
; Made nil the default value for mode-motion-focus-on-window. Too many people
; hate it when the cursor warps into Dired and GNUS buffers because some
; window managers auto-raise the window with keyboard focus with predictably
; nauseous results.
; Revision 3.13 Thu Sep 14 10:30:04 1995 Russell.Ritchie@gssec.bt.co.uk
; Fix the `spontaneous scrolling' problem (at last). It's funny how
; easy things are once you actually understand the issues involved.
; As ever, what we sought was the right question...
; Revision 3.12 Wed Jul 12 11:30:43 1995 Russell.Ritchie@gssec.bt.co.uk
; Track `don't highlight non-file lines in dired buffers' functionality (in a
; pretty tasteless manner if I say so myself :-)).
; Revision 3.11 Fri Jul 7 16:26:56 1995 Russell.Ritchie@gssec.bt.co.uk
; Minor extent detaching bug fix.
; Revision 3.10 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk
; Quiet, faster, non-interactive initialistion, mild list-motion-handlers
; chrome and minor formatting clean-ups.
; Revision 3.9 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk
; Fixed the `mouse-motion whilst reading filename in minibuffer auto-ftp' bug.
; Revision 3.8 Thus Mar 23 1995 tlp00@spg.amdahl.com
; added in menu controls from paquette@atomas.crim.ca
; re-added minibuffer support (from 3.5)
;
; Revision 3.7 Tue Feb 21 11:06:38 1995 Russell.Ritchie@gssec.bt.co.uk
; Extended mode-motion+-religion and made the defaulting frame-buffer aware.
; Reworked and added new mode-motion-handlers.
; Doc string clean up.
; Fixed unintentional frame/screen reversion.
; Revision 3.6 Mon Feb 20 11:46:32 1995 Russell.Ritchie@gssec.bt.co.uk
; Made mouse tracking use mode-motion-hook for better integration with
; the default mouse-motion system (help-echo and friends now work).
; Revision 3.5 1995/02/16 13:40:00 tlp00@spg.amdahl.com
; fixed sporatic scroll bug
; added M-button2 binding for mode-motion-copy
;
; Revision 3.4 1995/02/14 14:30:15 Russell.Ritchie@gssec.bt.co.uk
; Small code cleanups: let* -> let, duplicate defvars.
; Chromed list-motion-handlers a little.
; Added variable mode-motion+-religion for easy choice twixt underline & bold.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;tlp00 changes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; tlp00@spg.amdahl.com 2/11/93
; modified mode-motion-track-pointer to move cursor cross windows
; renamed mode-motion-delete to mode-motion-kill to follow kill
; convention
; mode-motion-highlight-with-handler to put cursor at beginning of line
; follow operations.
; mode-motion-copy/delete and mode-motion-kill to position cursor at
; delete point start. Also set this-command to avoid appends
; set mode-motion-extent priority to 1, so it will override font-lock
; changed default handlers for buffer-mode, c-mode, dired-mode, added occur
; and compilation mode.
; fixed bug in minibuffer-selection-boundaries where C-g was leaving the wrong
; syntax table.
; added support for pending-delete.
; adds the copy/delete motion-extent to the clipboard even if kill-hooks is nil.
;
; Revision 3.3 1995/02/13 tlp00@spg.amdahl.com
; merged Russell.Ritchie@gssec.bt.co.uk versions with molli/bosch versions
; renamed versioning 3.0+ for molli/bosch versions.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Russell Ritchie changes;;;;;;;;;;;;;;;;;;;;;;;;
; !Log: mode-motion+.el,v !
; Revision 2.14.R 1994/09/09 10:19:18 rieke@darmstadt.gmd.de
; Merged in my changes to support motion-gray. This needs a file
; named "gray1.xbm" in your data-directory (etc) like the following.
; -------------------------------snip--------------------------
; #define bg2_width 16
; #define bg2_height 16
; static char bg2_bits[] = {
; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00};
; -------------------------------snip--------------------------
; This one looks good on SUN 19'' screens with 10x20 font,
; black foreground and khaki background.
; To use the gray-handlers instead of the underline-handlers
; include the following into your .emacs:
; (set-mode-motion-handler 'emacs-lisp-mode 'gray-thing)
; (set-mode-motion-handler 'lisp-interaction-mode 'gray-thing)
; (set-mode-motion-handler 'c++-mode 'gray-c)
; (set-mode-motion-handler 'c-mode 'gray-c)
; (set-mode-motion-handler 'tcl-mode 'gray-tcl)
; (set-mode-motion-handler 'dired-mode 'gray-line@)
; (set-mode-motion-handler 'gnus-group-mode 'gray-vline@)
; (set-mode-motion-handler 'gnus-summary-mode 'gray-vline@)
; (set-mode-motion-handler 'texinfo-mode 'gray-Texinfo)
; (setq default-motion-handler (find-motion-handler 'gray-thing))
;
;
; Revision 2.13.R 1994/08/08 19:47:34 Russell.Ritchie@gssec.bt.co.uk
; Made default handler be underline-thing, as most bold fonts seem to
; be greater in height than their corresponding normal versions,
; causing irritating screen flicker.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Molli/bosch changes;;;;;;;;;;;;;;;;;;;;;;;;
;
; Revision 3.2 1994/09/28 15:14:29 molli
; add "(set-mode-motion-handler 'latex-mode 'raise-LaTeX)". Barry
; Waraw's C/C++ mode is now changed to cc-mode ...
;
; Revision 3.1 1994/09/28 15:10:36 molli
; Initial revision
;
; Revision 2.15 1993/11/18 08:13:28 bosch
; Constant `mode-motion+-version' added.
; Minor bug fix in `tcl-forward-sexp1'.
;
; Revision 2.14 1993/10/29 20:04:59 bosch
; Minibuffer name matching improved. Made `tcl-boundaries' smarter by
; use of new function `tcl-forward-sexp1'. `tcl-commands' list updated
; -- should be complete now. A message is printed if the syntax scanner
; matched or failed for known tcl/tk commands. Separated `tcl-commands'
; from `tk-commands' -- `tk-commands' not yet complete. New motion
; handler `raise-LaTeX' added, for tex-mode.
;
; Revision 2.13 1993/10/08 09:43:00 bosch
; New user option `mode-motion-setup-cut-and-paste-bindings'. Function
; `mode-motion-copy/delete' now takes into account the primary and the
; motion selection.
;
; Revision 2.12 1993/10/08 09:08:46 bosch
; Avoid highlighting empty lines, even if
; `mode-motion-highlight-lines-when-behind' is non-nil.
; Revision 2.12 1994/07/07 18:33:38 Russell.Ritchie@gssec.bt.co.uk
; Made list-motion-handlers and mode-motion-set-handler work in lemacs-19.10.
;
; Revision 2.11 1993/09/20 08:29:15 bosch
; Code reorganized: variables declared before used.
; Compatibility hack patched again.
;
; Revision 2.10 1993/09/17 18:50:33 bosch
; Bug in the compatibility hack fixed. Call to `make-cursor' replaced by
; `x-pointer-cache'. Compatibility hack for Lemacs 19.8 removed. Tcl
; motion handler improved (needs still some work).
;
; Revision 2.9 1993/09/15 17:52:53 bosch
; Compatibility patch for Lucid Emacs 19.8. tcl motion handler added.
;
; Revision 2.8 1993/08/27 15:17:07 bosch
; Select window conflict between motion handlers and process filters
; resolved by using `enqueue-eval-event' for selecting a different
; window (functions `mode-motion-track-pointer' and
; `mode-motion-highlight-with-handler' modified). This fixes the nasty
; bug that made GNUS hanging during NNTP activity while the mouse was
; moved.
;
; Revision 2.7 1993/08/27 12:50:10 bosch
; TeX and LaTeX motion handler generalized. Motion handler
; `highlight-Texinfo' added.
;
; Revision 2.6 1993/06/24 11:58:52 bosch
; Mode motion+ support for pcl-cvs added. #undef syntax for C added.
;
; Revision 2.5 1993/06/09 12:04:31 bosch
; Delivery motion handlers for `c++-c-mode', `gnus-group-mode', and
; `gnus-summary-mode' added. Mode motion commands bound to copy/cut/past
; keys for Sun keyboards (f16, f18, f20). Comment added.
;
; Revision 2.4 1993/02/15 12:59:47 bosch
; Modifications sent by Tibor Polgar integrated:
; Optional parameter added to `mode-motion-copy/delete'. User option
; `mode-motion-focus-on-window' added. It controls window selection for
; the motion handlers. Minor changes of the delivery motion handlers.
;
; Revision 2.3 1993/02/04 18:10:09 bosch
; User option `mode-motion-minibuffer-completion' added. It controls
; the minibuffer completion highlighting.
;
; Revision 2.2 1993/01/27 13:08:12 bosch
; Improved clearing of `sticky' mode-motion-extents when leaving screen
; or buffer. Function `mode-motion-clear-extent' added.
; Highlight line mouse cursor is behind.
; `mode-motion-highlight-with-handler' now takes an event as argument.
; Cut and paste functions renamed and rewritten. Now they are called:
; `mode-motion-move', `mode-motion-delete', `mode-motion-copy',
; `mode-motion-copy-as-kill'. Bug fixes in the C scanner stuff.
; Motion handler `underline-c' added.
;
; Revision 2.1 1993/01/19 18:29:58 bosch
; Scanner and motion handler for C syntax added.
; Function `set-default-motion-handler' added.
; Minor improvements on the `list-motion-handlers' interface done.
; Minor bug fixes.
;
; Revision 2.0 1993/01/14 19:17:29 bosch
; Lot of things rewritten and reorganized. This version fits in only
; one file (beside the required package thing.el).
;
; New basic features are:
; - buffer, mode and default motion handlers
; - easy composition of own motion handlers
; - listing of motion handlers in tabular form
; - menu interface for changing motion handlers
; - only two elisp files: mode-motion+.el, thing.el
;
(require 'thing)
(require 'mode-motion)
(defconst mode-motion+-version "3.16")
;;; This file defines a set of mouse motion handlers that do some
;;; highlighting of the text when the mouse moves over.
;;; An exhaustive list of the motion handlers defined in this file may be
;;; obtained with M-x list-motion-handlers.
;;; User Options and their Custommisation
;;;
;;; Mode-motion+ provides four user options, defined beyond. See their
;;; documentation string to know what they are good for. If you want
;;; to modify their default values, just setq them in your ~/.emacs.
(defvar mode-motion+-religion nil ; Initialised in mode-motion-init.
"*Default highlight religion: one of bold, gray, highlight, invert or underline.
Unless you setq this otherwise, it defaults to underline when
(x-display-color-p) is non-nil and invert otherwise.
Setting it to 'highlight should cause mode-motion+ extents to be
indistinguishable from any other type of highlighted extent which may or may
not be advisable, depending on your point of view.")
(defvar mode-motion-highlight-lines-when-behind t
"*If non-nil highlight the whole line if the mouse is past the end.")
(defvar mode-motion-focus-on-window nil
"*Controls whether moving the mouse into another window selects this window.
The following values are possible:
nil - Window selection isn't influenced at all by mode motion.
t - Window selection always follows the mouse cursor. Copying motion
active regions doesn't work any longer between different buffers.
any other - window selection follows the mouse cursor if the motion handler
of the buffer under the mouse has the follow-point property set.
Useful for selecting line mode buffers just by moving the mouse
inside in order to execute commands there (VM summary,
GNUS Group and Subject, DIRED, Buffer menu etc.)")
(defvar mode-motion-setup-cut-and-paste-bindings t
"*If non-nil, bind commands to the Copy, Paste and Cut keys.")
;; Options sub-menu for mode-motion+
(defvar mode-motion+-options-menu
'("Motion Highlighting"
"For Current Buffer"
"---"
["None"
(progn
(set-buffer-motion-handler (current-buffer) 'no-thing)
(mode-motion-clear-extent))
:style radio
:selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
'no)
:active (mode-motion+-active-p)]
["Bold"
(progn
(modify-buffer-motion-handler (current-buffer) 'bold))
:style radio
:selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
'bold)
:active (mode-motion+-active-p)]
["Underline"
(progn
(modify-buffer-motion-handler (current-buffer) 'underline))
:style radio
:selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
'underline)
:active (mode-motion+-active-p)]
["Gray"
(progn
(modify-buffer-motion-handler (current-buffer) 'gray))
:style radio
:selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
'gray)
:active (mode-motion+-active-p)]
["Highlight"
(progn
(modify-buffer-motion-handler (current-buffer) 'highlight))
:style radio
:selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
'highlight)
:active (mode-motion+-active-p)]
["Invert"
(progn
(modify-buffer-motion-handler (current-buffer) 'invert))
:style radio
:selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
'invert)
:active (mode-motion+-active-p)]
"---"
"For Current Mode"
"---"
["None"
(progn
(set-mode-motion-handler major-mode 'no-thing)
(mode-motion-clear-extent))
:style radio
:selected (eq (mode-motion+-mode-handler-religion major-mode) 'no)
:active (mode-motion+-active-p)]
["Bold"
(progn
(modify-mode-motion-handler major-mode 'bold))
:style radio
:selected (eq (mode-motion+-mode-handler-religion major-mode) 'bold)
:active (mode-motion+-active-p)]
["Underline"
(progn
(modify-mode-motion-handler major-mode 'underline))
:style radio
:selected (eq (mode-motion+-mode-handler-religion major-mode) 'underline)
:active (mode-motion+-active-p)]
["Gray"
(progn
(modify-mode-motion-handler major-mode 'gray))
:style radio
:selected (eq (mode-motion+-mode-handler-religion major-mode) 'gray)
:active (mode-motion+-active-p)]
["Highlight"
(progn
(modify-mode-motion-handler major-mode 'highlight))
:style radio
:selected (eq (mode-motion+-mode-handler-religion major-mode) 'highlight)
:active (mode-motion+-active-p)]
["Invert"
(progn
(modify-mode-motion-handler major-mode 'invert))
:style radio
:selected (eq (mode-motion+-mode-handler-religion major-mode) 'invert)
:active (mode-motion+-active-p)]
"---"
"For All"
"---"
["None"
(progn
(setq mode-motion+-religion 'no)
(mode-motion-init-handlers-according-to-religion 'force)
(mode-motion-clear-extent))
:style radio
:selected (eq mode-motion+-religion 'no)
:active (mode-motion+-active-p)]
["Bold"
(progn
(setq mode-motion+-religion 'bold)
(mode-motion-init-handlers-according-to-religion 'force))
:style radio
:selected (eq mode-motion+-religion 'bold)
:active (mode-motion+-active-p)]
["Underline"
(progn
(setq mode-motion+-religion 'underline)
(mode-motion-init-handlers-according-to-religion 'force))
:style radio
:selected (eq mode-motion+-religion 'underline)
:active (mode-motion+-active-p)]
["Gray"
(progn
(setq mode-motion+-religion 'gray)
(mode-motion-init-handlers-according-to-religion 'force))
:style radio
:selected (eq mode-motion+-religion 'gray)
:active (mode-motion+-active-p)]
["Highlight"
(progn
(setq mode-motion+-religion 'highlight)
(mode-motion-init-handlers-according-to-religion 'force))
:style radio
:selected (eq mode-motion+-religion 'highlight)
:active (mode-motion+-active-p)]
["Invert"
(progn
(setq mode-motion+-religion 'invert)
(mode-motion-init-handlers-according-to-religion 'force))
:style radio
:selected (eq mode-motion+-religion 'invert)
:active (mode-motion+-active-p)]
"---"
["Minibuffer highlighting" (setq mode-motion-use-minibuffer-motion-handler
(not mode-motion-use-minibuffer-motion-handler))
:style toggle :selected mode-motion-use-minibuffer-motion-handler]
["Customize..."
(list-motion-handlers)
t
;; nil
]
["Revert Customization"
(call-interactively 'mode-motion+-motion-hook-revert)
(and (boundp 'mode-motion+-previous-hook) mode-motion+-previous-hook)
])
"Menu for changing mode-motion+ religion and other things.")
(defun mode-motion+-active-p ()
(cond ((symbolp mode-motion-hook)
(eq mode-motion-hook 'mode-motion+-highlight))
((listp mode-motion-hook)
(memq 'mode-motion+-highlight mode-motion-hook))
(t nil)))
(defun mode-motion+-buffer-handler-religion (buffer)
(let* ((current-handler-name (symbol-name (motion-handler-name
(get-current-motion-handler))))
(religion-name (substring current-handler-name
0
(string-match "-" current-handler-name))))
(intern-soft religion-name)))
(defun mode-motion+-mode-handler-religion (buffer)
(let* ((mode-handler (or (get major-mode 'mode-motion-handler)
default-motion-handler))
(current-handler (symbol-name (motion-handler-name mode-handler)))
(religion (substring current-handler
0
(string-match "-" current-handler))))
(intern-soft religion)))
(defun modify-buffer-motion-handler (buffer religion)
(let* ((current-handler (symbol-name (motion-handler-name
(get-current-motion-handler))))
(suffix (substring current-handler
(string-match "-" current-handler))))
(set-buffer-motion-handler buffer
(intern-soft (concat (symbol-name religion)
suffix)))))
(defun modify-mode-motion-handler (mode religion)
(let* ((mode-handler (or (get major-mode 'mode-motion-handler)
default-motion-handler))
(current-handler (symbol-name (motion-handler-name mode-handler)))
(suffix (substring current-handler
(string-match "-" current-handler))))
(set-mode-motion-handler mode (intern-soft (concat (symbol-name
religion)
suffix)))))
;;;; This does not work. I would like to be able to modify in-place
;;;; the non-selectable items, but I don't know how.
;;;; --paquette, Wed Mar 8 23:32:32 1995 (Marc Paquette)
;;; Sensitize the mode motion+ options submenu, a la
;;; sensitize-file-and-edit-menus-hook.
(defun mode-motion+-sensitize-options-menu-hook ()
"Hook function that will adjust title items in the mode-motion+ submenu in Options"
(let* ((mm+-menu (cdr (car (find-menu-item
current-menubar
'("Options" "Motion Highlighting")))))
(buffer-item (find-menu-item mm+-menu '("For Current Buffer")))
(mode-item (find-menu-item mm+-menu '("For Current Mode"))))
(setcar buffer-item (format "For Buffer `%s'" (buffer-name nil)))
(setcar mode-item (format "For Mode `%s'" major-mode))
nil))
;;(add-hook 'activate-menubar-hook 'mode-motion+-sensitize-options-menu-hook)
;; Motion Handler Format:
;;
;; A motion handler is vector with the following format
;; [<name> - a symbol
;; <region computing function> - a function or name of function
;; that returns (<startpos> . <endpos>)
;; or nil.
;; <face or face name> - as it says ...
;; <highlight-p> - non-nil means that the motion extent
;; will be highlighted using the function
;; `highlight-extent'
;; <follow-point-p> - non-nil means that point will follow the
;; mouse motion.
;; ]
;; accessor functions
(defsubst motion-handler-name (handler) (aref handler 0))
(defsubst motion-handler-boundary-function (handler) (aref handler 1))
(defsubst motion-handler-face (handler) (aref handler 2))
(defsubst motion-handler-highlight (handler) (aref handler 3))
(defsubst motion-handler-follow-point (handler) (aref handler 4))
;; modifier functions
(defsubst set-motion-handler-boundary-function (handler x) (aset handler 1 x))
(defsubst set-motion-handler-face (handler x) (aset handler 2 x))
(defsubst set-motion-handler-highlight (handler x) (aset handler 3 x))
(defsubst set-motion-handler-follow-point (handler x) (aset handler 4 x))
;; Internal global variables
(defvar motion-handler-alist ()
"Alist with entries of the form \(<name> . <handler>\).")
;; Minibuffer motion handler
(defvar mode-motion-use-minibuffer-motion-handler t
"*Enable mousable highlighting when the minibuffer is active. When false only extents with the
highlight property are selectable (*Completion*)")
(defvar mode-motion-extent nil)
(make-variable-buffer-local 'mode-motion-extent)
(defvar buffer-motion-handler nil)
(make-variable-buffer-local 'buffer-motion-handler)
(defvar mode-motion-last-extent nil "The last used mode motion extent.")
(defvar default-motion-handler nil) ; Initialised in mode-motion-init.
;; Creation of motion handlers
(defun find-motion-handler (name)
(or (symbolp name)
(setq name (intern-soft name)))
(cdr (assq name motion-handler-alist)))
;; internal motion handler creator
(defsubst make-motion-handler-internal
(name boundary-function face highlight follow-cursor)
(vector name boundary-function (get-face face) highlight follow-cursor))
(defun make-motion-handler
(name boundary-function &optional face highlight follow-cursor)
"Create a motion handler named NAME (a symbol or string) using REGION-FUNCTION.
REGION-FUNCTION is the function that computes the region to be highlighted.
Optional arguments are:
FACE: A face or face name to be used to highlight the region computed
by REGION-FUNCTION. 'default is the default.
HIGHLIGHT: Flag that indicates whether the highlight attribute of the
mode-motion-extent should be set or not. If FACE is the default face,
HIGHLIGHT defaults to t, otherwise to nil.
FOLLOW-CURSOR: Flag that indicates whether the cursor should follow
the mouse motion. Default is nil."
;; required arguments
(or name (error "motion handler name required."))
(or (symbolp name)
(stringp name)
(error "motion handler name must be a string or symbol: %s" name))
(or boundary-function
(error "motion handler region function required."))
(or (fboundp boundary-function)
(error "not a function: %s." boundary-function))
;; defaults
(or face (setq face 'default))
;; store the mode motion handler on the 'mode-motion-handler property of
;; its name symbol
(let ((old-handler (cdr (assq name motion-handler-alist)))
new-handler)
(if old-handler
(progn
(set-motion-handler-boundary-function old-handler boundary-function)
(set-motion-handler-face old-handler (get-face face))
(set-motion-handler-highlight old-handler highlight)
(set-motion-handler-follow-point old-handler follow-cursor))
(setq motion-handler-alist
(cons (cons name
(setq new-handler (make-motion-handler-internal
name
boundary-function
(get-face face)
highlight
follow-cursor)))
motion-handler-alist)))
(or old-handler new-handler)))
(defvar list-motion-handlers-buffer-to-customize nil
"Name of buffer from where list-motion-handlers was called.")
(make-variable-buffer-local 'list-motion-handlers-buffer-to-customize)
(defvar list-motion-handlers-buffer-mode nil
"Name of mode of buffer from where list-motion-handlers was called.")
(make-variable-buffer-local 'list-motion-handlers-buffer-mode)
;; Listing available motion handlers in tabular form.
(defvar basic-motion-handlers (list 'mode-motion-highlight-line
'mode-motion-highlight-word
'mode-motion-highlight-symbol
'mode-motion-highlight-sexp)
"The basic motion handlers provided by the underlying XEmacs.")
(defun list-motion-handlers ()
"Display a list of available motion handlers.
The listing is in tabular form and contains the following columns:
NAME: the motion handlers name,
BOUNDARY FUNCTION: the name of the funtion used to compute the text
highlighted by the motion handler,
FACE: the face used to highlight the text.
Additionally, the following flags are used at the beginning of each line:
`*' Marks the motion handler current to the buffer this functions was called
from.
`H' Force highlighting of the selected text.
`F' Make point follow the mouse cursor as it moves."
(interactive)
(let ((current-handler (get-current-motion-handler))
(buffer (current-buffer))
(buffer-mode major-mode)
(bmmh (if (symbolp mode-motion-hook)
(car (memq mode-motion-hook basic-motion-handlers))
(if (and (listp mode-motion-hook)
(equal 1 (length mode-motion-hook)))
(car (memq (car mode-motion-hook)
basic-motion-handlers))))))
(save-excursion
(with-output-to-temp-buffer "*Mouse Motion Handlers*"
(let ((truncate-lines t))
(set-buffer "*Mouse Motion Handlers*")
(setq list-motion-handlers-buffer-to-customize buffer)
(setq list-motion-handlers-buffer-mode buffer-mode)
(let ((pos1 5)
(pos2 25)
(pos3 50)
(handlers
(sort
(mapcar 'cdr motion-handler-alist)
'(lambda (x y)
(string<
(symbol-name (motion-handler-boundary-function x))
(symbol-name (motion-handler-boundary-function y)))))))
(if bmmh
(let ((i 1)
(fw (frame-width)))
(while (< i fw)
(princ "*")
(setq i (1+ i)))
(princ "\nNote: this buffer is not using mode-motion+.\n\n")
(princ "It's using the `")
(princ bmmh)
(princ "' motion handler which claims it's:\n")
(insert (documentation bmmh))
(princ "\nSetting this motion handler will be irrevocable from this interface\n(but only for duration of this XEmacs session).\n")
(setq i 1)
(while (< i fw)
(princ "*")
(setq i (1+ i)))
(terpri)))
(princ " NAME BOUNDARY FUNCTION FACE\n")
(princ " ---- ----------------- ----\n")
(mapcar
#'(lambda (handler)
(let ((line-start (point)))
(princ (if (and (not bmmh) (eq handler current-handler))
"*" " "))
(princ (if (eq handler default-motion-handler) "D" " "))
(princ (if (motion-handler-highlight handler) "H" " "))
(princ (if (motion-handler-follow-point handler) "F" " "))
(indent-to-column pos1 1)
(princ (motion-handler-name handler))
(indent-to-column pos2 1)
(princ (motion-handler-boundary-function handler))
(indent-to-column pos3)
(let ((face-start (point)))
(princ (face-name (motion-handler-face handler)))
(let ((line-extent (make-extent line-start face-start))
(face-extent (make-extent face-start (point))))
(set-extent-face face-extent
(motion-handler-face handler))
(set-extent-property
face-extent
'mode-motion-handler (motion-handler-name handler))
(set-extent-property
line-extent
'mode-motion-handler (motion-handler-name handler))
(set-extent-property line-extent 'highlight t)))
(terpri)))
handlers)
(princ (format "
Flags: `D' the default motion handler
`H' handler with highlighting
`F' handler with `following' property
`*' the motion handler of buffer \"%s\""
list-motion-handlers-buffer-to-customize))))
(local-set-key 'button3 'mode-motion-set-handler)
(setq buffer-read-only t)))))
(defun mode-motion-set-handler (event)
(interactive "@e")
(let* ((handler (or (extent-property
(extent-at (event-point event) (current-buffer)
'mode-motion-handler)
'mode-motion-handler)
(error "Click on highlighted line to select a handler")))
(menu (list
(format "Make `%s' the Motion Handler of :" handler)
(vector (format "Buffer %s"
list-motion-handlers-buffer-to-customize)
(` (set-buffer-motion-handler
'(, list-motion-handlers-buffer-to-customize)
'(, handler))) t)
(vector "Another Buffer..."
(` (motion-handler-list-set-buffer-handler
'(, handler))) t)
"---"
(vector (format "Mode %s"
list-motion-handlers-buffer-mode)
(` (progn
(set-mode-motion-handler
'(, list-motion-handlers-buffer-mode)
'(, handler))
(save-excursion
(mapcar
(function
(lambda (buf)
(set-buffer buf)
(and (eq
'(, list-motion-handlers-buffer-mode)
major-mode)
(mode-motion+-hook-install buf t))))
(buffer-list))))) t)
(vector "Another Mode..."
(` (motion-handler-list-set-mode-handler
'(, handler))) t)
"---"
(vector "Default Motion Handler"
(` (set-default-motion-handler '(, handler))) t))))
(popup-menu menu)))
(defun motion-handler-list-set-buffer-handler (handler)
(let ((buffer (read-buffer-name
(format "Make `%s' the motion handler of buffer: " handler)
(buffer-name list-motion-handlers-buffer-to-customize))))
(set-buffer-motion-handler buffer handler)
(save-excursion
(set-buffer buffer)
(and (not (cond ((listp mode-motion-hook)
(memq 'mode-motion+-highlight mode-motion-hook))
((symbolp mode-motion-hook)
(eq 'mode-motion+-highlight mode-motion-hook))
(t t)))
(y-or-n-p (format "Augment the default mode motion hook for `%s'? "
(buffer-name nil)))
(mode-motion+-hook-install buffer t)))))
(defvar mode-motion+-previous-hook nil
"Value of previous `mode-motion-hook' in current buffer.")
(make-variable-buffer-local 'mode-motion+-previous-hook)
(defun motion-handler-list-set-mode-handler (handler)
(let ((mode (intern (completing-read
(format "Make `%s' the motion handler of mode: " handler)
obarray
'fboundp
t
(symbol-name list-motion-handlers-buffer-mode)))))
(set-mode-motion-handler mode handler)
(save-excursion
(mapcar (function
(lambda (buf)
(set-buffer buf)
(and (eq mode major-mode)
(mode-motion+-hook-install buf t))))
(buffer-list)))))
(defun mode-motion+-hook-install (&optional buffer remove-highlight-line-p)
"Add `mode-motion+-highlight' to the BUFFER `mode-motion-hook'.
If the optional second arg REMOVE-HIGHLIGHT-LINE-P is t, remove
`mode-motion-highlight-line' from `mode-motion-hook'.
See `mode-motion+-hook-uninstall' for reverting this operation."
(interactive "bInstall mode-motion+ hook for buffer :
XRemove highlight-line from hook ? :")
;; Check for the mode-motion-hook value to make sure it's under
;; the control of mode-motion+.
;; The reasonning here is that if the user went trough the hassles
;; of list-motion-handlers (or if he's calling this directly from
;; his .emacs) , he is prepared to give up on the current
;; mode-motion-hook.
;; However, we keep the previous hook value in a buffer-local
;; variable: it will be then possible to revert to the old motion
;; handling behavior with `mode-motion+-hook-uninstall'.
;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)
(setq buffer (or buffer (current-buffer)))
;; force the uninstall of mode-motion-highlight since if its second
;; you'll never see ours.
(setq remove-highlight-line-p t)
(save-excursion
(set-buffer buffer)
(if (boundp 'mode-motion-hook)
(progn
(setq mode-motion+-previous-hook
(cond ((sequencep mode-motion-hook)
(copy-sequence mode-motion-hook))
(t mode-motion-hook)))
;; Make sure that the mode-motion+-highlight is not saved in
;; the variable, otherwise, we could not revert back to the
;; "factory settings" after having played with different
;; handlers
;; --paquette, Mon Feb 27 08:54:21 1995 (Marc Paquette)
(remove-hook 'mode-motion+-previous-hook 'mode-motion+-highlight)))
(add-hook 'mode-motion-hook 'mode-motion+-highlight)
(and remove-highlight-line-p
;; Remove the standard mode-motion-highlight hook because we
;; provide an alternative to this. I don't use setq here because
;; something else could be hooked to mode-motion-hook.
;; --paquette, Mon Feb 27 08:53:51 1995 (Marc Paquette)
(remove-hook 'mode-motion-hook 'mode-motion-highlight-line))
(and mode-motion-extent
(delete-extent mode-motion-extent)
(setq mode-motion-extent nil))
;; Try to make this installed for any buffer of this mode
(let ((this-mode-hook (intern-soft (concat (symbol-name major-mode)
"-hook"))))
(and (boundp this-mode-hook)
(if remove-highlight-line-p
(add-hook this-mode-hook
#'(lambda () (mode-motion+-hook-install nil t))
'append)
(add-hook this-mode-hook 'mode-motion+-hook-install 'append)))))
mode-motion-hook)
(defun mode-motion+-hook-uninstall (buffer)
"Restore the value of `mode-motion-hook' in BUFFER to what it was at the time `mode-motion+-hook-install' was called.
See also `mode-motion+-hook-install'."
(interactive "bRestore `mode-motion-hook' of buffer :")
;; Check for the mode-motion-hook value to make sure it's under
;; the control of mode-motion+.
;; The reasonning here is that if the user went trough the hassles
;; of list-motion-handlers (or if he's calling this directly from
;; his .emacs) , he is prepared to give up on the current
;; mode-motion-hook.
;; However, we keep the previous hook value in a buffer-local
;; variable: it will be then possible to revert to the old motion
;; handling behavior with `mode-motion+-hook-uninstall'.
;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)
(save-excursion
(set-buffer buffer)
(and mode-motion-extent
(delete-extent mode-motion-extent)
(setq mode-motion-extent nil))
(if (boundp 'mode-motion+-previous-hook)
(progn
(setq mode-motion-hook mode-motion+-previous-hook)
(setq mode-motion+-previous-hook nil)
(let ((this-mode-hook (intern-soft (concat (symbol-name major-mode)
"-hook"))))
(and (boundp this-mode-hook)
(remove-hook this-mode-hook 'mode-motion+-hook-install))))
(error "No previous value for mode-motion-hook")))
mode-motion-hook)
(defun mode-motion+-motion-hook-revert (&optional buffer-only-p buffer mode)
"Revert the `mode-motion-hook' to its original value.
With optional arg BUFFER-ONLY-P non-nil, only revert in BUFFER
\(defaults to `\(current-buffer\)'\); otherwise, revert for all existing
buffers of MODE \(defaults to `major-mode' of BUFFER\)."
(interactive
(let* ((buffer-only-p
(y-or-n-p "Revert mode-motion-hook only for current buffer ? "))
(buffer (if buffer-only-p
(current-buffer)
(get-buffer (read-buffer-name
"Revert mode-motion-hook of buffer : "
(buffer-name (current-buffer))))))
(mode (if buffer-only-p
(save-excursion
(set-buffer buffer)
major-mode)
(intern-soft (completing-read "Major mode: "
obarray
'fboundp
nil
(symbol-name major-mode))))))
(list buffer-only-p buffer mode)))
(if buffer-only-p
(mode-motion+-hook-uninstall buffer)
(save-excursion
(mapcar (function
(lambda (buf)
(set-buffer buf)
(and (eq mode major-mode)
(mode-motion+-hook-uninstall buf))))
(buffer-list)))))
;; Setting buffer, mode and default motion handlers
(defun set-buffer-motion-handler (buffer handler-name)
"Make the motion handler named HANDLER-NAME (a symbol) the buffer
motion handler of BUFFER. If HANDLER-NAME is nil, the corresponding
buffer motion handler is removed. If HANDLER-NAME isn't the name of a
known motion handler, an error is signaled. When called interactively,
completion is provided for available buffers and motion handlers.
1.\) buffer motion handler
2.\) mode motion handler
3.\) default motion handler"
(interactive (list (read-buffer-name "Set motion handler of buffer: "
(buffer-name (current-buffer)))
(read-motion-handler-name)))
;; kill old mode motion extent, because the new handler
;; might want to initialize it differently
(if mode-motion-extent
(progn
(detach-extent mode-motion-extent)
(setq mode-motion-extent nil)))
(or buffer (setq buffer (current-buffer)))
(or (get-buffer buffer)
(error "No such buffer: %s" buffer))
(save-excursion
(set-buffer buffer)
(setq buffer-motion-handler
;; remove it if `nil'
(and handler-name
;; set the handler if known
(or (find-motion-handler handler-name)
;; error otherwise
(error "Not a known motion handler: %s"
handler-name)))))
(if (interactive-p)
(if handler-name
(message "Motion handler for buffer %s is `%s'."
(current-buffer) handler-name)
(message "Motion handler removed for buffer %s."
(current-buffer))))
handler-name)
(defun read-buffer-name (prompt &optional initial-input)
(completing-read prompt
(mapcar #'(lambda (buf) (list (buffer-name buf)))
(buffer-list))
;; don't take buffers that start with a blank
#'(lambda (list) (not (eq (aref (car list) 0) ? )))
t
initial-input))
(defun set-mode-motion-handler (mode handler-name)
"Make the motion handler named HANDLER-NAME (a symbol) the mode motion
handler for all buffers with major-mode MODE. If HANDLER-NAME is nil,
the corresponding mode motion handler is removed. If HANDLER-NAME
isn't the name of a known motion handler, an error is signaled. When
called interactively, completion is provided for available motion
handlers.
1.\) buffer motion handler
2.\) mode motion handler
3.\) default motion handler"
(interactive (list (intern (completing-read "Major mode: "
obarray
'fboundp
nil
(symbol-name major-mode)))
(read-motion-handler-name)))
;; kill old mode motion extent, because the new handler
;; might want to initialize it differently
(if mode-motion-extent
(progn
(detach-extent mode-motion-extent)
(setq mode-motion-extent nil)))
(put mode 'mode-motion-handler
;; remove it if `nil'
(and handler-name
;; set the handler if known
(or (find-motion-handler handler-name)
;; error otherwise
(error "Not a known mode motion handler: %s" handler-name))))
(if (interactive-p)
(if handler-name
(message "Motion handler for %s is `%s'." mode handler-name)
(message "Mode motion handler for %s removed." mode)))
handler-name)
(defun set-default-motion-handler (handler-name)
"Make the motion handler named HANDLER-NAME (a symbol) the default.
If HANDLER-NAME is nil, the current default motion handler is removed. If
HANDLER-NAME isn't the name of a known motion handler, an error is
signalled. When called interactively, completion is provided for available
motion handlers.
The motion handler used in a given buffer is determined by the following
most-specific first list: buffer motion handler, mode motion handler, default
motion handler."
(interactive (list (read-motion-handler-name)))
;; kill old mode motion extent, because the new handler
;; might want to initialize it differently
(if mode-motion-extent
(progn
(detach-extent mode-motion-extent)
(setq mode-motion-extent nil)))
(setq default-motion-handler
;; remove it if `nil'
(and handler-name
;; set the handler if known
(or (find-motion-handler handler-name)
;; error otherwise
(error "Not a known motion handler: %s" handler-name))))
(if (interactive-p)
(if handler-name
(message "Default motion handler is `%s'." handler-name)
(message "Default motion handler removed.")))
handler-name)
(defun read-motion-handler-name ()
(intern-soft (completing-read "Motion handler: "
(mapcar #'(lambda (entry)
(list (symbol-name (car entry))))
motion-handler-alist)
nil t)))
;; clear the last active motion extent when leaving a frame.
(defun mode-motion-clear-extent (&optional extent)
"Clear EXTENT, i.e. make it have no visible effects on the frame.
EXTENT defaults to the current buffer's mode-motion-extent."
(or extent (setq extent mode-motion-extent))
(and extent
(extent-live-p extent)
(not (extent-detached-p extent))
(extent-buffer extent)
(buffer-name (extent-buffer extent))
(progn
;; unhighlight it
(highlight-extent extent nil)
;; make it span a region that isn't visible and selectable
;; Can this be done more elegantly?
(detach-extent extent))))
(defun mode-motion-clear-last-extent (&optional frame)
"Clear the mode-motion-last-extent."
(or (popup-menu-up-p) (mode-motion-clear-extent mode-motion-last-extent)))
(defun mode-motion+-highlight (event)
"Highlight the thing under the mouse using a mode-specfic motion handler.
See list-motion-handlers for more details."
(mode-motion-clear-last-extent)
(and (event-buffer event)
(cond ((and mouse-grabbed-buffer
;; first try to do minibuffer specific highlighting
(find-motion-handler 'minibuffer)
(let ((mode-motion-highlight-lines-when-behind nil))
(and (event-point event)
(or (extent-at (event-point event)
(event-buffer event) 'highlight)
(mode-motion-highlight-with-handler
(find-motion-handler 'minibuffer) event))))))
(t (mode-motion-highlight-with-handler
(get-current-motion-handler) event))))
;; Return nil since now this is used as a hook, and we want to let
;; any other hook run after us.
nil)
(defun get-current-motion-handler ()
(or (and (boundp 'buffer-motion-handler) buffer-motion-handler)
(get major-mode 'mode-motion-handler)
default-motion-handler))
(defun mode-motion-highlight-with-handler (handler event)
;; Perform motion highlighting using HANDLER. Information about the
;; current mouse position is taken form EVENT.
(and handler
(let ((point (event-point event))
(buffer (event-buffer event))
(window (event-window event))
(window-config (current-window-configuration))
(buffer-save (current-buffer))
(point-save (point))
region)
;; save-window-excursion and restore buffer
(unwind-protect
(progn
(and buffer
(set-buffer buffer)
(select-window window))
;; Create a new mode-motion-extent if there isn't one
;; (or a destroyed one)
(if (and (extent-live-p mode-motion-extent)
(extent-buffer mode-motion-extent))
()
(setq mode-motion-extent (make-extent nil nil buffer))
(set-extent-priority mode-motion-extent 1))
(if (and
;; compute the region to be highlighted
(setq region
(if point
;; compute the mode-motion region using the
;; handlers boundary function
(condition-case nil;; c
(funcall
(motion-handler-boundary-function handler)
point)
;; Messages that appear during computing the
;; region may be displayed not done
;; here because it's rather disturbing
(error
;; (setq message (format "%s" (car (cdr c))))
nil))
;; otherwise highlight the whole line mouse is
;; behind but only if the line isn't empty
(if mode-motion-highlight-lines-when-behind
(unwind-protect
(progn
;; (message "%s" (event-window event))
(move-to-window-line
(if (and (= emacs-major-version 19)
(< emacs-minor-version 12))
(- (event-y event)
(nth 1 (window-edges window)))
(event-y event)))
(beginning-of-line)
(if (= (following-char) ?\n)
;; empty line
()
(thing-region
(point)
(progn
(end-of-line)
;; for `follow-point' behavoir
(setq point (point))
;; fetch also the newline, if any
;; -- handy for copying >1 line
(if (eobp) point (1+ point))))))
(goto-char point-save)))))
;; (message "region: %s" region)
;; the region might be in reverse order. Stop in this case
(<= (car region) (cdr region)))
(if (or (not (motion-handler-follow-point handler))
(pos-visible-in-window-p point))
(progn
(set-extent-endpoints
mode-motion-extent (car region) (cdr region))
(set-extent-face
mode-motion-extent (motion-handler-face handler))
;; make point follow the mouse or point to
;; the beginning of the line do not move the
;; cursor if a mark is set.
(cond ((and (motion-handler-follow-point handler)
(not (mark)))
(goto-char point)
;; kludge to keep the cursor out the way
(if (or (eq (motion-handler-boundary-function
handler)
'line-boundaries)
(eq (motion-handler-boundary-function
handler)
'visible-line-boundaries))
(beginning-of-line))))
(if (and mode-motion-focus-on-window
(or (eq mode-motion-focus-on-window t)
(motion-handler-follow-point handler)))
;; Select the current window FROM OUTSIDE the
;; `save-window-excursion' that surrounds the call
;; to the current function. This also avoids
;; conflicts with running process filters.
(enqueue-eval-event 'select-window
(selected-window)))
;; snap in effect, but it ain't yet workin'
;; (message "X: %sl; Y: %s"(event-x event)(event-y event))
;; (and motion-handler-snap-in
;; (set-mouse-position
;; (window-frame (event-window event))
;; (event-x event)
;; (event-y event)))
(setq mode-motion-last-extent mode-motion-extent)
;; signal success
t))
;; signal failiure
nil))
(set-window-configuration window-config)
(set-buffer buffer-save)))))
;; Motion Event debugging
;;
;; Useful to see what information is available from motion events
(defun debug-motion-handler (event)
(let* ((window (event-window event))
(frame (or (event-frame event) (selected-frame)))
(buffer (and window (event-buffer event)))
(point (and buffer (event-point event))))
(with-output-to-temp-buffer "*Debug Motion Handler Output*"
(princ
(format "\
Window: %s
Frame: %s
Buffer: %s
(event-x, event-y): (%s, %s)
(event-x-pixel, event-y-pixel): (%s, %s)
Point: %s
Timestamp: %s"
window
frame
buffer
(event-x event) (event-y event)
(event-x-pixel event) (event-y-pixel event)
point
(event-timestamp event))))))
;(let ((mouse-motion-handler 'debug-motion-handler)
; (temp-buffer-show-function nil))
; (read-char))
;; Set of copy/kill/move functions for usage with highlighted regions
(put 'mode-motion-move 'pending-delete t)
(put 'mode-motion-copy 'pending-delete t)
(defun mode-motion-move ()
"Move the motion active region to point."
(interactive)
(mode-motion-insert-text (mode-motion-copy/delete t)))
(defun mode-motion-kill ()
"Kill the motion active region and push it onto the kill ring."
(interactive)
(mode-motion-copy/delete t t t))
(defun mode-motion-copy ()
"Copy the motion active region to point."
(interactive)
(mode-motion-insert-text (mode-motion-copy/delete)))
(defun mode-motion-copy-as-kill ()
"Delete the motion active region and push it onto the kill ring.
Set point to the place where deletion happened."
(interactive)
(mode-motion-copy/delete nil t)
(message "Text copied to the to ring and cut buffer."))
(defun mode-motion-copy/delete (&optional delete copy-as-kill set-point)
"Return the string that is designated by the current motion active region.
Arguments are:
EVENT - a mouse click event used to identify the buffer and window
&optional DELETE - delete the motion active text region
COPY-AS-KILL - copy the string to the kill ring
SET-POINT - set point to the start of the motion active region."
(let ((old-buf (current-buffer))
(old-window (selected-window)))
(unwind-protect
(let ((extent (or primary-selection-extent
(and (extentp mode-motion-last-extent)
(not (extent-property mode-motion-last-extent
'detached))
mode-motion-last-extent))))
(if (and (extentp extent)
(set-buffer (extent-buffer extent))
(not
;; zero length extents
(= (extent-start-position extent)
(extent-end-position extent))))
(let* ((start (extent-start-position extent))
(end (extent-end-position extent))
(text
(buffer-substring
(extent-start-position extent)
(extent-end-position extent))))
(cond (copy-as-kill
(copy-region-as-kill start end)
(if (or (not kill-hooks)
(eq kill-hooks 'ignore))
(progn
(x-own-selection-internal 'PRIMARY text)
(x-own-clipboard text)))))
(cond (delete
(kill-region start end)
(x-own-selection-internal 'PRIMARY text)
;; (select-window window)
(if set-point
(goto-char start))))
(setq this-command 'mode-motion+)
text)
(error "No current primary or motion selection.")
))
(set-buffer old-buf)
(select-window old-window))))
(defun mode-motion-insert-text (text)
"Insert TEXT at point. Also insert one space if the
preceding character is a word constituent or a closing paren."
(or text (error "No highlighted text to copy."))
(let ((prec-char-syntax (char-syntax (preceding-char))))
(if (memq prec-char-syntax '(?w ?\))) (insert " "))
(insert text)))
;; Boundary functions
;;
;; The following functions are already provided by the thing package:
;; thing-boundaries
;; thing-symbol
;; thing-word
(defun char-boundaries (point) (thing-region point (1+ point)))
(defun visible-line-boundaries (point)
(save-excursion
(goto-char point)
(beginning-of-line)
(skip-chars-forward " \t")
(if (and (eq major-mode 'dired-mode)
(save-excursion (dired-move-to-filename)))
(let ((start (point)))
(end-of-line)
(skip-chars-backward " \t")
(thing-region start (point))))))
(defun line-boundaries (point)
(save-excursion
(goto-char point)
(beginning-of-line)
(if (and (eq major-mode 'dired-mode)
(save-excursion (dired-move-to-filename)))
(let ((start (point)))
(end-of-line)
(thing-region start (point))))))
(defun cvs-line-boundaries (point)
(save-excursion
(goto-char point)
(beginning-of-line)
(if (looking-at "^[* ] ")
(thing-region (point) (progn (end-of-line) (point))))))
(defun latex-boundaries (here)
(setq *last-thing* 'sexp)
(tex-boundaries
here ?\\ "a-zA-Z"
;; begin-fwd-regexp
"\\\\begin *{ *\\([a-z]*\\) *}"
;; end-fwd-regexp
"\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)"
;; begin-bwd-regexp
"\\\\end *{ *\\([a-z]*\\) *}"
;; begin-bwd-regexp
"\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)"
;; param-cmd-regexp
"\\\\[a-zA-Z]+[ \n\t]*{"))
(defvar texinfo-paired-commands
(mapconcat
'identity
'(
"enumerate"
"example"
"group"
"ifinfo"
"iftex"
"ignore"
"itemize"
"menu"
"quotation"
"table"
"tex"
"titlepage"
)
"\\|"))
(defvar texinfo-begin-fwd-regexp
(format "@\\(%s\\)" texinfo-paired-commands))
(defvar texinfo-end-bwd-regexp
(format "@end *\\(%s\\)" texinfo-paired-commands))
(defun texinfo-boundaries (here)
(tex-boundaries
here ?@ "a-z"
texinfo-begin-fwd-regexp
;; end-fwd-regexp
"\\(@end *%s\\)\\|\\(@%s\\)"
;; end-bwd-regexp
texinfo-end-bwd-regexp
;; begin-bwd-regexp
"\\(@end *%s\\)\\|\\(@%s\\)"
;; param-cmd-regexp
"@\\(TeX\\|[a-zA]+\\)[ \n\t]*{"))
(defun tex-boundaries
(here cmd-start-character cmd-word-character
begin-fwd-regexp end-fwd-regexp
end-bwd-regexp begin-bwd-regexp
param-cmd-regexp)
"Generic TeX dialect scanner.
Parameters:
cmd-start-character: character that starts a command
(`\' in (La)TeX, `@' in Texinfo)
cmd-word-character: regexpression to be used by the function
`skip-chars-backward' allowing to skip over command
characters other than `cmd-start-character'
begin-fwd-regexp: regexpression matching the begin part of a
text stretch, used in forward search.
end-fwd-regexp: regexpression matching the end part of a
text stretch, used in forward search
end-bwd-regexp: regexpression matching the end part of a
text stretch, used in backward search.
begin-bwd-regexp: regexpression matching the begin part of a
text stretch, used in backward search.
param-cmd-regexp: regexpression matching a parameterized command
\(including the open parenthesis\)"
(save-excursion
(goto-char here)
(cond ((= (following-char) cmd-start-character)
(forward-char 1))
((= (char-syntax (following-char)) ?w)
(skip-chars-backward cmd-word-character)))
(if (/= (preceding-char) cmd-start-character)
(thing-boundaries here)
(forward-char -1)
(catch 'return
(cond ((looking-at begin-fwd-regexp)
(let* ((start (point))
(env (buffer-substring
(match-beginning 1) (match-end 1)))
(regexp (format end-fwd-regexp env env))
(count 0))
(while (re-search-forward regexp nil t)
(cond ((match-beginning 2) ; \begin
(setq count (1+ count)))
((match-beginning 1) ; \end
(setq count (1- count))
(if (= count 0)
(throw 'return
(thing-region start (point)))))))))
((looking-at end-bwd-regexp)
(let* ((end (match-end 0))
(env (buffer-substring
(match-beginning 1) (match-end 1)))
(regexp
(format begin-bwd-regexp env env))
(count 1))
(while (re-search-backward regexp nil t)
(cond ((match-beginning 1) ; \end
(setq count (1+ count)))
((match-beginning 2) ; \begin
(setq count (1- count))
(if (= count 0)
(throw 'return (thing-region (point) end))))
))))
;; tex macros of the form \cmd {...}
((looking-at param-cmd-regexp)
(thing-region
(point)
(progn
(goto-char (1- (match-end 0)))
(forward-sexp 1)
(point))))
;; fetch the current macro (with backslash)
(t (thing-region (point) (progn (forward-word 1) (point)))))))))
;; special parse of buffer for valid selectable info
(defun minibuffer-selection-boundaries (point)
(let ((old-syntax (syntax-table)))
(unwind-protect
(progn
;; best syntax table for recognizing symbols
(set-syntax-table emacs-lisp-mode-syntax-table)
(let ((file-completion (eq minibuffer-completion-table
'read-file-name-internal))
region
minibuf-string ;contents of minibuffer
buffer-string ;string to be highlighted (or not)
prefix ;prefix calculated from minibuf-string
string ;string to be verified in the
;completion table
)
(and
(setq region (if file-completion
(thing-filename point)
(thing-symbol point)))
(setq
minibuf-string ; contents of minibuffer
(save-excursion
(set-buffer mouse-grabbed-buffer)
(buffer-string))
buffer-string ; string to be highlighted (or not)
(buffer-substring (car region) (cdr region))
prefix
(if file-completion
(file-name-nondirectory minibuf-string)
minibuf-string)
string
(if file-completion
(concat (file-name-directory minibuf-string) buffer-string)
buffer-string))
(if (or (and (fboundp 'ange-ftp-ftp-path)
(or (ange-ftp-ftp-path buffer-string)
(ange-ftp-ftp-path string)))
(and (fboundp 'efs-ftp-path)
(or (efs-ftp-path buffer-string)
(efs-ftp-path string))))
;; #### Like our counterpart in mode-motion: evil evil evil
t
(if file-completion
(try-completion string
minibuffer-completion-table
minibuffer-completion-predicate)
(eq 't (try-completion string
minibuffer-completion-table
minibuffer-completion-predicate))))
;; the result is the region to be highlighted
region)))
(set-syntax-table old-syntax))))
;; C source code scanner
(defvar c-statement-starting-keyword-regexpr
"\\(if\\|for\\|while\\|do\\|switch\\|break\\|continue\\)\\b")
(defun c-boundaries (here)
(setq *last-thing* 'sexp)
(save-excursion
(goto-char here)
(let ((following-char (following-char))
(preceding-char (preceding-char))
aux)
(if (= (char-syntax following-char) ?w)
(progn
(skip-chars-backward "a-zA-Z")
(setq aux (point))
(skip-chars-backward "\n\t ")
(if (= (preceding-char) ?#)
(forward-char -1)
(goto-char aux))))
(if (and (= following-char ?*)
(= preceding-char ?/))
(forward-char -1))
(if (and (= following-char ?/)
(= preceding-char ?*))
(forward-char -1))
(cond
((= (following-char) ?#) (c-scan-preproc-macros))
((looking-at "/\\*") ; begin comment
(let ((start (match-beginning 0)))
(if (search-forward "*/" nil t)
(thing-region start (match-end 0)))))
((looking-at "\\*/") ; end comment
(let ((end (match-end 0)))
(if (search-backward "/*" nil t)
(thing-region (match-beginning 0) end))))
((looking-at c-statement-starting-keyword-regexpr) ; if for while do etc
(thing-region (match-beginning 0)
(c-forward-statement
(buffer-substring (match-beginning 1) (match-end 1)))))
((looking-at "else\\b")
(thing-region (match-beginning 0) (c-forward-else)))
(t (if (= (char-syntax (following-char)) ?.)
(thing-region here (1+ here))
(thing-boundaries here)))))))
(defun c-scan-preproc-macros ()
(cond
((looking-at "^#[ \n\t]*include[ \n\t]*[<\"][^>\"]*[>\"]") ; #include
(thing-region (match-beginning 0) (match-end 0)))
((looking-at "^#[ \n\t]*\\(define\\|undef\\)") ; #define, #undef
(thing-region
(match-beginning 0)
(progn
(end-of-line)
(while (= (preceding-char) ?\\)
(forward-line 1)
(end-of-line))
(point))))
;; #if, #ifdef, #ifndef, #else, #elif
((looking-at "^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|else\\|elif\\)\\b")
(let ((start (match-beginning 0))
(counter 1)
match)
(goto-char (match-end 0))
(while (and (>= counter 1)
(re-search-forward
"^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"
nil t))
(setq match
(buffer-substring (match-beginning 1) (match-end 1)))
(setq counter
(if (string= match "endif")
(1- counter)
(1+ counter))))
(if (= counter 0)
(thing-region start (match-end 0)))))
((looking-at "^#[ \n\t]*endif\\b") ; #endif
(let ((end (match-end 0))
(counter 1)
match)
(goto-char (match-beginning 0))
(while (and (>= counter 1)
(re-search-backward
"^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"
nil t))
(setq match
(buffer-substring (match-beginning 1) (match-end 1)))
(setq counter
(if (string= match "endif")
(1+ counter)
(1- counter))))
(if (= counter 0)
(thing-region (match-beginning 0) end))))))
(defun c-skip-over-comment ()
(let ((aux (point)))
(skip-chars-forward "\n\t ")
(or (and (= (following-char) ?/)
(= (char-after (1+ (point))) ?*)
(search-forward "*/" nil t)
(point))
(goto-char aux))))
(defun c-forward-statement (&optional keyword)
(c-skip-over-comment)
(skip-chars-forward " \n\t")
(or keyword (setq keyword
(if (looking-at c-statement-starting-keyword-regexpr)
(buffer-substring
(match-beginning 1)
(match-end 1)))))
(if keyword
(cond ((string= keyword "if")
(c-forward-if))
((string= keyword "do")
(c-forward-do-while))
((member keyword '("for" "while" "switch"))
(c-forward-for/while/switch))
((member keyword '("break" "continue"))
(c-forward-break/continue)))
(cond ((= (following-char) ?\{)
(forward-list 1)
(point))
(t
;; Here I use that each C statement other then
;; a bloc, if, while, for, do ... ends in a `;'
(let (char)
(catch 'exit
(while t
(if (eobp) (throw 'exit nil))
(setq char (following-char))
(cond ((= (char-syntax char) ?.)
(forward-char 1)
(if (= char ?\;) (throw 'exit (point))))
(t (forward-sexp 1)
(skip-chars-forward " \n\t"))))))))))
(defun c-forward-if ()
(let (aux)
(forward-word 1) ; if
(forward-list 1)
(c-forward-statement)
(setq aux (point))
(skip-chars-forward "\n\t ")
(if (looking-at "else\\b")
(c-forward-else)
(goto-char aux))))
(defun c-forward-else ()
(forward-word 1) ; else
(c-forward-statement))
(defun c-forward-for/while/switch ()
(forward-word 1) ; for
(forward-list 1)
(c-forward-statement))
(defun c-forward-do-while ()
(forward-word 1) ; do ... while
(c-forward-statement)
(c-forward-for/while/switch))
(defun c-forward-switch ()
(forward-word 1) ; switch
(forward-list 2)
(point))
(defun c-forward-break/continue ()
(forward-word 1) ; keyword
(c-skip-over-comment)
(skip-chars-forward "\n\t ")
(if (= (following-char) ?\;)
(goto-char (1+ (point)))))
;; Tcl syntax scanner
(defvar tcl-builtin-commands nil
"Alist of information about tcl syntax for the tcl-boundaries function.
An entry has the form
\(<command-string> . <syntax description>\)
where
<command-string> is the name of a tcl command
<syntax description> is one of
list of integers: the number of possible arguments
t: any number of arguments")
(defconst tcl-commands
'(
("append" . (2 . nil))
("array" . (2 . 3))
("break" . 0)
("case" . 3)
("catch" . 1)
("cd" . 1)
("close" . 1)
("concat" . t)
("continue" . 0)
("else" . (1 . nil))
("elseif" . (1 . nil))
("eof" . 1)
("error" . t)
("eval" . t)
("exec" . t)
("exit" . (0 . 1))
("expr" . 1)
("file" . (2 . nil))
("flush" . 1)
("for" . 4)
("foreach" . 3)
("format" . (1 . nil))
("gets" . (1 . 2))
("glob" . t)
("global" . (1 . nil))
("history" . t)
("if" . (2 . nil))
("incr" . (1 . 2))
("info" . (1 . 4))
("join" . (1 . 2))
("lappend" . (2 . nil))
("lindex" . 2)
("linsert" . (3 . nil))
("list" . t)
("llength" . 1)
("lrange" . 3)
("lreplace" . (3 . nil))
("lsearch" . 2)
("lsort" . 1)
("open" . (1 . 2))
("proc" . 3)
("puts" . (1 . 3))
("pwd" . 0)
("read" . (1 . 2))
("regexp" . (2 . nil))
("regsub" . (4 . 6))
("rename" . 2)
("return" . (0 .1))
("scan" . (3 . nil))
("seek" . (2 . 3))
("set" . (1 . 2))
("source" . 1)
("split" . (1 . 2))
("string" . (2 . 4))
("tell" . 1)
("time" . (1 .2))
("trace" . (1 . nil))
("unknown" . (1 . nil))
("unset" . (1 . nil))
("uplevel" . (1 . nil))
("upvar" . (2 . nil))
("while" . 2)
))
(defconst tk-commands
'(("bind" . 3)
("button" . t)
("canvas" . t)
("frame" . t)
("label" . t)
("listbox" . t)
("menu" . t)
("menubutton" . t)
("pack" . t)
("scrollbar" . t)
("tree" . t)
("wm" . t)
))
(defconst tcl-tk-commands
(nconc tcl-commands tk-commands))
(defconst tcl-tk-commands-regexp
(format "\\(%s\\\)\\W" (mapconcat 'car tcl-tk-commands "\\|")))
(defun tcl-boundaries (here)
(save-excursion
(goto-char here)
(skip-chars-backward "a-z")
(if (looking-at
tcl-tk-commands-regexp)
(let* ((count 0)
(start (point))
(keyword (buffer-substring
(match-beginning 1)
(match-end 1)))
(syntax-description
(cdr (assoc keyword tcl-tk-commands))))
(goto-char (match-end 0))
(while (not (looking-at "[ \t]*[]\n;}]"))
(setq count (1+ count))
(tcl-forward-sexp1)
;; skipping over the parentheses of array expressions:
(while (not (or (looking-at "[ \t]*[]\n;}]")
(= (char-syntax (following-char)) ? )))
(tcl-forward-sexp1)))
(if (cond ((eq syntax-description t))
((integerp syntax-description)
(= syntax-description count))
((consp syntax-description)
(and (<= (car syntax-description) count)
(or (null (cdr syntax-description))
(<= count (cdr syntax-description))))))
(progn
(message "`%s' matched." keyword)
(thing-region start (point)))
(progn
(message "wrong syntax: `%s'." keyword)
nil)))
(message "")
(thing-boundaries here))))
(defun tcl-forward-sexp (&optional arg)
"Move forward across one balanced tcl expression.
With argument, do it that many times."
(interactive "p")
(if (< arg 0) (error "negative argument not allowed"))
(or arg (setq arg 1))
(while (> arg 0)
(tcl-forward-sexp1)
(setq arg (1- arg))))
(defun tcl-forward-sexp1 ()
(interactive "")
(let ((start (point))
next-char syntax (first-scan t))
(setq next-char (following-char)
syntax (char-syntax next-char))
(while (or (= next-char ?\;)
(memq syntax '(? ?>)))
(forward-char 1)
(setq next-char (following-char)
syntax (char-syntax next-char)))
(condition-case var
(catch 'exit
(while t
(setq next-char (following-char)
syntax (char-syntax next-char))
(cond ((= next-char ?\;)
(throw 'exit nil))
((memq syntax (if first-scan '(? ?>) '(? ?> ?\))))
(throw 'exit nil))
(t
(goto-char (or (scan-sexps (point) 1)
(point-max)))))
(setq first-scan nil)))
(error (goto-char start)
(error (car (cdr var)))))))
;; (define-key tcl-mode-map "\M-\C-f" 'tcl-forward-sexp)
(defun mode-motion-eval-func (eval-func)
(let ((old-buf (current-buffer))
(old-window (selected-window)))
(unwind-protect
(let ((extent (or primary-selection-extent
(and (extentp mode-motion-last-extent)
(not (extent-property mode-motion-last-extent
'detached))
mode-motion-last-extent))))
(if (and (extentp extent)
(set-buffer (extent-buffer extent))
(not
;; zero length extents
(= (extent-start-position extent)
(extent-end-position extent))))
(let* ((start (extent-start-position extent))
(end (extent-end-position extent)))
(funcall eval-func start end))
(error "No current primary or motion selection.")
))
(set-buffer old-buf)
(select-window old-window))))
(defun mode-motion-eval-region ()
(interactive)
(mode-motion-eval-func 'eval-region))
;; Motion highlight faces and initialization.
(defun sect-handler (string)
"Return the symbol corresponding to the foo-STRING handler for this sect."
(intern-soft (concat (symbol-name mode-motion+-religion) string)))
(defun mode-motion-init-handlers-according-to-religion (&optional forcep)
(interactive)
;; Initialise default motion handlers depending on religious sect!
(let ((foo-thing (sect-handler "-thing"))
(foo-c (sect-handler "-c"))
(foo-LaTeX (sect-handler "-laTeX"))
(foo-line@ (sect-handler "-line@"))
(foo-vline@ (sect-handler "-vline@")))
(if forcep
(progn
(setq default-motion-handler (find-motion-handler foo-thing))
(set-mode-motion-handler 'emacs-lisp-mode foo-thing)
(set-mode-motion-handler 'lisp-interaction-mode foo-thing)
(set-mode-motion-handler 'c-mode foo-c)
(set-mode-motion-handler 'c++-mode foo-c)
(set-mode-motion-handler 'c++-c-mode foo-c)
(set-mode-motion-handler 'tex-mode foo-LaTeX)
(set-mode-motion-handler 'latex-mode foo-LaTeX)
(set-mode-motion-handler 'Buffer-menu-mode foo-vline@)
(set-mode-motion-handler 'Electric-Buffer-menu-mode foo-vline@)
(set-mode-motion-handler 'gnus-Group-mode foo-vline@)
(set-mode-motion-handler 'gnus-Subject-mode foo-vline@)
(set-mode-motion-handler 'gnus-group-mode foo-vline@)
(set-mode-motion-handler 'gnus-subject-mode foo-vline@)
(set-mode-motion-handler 'gnus-summary-mode foo-vline@)
(set-mode-motion-handler 'dired-mode foo-line@)
(set-mode-motion-handler 'compilation-mode foo-line@)
(set-mode-motion-handler 'occur-mode foo-line@)
(set-mode-motion-handler 'tar-mode foo-vline@)
(set-mode-motion-handler 'rmail-summary-mode foo-vline@)
(set-mode-motion-handler 'vm-summary-mode (sect-handler "-line"))
(set-mode-motion-handler 'tcl-mode (sect-handler "-tcl"))
(set-mode-motion-handler 'texinfo-mode (sect-handler "-TeXinfo"))
(set-mode-motion-handler 'cvs-mode (sect-handler "-cvs-line")))
(setq default-motion-handler
(or default-motion-handler (find-motion-handler foo-thing)))
(or (get 'emacs-lisp-mode 'mode-motion-handler)
(set-mode-motion-handler 'emacs-lisp-mode foo-thing))
(or (get 'lisp-interaction-mode 'mode-motion-handler)
(set-mode-motion-handler 'lisp-interaction-mode foo-thing))
(or (get 'c-mode 'mode-motion-handler)
(set-mode-motion-handler 'c-mode foo-c))
(or (get 'c++-mode 'mode-motion-handler)
(set-mode-motion-handler 'c++-mode foo-c))
(or (get 'c++-c-mode 'mode-motion-handler)
(set-mode-motion-handler 'c++-c-mode foo-c))
(or (get 'tex-mode 'mode-motion-handler)
(set-mode-motion-handler 'tex-mode foo-LaTeX))
(or (get 'latex-mode 'mode-motion-handler)
(set-mode-motion-handler 'latex-mode foo-LaTeX))
(or (get 'Buffer-menu-mode 'mode-motion-handler)
(set-mode-motion-handler 'Buffer-menu-mode foo-vline@))
(or (get 'Electric-Buffer-menu-mode 'mode-motion-handler)
(set-mode-motion-handler 'Electric-Buffer-menu-mode foo-vline@))
(or (get 'gnus-Group-mode 'mode-motion-handler)
(set-mode-motion-handler 'gnus-Group-mode foo-vline@))
(or (get 'gnus-Subject-mode 'mode-motion-handler)
(set-mode-motion-handler 'gnus-Subject-mode foo-vline@))
(or (get 'gnus-group-mode 'mode-motion-handler)
(set-mode-motion-handler 'gnus-group-mode foo-vline@))
(or (get 'gnus-subject-mode 'mode-motion-handler)
(set-mode-motion-handler 'gnus-subject-mode foo-vline@))
(or (get 'gnus-summary-mode 'mode-motion-handler)
(set-mode-motion-handler 'gnus-summary-mode foo-vline@))
(or (get 'dired-mode 'mode-motion-handler)
(set-mode-motion-handler 'dired-mode foo-line@))
(or (get 'compilation-mode 'mode-motion-handler)
(set-mode-motion-handler 'compilation-mode foo-line@))
(or (get 'occur-mode 'mode-motion-handler)
(set-mode-motion-handler 'occur-mode foo-line@))
(or (get 'tar-mode 'mode-motion-handler)
(set-mode-motion-handler 'tar-mode foo-vline@))
(or (get 'rmail-summary-mode 'mode-motion-handler)
(set-mode-motion-handler 'rmail-summary-mode foo-vline@))
(or (get 'vm-summary-mode 'mode-motion-handler)
(set-mode-motion-handler 'vm-summary-mode (sect-handler "-line")))
(or (get 'tcl-mode 'mode-motion-handler)
(set-mode-motion-handler 'tcl-mode (sect-handler "-tcl")))
(or (get 'texinfo-mode 'mode-motion-handler)
(set-mode-motion-handler 'texinfo-mode (sect-handler "-TeXinfo")))
(or (get 'cvs-mode 'mode-motion-handler)
(set-mode-motion-handler 'cvs-mode (sect-handler "-cvs-line"))))))
;; Null Handlers (for disabling motion highlighting)
(defun thing-null (here) nil)
(make-motion-handler 'no-thing 'thing-null)
(make-motion-handler 'no-c 'thing-null)
(make-motion-handler 'no-laTeX 'thing-null)
(make-motion-handler 'no-line 'thing-null)
(make-motion-handler 'no-line@ 'thing-null)
(make-motion-handler 'no-vline 'thing-null)
(make-motion-handler 'no-vline@ 'thing-null)
(make-motion-handler 'no-tcl 'thing-null)
(make-motion-handler 'no-TeXinfo 'thing-null)
(make-motion-handler 'no-cvs-line 'thing-null)
(defun mode-motion-init ()
"enable mode-motion+ package"
(interactive)
(setq mode-motion-last-extent nil)
(global-set-key '(meta button2) 'mode-motion-copy)
(global-set-key '(meta shift button2) 'mode-motion-move)
(global-set-key '(meta control button2) 'mode-motion-kill)
(global-set-key '(meta control shift button2) 'mode-motion-copy-as-kill)
(global-set-key '(meta control symbol button2) 'mode-motion-copy-as-kill)
(if mode-motion-setup-cut-and-paste-bindings
(progn
(global-set-key 'f16 'mode-motion-copy-as-kill) ; Copy
(global-set-key 'f18 'yank) ; Paste
(global-set-key 'f20 'mode-motion-kill))) ; Cut
;; I don't want the thing-boundaries function select whitespaces
(setq thing-report-whitespace nil thing-report-char-p nil)
;; bold motion face (bold, if this is not the default, unbold otherwise)
(if (find-face 'motion-bold)
()
(make-face 'motion-bold)
(make-face-bold 'motion-bold)
(or (face-differs-from-default-p 'motion-bold)
(make-face-unbold 'motion-bold)))
;; an underline face
(if (find-face 'motion-underline)
()
(make-face 'motion-underline)
(set-face-underline-p 'motion-underline t))
;; an inverted face
(if (find-face 'motion-inverted)
()
(make-face 'motion-inverted)
(make-face-bold 'motion-inverted)
(invert-face 'motion-inverted))
(if (find-face 'motion-gray)
()
(make-face 'motion-gray)
(set-face-background-pixmap 'motion-gray "gray1.xbm"))
;; Motion Handlers
;; Special Minibuffer handler
(make-motion-handler 'minibuffer 'minibuffer-selection-boundaries 'highlight t nil)
;; Things
(make-motion-handler 'bold-thing 'thing-boundaries 'motion-bold)
(make-motion-handler 'gray-thing 'thing-boundaries 'motion-gray)
(make-motion-handler 'highlight-thing 'thing-boundaries 'highlight)
(make-motion-handler 'invert-thing 'thing-boundaries 'motion-inverted)
(make-motion-handler 'underline-thing 'thing-boundaries 'motion-underline)
;; Lines
(make-motion-handler 'bold-line 'line-boundaries 'motion-bold)
(make-motion-handler 'gray-line 'line-boundaries 'motion-gray)
(make-motion-handler 'highlight-line 'line-boundaries 'highlight)
(make-motion-handler 'invert-line 'line-boundaries 'motion-inverted)
(make-motion-handler 'underline-line 'line-boundaries 'motion-underline)
(make-motion-handler 'bold-line@ 'line-boundaries 'motion-bold t t)
(make-motion-handler 'gray-line@ 'line-boundaries 'motion-gray nil t)
(make-motion-handler 'highlight-line@ 'line-boundaries 'highlight nil t)
(make-motion-handler 'invert-line@ 'line-boundaries 'motion-inverted nil t)
(make-motion-handler 'underline-line@ 'line-boundaries 'motion-underline nil t)
;; Visible text of line
(make-motion-handler 'bold-vline 'visible-line-boundaries 'motion-bold)
(make-motion-handler 'gray-vline 'visible-line-boundaries 'motion-gray)
(make-motion-handler 'highlight-vline 'visible-line-boundaries 'highlight)
(make-motion-handler 'invert-vline 'visible-line-boundaries 'motion-inverted)
(make-motion-handler 'underline-vline 'visible-line-boundaries 'motion-underline)
(make-motion-handler 'bold-vline@ 'visible-line-boundaries 'motion-bold t t)
(make-motion-handler 'gray-vline@ 'visible-line-boundaries 'motion-gray nil t)
(make-motion-handler 'highlight-vline@ 'visible-line-boundaries 'highlight nil t)
(make-motion-handler 'invert-vline@ 'visible-line-boundaries 'motion-inverted nil t)
(make-motion-handler 'underline-vline@ 'visible-line-boundaries 'motion-underline nil t)
;; CVS lines
(make-motion-handler 'bold-cvs-line 'cvs-line-boundaries 'motion-bold)
(make-motion-handler 'gray-cvs-line 'cvs-line-boundaries 'motion-gray)
(make-motion-handler 'highlight-cvs-line 'cvs-line-boundaries 'highlight)
(make-motion-handler 'invert-cvs-line 'cvs-line-boundaries 'motion-inverted)
(make-motion-handler
'underline-cvs-line 'cvs-line-boundaries 'motion-underline)
;; (La)TeX
(make-motion-handler 'bold-LaTeX 'latex-boundaries 'motion-bold)
(make-motion-handler 'gray-LaTeX 'latex-boundaries 'motion-gray)
(make-motion-handler 'highlight-LaTeX 'latex-boundaries 'highlight)
(make-motion-handler 'invert-LaTeX 'latex-boundaries 'motion-inverted)
(make-motion-handler 'underline-LaTeX 'latex-boundaries 'motion-underline)
;; TeXinfo
(make-motion-handler 'bold-TeXinfo 'texinfo-boundaries 'motion-bold)
(make-motion-handler 'gray-TeXinfo 'texinfo-boundaries 'motion-gray)
(make-motion-handler 'highlight-TeXinfo 'texinfo-boundaries 'highlight)
(make-motion-handler 'invert-TeXinfo 'texinfo-boundaries 'motion-inverted)
(make-motion-handler 'underline-TeXinfo 'texinfo-boundaries 'motion-underline)
;; C and C++
(make-motion-handler 'bold-c 'c-boundaries 'motion-bold)
(make-motion-handler 'gray-c 'c-boundaries 'motion-gray)
(make-motion-handler 'highlight-c 'c-boundaries 'highlight)
(make-motion-handler 'invert-c 'c-boundaries 'motion-inverted)
(make-motion-handler 'underline-c 'c-boundaries 'motion-underline)
;; Tcl/Tk
(make-motion-handler 'bold-tcl 'tcl-boundaries 'motion-bold)
(make-motion-handler 'gray-tcl 'tcl-boundaries 'motion-gray)
(make-motion-handler 'highlight-tcl 'tcl-boundaries 'highlight)
(make-motion-handler 'invert-tcl 'tcl-boundaries 'motion-inverted)
(make-motion-handler 'underline-tcl 'tcl-boundaries 'motion-underline)
;; mouse tracker
(make-motion-handler 'track-mouse@ 'char-boundaries nil nil t)
(make-motion-handler 'highlight-char 'char-boundaries 'highlight)
;; augment the basic mouse motion handler (if any)
(setq-default mode-motion-hook
(if (listp mode-motion-hook)
(if (memq #'mode-motion+-highlight mode-motion-hook)
mode-motion-hook
(append mode-motion-hook (list #'mode-motion+-highlight)))
(list mode-motion-hook #'mode-motion+-highlight)))
(or mode-motion+-religion
(setq mode-motion+-religion (if (x-display-color-p) 'underline 'invert)))
(add-menu '("Options") (car mode-motion+-options-menu)
(cdr mode-motion+-options-menu)
"Paren Highlighting")
;; shut your eyes, this is a kludge. I didn't have time to find/write
;; a function to do this.
(or (member ["Eval Motion Region" mode-motion-eval-region t]
lisp-interaction-mode-popup-menu)
(and (setq lisp-interaction-mode-popup-menu
(copy-sequence lisp-interaction-mode-popup-menu))
(setcdr (nthcdr 1 lisp-interaction-mode-popup-menu)
(cons ["Eval Motion Region" mode-motion-eval-region t]
(nthcdr 2 lisp-interaction-mode-popup-menu)))))
(or (member ["Eval Motion Region" mode-motion-eval-region t]
emacs-lisp-mode-popup-menu)
(and (setq emacs-lisp-mode-popup-menu
(copy-sequence emacs-lisp-mode-popup-menu))
(setcdr (nthcdr 3 emacs-lisp-mode-popup-menu)
(cons ["Eval Motion Region" mode-motion-eval-region t]
(nthcdr 4 emacs-lisp-mode-popup-menu)))))
;; Clear the last active motion extent when leaving a frame.
(if (boundp 'mouse-leave-frame-hook)
(add-hook 'mouse-leave-frame-hook 'mode-motion-clear-last-extent)
(add-hook 'mouse-leave-screen-hook 'mode-motion-clear-last-extent))
(run-hooks 'mode-motion+-load-hook)
(mode-motion-init-handlers-according-to-religion)
(if (interactive-p) (message "mode-motion+ enabled")))
(if (and (not purify-flag)
(or (not (boundp 'opt-mode-motion+)) opt-mode-motion+))
(mode-motion-init))
(provide 'mode-motion+)
;; end mode-motion+
|